Skip to content

fix(types,docs): AutoNumberFieldMetadata declares the spec's autonumberFormat, and the auto-number page teaches it (objectui#12282) - #12298

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-12282-autonumber-format-type
Oct 13, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-12282-autonumber-format-type

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #12282

Clause-②: yes

AutoNumberFieldMetadata (@object-ui/types) declares autonumberFormat, typed by reference to @objectstack/spec's FieldSchema.autonumberFormat, and keeps format as the shorthand. The auto-number docs page teaches autonumberFormat for a new field and format as the shorthand, and says which one wins.

What changed

  • packages/types/src/field-types.ts, AutoNumberFieldMetadata only.
    • New member autonumberFormat?: SpecField['autonumberFormat'], in the file's existing by-reference idiom (import type { Field as SpecField } from '@objectstack/spec/data').
    • Its docblock states the spec's precedence: a non-empty autonumberFormat, then a non-empty format, then the contract default {0000}. That is what resolveAutonumberFormat (@objectstack/spec/data) does.
    • format?: string stays, with a new docblock calling it the shorthand.
    • The starting_number tombstone's docblock now says the number is minted from autonumberFormat or its shorthand format.
  • content/docs/fields/auto-number.mdx.
    • Both typed literals (invoiceNumber, orderNumber) carry autonumberFormat.
    • One new paragraph under the first literal teaches format as the older shorthand (format: 'INV-{0000}'). It also says autonumberFormat wins when a field sets both.
    • The nine Format Templates lines change their key from format: to autonumberFormat:. Every pattern and its comment is unchanged: the nine pattern and comment pairs were compared by script before and after, and they are equal.
    • PR objectui#12280's token list (Format Placeholders) and renderer text (Backend Implementation) are untouched.
  • New pin packages/types/src/__tests__/autonumber-format-declared-12282.test.ts.
    • Type half, read by type-check through tsconfig.test.json: the member equals SpecField['autonumberFormat']. Fresh literals carrying autonumberFormat, format (the control) and both keys compile.
    • Runtime half, against the installed spec: FieldSchema.safeParse accepts all three literals, behind a control that refuses an undeclared key by name. resolveAutonumberFormat returns autonumberFormat when both keys are set, and format when it is alone.
    • The objectui#12242 pin file is not edited.
  • .changeset/12282-types-autonumber-format.md: @object-ui/types, minor.

Premises checked against main before the edit

  • AutoNumberFieldMetadata declared type: 'autonumber', format?: string and starting_number?: never, and no autonumberFormat.
  • The installed @objectstack/spec is 17.7.0. Its FieldSchema declares autonumberFormat: z.string().optional(). Its format describe calls format "the shorthand that predates autonumberFormat, which wins when both are present".
  • resolveAutonumberFormat takes a non-empty autonumberFormat, then a non-empty format, then {0000}. Probed: { autonumberFormat: 'A-{0000}', format: 'F-{0000}' } gives A-{0000}, and { autonumberFormat: '', format: 'F' } gives F.
  • The spec's own field forms offer autonumberFormat when type == 'autonumber'. app-shell's predicate.test.ts lists it among the Studio sub-fields.

Clause-② reading: the built .d.ts, base vs head

I measured this with the TypeScript compiler API on packages/types/dist, built at base 5d3f437a (the main tip this branch merges) and at head aae05a1a:

  • Export closure: unchanged. All 12 exports entries resolve and export the same names: 1222 entry and name pairs, the same set at base and head. The same reading at the original base, 45ae6b89 against e9325f4c, gave the same result.
  • AutoNumberFieldMetadata members: exactly one is added, autonumberFormat?: string | undefined. No member is removed or retyped.

Reverse check (one-off, no permanent test file)

I started from the committed implementation (e9325f4c). objectstack's scripts/ablation-replace.mjs deleted the declaration line autonumberFormat?: SpecField['autonumberFormat'];: the anchor hit once and went from 1 to 0, and the blob went from a067fe16 to 19c4a973. The tool held the mutation while these legs ran:

  • tsc -p tsconfig.test.json (the type-check test leg): exit 2. TS2353 on both fresh literals that carry autonumberFormat, and TS2339 on the by-reference assertion and the two runtime reads.
  • check:doc-snippets: I rebuilt @object-ui/types with the mutation, and the declaration count in dist/field-types.d.ts read 0. The gate then exited 1: 789 of 789 blocks judged, 2 failed. Both failures are the typed literals on content/docs/fields/auto-number.mdx, with TS2353.
  • The pin's vitest half stayed green (5 passed). That is the expected direction: it reads the installed spec, not the type.
  • Restore: the blob equals HEAD, git diff HEAD is empty, and git status --porcelain is empty. I rebuilt the package from HEAD, and the declaration count in dist read 1 again.

Gates (all on head aae05a1a, after merging origin/main, which includes PR objectui#12293)

  • The check:doc-snippets --build-filter closure (34 filters, which includes @object-ui/types), built with turbo run build --concurrency=2 under the shared verify lock: 35 of 35 tasks, VERDICT command-exit 0.
  • pnpm --filter @object-ui/types type-check, which echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json: exit 0. The new pin is in the tsconfig.test.json program (--listFilesOnly).
  • pnpm exec vitest run packages/types/: 374 files, 10237 tests passed. The new pin run alone: 5 passed.
  • pnpm check:doc-snippets: exit 0, "Semantic phase: 790 of 790 block(s) judged, 0 failed."
  • pnpm check:doc-examples: exit 0, "Every covered @example compiles, or fails exactly as its ledger row declares."
  • node scripts/check-doc-links.mjs: exit 0, "Links are valid across 17 scan roots."
  • Each exited 0:
    • check:doc-fences, check:doc-types, check:doc-json, check:doc-example-ids
    • check:readme-exports, check:spec-symbols
    • check:changeset-claims, check:pending-changeset-literals, node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-presence.mjs (1 changeset declared for 1 released package)
    • check:control-bytes
    • check:new-line-citations: "0 new citation(s)"
    • type-check:coverage, check:test-path-roots
  • pnpm exec vitest run scripts/__tests__/: 187 files passed and 2 skipped; 5632 tests passed and 2 skipped; VERDICT command-exit 0.
  • node scripts/check-governed-queue-guard.mjs --test on the four changed paths: NOT GOVERNED.
  • ESLint, narrowed to the touched package and shown to exclude nothing:
    1. Population, from eslint's own configuration: CI's pnpm lint is turbo run lint, and @object-ui/types' lint script is eslint . against the root eslint.config.js. I ran that same eslint . in packages/types.
    2. Count, from --format json: 455 files, 0 errors. field-types.ts has 3 no-explicit-any warnings, the same 3 as at base. The new pin has none.
    3. Invariance: eslint.config.js sets no parserOptions.project or projectService, so type-aware linting is not enabled. This diff therefore cannot move the verdict on any file it does not touch. The .mdx and .md files fall outside eslint's **/*.{ts,tsx} rule blocks.

Acceptance notes

  • PR objectui#12293 (objectui#12242) landed in main during this run and is merged into this branch. Its diff and this one touch disjoint interfaces in field-types.ts. It adds no member-level census over AutoNumberFieldMetadata, so autonumberFormat owes no row there.
  • strict-face-read-keys-11070.test.ts records keys that a registered renderer reads on form.fields[] entries. No renderer reads autonumberFormat: the backend mints the value, and AutoNumberField prints it as stored. So it is not added there.
  • The @object-ui/types README lists no AutoNumberFieldMetadata keys, so it is unchanged.
  • resolveCellRendererType (@object-ui/fields) reads a field's format generically, but only acts on textual base types. So format never changes how an autonumber cell draws. Noted, not a finding.

Session: https://claude.ai/code/session_015YrgVw7e65cs1ndbebt46G


Generated by Claude Code

…erFormat, and the auto-number page teaches it (objectui#12282)

`AutoNumberFieldMetadata` declares `autonumberFormat`, typed by reference
to `@objectstack/spec`'s `FieldSchema.autonumberFormat`, the key the spec
prefers on a new field. `format` stays, documented as the shorthand that
predates it; when a field sets both, `autonumberFormat` wins
(`resolveAutonumberFormat`). The auto-number docs page's typed literals
and format templates use `autonumberFormat`, and one line teaches
`format` as the shorthand.

Claude-Session: https://claude.ai/code/session_015YrgVw7e65cs1ndbebt46G
Co-authored-by: Claude <noreply@anthropic.com>
…tonumber-format-type

Brings in PR objectui#12293 (objectui#12242), which edits other
interfaces in packages/types/src/field-types.ts.

Claude-Session: https://claude.ai/code/session_015YrgVw7e65cs1ndbebt46G
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation package: types tests labels Oct 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 72 chunks) 3131.3 KB 3204.6 KB
Main entry chunk (gzip) 73.5 KB 350 KB
Entry file index-DpRVHUwk.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 20.69KB 7.62KB
app-shell (runtime-config.js) 22.59KB 7.89KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 41.19KB 11.12KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.26KB 8.03KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.28KB 2.60KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (commentAuthorship.js) 1.39KB 0.78KB
collaboration (index.js) 1.93KB 0.85KB
collaboration (useCollaborationTranslation.js) 6.50KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 588.51KB 141.71KB
core (index.js) 10.18KB 4.04KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 244.49KB 68.27KB
fields (index.js) 279.76KB 71.33KB
i18n (LocalizationContext.js) 2.92KB 1.42KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.52KB 2.39KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 36.87KB 9.88KB
i18n (useSafeTranslation.js) 7.14KB 2.92KB
layout (index.js) 40.26KB 11.71KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 15.35KB 5.51KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.82KB 2.38KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.04KB 3.92KB
plugin-calendar (index.js) 54.31KB 15.86KB
plugin-charts (index.js) 84.72KB 23.27KB
plugin-chatbot (index.js) 201.72KB 48.07KB
plugin-dashboard (index.js) 143.63KB 38.79KB
plugin-designer (index.js) 233.77KB 50.02KB
plugin-detail (index.js) 254.49KB 67.01KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 178.28KB 46.22KB
plugin-gantt (index.js) 178.63KB 45.19KB
plugin-grid (index.js) 255.12KB 70.93KB
plugin-kanban (index.js) 53.23KB 16.71KB
plugin-list (index.js) 123.35KB 31.54KB
plugin-map (index.js) 27.24KB 9.03KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 45.65KB 12.81KB
plugin-timeline (index.js) 39.21KB 11.85KB
plugin-tree (index.js) 15.07KB 5.33KB
plugin-view (index.js) 92.11KB 23.27KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 12.07KB 3.68KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 120.63KB 39.56KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.31KB 2.07KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.07KB 1.30KB
sdui-parser (index.js) 7.30KB 3.12KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.81KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 23.87KB 7.83KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (authoring-nodes.js) 0.20KB 0.19KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (cloud.js) 0.20KB 0.18KB
types (complex.js) 4.44KB 2.07KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (dashboard-widget-layout.js) 2.06KB 0.96KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 1.13KB 0.65KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 5.78KB 2.70KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (node-slots.js) 7.18KB 2.34KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.93KB 7.26KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.48KB 3.50KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: aae05a1ad64768014b24888b05f038233145019c
Local-runs: none

Read at 2026-10-13T03:34Z · PR objectui#12298 (draft, base main, head repo = base repo, 4 files, +144/−15) against card objectui#12282 · triage 6135734642 · serial note 6135879674 · claim 6136988134 · dev report 6137456997. Inputs: the card body and all 4 comments, the PR body, its 4-file list, the net diff against main (5d3f437a) at the head, and the head's check-runs. The head is a merge of main (which brought PR objectui#12293) onto the implementation commit e9325f4c; the net diff against main was judged (236 diff lines, byte-identical between the API's diff and a fetch of the branch), not the merge commit. The spec premises were read at the @objectstack/spec 17.7.0 version commit in the sibling checkout, which is the version packages/types/package.json and the lockfile resolve on this head. Nothing was built, run or re-run.

① Derived judgments

Every accept-set and public-surface change the diff implies, each judged:

  1. AutoNumberFieldMetadata gains autonumberFormat?: SpecField['autonumberFormat'] — RIGHT. The spec's FieldSchema at 17.7.0 declares autonumberFormat: z.string().optional(), with the contract default {0000} as a JSON-Schema annotation rather than a parse-time default, and Field is the z.input of FieldSchema, so the member resolves to string | undefined and tracks the spec by reference (objectui AGENTS.md #0.1: declare a key the spec owns by reference, not by retyping) in the file's existing import type { Field as SpecField } from '@objectstack/spec/data' idiom. The widening is the one the card asked for: a fresh typed literal carrying autonumberFormat now compiles where it failed TS2353. The new pin autonumber-format-declared-12282.test.ts holds both halves: the Equal assertion of AutoNumberFieldMetadata['autonumberFormat'] against SpecField['autonumberFormat'] is compiled by the package's type-check through tsconfig.test.json (its include is src/**/*.test.ts, which this file matches), and the runtime half parses the three fresh literals through the installed FieldSchema behind a control that refuses an undeclared key by name.

  2. format?: string stays — RIGHT. Triage 6135734642 answered the card's own question (⛔ format is not retired: dropping it would make the type refuse a key the spec accepts). The spec's format describe at 17.7.0 says what the new docblock says: on an autonumber field it is the record-number pattern, the shorthand that predates autonumberFormat, which wins when both are present; prefer autonumberFormat on a new field. The member's type did not move (pinned Equal to string | undefined); only its docblock was written. Observation, not a finding: format stays a bare string rather than SpecField['format']; the two are the same type today, and the card scoped autonumberFormat only.

  3. The precedence stated in the docblocks, the page and the changeset — RIGHT. resolveAutonumberFormat at 17.7.0 takes a non-empty string autonumberFormat, then a non-empty string format, then DEFAULT_AUTONUMBER_FORMAT ({0000}), and @objectstack/spec/data exports it (export * from './autonumber-format'). The pin re-derives "wins when both" and "format is read only without it" on the installed spec on every run rather than asserting it in prose (完善设计器的每一个细节 #9).

  4. No other public-surface or accept-set change — RIGHT. field-types.ts adds no export; the starting_number?: never tombstone changes docblock only; the barrel packages/types/src/index.ts is untouched. The new test file's exports publish nothing: the build program excludes tests and tsconfig.test.json is noEmit. objectui has no zod face that enumerates AutoNumberFieldMetadata's keys — a form.fields[] entry parses through the spec's own FieldSchema, which already accepts autonumberFormat, so StrictAnyComponentSchema is asked no new question and strict-face-read-keys-11070.test.ts owes no row: no registered renderer reads the key (AutoNumberField prints the stored value; resolveCellRendererType reads format only when the base type is in TEXTUAL_BASE_TYPES, which autonumber is not). The dev's compiler-API reading of the built .d.ts (export closure unchanged, exactly one member added) agrees with the diff.

  5. content/docs/fields/auto-number.mdx — RIGHT. Both typed literals and the nine plaintext Format Templates lines carry autonumberFormat; one new paragraph teaches format as the older shorthand and says autonumberFormat wins when a field sets both — the spec's own sentence. Checked line by line against the diff: the nine pattern-and-comment pairs are unchanged, only the key moved; the Format Placeholders token list and the Backend Implementation text from PR objectui#12280 are untouched; the Field Schema prose now names the key. The two ts blocks are compiled against the built @object-ui/types by check:doc-snippets, which runs inside Repo Gates (success on this head). The three schema-catalog examples the page embeds are renderer forms carrying no format key and are untouched.

  6. Scope — inside the claim's file surface — RIGHT. The four files are exactly the claim's declared surface (AutoNumberFieldMetadata only in field-types.ts, the page, one new pin that is not field-metadata-family-retired-12242.test.ts, the changeset); the @object-ui/types README lists no AutoNumberFieldMetadata keys, so leaving it alone is right. No content/docs/releases/ or CHANGELOG.md edit; no governed path (Governed Surface Queue Guard success). Fixes #12282 on the first line is right: triage's direction — the type declares, the page teaches both and says which wins, the pins, the changeset — is delivered whole, so the card closes with the merge.

② Semver level

  • .changeset/12282-types-autonumber-format.md declares '@object-ui/types': minor — RIGHT. A member is added to a published type of a released package (@object-ui/types is not private); patch would understate a widened authoring face; objectui's fixed group never declares major (Changeset Bump Policy success). The only released package whose source changed is @object-ui/types (Changeset Declaration success: one changeset declared for one released package); content/docs/** is no published package.
  • Clause-②: yes on the PR body (its own line, at line start) and on claim 6136988134 — RIGHT: the diff widens the published authoring face with a new optional member, no narrowing arm. yes takes at least minor, and minor is what the changeset declares. The changeset body carries the same marker, as this repository's other pending changesets do; no ADR-0087 disposition is owed because nothing is removed or renamed.
  • The changeset body names the shape before and after, says format is not retired and which key wins, and names the pin; it carries no model identifier and no line address (Line Citation Gate success: 0 new citations).

③ Boundary flags

open_questions: [] and out_of_scope_findings: [] in report 6137456997. Its five deviations, each answered:

  1. Reverse check, dist leg proven by a hand count (the declaration in dist/field-types.d.ts counted 0 mutated, 1 restored) rather than by scripts/ablation-dist-preflight.mjs, which roots at the objectstack checkout — ACCEPTED. The mutation and the restore went through ablation-replace.mjs with blob hashes on both sides (a067fe16 → 19c4a973 → a067fe16, git status --porcelain empty); the two legs that read the type went red (TS2353 ×2 and TS2339 ×3 under tsc -p tsconfig.test.json; check:doc-snippets 2 of 789 failed, both the page's typed literals) and the leg that reads the installed spec stayed green, which is the expected direction. The reversal shows the pin and the page would both catch the declaration's removal.
  2. Attribution: commits carry the model-free trailer pair and the PR body ends with the session-URL footer — ACCEPTED, read on both branch commits (e9325f4c, aae05a1a): a Claude-Session: URL line and a Co-authored-by: Claude line with the noreply address, no model identifier anywhere. That is what objectui AGENTS.md and objectstack AGENTS.md both prescribe, and the harness reminder yields to them.
  3. The merge commit's default message amended locally before its first push — ACCEPTED; no pushed history was rewritten (the branch's pushed commits are the implementation and the merge, and both read as described).
  4. Scope call: the nine plaintext Format Templates lines moved to autonumberFormat, not only the two typed literals the route named — ACCEPTED, inside the claimed file surface and inside triage's direction ("teaches autonumberFormat as the spelling for a new field"). A page that taught the shorthand on nine lines and the preferred key on two would teach two spellings of one setting, which is the defect the card names.
  5. The docblock and changeset say the spec's field form, which Studio's field designer renders, OFFERS autonumberFormat, not that Studio WRITES it; the live designer was not driven — ACCEPTED, and the narrower sentence is the right one (完善设计器的每一个细节 #9): the card's "Studio writes it" rested on the predicate.test.ts and SchemaForm.unresolvedPredicate.test.tsx pins, which show the form offers the key under type == 'autonumber', exactly what the text now claims.

No flag is escalated.

Check-runs on the head

33 check-runs on this head, every one completed by the time of this write: 30 success, 3 skipped (dependabot, Test (coverage) and the coverage-shard matrix placeholder, none of which runs on a pull request), 0 failures, 0 still running. The gate-carrying contexts read success: Type Check, Lint, Repo Gates, Test and its twelve shards, Test (dist pins), Build & E2E, Build Docs, Spec Main Shape Gate, Governed Surface Queue Guard, Line Citation Gate, the five changeset gates (Changeset Declaration, Changeset Bump Policy, Changeset Fixed Group Check, Changeset Overwrite Report, Changeset Claim Re-read), Bundle Analysis, Live E2E (informational) and label. When this review began, Type Check, Spec Main Shape Gate, Repo Gates, Bundle Analysis and the test shards were still in_progress; each was read again until it completed (the last to finish was Spec Main Shape Gate), and nothing was re-run. The needs:contract-review marker is not on the PR (labels: documentation, package: types, tests), so there is nothing to remove with this record.

Implemented-by: claude/issue-12282-autonumber-format-type
Reviewed-by: session_015YrgVw7e65cs1ndbebt46G

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 13, 2026 03:36
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 13, 2026 03:36
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 13, 2026
Merged via the queue into main with commit fd4872f Oct 13, 2026
34 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-12282-autonumber-format-type branch October 13, 2026 03:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation package: types tests

Projects

None yet

2 participants