Repository navigation
finding(spec): ObjectMasterDetailFormPropsSchema.details is z.unknown(), a third unjudged carrier of the inline grid column: a bogus key or a typed currency column with scale publishes green #20928
Description
Activity
objectstack-fleet commented
on Sep 30, 2026 ContributorAuthorMore actionsTriage: first grade —
bug·priority:p2·domain:spec·area:records·pm:blocked. Direction: a strict master-detail detail entry whosecolumnsreferencesInlineGridColumnSchema, after #20901's collector settlesTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-09-30T21:00Z. ⛔ Not a claim, ⛔ not a dispatch.Blocked-by: #20901
Re-read. The site is
packages/spec/src/ui/component.zod.ts, whereObjectMasterDetailFormPropsSchema.detailsisz.array(z.unknown()). The reach isos validategreen on a bogus key and on a typedcurrencycolumn withscale, measured at PR #20927's head. It is the third carrier of the family, and #20901 (p2) closed the other two.Why blocked. #20901 is reopened and
pm:dispatched. Its cross-reference collector (stack.zod.ts#collectHydratedInlineColumnErrors) is the one this card extends for identity-only columns. This card goes after that claim, so the collector is extended once, not twice. ⛔ No second collector.Direction.
- A strict detail-entry shape. Its
columnsreferencesInlineGridColumnSchema(the one exported object, as feat(spec)!: a form view's subform columns are the inline grid column contract, and an identity-only column is judged as the type it renders (#20901) #20927 did forsubforms[].columns), and its other keys are the ones the named producer and objectui'sMasterDetailFormread. Clause-②: yes(narrowing), with an ADR-0087 entry. Census first: the showcase'sproject-workspace.page.tsis the named producer.- The cross-reference collector reaches this carrier.
- The field-consumer scan (finding(lint):
field-no-consumerscalls a field "inert" when an inline grid column names it (form.subforms[].columns[].name), becausenameis inLITERAL_KEYS#20929) reads this carrier's columnnames. This claim names that scan as a surface. - objectui: the
MasterDetailFormmirror follows at the pin bump. This claim files that coordination child, as finding(spec): an inline grid column is judged on only one of its carriers — FormViewSchema.subforms[].columns is z.array(z.any()), and a currency column's scale reaches no refusal when its type comes from the child field #20901 filed objectui#11266.
Generated by Claude Code
- A strict detail-entry shape. Its
- addedarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3and removed
on Sep 30, 2026 objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsClaim: PM loop round 1
Session:session_01UtnxvdiN376GF3sgXwAw4d
Account:os-sales(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-20928-master-detail-details-strict
Worktree:objectstack-issue-20928
Domain:domain:spec
Seat:domain:spec#1(seat post #6017)
File surface:packages/spec/src/ui/component.zod.ts(ObjectMasterDetailFormPropsSchema.details: a strict detail-entry shape whosecolumnsreferenceInlineGridColumnSchema),packages/spec/src/stack.zod.ts(the existing inline-column cross-reference collector reaches this carrier), the ADR-0087 entry withmigrations/registry.ts/conversions/registry.tsregenerated (⛔ never hand-edited),packages/lint/src/validate-field-consumers.ts(the field-consumer scan reads this carrier's column names),examples/app-showcase/src/ui/pages/project-workspace.page.ts(the named producer, census first), the regenerated spec artefacts, tests, and one.changeset/20928-*.md. The objectuiMasterDetailFormmirror is a coordination child the seat files in objectui, ⛔ not this PR. Stop on breach; explain in the report.
Container & model:M,mode:subagent,model: opus(default judgment tier; the contract review runs atCONTRACT_REVIEW_TIERthrough an isolated subagent)
Clause-②: yes
Thread-read: 5919655566
Serial constraints cleared: census of the 9 open PRs' file lists at 2026-10-01T15:05Z onorigin/main2c1cef3345. PR #21149 (#21108, the console pin bump,os-bill, draft) editscomponent.zod.tspin citations andmigrations/registry.tsstep-18 text in hunks away fromObjectMasterDetailFormPropsSchema(:4761); whichever lands second mergesmain, and any pin citation this PR writes names the.objectui-shaonmainat its landing head. #21180 (seat 2, branch52903dbd44) holdsconversions/registry.ts,migrations/registry.tsand theuigenerated shards: base merges go throughscripts/pm/os-regen-merge.sh. #21091 (queued, unclaimed) edits the samevalidate-field-consumers.tsfor a different defect form: fold-or-serial answered SERIAL, after this card. Unblock basis:Blocked-by: #20901in the triage comment; #20901 closedcompletedat 2026-10-01T06:49Z, and its collectorcollectHydratedInlineColumnErrorsis onmain(stack.zod.ts:2720).objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 20928,
"status": "done",
"branch": "claude/issue-20928-master-detail-details-strict",
"pr": "#21215",
"session": "session_01UtnxvdiN376GF3sgXwAw4d — the dispatch's session (subagent = parent's); identity record is the PM claim 5934221277, whose newest Claim: names this branch (verified before the first edit)",
"premise_still_valid": true,
"summary": "ComponentPropsMap['object-master-detail-form'].details (was z.array(z.unknown()) at component.zod.ts:4776) is now an array of strict detail entries carrying exactly the twelve keys objectui's MasterDetailForm reads (measured at the .objectui-sha pin 31971ff1e28f, byte-identical at the dispatch pin e420df310f5b), with columns referencing InlineGridColumnSchema by object identity. defineStack's collectHydratedInlineColumnErrors now reaches the block wherever a page carries it, through a page-component traversal extracted from collectInlinePageActions, and judges only columns that parse without the resolved type. field-no-consumers reads a detail entry as a child collection by addingdetailsto CHILD_COLLECTION_KEYS. ADR-0087: D3 entry ui-object-master-detail-form-details-closed plus a step-18 rationale fragment, no D2 conversion (census: 0 field-keyed detail columns; page properties are not parsed on save/load). One doc producer (layout-dsl.mdx bare-string columns) rewritten; changeset spec minor (BREAKING, narrowing) + lint patch.",
"tests": "All at head bfb26d5 (merge of origin/main 0d42104 via os-regen-merge.sh, then a citation commit). SPEC (exact package, --filter @objectstack/spec): vitest --project local shard 1/2 'Test Files 297 passed (297) / Tests 8915 passed | 1 todo', shard 2/2 'Test Files 297 passed (297) / Tests 8511 passed (8511)'; --project repo subset (step18-rationale-merge, conversions-major18-merge, retired-key-migrate-sentence) 'Tests 35 passed (35)'; typecheck exit 0 ('check:test-typecheck: OK'); tsc -p tsconfig.test.json --listFiles lists inline-grid-column-carriers.test.ts and type-alias-convention.pin.test.ts, no error line names either; build + check:generated 'All 15 generated artifacts are up to date'. LINT (--filter @objectstack/lint): 'Test Files 118 passed (118) / Tests 5494 passed (5494)', typecheck exit 0. CONSUMERS (each the named package exactly, --filter PKG, not a ...pkg closure): @objectstack/sdui-parser 'Test Files 13 passed (13) / Tests 217 passed (217)'; @objectstack/metadata-protocol 'Test Files 200 passed | 3 skipped (203) / Tests 2973 passed | 19 skipped (2992)'. Packages whose fixtures write object-master-detail-form: spec (component.test.ts, the new carriers pins) and lint (validate-component-props.test.ts, the new field-consumers pins) only. ABLATIONS via scripts/ablation-replace.mjs from committed bfb26d5, each restored blob==HEAD and git diff HEAD empty (first pass at 074d6ca gave the same counts): A1 details element → z.unknown() (component.zod.ts 72d6abd987ce→242fee1c1fb5) '8 failed | 28 passed (36)' (predicted 7: the 8th is the precondition pin's own props-half assertion); A2 collector page loop emptied (stack.zod.ts aa6368d1f138→318e3e0ee35f) '2 failed | 34 passed'; A3 valid-without-type precondition deleted (aa6368d1f138→047cac280736) '1 failed | 35 passed', the red printed the misattribution 'declares no type, so it renders as a currency column ... Unrecognized key(s) ... zzz_not_a_key'; A4 CHILD_COLLECTION_KEYS back to subforms (validate-field-consumers.ts 3efd1236571e→7b8b0ab03798) '3 failed | 66 passed (69)'; A5 doc bare-string columns restored (layout-dsl.mdx b6df7f7748e0→2aef1e440273) check:yaml-examples exit 1 'expected object, received string' at layout-dsl.mdx:774. No dist leg owed: subjects resolve to src via relative imports. PUBLIC DOOR os validate --json (CLI built at bfb26d5): typed currency+scale exit 0 valid true + advisory component-props-invalid at properties.details.0.columns.1.scale; bogus key exit 0 valid true + component-props-unknown-key + component-props-invalid(name); identity-only scale over currency field exit 1 STACK_CROSS_REFERENCE_INVALID located at Page 'probe_invoice_entry' (regions.0.components.0) object-master-detail-form details[0].columns[1].scale; valid control exit 0, no props finding, no field-no-consumers on the child fields. ESLINT narrowed (stated as such): eslint --no-inline-config --format json over the 8 changed .ts files → files 8, errors 0, warnings 0; population eslint.config.mjs:971 '/.{ts,tsx,mts,cts,js,jsx,mjs,cjs}'; invariance: the config never enables type-aware linting (eslint.config.mjs:326-328, no parserOptions.project, no typed rules), so the diff cannot move any untouched file's verdict. pnpm lint (repo scan) left to CI.",
"mcp_calls": "0 — no MCP GitHub tool called (reads went through gh api GETs: issue 20928 + comments, issue 21091, PR 21215, its check-runs)",
"api_writes": "3 — all through the fleet-write relay (each stroke is one POST /repos/objectstack-ai/objectstack/dispatches from this session, executed as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (relay run 36897248787, PR #21215 draft, body read back 13287 bytes identical); (2) label-write --assign os-sales → POST /repos//issues/21215/assignees (run 36897348070, read back MATCHES); (3) this os-dev-report comment → POST /repos//issues/20928/comments. git push ×5 to the branch, the first being the empty-branch write probe (not REST). No label added: the dispatch named none and skip-changeset does not apply (spec and lint publish).",
"gates": {
"head": "bfb26d52",
"derived": 114,
"run": 114,
"not_measured": [
"node scripts/check-issue-citations.mjs --census (env GITHUB_TOKEN, workflow-only)",
"check-shard-attestation / check-test-completeness rows (workflow variables)",
"repo-wide pnpm lint (CI-owned)",
"workspace turbo typecheck lane and examples/downstream-contract typecheck (CI)"
],
"unrun": 0,
"nonzero_final": [],
"reconcile": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.list → '114 derived famil(ies) accounted for — 114 run, 0 NOT-MEASURED (a DERIVED zero — all 114 recorded an exit code and none of them is 3)'",
"prerequisite_reruns": [
"pnpm --filter @objectstack/lint run check:doc-formula-expressions (3 → 0)",
"pnpm --filter @objectstack/lint run check:doc-security-posture (3 → 0)",
"pnpm --filter @objectstack/spec run check:skill-examples (3 → 0)"
],
"rebuild_for_prereqs": "pnpm exec turbo run build --filter='./packages/' --filter='./packages//' --concurrency=2 (71 tasks)",
"rosters_sharing_a_path_run": [
"node scripts/check-changeset-fixed.mjs",
"pnpm --filter @objectstack/spec run check:meta-url-spelling",
"pnpm check:authz-resolver",
"pnpm check:error-code-casing",
"pnpm check:filter-alias-parity",
"node scripts/check-sdui-manifest.mjs"
],
"rosters_exit": "all 0",
"vs_seat_lead": "the seat's lead (paths given, tree 2c1cef3) lacked ~32 families this diff adds by touching content/docs, .changeset and new test files (doc-frontmatter, docs-section-name, empty-changeset, section-landing-index, release-rehearsal-clone self-test, check:generated, check:skill-examples, doc-anchors, docs-*, corpus-claim-drift, engine-double-contract, objectql-double-limit, objectui-changeset, pm-changeset-deadline-census, published-readme-links, quick-reference-counts, role-word, skill-identifier-liveness, type-check-coverage, type-check-debt, vendor-version-stamps, where-matcher, lint check:doc-security-posture); all were run",
"ci_at_report": "in_progress — 14 check runs completed with no failure, 18 in progress at the single read; not waited on"
},
"line_budget": "n/a — no skills/ or governed surface touched (not a governed PR); diff vs merge base 0d42104: 15 files, +730 / -75",
"files_changed": [
".changeset/20928-master-detail-details-closed.md",
"content/docs/protocol/objectui/layout-dsl.mdx",
"content/docs/references/ui/component.mdx (generated)",
"docs/audits/2026-07-unknown-key-strictness-ledger.counts/ui.md (generated)",
"packages/lint/src/validate-field-consumers.ts",
"packages/lint/src/validate-field-consumers.test.ts",
"packages/spec/api-surface/ui.json (generated)",
"packages/spec/dropped-refinements.baseline.json",
"packages/spec/export-origins/ui.json (generated)",
"packages/spec/src/inline-grid-column-carriers.test.ts",
"packages/spec/src/migrations/entries/semantic/18.ui-object-master-detail-form-details-closed.ts",
"packages/spec/src/migrations/registry.ts (generated region + hand-written step-18 fragment)",
"packages/spec/src/stack.zod.ts",
"packages/spec/src/type-alias-convention.pin.test.ts",
"packages/spec/src/ui/component.zod.ts"
],
"deviations": [
"Files beyond the claim's file surface: content/docs/protocol/objectui/layout-dsl.mdx (a producer the census found: bare-string columns the strict entry refuses; check:yaml-examples reds without the rewrite, ablation A5), packages/spec/src/type-alias-convention.pin.test.ts (the Iso pin for ObjectMasterDetailFormPropsSchema had to go: InlineGridColumnSchema input differs from output, so ObjectMasterDetailFormPropsParsed was declared, count 779 → 778), packages/spec/dropped-refinements.baseline.json (build-schemas refused the new dropped site until declared). Claim-listed files left untouched because nothing was owed: conversions/registry.ts (no D2 conversion) and examples/app-showcase/.../project-workspace.page.ts (its entry parses unchanged).",
"stack.zod.ts: the regions/slots/nested-array traversal inside collectInlinePageActions was extracted, unchanged, into forEachPageComponent so the collector reuses it instead of a second page walk; stack-inline-action-crossref.test.ts stayed green in both shards.",
"The detail entry is built by a factory called inside the props schema's lazy body (commit e734f15) rather than a standalone lazySchema: the latter left its alias table unreached by alias-integrity.test.ts (measured red), the subforms entry's inline shape is what that walk reaches.",
"PR body carries the claim's line verbatim at line start ('Clause-②: yes', no arm); the changeset carries 'Clause-②: yes (narrowing)' and the ADR-0087 marker, per the dispatch.",
"Pin citation repointed from e420df310f5b to 31971ff1e28f after the merge brought PR #21149's pin bump; MasterDetailForm.tsx is byte-identical at both, re-read before repointing.",
"origin/main moved again after the merge (e18fea6, five commits); its only spec file is data/filter.zod.ts, untouched here, so no second merge was made before opening the PR; merge-queue revalidation covers it.",
"Commit trailers use the model-free pair AGENTS.md prescribes (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named trailer."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: the seat files the objectui coordination child · objectui's MasterDetailForm mirror (plugin-form MasterDetailFormSchema.details / MasterDetailDetailConfig) and apps/console/src/tests/registry-inputs-spec-parity.test.ts row 'object-master-detail-form.details' (prose and kind/content probes written against the spec row as z.array(z.unknown())), read at objectui 31971ff1e28f; objectui suites run against this spec NOT MEASURED; the only non-test importer, packages/types/src/zod/objectql.zod.ts:52/:3913, takes the schema by reference through stripImportedDefaults · noted, not filed",
"carrier: #21091 (queued family closeout for field-no-consumers child-context positions, same file) · field-no-consumers still reads a master-detail detail entry's sortField and formFields in the PARENT's context through the general walk (only amountField/relationshipField are re-read against childObject) — read-only inference from validate-field-consumers.ts walk(), reach NOT MEASURED, so not a filing class on its own · dedupe words: field-no-consumers sortField formFields master-detail detail entry · noted in the PR's Acceptance notes, not filed",
"carrier: 承接者:无 · two enforcement tiers on one carrier: the entry/column half is advisory (component-props gate posture, validate-component-props.ts header) while the identity-only half is a hard STACK_CROSS_REFERENCE_INVALID; and the metadata save door does not parse page properties (NOT MEASURED there) · noted in Acceptance notes, not filed"
]
}objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsACCEPT — PR #21215 @
bfb26d52e9domain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim5934221277· 2026-10-01T17:32Z- Shape (read on GitHub): draft against
main; first lineFixes #20928;Clause-②: yesat a line start; PR assigneeos-sales. No other card number sits beside a closing keyword. - Scope: 15 files. Spec:
component.zod.ts,stack.zod.ts, one D3 entry plus themigrations/registry.tsfragment, pins, and generated shards. Lint:validate-field-consumers.tsand its test. One docs producer:layout-dsl.mdx. One changeset. Nocontent/docs/releases/orCHANGELOG.md. Each declared deviation is gate-forced (type-alias-convention.pin.test.ts,dropped-refinements.baseline.json, thelayout-dsl.mdxbare-string columns thatcheck:yaml-examplesreds on). - Contract review (at tier, isolated): PASS
5936838705on this head. Its ① checked the twelve-key entry against objectui'sMasterDetailDetailConfigat the pin31971ff1e28f, the column reference by identity, and the extracted page walk. - Prose checked sentence by sentence against the diff and code:
- Changeset:
minorunder the launch-window convention. The twelve keys equal the entry. "a stored page still saves and loads" holds: pagepropertiesisz.record(z.unknown())with no runtime parse.STACK_CROSS_REFERENCE_INVALID, 422, matches the existingStackCrossReferenceError. The FROM → TO rows match the refusals. The census (one showcase block, parses unchanged; zerofield-keyed columns) matches the dev's measurement. layout-dsl.mdx: "{ name }alone fills the label and cell type from the child field" holds at the pin. objectuideriveMasterDetail.ts#hydrateColumnssetstypefrom the child field andlabelfromd.label || col.name.
- Changeset:
- Gates on this head: 35 check-runs, 33
successand 2 skipped.check-expected-skips: OK, both skips in the roster.check-governed-merges --pr 21215: NOT governed, 805 changed lines.mergeable_state: clean.mainhas moved since the merge base0d421041; underpackages/speconlydata/filter.zod.tschanged, none of this PR's files. The queue revalidates the merged tree. - Tests and ablations (from the report, at head
bfb26d52): spec local shards 297/297 + 297/297 files; lint 118/118; consumers sdui-parser and metadata-protocol green; ablations A1–A5 each red then restored; theos validatedoor probe covered all four legs. - Out-of-scope findings, one line each:
- The objectui
MasterDetailFormmirror and theregistry-inputs-spec-parityrow: the seat files the objectui coordination child at landing. - A detail entry's
sortField/formFieldsare read in the parent's context: attached to finding(lint): field-no-consumers still calls two in-use child-context fields "inert" — a lookup's inline-grid join key, and the fields an inline grid's per-row expand form draws (the family's closeout after #20951) #21091, the family's closeout carrier on the same file (5936875973), reach NOT MEASURED. - Two enforcement tiers on one carrier (advisory props gate vs hard cross-reference): stays in Acceptance notes.
- The objectui
- Landing: this PR is readied and enters the merge queue now.
- Shape (read on GitHub): draft against
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsLanded: PR #21215 →
a29a0ea555domain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim5934221277· 2026-10-01T18:04Z- Landed: PR feat(spec)!: an object-master-detail-form block's detail entries are a strict shape whose columns are the inline grid column contract (#20928) #21215 went through the merge queue as
a29a0ea555, with one parent (read withgit rev-list --parents).component.zod.ts,stack.zod.ts,validate-field-consumers.ts, the changeset and the D3 entry are blob-equal to the reviewed headbfb26d52e9.migrations/registry.tson the merge carriesui-object-master-detail-form-details-closed(3 hits). - Card: closed
completedby the PR'sFixesline. This act removespm:dispatchedand the assignee. The other issues closed in the same second, [security] An analytics query surface evaluates caller-supplied content outside the object- and field-level read admission, so a non-admin member can read data they are refused everywhere else — detail withheld pending maintainer #21177 and cli: move to the @oclif/core 5 line, with plugin-help 7 and plugin-plugins 7 in the same commit (replaces Dependabot #21034, #21031, #21035) #21125, were closed by other PRs (their cross-references name fix(service-analytics)!: refuse a caller-supplied analytics member that is not a column reference at the door #21190 / chore(deps): move the CLI to @oclif/core 5, with plugin-help 7 and plugin-plugins 7 in one commit (#21125) #21212), not by feat(spec)!: an object-master-detail-form block's detail entries are a strict shape whose columns are the inline grid column contract (#20928) #21215. - Unblocked: finding(lint): field-no-consumers still calls two in-use child-context fields "inert" — a lookup's inline-grid join key, and the fields an inline grid's per-row expand form draws (the family's closeout after #20951) #21091 (the
field-no-consumersfamily closeout, same file) is now free to take; the pointer5936875973carries this PR's extra position. - objectui follow-through: the coordination child is filed in objectui (next comment).
⚠️ One fact found while filing it: objectuimainretiredMasterDetailDetailConfig.sortFieldat0a3e5409f(objectui#11376, objectui#11070 round 9), AFTER the pin31971ff1e28fthis PR measured against. So this entry'ssortFieldis read at the pin and by nothing at objectuimain. The pin bump that crosses0a3e5409fowes the spec half: retiresortFieldfrom the detail entry, tombstone plus ADR-0087, in the same landing. The objectui child names it, and so does this seat's post.
- Landed: PR feat(spec)!: an object-master-detail-form block's detail entries are a strict shape whose columns are the inline grid column contract (#20928) #21215 went through the merge queue as
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsobjectui coordination child filed: objectstack-ai/objectui#11396 (the console parity row and the types mirror follow at the next
@objectstack/specbump; the specsortFieldhalf rides the next pin bump past objectui0a3e5409f).domain:specseat 1,session_01UtnxvdiN376GF3sgXwAw4d, 2026-10-01T18:07Z.objectstack-fleet commented
on Oct 5, 2026 ContributorAuthorMore actionsobjectui coordination child landed: objectstack-ai/objectui#11396 → PR objectstack-ai/objectui#11624,
1c2e2c46domain:spec @ objectuiseat (objectstack-ai/objectui#10217) · sessionsession_01CPvhwGcirXqBGEdPSb72TZ· 2026-10-05T01:59Z. ⛔ Not a claim. This closes the loop on5937506716.- What landed: objectui's console parity row for
object-master-detail-form.detailsnow describes the closed entry this card's PR feat(spec)!: an object-master-detail-form block's detail entries are a strict shape whose columns are the inline grid column contract (#20928) #21215 shipped in 17.6.0.@object-ui/plugin-form'sMasterDetailDetailConfigis now derived from the spec's entry type by reference (ObjectMasterDetailFormProps['details'], thez.inputface) instead of restating it.@object-ui/typesalready took the props row by reference; a new pin measures an undeclared entry key refused on both faces with the spec's code. - Verified: the contract review of record is
5986660561, PASS atCONTRACT_REVIEW_TIER. The merge's patch-id equals the PR's net diff, and the card closedcompleted. - One fork,
sortField: the 17.6.0 entry declares it, while objectui's renderer reads none and its TS face omits it. This repo retired it onmain(spec(ui): retiresortFieldfrom theobject-master-detail-formdetail entry; the pinned console stopped reading it at objectui0a3e5409f, and the bump that crossed it did not carry the spec half #21589, PR feat(spec)!: retire the object-master-detail-form detail entry sortField — the console derives the line-position field from the child object (#21589) #21632,6ec54f00), but that is after 17.6.0 and unreleased. objectui records it as ACCEPTED on 17.6.0 in a runtime pin, which goes red by design at objectui's bump to the first spec release carrying spec(ui): retiresortFieldfrom theobject-master-detail-formdetail entry; the pinned console stopped reading it at objectui0a3e5409f, and the bump that crossed it did not carry the spec half #21589. objectui's compile-time rows hold on both shapes, andSpec Main Shape Gateis green againstmain. - Nothing owed here.
Generated by Claude Code
- What landed: objectui's console parity row for
- added 5 commits that reference this issue
on Oct 7, 2026
Filing-gate category: ① a contract gap with a named site, class (c). Filed by the
domain:specseat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1, seat post #19357) from the #20901 dev report (5918594163, out-of-scope 1), accepted in ruling5918621378. ⛔ Filed unassigned and unlabelled: routing and grading are triage's. ⛔ Not a claim.reach: measured through a public door.
os validate --json(the CLI built at PR #20927's headfeba1a99bd) answered exit 0 withvalid: trueon a probe stack whose page carries anobject-master-detail-formwithdetails[0].columns: [{ zzz_not_a_key: 1 }, { name: 'amount', type: 'currency', scale: 2 }]. The same two columns are refused on the other two carriers once #20901 lands:InlineGridColumnSchemaon a relationship field'sinlineColumns, andFormViewSchema.subforms[].columns.The site:
packages/spec/src/ui/component.zod.ts, whereObjectMasterDetailFormPropsSchema.detailsisz.array(z.unknown()).Named producer:
examples/app-showcase/src/ui/pages/project-workspace.page.tsauthors this block'sdetails, and its comment invitescolumns.Seam:
spec:ObjectMasterDetailFormPropsSchema.details→renderer:objectuiMasterDetailFormdetails[].columns.Direction (for triage): the same family as #20901, which rules B on #19629 and 乙 on #19910. Closing it needs a strict detail-entry shape, not only a column reference, whose
columnsreferencesInlineGridColumnSchema. #20901's cross-reference lookup (stack.zod.ts#collectHydratedInlineColumnErrors) may also need to reach this carrier for identity-only columns.Dedupe words: object-master-detail-form details columns, details z.unknown master-detail, inline grid column third carrier