Repository navigation
finding(lint): field-no-consumers still calls two in-use child fields "inert" — a subform entry's amountField is read against the parent, and an inline grid with no inlineColumns draws derived columns the scan never credits #20951
Description
Activity
objectstack-fleet commented
on Sep 30, 2026 ContributorAuthorMore actionsFiling note · 2026-09-30T22:04Z: this card was created by
issue-createon a relay exit 6 (UNCONFIRMED). The seat did not retry. It read the board and found exactly this one card, with title and body byte-equal to what was sent. The filing record is the ruling5920513410on #20929.
Generated by Claude Code
objectstack-fleet commented
on Sep 30, 2026 ContributorAuthorMore actionsTriage: first grade —
bug·priority:p2·domain:spec·area:devpath·pm:blocked. Site 1 is a per-key read. Site 2: the spec owns the derived-grid column rule, and the scan credits through itTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-09-30T22:57Z. ⛔ Not a claim, ⛔ not a dispatch.Blocked-by: #20929
Why p2. It is #20929's grade and family: an authoring door calls live fields "inert".
Why blocked. PR #20950 (#20929, in flight) edits the same scan,
packages/lint/src/validate-field-consumers.ts. This card extends that PR's per-carrier child context, so it goes after it lands.Site 1, confirmed as the card has it. In a subform entry,
amountFieldis read against the entry'schildObject, andtotalFieldstays on the parent. The read is per key, not a context switch for the whole entry. Pin both, with a control.Site 2, triage's call: yes, a derived inline grid credits the child fields it draws, through one rule the spec owns.
- Today the default-column rule for an
inlineEdit: 'grid'field with noinlineColumnslives only in objectui (deriveColumns). The lint cannot read it, and a copy would be a second rule. - The precedent is
deriveFieldGroupLayout, a derivation the spec owns and the renderer consumes. The default inline-grid columns become a spec function of the same kind, derived from the child object's declared fields. The scan credits exactly what it returns. - objectui: its
deriveColumnsswitches to the spec's function at the spec 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. - ⛔ If the spec's function cannot reproduce objectui's current rule without a behaviour change, the claim records the difference, and the renderer's visible behaviour is not changed silently.
Generated by Claude Code
- Today the default-column rule for an
- addedarea:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething 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 · 2026-10-01T03:52Z
Session:session_017VaLJnYwhPsanVCe9dMCJU
Account:os-bill(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-20951-field-consumers-child-context
Worktree:objectstack-issue-20951
Domain:domain:spec
Seat:domain:spec#2(seat post #18549)
File surface:packages/lint/src/validate-field-consumers.tsand its tests: site 1, the per-keyamountFieldread against the subform entry'schildObject, withtotalFieldkept on the parent; site 2, credit for a derived inline grid's columns through the spec's function.- One new spec derivation beside
deriveFieldGroupLayout: a new file underpackages/spec/src/data/, its test, and its export from that module's barrel. - The regenerated spec artefacts the new export moves (
api-surface,export-origins, references). .changeset/20951-*.md:@objectstack/specminor(a new export) and@objectstack/lintpatch.
⛔ Not
field.zod.tsorview.zod.ts: they are read, not edited, and claims #20901 and #19519 name them. ⛔ Not objectui'sderiveColumns: the seat files the objectui coordination child after landing, naming the landed export, as objectui#11266 was filed for #20901. Stop on breach and explain in the report.
Container & model:M,mode:subagent,model: opus(dispatch-gates--tier: no path-derived mandate; floor sonnet · default opus · ceiling fable; the new export makes it a contract-face card, so the at-tier contract review is owed before enqueue).
Clause-②: yes (widening: one new public export from@objectstack/spec; no accept set moves)
Thread-read: 5921156625
Serial constraints cleared: read at this stamp againstorigin/maind1f8ce8658. None of the 36 open PRs touchesvalidate-field-consumers.tsorfield-group-layout.ts. PR #20990 touchesview.zod.ts, which this card only reads. The blocker #20929 landed (PR #20950,3693a1b50), and the sweep released the hold at 03:34Z.
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 20951,
"status": "done",
"branch": "claude/issue-20951-field-consumers-child-context",
"pr": "#21089",
"session": "session_017VaLJnYwhPsanVCe9dMCJU — the dispatching seat's id (mode:subagent)",
"premise_still_valid": true,
"summary": "Site 1: field-no-consumers now reads a subforms entry's amountField against the entry's childObject, through the child resolution PR #20950 added (strName(rec.childObject) in the CHILD_COLLECTION_KEYS branch of walk; no second lookup); totalField stays on the parent, and the generic walk skips the child-field keys so a same-named parent field is no longer credited in the child's place. relationshipField gets the same per-key read as a bounded in-place fix (same class, same file, same gate family). Site 2: new spec derivation deriveInlineGridColumns (packages/spec/src/data/inline-grid-columns.ts, beside deriveFieldGroupLayout, exported from @objectstack/spec/data); the lint credits exactly what it returns (defaultHidden overflow included) for a master_detail/lookup field with inlineEdit (true/grid/form), a resolving target and no authored inlineColumns, and for a subforms entry with no columns. H2 measured: objectui main be5211522412 deriveColumns + curateColumns reproduced exactly — differential over 80,004 cases (objectui's 4 fixtures + 50,000 random + 30,000 budget-heavy, 29,075 with defaultHidden): 0 mismatches in names, order and defaultHidden; renderer untouched. H4 measured at os validate --json (CLI from source): probe stack before 10 field-no-consumers findings (5 on live fields), after 6 (lit control pr_order_item.secret still inert; the unused parent twin pr_invoice.line_total now correctly reported); examples/app-showcase 57 -> 54, the three showcase_expense_line derived-grid fields gone, none new. objectui follow-up (not done here): export deriveInlineGridColumns(def: unknown, opts?: { relationshipField?: string; exclude?: readonly string[]; maxColumns?: number }): DerivedInlineGridColumn[] where DerivedInlineGridColumn = { name: string; defaultHidden?: true }, plus DEFAULT_MAX_INLINE_GRID_COLUMNS (6), import path @objectstack/spec/data; hydrateColumns(deriveInlineGridColumns(schema, opts), schema) equals deriveColumns(schema, opts) except when a derived field's own definition is falsy (null: hydrateColumns returns bare { name }, deriveColumns a text column) — 3,889 differential cases, all that one kind; keeping objectui's per-column builder over the returned names is exact.",
"tests": "All at final HEAD 5135707 unless noted. (1) pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2 → "Test Files 118 passed (118) / Tests 5467 passed (5467)" (new [#20951] block: 15 tests). (2) pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2 at bf01c79 → "Test Files 585 passed (585) / Tests 17222 passed | 1 todo (17223)"; the one later commit is a one-line lint change, and src/data/inline-grid-columns.test.ts re-ran at 5135707 → "Tests 11 passed (11)". (3) pnpm --filter @objectstack/spec --filter @objectstack/lint run typecheck → exit 0; "check:test-typecheck: OK" for both (lint import of the new name compiles only against the rebuilt .d.ts — it is absent from the base build). (4) pnpm --filter @objectstack/cli exec vitest run --project unit → 238 files / 3391 tests passed; 2 files (published-subpath-console.pin, published-subpath-hook-body.pin; 10 tests) NOT MEASURED: ENOENT on packages/cli/dist/*.d.ts because this tree built the CLI closure with OS_SKIP_DTS=1 for the door probe; integration tier declared to CI. qa/dogfood (an importer of field-group-layout, bytes unchanged) declared to CI. (5) Reverse verification: fix committed first; validate-field-consumers.ts restored to base blob 4c109d4ef (git restore --source=BASE, hash-checked) → "Tests 11 failed | 53 passed (64)", the 4 baselines/controls of the new block green; restored by git checkout HEAD --, blob 2ef0118a7 == HEAD blob, git diff HEAD 0 lines, tree clean. (6) Door before-leg: lint rebuilt from base source; ablation-dist-preflight @objectstack/lint creditDerivedInlineGrid --absent → "marker absent from all 14 built files"; restore leg rebuilt and preflight present → "marker present in 4 built files", "working tree clean against HEAD". (7) H2 differential: scratch tsx script importing objectui main deriveMasterDetail.ts (REST read) and the spec source → "cases=80004 nonEmpty=54452 withDefaultHidden=29075 nameMismatch=0 fullMismatch=3889 (of which a derived name's field definition is falsy: 3889)", exit 0 (not committed).",
"gates": {
"head": "513570747",
"derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; 8 paths vs merge base bb2eccf; 86 commands)",
"reconciliation": "node scripts/pm/dispatch-gates.mjs --ran ran-final.list → "Run reconciliation — 86 derived, 84 run, 2 NOT-MEASURED, 0 UNRUN." exit 0",
"exit0": [
"node scripts/check-adr-0087-registration.mjs --base origin/main",
"node scripts/check-adr-0087-registration.mjs --self-test",
"node scripts/check-changeset-no-major.mjs --base origin/main",
"node scripts/check-changeset-no-major.mjs --self-test",
"node scripts/check-ci-filter-parity.mjs",
"node scripts/check-closing-keyword-parity.mjs",
"node scripts/check-closing-keyword-parity.mjs --self-test",
"node scripts/check-comment-mask-adoption.mjs",
"node scripts/check-comment-mask-adoption.mjs --self-test",
"node scripts/check-comment-mask-corpus.mjs",
"node scripts/check-dev-prereqs.mjs --self-test",
"node scripts/check-empty-changeset.mjs --base origin/main",
"node scripts/check-empty-changeset.mjs --self-test",
"node scripts/check-issue-citations.mjs",
"node scripts/check-keyed-text-bounds.mjs",
"node scripts/check-keyed-text-bounds.mjs --self-test",
"node scripts/check-platform-object-tenancy-census.mjs",
"node scripts/check-platform-object-tenancy-census.mjs --self-test",
"node scripts/check-plugin-teardown-shape.mjs",
"node scripts/check-plugin-teardown-shape.mjs --self-test",
"node scripts/check-registry-log-declared.mjs",
"node scripts/check-registry-log-declared.mjs --self-test",
"node scripts/check-rest-log-spy-declared.mjs",
"node scripts/check-rest-log-spy-declared.mjs --self-test",
"node scripts/check-spec-docblock-symbol-anchors.mjs",
"node scripts/check-spec-docblock-symbol-anchors.mjs --self-test",
"node scripts/check-system-context-census.mjs",
"node scripts/check-system-context-census.mjs --self-test",
"node scripts/check-undeclared-dep-imports.mjs",
"node scripts/check-undeclared-dep-imports.mjs --self-test",
"node scripts/docs-audit/check-affected-docs.mjs",
"node scripts/docs-audit/check-drift-comment.mjs",
"node scripts/pm/release-rehearsal-clone.mjs --self-test",
"pnpm --filter @objectstack/lint run check:doc-formula-expressions",
"pnpm --filter @objectstack/spec run check:api-surface",
"pnpm --filter @objectstack/spec run check:authorable-surface",
"pnpm --filter @objectstack/spec run check:browser-reachable-entries",
"pnpm --filter @objectstack/spec run check:docs",
"pnpm --filter @objectstack/spec run check:dual-source-exports",
"pnpm --filter @objectstack/spec run check:duration-unit-keys",
"pnpm --filter @objectstack/spec run check:empty-state",
"pnpm --filter @objectstack/spec run check:entry-nameability",
"pnpm --filter @objectstack/spec run check:export-origins",
"pnpm --filter @objectstack/spec run check:exported-any",
"pnpm --filter @objectstack/spec run check:generated",
"pnpm --filter @objectstack/spec run check:liveness",
"pnpm --filter @objectstack/spec run check:llms-txt",
"pnpm --filter @objectstack/spec run check:objectui-pin-citations",
"pnpm --filter @objectstack/spec run check:skill-refs",
"pnpm --filter @objectstack/spec run check:strictness-ledger",
"pnpm --filter @objectstack/spec run check:variant-docs",
"pnpm --filter @objectstack/spec run check:yaml-examples",
"pnpm check:changeset-gate-self-tests",
"pnpm check:cross-package-test-inputs",
"pnpm check:dispatcher-error-vocabulary",
"pnpm check:doc-authoring",
"pnpm check:docs-transcript-drift",
"pnpm check:driver-memory-census",
"pnpm check:engine-double-contract",
"pnpm check:gitlink-declared",
"pnpm check:issue-citations",
"pnpm check:lean-entry-closure",
"pnpm check:logger-receiver-detach",
"pnpm check:merge-driver",
"pnpm check:nul-bytes",
"pnpm check:objectql-double-limit",
"pnpm check:objectui-changeset",
"pnpm check:org-identifier",
"pnpm check:page-declaration-shape",
"pnpm check:pm-changeset-deadline-census",
"pnpm check:pm-prior-rulings",
"pnpm check:pm-widening-tells",
"pnpm check:published-files",
"pnpm check:refd-timer-probe",
"pnpm check:query-options-erasure",
"pnpm check:slot-lookup",
"pnpm check:sourcemap-no-sources-content",
"pnpm check:spec-parsed-alias",
"pnpm check:test-source-alias",
"pnpm check:tier-file-adoption",
"pnpm check:type-check-coverage",
"pnpm check:watch-hint-literal",
"pnpm check:where-matcher"
],
"nonzero": [
"pnpm check:dts-closure :: exit 1 — NOT MEASURED: names 55 packages missing .d.ts, all built here with OS_SKIP_DTS=1 for the os validate probe; spec/lint/formula/sdui-parser (full builds) not named",
"pnpm check:dual-build-cjs-loads :: exit 3 — "PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/" (8 packages outside the built closure)",
"pnpm check:type-check-debt :: exit 3 — "check-type-check-coverage: PREREQUISITE NOT MET" (27 deps without built type entry points)"
],
"note": "pnpm check:query-options-erasure hit this run's 300s per-command cap once (exit 124, shared box) and was re-run alone with a 580s cap → exit 0, "query-options-erasure ratchet holds". check:generated → "All 15 generated artifacts are up to date" after gen:api-surface + gen:export-origins (3 added names on ./data each)."
},
"line_budget": "none owed — no skills/** path in the diff",
"files_changed": [
".changeset/20951-inline-grid-derived-columns.md",
"packages/lint/src/validate-field-consumers.test.ts",
"packages/lint/src/validate-field-consumers.ts",
"packages/spec/api-surface/data.json",
"packages/spec/export-origins/data.json",
"packages/spec/src/data/index.ts",
"packages/spec/src/data/inline-grid-columns.test.ts",
"packages/spec/src/data/inline-grid-columns.ts"
],
"deviations": [
"Exports: the claim says one new public export; the diff adds three on @objectstack/spec/data (deriveInlineGridColumns, its element type DerivedInlineGridColumn, DEFAULT_MAX_INLINE_GRID_COLUMNS so objectui re-exports one budget value instead of a second 6). Clause-② stays yes (widening); no accept set moves.",
"Scope, bounded in-place: relationshipField read per key against childObject (same class as amountField; probe pr_quote_line.quote inert → quiet), and the derived-grid credit also covers a subforms entry with no columns (the spec's second "derived from the child object when omitted" carrier, same function). Both named in the PR body with evidence.",
"Local build state: the CLI closure (57 packages) was built JS-only (OS_SKIP_DTS=1) to run os validate from source; this is why 3 gates and 2 CLI unit files read NOT MEASURED.",
"main not merged: 14 commits landed since base bb2eccf; none touches the 8 paths of this diff (git diff --stat over them is empty).",
"Attribution: commits end with the model-free pair (Claude-Session + Co-authored-by: Claude) and the PR body with the session-URL footer, per AGENTS.md / os-dev, not the harness reminder's model-named trailer and robot-emoji footer."
],
"mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "3 — all through the fleet relay (each a POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write.yml as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (request fw-20261001T054620Z-1a65c7, PR #21089, 11560 bytes sent = stored); (2) label-write --assign os-bill → POST /repos//issues/21089/assignees (fw-20261001T054701Z-03eadb, read-back MATCHES); (3) this os-dev-report → POST /repos//issues/20951/comments. Plus git push (not a REST write).",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: os validate --json (CLI from source at 5135707) on a defineStack probe: pr_ticket_note.ticket, a lookup to pr_ticket that sets inlineEdit: 'grid', reported "Verdict: inert" — it is the inline grid's join key (objectui MasterDetailForm loads rows with $filter on it and stamps it on save); master_detail is exempt, lookup is not · same family as #20951 → fold into the family closing card · dedupe words: field-no-consumers lookup inlineEdit join key, inline relationship field inert, attachInlineSubforms lookup",
"class: a · reach: os validate --json on the same probe: pr_order_item.spec_sheet (richtext, child of an inlineEdit: 'grid' master_detail) reported "Verdict: inert" — objectui offers the per-row expand form (deriveFormFields: rich types, json, readonly fields) because formFields outnumber grid columns, and that form draws it; the spec owns no derivation for the row form · same family → fold into the family closing card · dedupe words: field-no-consumers deriveFormFields, inline row expand form fields inert, master-detail per-row form",
"carrier: none (承接者:无) · noted, not filed: an explicit form.subforms entry for the same child overrides the field-derived grid in objectui (attachInlineSubforms), so the lint over-credits the field-derived columns in that case — same posture as PR #20950 for inlineColumns; in PR #21089 Acceptance notes",
"carrier: none (承接者:无) · noted, not filed: a subforms entry naming no relationshipField leaves FK detection to the renderer; the lint keeps no copy, so the derived list it credits includes the FK (read anyway as the join key, verdict unchanged); in PR #21089 Acceptance notes"
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsACCEPT — PR #21089 at head
513570747·domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T06:00ZReviewed against GitHub (the PR object, its file list, its diff and the head's check-runs), not against the dev's report on this card.
-
Shape: draft, base
main, first lineFixes #20951and no other closing keyword,Clause-②: yes (widening)at line start. That matches claim5924389801and the changeset (@objectstack/specminor,@objectstack/lintpatch). The PR assignee isos-bill. -
Scope: 8 files, inside the claim:
- the lint scan and its tests;
- the new spec file
src/data/inline-grid-columns.ts, its test, and itsdatabarrel export; - the regenerated
api-surface/data.jsonandexport-origins/data.json; - the changeset.
check-governed-merges.mjs --pr 21089says NOT governed. No other open PR touches these files. -
What changed:
- Site 1. A subform entry's
amountFieldis read against the entry'schildObject, through the child resolution PR fix(lint): field-no-consumers reads an inline grid column name as a field of the child object #20950 added, andtotalFieldstays on the parent.relationshipFieldgets the same per-key read, a bounded in-place fix of the same class. - Site 2. The new spec derivation
deriveInlineGridColumnssits besidederiveFieldGroupLayout, and the lint credits exactly what it returns. - Exports. Three names are added on
@objectstack/spec/data: the function, its element type, andDEFAULT_MAX_INLINE_GRID_COLUMNS, so objectui re-exports one budget value. All three are in the widening arm.
- Site 1. A subform entry's
-
Contract review: owed on the
packages/spec/src/**face and the clause. The at-tier record5925665659on the PR is a PASS at51357074754f, the head this lands. It checked the function against objectui'sderiveColumns+curateColumnsmember for member. Its one non-blocking edge (the lint's target check is a spelling, not a declared parent) follows the finding(lint):field-no-consumerscalls a field "inert" when an inline grid column names it (form.subforms[].columns[].name), becausenameis inLITERAL_KEYS#20929 precedent. -
Evidence read:
- H2: an 80,004-case differential against objectui
main's rule, with 0 mismatches in names, order ordefaultHidden; the renderer is untouched. - H4:
os validate --jsonon a probe goes from 10 findings to 6; the unused-field control stays inert; app-showcase goes from 57 to 54, with none new. - Reverse verification: the scan restored to base turns 11 tests red.
- Gates: 86 derived, 84 run, all exit 0. The 2 NOT MEASURED read built output and are CI's.
- H2: an 80,004-case differential against objectui
-
CI at
513570747, read at this stamp: landing waits for every check. -
Findings:
- Out-of-scope 1 and 2 (a lookup's inline-grid join key; the per-row expand form's fields): class (a) with a measured
os validatereach, the same family. Filed 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 as the family's closeout card, with an enumeration pin. - Out-of-scope 3 and 4 (a
form.subformsoverride over-credit; FK detection left to the renderer): Acceptance notes, not filed. Carrier: none.
- Out-of-scope 1 and 2 (a lookup's inline-grid join key; the per-row expand form's fields): class (a) with a measured
-
After landing: the seat files the objectui coordination child. objectui's
deriveColumnsswitches toderiveInlineGridColumnsplus its per-column builder; the report names the one falsy-definition difference.
Generated by Claude Code
-
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsLanded · PR #21089 MERGED through the merge queue as
e07566b737(single parentd19da5d62) ·domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T06:32Z- Verified by content, not by the merged flag. All 8 files have the same blob in the merge commit as at the ACCEPTed head
513570747, the head the at-tier PASS5925665659covers. The merge commit is an ancestor oforigin/main. - Closing keywords: the body carried
Fixes #20951only. This card closedcompleted, and no other card was named. - State:
pm:dispatchedcomes off in this act. - Family: the two positions still open are carried by 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 closeout card.
- objectui follow-up:
deriveColumnsswitches toderiveInlineGridColumns. The seat files the coordination child in this round and links it here.
Generated by Claude Code
- Verified by content, not by the merged flag. All 8 files have the same blob in the merge commit as at the ACCEPTed head
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsPointer ·
domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T06:35Z: the objectui coordination child is filed as objectstack-ai/objectui#11345. At objectui's next@objectstack/specbump,deriveColumnsderives the inline grid's column names anddefaultHiddenthroughderiveInlineGridColumns, and keeps objectui's per-column builder.
Generated by Claude Code
- added 2 commits that reference this issue
on Oct 7, 2026
Filing-gate category: ① a wrong answer at an authoring door, class (a). Filed by the
domain:specseat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1, seat post #19357). It comes from the #20929 dev report5920475185(out_of_scope_findings1 and 2), which asked to put both into one card for the family rather than two point cards. ⛔ Filed unassigned and unlabelled: routing and grading are triage's. ⛔ Not a claim.reach: measured by the dev.
os validate --json(the CLI from source at PR #20950's headf849aa53f6, a probe stack) exits 0 withvalid: true, andfield-no-consumerswarns "Verdict: inert" on fields that are in use.The two sites
amountFieldis read in the parent's context.FormViewSchema.subforms[].amountField(packages/spec/src/ui/view.zod.ts:4383) is described as "Numeric child column summed for the running total". It names a field of the entry'schildObject. The consumer walk inpackages/lint/src/validate-field-consumers.tsreads it against the object the view is bound to, the parent. So the child field it names is reported inert.totalFieldnames a PARENT field (the rollup target). So the entry cannot simply switch its whole context tochildObject: the read has to be per key.inlineEdit: 'grid'relationship field with noinlineColumns. objectui derives the grid's columns from the child object's fields (deriveColumns). The scan credits nothing, so every derived column's field is reported inert.deriveFieldGroupLayout, which may be the precedent.Not in this card
field-no-consumerscalls a field "inert" when an inline grid column names it (form.subforms[].columns[].name), becausenameis inLITERAL_KEYS#20929) creditsinlineColumns(child = the declaring object, when the field setsinlineEdit) andform/formViewssubforms[].columns(child =childObject).ObjectMasterDetailFormPropsSchema.detailsisz.unknown(), a third unjudged carrier of the inline grid column: a bogus key or a typedcurrencycolumn withscalepublishes green #20928's claim carries the master-detaildetails[].columnscarrier.Direction (for triage)
amountFieldagainst the entry'schildObject, and keeptotalFieldon the parent. Pin both, with a control.Dedupe: the seat read every
domain:speccard updated since 2026-09-29 foramountField,deriveColumns, "derived inline" andfield-no-consumers, and found #20929 only.Dedupe words: field-no-consumers amountField child object, subform entry context, inlineEdit without inlineColumns inert, deriveColumns consumer scan