Uh oh!
There was an error while loading. Please reload this page.
feat(spec)!: narrow ObjectMasterDetailFormPropsSchema.formType to the measured simple | tabbed - #11963
Conversation
…d simple | tabbed Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K93P8PbH7kVjsAXkqzH1zY
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K93P8PbH7kVjsAXkqzH1zY
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K93P8PbH7kVjsAXkqzH1zY
📓 Docs Drift Check2 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. 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 4a0ff18206cc7e9de5b6e5c1aa40e85187ab1dcc && git checkout 4a0ff18206cc7e9de5b6e5c1aa40e85187ab1dcc
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 178f90c768155577dfacc04d5cf03aa4c5470e85 11294ac5337c698ad7e178f55afa5be20847eb03 && git checkout -B drift-repro 178f90c768155577dfacc04d5cf03aa4c5470e85 && git merge --no-ff 11294ac5337c698ad7e178f55afa5be20847eb03
node scripts/docs-audit/affected-docs.mjs --json 178f90c768155577dfacc04d5cf03aa4c5470e85 |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11873
What
ObjectMasterDetailFormPropsSchema.formTypenarrows from barez.string()to the measuredz.enum(['simple', 'tabbed'])— the spec half of objectui#5939, which already tightened the objectui registry declaration to the same pair on the same measurement. Direction per triage (comment 5403285119): not open; only the retirement mechanics were this card's work.object-formspellings that name real renderer branches (wizard/split/drawer/modal) refuse with a per-value prescription carried by the enum's own error map, keyed onissue.input— therecord:chatterpositionprecedent (spec:RecordChatterProps.positiondeclares a vocabulary no read point compares —sidebar/inline/drawervs the renderer'sbottom/right/left— and itscollapsibledefault inverts the renderer's #8762) and theview.exportOptions'pdf'precedent (spec:ListView.exportOptionsis typed as a bare array, but the only renderer readsexportOptions.formats#8010). Each prescription names the measured way that branch breaks the block's atomic parent+details contract (ADR-0001) and prescribessimple/tabbed, pointing atobject-formfor the overlay/wizard/split presentations.'wizzard', the issue's own repro) now gets zod's plain enum refusal instead of parsing clean and rendering a silently sectionless parent form.ObjectFormPropsSchema.formTypekeeps its six values — only the master-detail block narrows.tabbedpresentationally honoured but escaping the atomic batch) is a renderer defect tracked there; per triage constraint 3 it does not change this vocabulary.Census (triage constraint 2 — run BEFORE narrowing)
In-repo authored-value census over every
formTypeon master-detail blocks (fixtures, examples, catalog entries, tests, docs —*.ts/tsx/js/json/md/mdx/yml/yaml, excludingnode_modules/dist/.cache): 106 repo-wideformTypementions, all classified; zero out-of-vocabulary values on master-detail blocks. The three authored master-detail values are all'simple':examples/app-showcase/src/ui/pages/project-workspace.page.ts:45packages/spec/src/ui/component.test.ts(showcase master-detail pin)packages/lint/src/validate-component-props.test.ts(master-detail node)Positive control: the same sweep resolves real authored out-of-
simple|tabbedvalues on the siblingobject-formblock —'wizard'(component.test.ts,validate-component-props.test.ts,new-project-wizard.page.ts) and'drawer'/'modal'(task-desk / renewals-pipeline JSX pages) — proving it sees authored values, not just declarations. objectui's equivalent census (objectui#5939) also read zero. No premise fork.Retirement mechanics — why no ADR-0087 conversion entry
Both precedents (#8762, #8010) registered a conversion + migration entry; this narrowing deliberately does not, and the reasoning is recorded in the schema comment:
check:authorable-surfacetracks keys (the key survives), and no gate diffs enum values against the registries.check-adr-0087-registrationrequires the question answered in writing — the changeset carries theadr-0087: not-required (no-migration-prescription)disposition, and the gate accepts it (green).z.string(). There is nothing spec-promised to rewrite, and both censuses read zero authored occurrences.packages/spec/src/migrations/registry.ts(conversionIdslist + semantic entry), which is HELD by a sibling family dispatch this wave — the dispatch constraint forbids touching it. Since (1) and (2) make the entry unnecessary rather than deferred, this is a completed shape, not a debt; if the maintainer wants a belt-and-braces conversion (rewriting the four names →'simple') it can land as a follow-up once the hold lifts.Tests
'simple'and'tabbed'parse green onobject-master-detail-form.code: 'invalid_value',path: ['formType']— for'wizzard'(plain enum refusal, no prescription) and for each ofwizard/split/drawer/modal(per-value prescription naming the honoured pair andobject-form).type-alias-convention.pin.test.tsIso844 (input ≡ infer) verified green without edits — an error-mapped enum with no default/transform stays isomorphic, so the pin file is deliberately not in the diff.Gates
Full
@objectstack/specbuild +check:generated(→gen:docsregeneratedcontent/docs/references/ui/component.mdx, included; re-run green after fix) + full spec test suite:Test Files 424 passed (424)/Tests 11281 passed (11281)(lock verdictcommand-exit 0, run at7b3020f; the one later commit11294actouches only the.changeset/marker, no test input) + typecheck incl. the test layer,check:liveness,check:empty-state,check:strictness-ledger,check:variant-docs— all green at final head11294ac(command-exit 0).check-adr-0087-registrationgreen at11294ac(disposition accepted). Reverse verification from the committed state: reverting the enum toz.string()(mutation disk-confirmed: injected=1 / removed-remaining=0) turns exactly the 5 rejection pins red (5 failed | 2 passed) with the 2 acceptance pins green, restore disk-confirmed (get-calls=1). Full gate readings quoted in the report comment on #11873. Gate family re-derived from the actual diff withnode scripts/pm/dispatch-gates.mjs.Breaking ships as minor per the launch-window convention (
scripts/check-changeset-no-major.mjs); the changeset names the four newly-rejected values and points authors at the two honoured ones.Generated by Claude Code
Generated by Claude Code