Repository navigation
spec(ui): an object-master-detail-form detail entry's sortField describe says it is derived when omitted; on the renderer's fast path nothing derives it #21315
Description
Activity
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsTriage: first grade —
documentation·priority:p2·domain:spec·area:records·pm:queue. The detail entry'ssortField(andamountField) describes state both pathsTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-02T05:02Z. ⛔ Not a claim, ⛔ not a dispatch.Why p2. It is the #21284 class, on the next member. #21284 was p1 under the release rule. This sentence already shipped in 17.6.0, so it is repaired in the next release rather than gating one.
Direction: #21284's shape. Each derived-when-omitted describe on the entry states the derived path and the kept-as-authored fast path.
amountFieldis in the same edit. Regenerate the reference page.patch,Clause-②: no. ⛔ No point card per member: the claim reads every member ofmasterDetailDetailEntry()for the same gap.
Generated by Claude Code
- addedarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, searchdocumentationImprovements or additions to documentationImprovements or additions to documentationpriority:p2Medium: important, M3Medium: important, M3and removed
on Oct 2, 2026 objectstack-fleet commented
on Oct 2, 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-21315-detail-entry-sortfield-describe
Worktree:objectstack-issue-21315
Domain:domain:spec
Seat:domain:spec#1(seat post #6017)
File surface: the member describes ofmasterDetailDetailEntry()inpackages/spec/src/ui/component.zod.ts(about:5030–:5045onorigin/main97239c3c8a). That issortFieldandamountFieldfirst, and any other member whose describe claims a derivation the renderer's fast path does not make (triage5945912211: every member is read, with no point card per member). Also the regeneratedcontent/docs/references/ui/component.mdx, and one.changeset/21315-*.md(@objectstack/specpatch). ⛔ No shape, default or nullability change, and no objectui edit. Stop on breach; explain in the report.
Container & model:S,mode:subagent,model: opus(default judgment tier; the edit is in non-testpackages/spec/src/**, so the contract review runs atCONTRACT_REVIEW_TIERthrough an isolated subagent)
Clause-②: no
Thread-read: 5945912211
Serial constraints cleared: PR #21307 (#21284), which last held these describes, landed as75260587b3. At 2026-10-02T06:00Z, none of the open PRs' file lists touchescomponent.zod.tsorreferences/ui/component.mdx, and no openpm:dispatchedclaim names them in its file surface. #21279 (priority:p3, the same file) is queued, not in flight.objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 21315,
"status": "done",
"branch": "claude/issue-21315-detail-entry-sortfield-describe",
"pr": "#21355",
"session": "session_01UtnxvdiN376GF3sgXwAw4d",
"premise_still_valid": true,
"summary": "The object-master-detail-form detail entry's sortField and amountField describes (packages/spec/src/ui/component.zod.ts, masterDetailDetailEntry()) now state both renderer paths, in #21284's shape: what is derived when omitted, and that an entry naming relationshipField plus at least one column with every column typed is kept exactly as authored, so nothing is derived (sortField: no line position stamped, drag-reorder not saved; amountField: nothing picked, the sums read a child column named amount, the grid shows a running total only when totalField is set). content/docs/references/ui/component.mdx regenerated by check:generated --fix; changeset @objectstack/spec patch, Clause-② no. No shape/default/nullability change, no objectui edit, sortField not retired (PR body says the retirement waits on the .objectui-sha bump that crosses objectui 0a3e5409f). Zone 2 measured at pin 31971ff1e28f, MasterDetailForm.tsx: (1) CONFIRMED with one refinement: fast path 965-967 returns the entry unchanged (plus the block-level shortcut at 958 when no entry needs resolution), 862 passes sort_field: d.sortField = undefined; hydrate path computes amountField/sortField at 1037-1038 and returns them at 1048-1055 while keeping formFields/inlineMode as authored; derived path 1056-1069 (1065-1066). So the split differs from #21284: formFields/inlineMode are kept on fast+hydrate (FK + at least one column); sortField/amountField only on fast (FK + every column typed); each describe states its own split. deriveMasterDetail.ts: sortField 540 with SORT_FIELD_NAMES 55; amountField 534 with pickAmountField 476-495; GridField.tsx 726-737 stamps only when sort_field is set. (2) DECIDED to state amountField's derivation and fast-path behaviour, not hold it: triage ruled it into the edit, and omission is path-dependent with a visible consequence read at 728/861/1549-1550 (a fully typed entry with totalField set, amountField omitted and a line_total column writes 0 into the parent's totalField; the derived path would have picked line_total) -- a reading, not a run. (3) CONFIRMED: git merge-base --is-ancestor PIN 0a3e5409f exit 0 (so 0a3e5409f is not in the pin's history; the reverse leg exit 1 is proven by it), and sortField is still read at the pin (85, 862, 1038). At objectui main d8edfe2576 the fast path (979) still returns unchanged and the sums still read amountField or 'amount' (740, 1564), so the bump owes no amountField change as of that commit; there a fully configured entry gets no sort field at all, documented in its own DetailEntry docblock (363-371) -- context for the retirement landing. (4) Regenerated via check:generated --fix only. Every other member read and holds (childObject, relationshipField, columns, formFields, inlineMode, totalField, title, minRows, maxRows, addLabel; the factory TSDoc claims no sortField derivation); verdicts per member are in the PR body.",
"tests": "All readings on HEAD e0b2374. pnpm --filter @objectstack/spec build: VERDICT command-exit 0. check:generated: first run '1 of 15 artifact(s) stale: content/docs/references/' (authorable surface + JSON schemas current); --fix regenerated it, '✓ check:docs'; in the union exit 0. pnpm --filter @objectstack/spec typecheck: exit 0. pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2: 'Test Files 597 passed (597)', 'Tests 17487 passed | 1 todo (17488)'. No new test: the change is describe text only; check:docs holds the reference page equal to the describes, and describe prose is not pinned (no consumer parses it). No ablation: no behaviour changed. eslint narrowed (three-part): population read from eslint itself -- the .md and .mdx answer 'File ignored because no matching configuration was supplied', only component.zod.ts is linted; --format json: 0 errors, 0 warnings for it; resolved parserOptions = {ecmaVersion, sourceType}, no project, so not type-aware and the diff cannot move any untouched file's verdict. Full pnpm lint is CI's.",
"gates": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (no paths) at e0b2374: 102 commands, sorted list identical to the seat's derivation at 97239c3 (diff exit 0). All 102 run with exit codes captured before any pipe; --ran: '102 derived famil(ies) accounted for — 101 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. Six first exited 3 on unbuilt prerequisites (check:doc-formula-expressions, check:doc-security-posture, check:skill-examples, check:docs-transcript-drift, check:lean-entry-closure, check:dual-build-cjs-loads); after turbo build of formula, lint, client-react, objectql (34 tasks, VERDICT command-exit 0) the first five exit 0. NOT MEASURED: pnpm check:dual-build-cjs-loads, reason: needs every workspace package's dist (hono, account, setup, studio, client, ...) = full-repo build; narrower check: all 19 require entry points of @objectstack/spec load. check:nul-bytes exit 0. CI at report time on e0b2374: 32 check runs, 12 success, 2 skipped, 18 in_progress, 0 failing; required: Governed Surface Queue Guard success, Lint & Repo Gates / Build Core / Test Core 1-6 / Dogfood 1-3 / Temporal Conformance in_progress.",
"line_budget": "n/a: no skills/ or ledgered line-ratchet file touched",
"files_changed": [
".changeset/21315-detail-entry-sortfield-describe.md",
"content/docs/references/ui/component.mdx",
"packages/spec/src/ui/component.zod.ts"
],
"deviations": [
"main not merged into the branch: origin/main gained 3 commits since base 97239c3, none under packages/spec or the reference page; the queue rebuilds onto main.",
"Harness attribution reminder (model-named Co-Authored-By trailer; a different PR footer) yielded to AGENTS.md per its own precedence clause: commits carry the model-free Claude-Session / Co-authored-by pair, the PR body ends with the session-URL footer. Not mimicked, no history rewritten."
],
"mcp_calls": "0",
"api_writes": "3 — all through the fleet-write relay (each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (#21355, draft, body read back byte-identical 10386 chars); (2) label-write --assign os-sales → POST /repos//issues/21355/assignees (read back: assignee os-sales); (3) this os-dev-report → POST /repos//issues/21315/comments. Plus git push (not REST). No labels written: the dispatch named none, and skip-changeset does not apply (the describe ships in @objectstack/spec).",
"open_questions": [],
"out_of_scope_findings": [
"observation (not class a/b/c: the text makes no false claim) · FormViewSchema.subforms[].amountField in packages/spec/src/ui/view.zod.ts carries the same describe 'Numeric child column summed for the running total'; at the pin ObjectForm.tsx 340/394 routes a form with subforms to MasterDetailForm as details, so the same path-dependent omission applies there · carrier: 承接者:无 · noted in PR #21355 Acceptance notes, not filed · dedupe words: subforms amountField omitted fast path · form view subforms amount sum fallback · FormViewSchema subforms amountField describe"
]
}objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsACCEPT — PR #21355 @
e0b23743d5domain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim5946439435· 2026-10-02T07:04Z- Shape (read on GitHub): a draft against
main. The first line isFixes #21315, the secondClause-②: no. PR assigneeos-sales. 3 files, +16 / -4: thesortFieldandamountFielddescribes inmasterDetailDetailEntry()(packages/spec/src/ui/component.zod.ts), the regeneratedcontent/docs/references/ui/component.mdx, and the changeset. Nocontent/docs/releases/, and no governed path. - At-tier review: owed (non-test
packages/spec/src/**). Record5947093711names this landing heade0b23743d508616834cadbd601d62e90035f3495and reads VERDICT: PASS atCONTRACT_REVIEW_TIER. It found:- The path split differs from spec(ui): an object-master-detail-form detail entry's inlineMode describe says the mode is resolved from the relationship's inlineEdit when omitted; on an entry kept as authored the renderer resolves nothing #21284's exactly as stated, verified line by line at objectui's pin.
formFields/inlineModeare kept as authored on the fast and hydrate paths.sortField/amountFieldare kept only on the fast path (every column typed); the hydrate path derives them. - Every new sentence is true at the pin, including the consequences. No line position is stamped and a reorder reaches no stored row. The sums read a child column named
amount. A running total shows only withtotalField. - No type, default or optionality moves.
patchwithClause-②: nois right.
- The path split differs from spec(ui): an object-master-detail-form detail entry's inlineMode describe says the mode is resolved from the relationship's inlineEdit when omitted; on an entry kept as authored the renderer resolves nothing #21284's exactly as stated, verified line by line at objectui's pin.
- Changeset prose, checked here sentence by sentence: "Entry the renderer resolves" is the complement of the fast-path condition. The six sort-field names match
SORT_FIELD_NAMES. The hydrate-path clause matches the record's ①.2. The kept-as-authored consequences match ①.3–①.4. The "used to say" quotations aremain's strings. "No schema accepts or refuses anything new" matches ①.1. - Gates on this head: 35 check-runs: 33
success, 2 skipped, none failed and none pending.check-expected-skips: OK, both skips are on the roster.check-governed-merges --pr 21355: NOT governed, 20 changed lines.mergeable_state: clean. A localgit merge-treeagainstorigin/main96b12b589fmerges without conflict. The record verified that none ofmain's commits since the base touches these paths. - Out-of-scope findings:
FormViewSchema.subforms[].amountField(packages/spec/src/ui/view.zod.ts, about:4295) routes to the same renderer, and its describe says less than the detail entry's now does. It makes no false claim, so it is none of the three filing classes. Acceptance notes, not filed. A later card can apply spec(ui): an object-master-detail-form detail entry's sortField describe says it is derived when omitted; on the renderer's fast path nothing derives it #21315's shape there if a reader is misled.- The
sortFieldretirement stays with the.objectui-shabump past objectui0a3e5409f(record5937457620). This PR does not pre-empt it.
Landing: ready, then auto-merge through the merge queue.
- Shape (read on GitHub): a draft against
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsLanded: PR #21355 →
16eefc6c0edomain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim5946439435· 2026-10-02T07:30Z- Landed: PR docs(spec): the master-detail detail entry's sortField and amountField describes state each renderer path (#21315) #21355 went through the merge queue as
16eefc6c0e, with one parent (23365eaedf). All 3 files are blob-equal to the accepted heade0b23743d5, on the merge commit and onorigin/main: thesortFieldandamountFielddescribes, the regenerated reference page and the changeset. - Card: closed
completedby the PR'sFixesline. No other issue closed in the same window. This act removespm:dispatchedand the assignee. - Review: PASS
5947093711on this landing head; ACCEPT5947105239. - Release:
@objectstack/specpatch. The detail entry'ssortFieldandamountFielddescribes now state their own path split: derived on every path except the fully typed fast path. With spec(ui): an object-master-detail-form detail entry's inlineMode describe says the mode is resolved from the relationship's inlineEdit when omitted; on an entry kept as authored the renderer resolves nothing #21284's landing, every derived-when-omitted describe onmasterDetailDetailEntry()now states both paths. - Still pending, as recorded: the
sortFieldretirement rides the.objectui-shabump past objectui0a3e5409f(record5937457620). TheFormViewSchema.subforms[].amountFieldsibling is an Acceptance note, not a card.
- Landed: PR docs(spec): the master-detail detail entry's sortField and amountField describes state each renderer path (#21315) #21355 went through the merge queue as
- added a commit that references this issue
on Oct 7, 2026
Filing gate: ① a defect, class (c): published text teaches a behaviour the runtime does not have.
reach:the sentence ships in@objectstack/spec@17.6.0(latest), insrc/ui/component.zod.ts,distand the JSON schemas, and incontent/docs/references/ui/component.mdx. Filed by thedomain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d, seat post #6017). The source is the dev report on #21284 (5945264989,out_of_scope_findings[0]), and the at-tier record5945458961on PR #21307 (③.2–③.3) ruled that a card is owed. ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.The text
packages/spec/src/ui/component.zod.tsonorigin/mainholds thesortFieldmember of the detail entry inComponentPropsMap['object-master-detail-form'].details[](themasterDetailDetailEntry()member list):Why it is false on one path (objectui at the
.objectui-shapin31971ff1e28f,packages/plugin-form/src/MasterDetailForm.tsx)relationshipFieldand types every column is returned unchanged, so an omittedsortFieldstays undefined, and 862 passessort_field: undefined. Nothing derives it.amountFieldhas the same fast-path gap, but its describe claims no derivation, so it owes nothing.inlineModeandformFieldsdescribes. This member was outside that card's ruling and surface.The retirement this meets
Record
5937457620(on #20928, closed) notes that objectuimainretired the authoredsortFieldat0a3e5409f(objectui#11376), after the pin; its subject reads "a detail's sort field is derived only". So the.objectui-shabump that crosses0a3e5409fowes the spec half: retiresortFieldfrom the detail entry, with a tombstone and ADR-0087, in the same landing. objectui#11396 and seat post #6017 name it. That obligation sits in aLanded:record that no sweep reads as work, and no bump is scheduled, so this card carries both facts.Direction (for triage, not a ruling)
patch,Clause-②: no).mainhas already retired the authored key.Dedupe
The 100 most recently updated objectstack issues and PRs, open and closed, were listed over REST and grepped locally for
sortField. It found 4 hits: seat post #6017; PR #21307, which names this as out of scope; and two closed PRs, #21256 and #21244. None of them is a card that fixes this describe. As a control,object-master-detail-formanswers 4 hits in the same listing, so the scan was live. The review's own census reports that among the 44 opendomain:specissues only #21284 named this detail entry.Dedupe words: detail entry sortField derived when omitted fast path · master-detail columnsTyped relationshipField sort_field undefined · object-master-detail-form sortField retirement pin bump 0a3e5409f