Uh oh!
There was an error while loading. Please reload this page.
feat(spec): declare editMode?: 'modal' | 'page' on the object document - #12208
Conversation
#11408) Maintainer ruling 2026-08-24 (declare — #10144 declare-or-rule-out family): objectui's shipped runtime reads objectDef.editMode for record-edit routing while the spec's strict parse rejected the key with unrecognized_keys. The object document now declares it beside the other display hints; values outside the enum fail as a located value error at editMode. Accept-set widening; consumer-side retirement of ObjectSchemaClientExtensions.editMode is a release-gated objectui follow-up per the recorded ruling. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NDGG54XF5gbTLdQzCtnaVV
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 126 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 5e531b0adb7d51a64a4282c4712081f66743856c && git checkout 5e531b0adb7d51a64a4282c4712081f66743856c
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 494279cb31f1d92adab959763085e19c923a8652 08da3eb5c33461ee942b8b8d6613d3fb90fd9718 && git checkout -B drift-repro 494279cb31f1d92adab959763085e19c923a8652 && git merge --no-ff 08da3eb5c33461ee942b8b8d6613d3fb90fd9718
node scripts/docs-audit/affected-docs.mjs --json 494279cb31f1d92adab959763085e19c923a8652
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11408
What
Declares
editMode?: 'modal' | 'page'as an optional authored key on the spec's object document, per the maintainer ruling recorded on the issue (2026-08-24, declare — the #10144 declare-or-rule-out family; ruling comment quotes 「接受你的建议。」 on the aligned four-facet analysis).packages/spec/src/data/object.zod.ts: the key joins the Display & UI Hints block besidenameField/highlightFields/stageField. TSDoc +.describe()state the cross-renderer semantics ('modal'= edit form as a dialog over the current view;'page'= dedicated full-page edit route), the absent-key behaviour (renderer picks its own default; objectui defaults to modal), and the objectui read points (recordFormNavigation.tsbranches oneditMode !== 'page';AppContent'shandleEditdispatcher routes on it).packages/spec/liveness/object.jsonclassifiesobject/editModeaslive(objectui runtime read, prose evidence per the ledger's convention for renderer-side readers);state-counts.mdregenerated.check:generatedproved them stale:authorable-surface/data.json(+data/Object:editMode) andcontent/docs/references/data/object.mdx(new row in the object reference table).minorfor@objectstack/spec(accept-set widening; nothing removed, no existing document changes meaning).check-adr-0087-registrationverdict: "this PR adds no declared-breaking changeset (1 non-breaking changeset(s) seen)" — no ADR-0087 entry required, matching the dispatch's expectation for a pure widening.Before / after (both measured on the freshly built dist, not src)
ObjectSchema.safeParse({ name, fields, editMode: 'page' })→success: false,issues[0] = { code: 'unrecognized_keys', keys: ['editMode'], path: [] }; positive control without the key parses green. (Matches the issue's measurement on published spec 17.2.0.)'modal'and'page'accepted and carried on the parsed output; absent accepted;editMode: 'drawer'rejected as{ code: 'invalid_value', values: ['modal','page'], path: ['editMode'] }— the failure moved from key-levelunrecognized_keysto a located value error, proving the key is recognised and its value contract enforced.Tests
Four new tests in
packages/spec/src/data/object.test.ts(ObjectSchema editMode (#11408 ...)describe block): both enum values accepted end-to-end (full parse green, not merely "no unrecognized_keys"); optionality; out-of-enum values ('drawer','inline',true,3) each fail with a non-unrecognized_keysissue at path['editMode']; the authoring path (create()) accepts it. Full@objectstack/specsuite green — see the union run cited below.Scope
ObjectSchemaClientExtensions.editModemember retires in a follow-up the accepting seat files in objectui, release-gated on the@objectstack/specrelease containing this change (per the recorded ruling) — its pinned rejection tests flip by design there. This PR touches no objectui code and no pins on sibling behaviour.*.form.tsfiles change — titleFormat precedent: object-level display keys carry no authoring-form row; also keeps this batch disjoint from the spec:minLengthstill has the pre-#11566 defect pair — validated as no more than a number, authorable on every field type #11949 form-row work.Verification at the final head
Union re-run at the final commit (
git rev-parse --short HEAD= b7be080): spec build +check:generated"All 14 generated artifacts are up to date" (includescheck:authorable-surface,check:api-surface,check:docs,check:liveness,check:strictness-ledger— the ratchet families) · full@objectstack/specvitest suite (426 files / 11352 tests passed) ·@objectstack/spectypecheck · and the per-card gate list below, every one exit 0 with exits captured before any pipe:check:merge-driver·check:published-files·check:slot-lookup·check:spec-parsed-alias·check:test-source-alias·check:type-source-resolution·check-adr-0087-registration·check-changeset-no-major·check-empty-changeset·check:nul-bytes·check:changeset-gate-self-tests·check:objectui-changeset·check-ci-filter-parity·check:cross-package-test-inputs·check-plugin-teardown-shape· docs-auditcheck-affected-docs+check-drift-comment·release-rehearsal-clone --self-test· speccheck:empty-state/check:strictness-ledger/check:variant-docs· lintcheck:doc-formula-expressions·check:query-options-erasure·check:type-check-coverage·check:engine-double-contract·check:where-matcherDeclared local narrowings (CI runs the full farm regardless):
check-dev-prereqs— red locally only on its workspace-built precondition: 66 of 67 packages have nodist/in this fresh worktree. Not a diff finding; the one diff-coupled row (packages/spec/distfreshness, content-hashed) is green — spec was rebuilt at the final head with its.build-input-hashwritten.check:type-check-debt --re-measure— refuses on an unbuilt workspace closure (its own doc: the throw means NOT MEASURED). Spec-scoped equivalents ran green at head:@objectstack/spectypecheck, andcheck:test-typecheck --package packages/spec"OK — test layer compiles; 55 file(s) / 263 error(s) held" (ledger unchanged). My diff touches onlypackages/spec+.changeset+ generated docs, so no other ledger entry's tsc program gains an input from this diff.Generated by Claude Code