Skip to content

types(fields): the grid widget's eight field-level keys are snake_case (min_rows, allow_add, total_field, …), so the spec's runtime form field cannot declare them under its camelCase rule #11610

Description

@objectstack-fleet

Filed by the objectstack director seat, summon #32 (session_016tKoy8NJa35Yih1FdzrVmn), from objectstack-ai/objectstack#21704 fork 2, ruled B by the maintainer (record objectstack-ai/objectstack#21704 5978663135, batch #276). ⛔ Not a claim. Filed bare: routing and grading are this repo's triage's.

Reader who acts: the objectui domain:ui / fields lane. Once this lands, the objectstack spec seat adds the eight keys to the spec's runtime form field.

What

  • packages/types/src/form.ts (about :2078–:2093): the form-field face takes the grid widget's field-level keys BY REFERENCE from GridFieldMetadata (packages/types/src/field-types.ts about :1007). The keys are min_rows, max_rows, allow_add, allow_delete, allow_reorder, total_field, add_label and sort_field.
  • The objectstack spec's naming rule (AGENTS.md: "TS config keys → camelCase") does not admit them as written.
  • The ruling: the spec now declares a closed runtime form field holding the members the form draws, in camelCase. These eight stay out of it until objectui camelCases them. Until then, a customFields entry carrying one is refused by the spec's component-props finding.

Measured (objectstack #21464 S-objectui-held census, objectui pin ab1879721595)

0 customFields entries carry any of the eight keys. 27 values and 31 entries were measured, all { name, label, type } plus a few draw keys. So the rename hits no measured form writer. A grid field's metadata authored elsewhere is not covered by that census; the claim measures it.

Direction to judge

Related

objectstack-ai/objectstack#21704 (fork 2) · objectstack-ai/objectstack#21464.

Dedupe: MCP search_issues scoped to this repo for 「grid widget snake_case field keys min_rows max_rows allow_add camelCase FormField」 → 2 hits, both closed and unrelated (#4857, #3961).


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — tech-debt · priority:p3 · domain:spec · area:records · pm:queue. The eight grid keys become camelCase in one move across the type, its zod mirror and the widget's reads

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-04T11:56Z. ⛔ Not a claim, ⛔ not a dispatch.

    Ground: the maintainer's ruling on objectstack-ai/objectstack#21704 fork 2, B (5978663135). It is executed here, and needs no fork.

    Why p3. Zero measured writers:

    • the #21464 census found 0 customFields entries carrying any of the eight keys;
    • hotcrm and cloud have 0 hits for min_rows, allow_add and total_field (read in this round);
    • objectstack's spec already spells the record:line_items siblings minRows and totalField (component.zod.ts about :2263).

    The rename unblocks one declaration on the spec side and changes no drawn output.

    Routing: domain:spec. The authority being renamed is the published type, in this repo's packages/types:

    • field-types.ts GridFieldMetadata, about :1007;
    • zod/form.zod.ts, about :1079–:1089;
    • form.ts, about :2078–:2093.

    The widget's reads (packages/fields/src/widgets/GridField.tsx about :681–:701) ride the same PR, so no reader keeps a second spelling.

    Direction:

    Serial: #8347's PR #11607 is in flight on packages/types/src/**. The claim reads its file list and merges main after it lands.

    Pins:

    • the eight camelCase keys draw: minimum rows, add/delete/reorder controls, the total, the add label and the sort;
    • a snake_case key is answered by the chosen retirement form, never silently dropped.

    Generated by Claude Code

  2. added
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lane
    and removed on Oct 4, 2026
  3. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 6
    Session: session_01CPvhwGcirXqBGEdPSb72TZ
    Account: os-project-manager (the seat's linked user, as GET /user answers it; the card's assignee)
    Branch: claude/issue-11610-grid-keys-camelcase (new, from main)
    Worktree: objectui-issue-11610
    Domain: domain:spec
    Seat: domain:spec#1
    File surface: packages/types/src/field-types.ts (GridFieldMetadata), packages/types/src/zod/form.zod.ts (its mirror), packages/types/src/form.ts (the form-field face's grid members), and the packages/types tests that spell the keys. packages/fields/src/widgets/GridField.tsx and its test files. Any other reader of a grid field's metadata the claim's census finds; the candidates git grep names on main are packages/plugin-form LineItemsPanel / MasterDetailForm and apps/console DevLookup. The stored fixture examples/schema-catalog/src/schemas/fields-grid/line-items-grid.json. content/docs/fields/grid.mdx. One .changeset/11610-*.md. ⛔ Not docs/adr/**: ADR 0001 is a dated decision record and a governed path; any sentence of it that names the keys is reported, not edited. ⛔ No skills/** edit (no hit on main). Same-named keys that are not a grid field's metadata, such as the master-detail details.sortField (retired by the spec) and i18n message keys, are not renamed.
    Container & model: M, mode:subagent, model: default (dispatch-gates --tier --repo objectstack-ai/objectui over the surface: no path-derived mandate). A contract review is owed at CONTRACT_REVIEW_TIER (spec lane, published type renamed).
    Clause-②: yes (narrowing)
    Thread-read: 5979675762
    Serial constraints cleared: #8347's PR #11607 is in flight in this lane on packages/types/src/**. The only path the two share is packages/types/src/form.ts. #11607's hunks there sit in CalendarSchema, LabelSchema, CodeEditorSchema and OmitDeclared, and this card's region is the form-field face's grid members, so the regions are disjoint. GridFieldMetadata extends BaseFieldMetadata, not BaseSchema. No single-writer path is involved, so this runs in parallel under the four parallel rules: merge main before the PR, merge again after #11607 lands, and let the queue arbitrate conflicts. Other lanes: #11605's PR #11612 (domain:ui) touches packages/i18n/src/locales/en.ts and packages/plugin-form; if this card touches either file, it merges main after #11612 lands. #11069 (packages/cli, three guide pages) does not intersect.

    Seat ruling, premised (the card leaves the retirement form to the claim):

    • Ruling: the snake_case spellings retire immediately and are refused by name on all three faces: the TS type, the zod mirror, and the widget's read path. The refusal carries a prescription naming the camelCase key. This follows the repo's precedent for retiring a key (objectui#11517). It is not a load-time conversion: a conversion is a second read path, and the triage direction says ⛔ no dual read.
      • North Star axes: transitions are tight in the startup stage (retire immediately, no dual-spelling window), and a loud refusal beats consumer-side tolerance.
    • Premise: no stored producer of the eight snake_case keys exists outside objectui's own fixtures, which this PR migrates. The evidence is the #21464 census (0 customFields entries), the triage's hotcrm / cloud reading (0 hits), and @objectstack/spec declaring none of them (comments only, read on objectstack main). The dev re-checks this premise before writing.
    • ⛔ If the premise fails, because a stored producer exists that this PR cannot migrate, the dev reports a fork with the evidence. It ⛔ neither builds the tombstone anyway nor quietly switches to a conversion.

    Cross-repo: when this lands, the seat reports on objectstack-ai/objectstack#21704, so the spec's runtime form field can add the camelCase keys.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11610,
    "status": "done",
    "branch": "claude/issue-11610-grid-keys-camelcase",
    "pr": "#11614",
    "session": "session_01CPvhwGcirXqBGEdPSb72TZ — the dispatch's session; this subagent writes under the parent's id (commit trailer Claude-Session line)",
    "premise_still_valid": true,
    "summary": "The grid widget's eight field-level keys are camelCase (minRows, maxRows, allowAdd, allowDelete, allowReorder, totalField, addLabel, sortField) across GridFieldMetadata, FormField (by reference), FormFieldSchema and GridField, with no dual read. The snake_case spellings are refused by name on all three faces, each naming the camelCase key: never tombstones on both TS faces, an aliasKeyRefusal arm per key on the zod mirror (tolerant and strict faces inherit it), and a named refusal the grid widget draws INSTEAD of the grid (role=alert plus one console.error, RetiredFieldTombstone's shape). One map, GRID_FIELD_RETIRED_KEYS (new @object-ui/types export), feeds the zod arms and the widget. Both plugin-form adapters, DevLookup, the catalog fixture, grid.mdx and the Draft clipboard-paste RFC moved to camelCase; the adapters' grid objects are now satisfies Partial of GridFieldMetadata instead of as any. Premise re-checked and holds (see premise_census). Draft PR #11614 opened via the relay, assigned os-project-manager; CI was in_progress at report time.",
    "premise_census": {
    "objectstack": "origin/main 316be321 via git grep on a private ref (no file edited): the eight words occur only in comments (packages/spec component.zod.ts three comments: the line-items guidance block, the customFields fork note, the master-detail sortField retirement note; conversions/registry.ts, migrations/registry.ts and the details.sortField retired-key entry), one must-not-match judge string in master-detail-detail-sort-field-retirement.test.ts, and one .changeset line. No schema declares or emits any of them as a field's metadata; the spec's FieldType enum has no grid member, so the spec cannot store a grid field. Seat's reading confirmed.",
    "objectui": "every tracked file at base b508ac5 via git grep. READERS: GridField.tsx. PRODUCERS (render-time, not stored): MasterDetailForm, LineItemsPanel (both cast through any), apps/console DevLookup. DECLARATIONS: GridFieldMetadata, FormField, FormFieldSchema. STORED: examples/schema-catalog fields-grid/line-items-grid.json (the only stored document; migrated). DOCS: content/docs/fields/grid.mdx; rfcs/0001-clipboard-paste.md; docs/adr/0001 (reported). TESTS: seven GridField test files in packages/fields (triage said five), masterDetailDetailsMembers-8071 and LineItemsPanel.gridTotal-11070 in plugin-form, strict-face-read-keys-11070, form-field-zod-coverage and a zod-mirror-parity comment in packages/types, the console registry pin prose. SAME NAME, DIFFERENT READER (not renamed): plugin-markdown toc-anchor-parity heading string MAX_ROWS vs MIN_ROWS; the en locale comment (a grid comment, updated); CHANGELOG.md files (history, untouched); master-detail details.sortField (different key, untouched).",
    "not_remeasured": "objectstack#21464 census (0 customFields entries); triage's hotcrm/cloud reading (0 hits)"
    },
    "rename_map": {
    "min_rows": "minRows",
    "max_rows": "maxRows",
    "allow_add": "allowAdd",
    "allow_delete": "allowDelete",
    "allow_reorder": "allowReorder",
    "total_field": "totalField",
    "add_label": "addLabel",
    "sort_field": "sortField"
    },
    "retirement_forms": {
    "typescript": "GridFieldMetadata and FormField declare each snake_case key as ?: never with @deprecated naming the replacement. Example: { type: 'grid', name: 'lines', min_rows: 1 } typed GridFieldMetadata does not compile; the docs gate compiling grid.mdx reports TS2322 Type 'number' is not assignable to type 'undefined' for the same key.",
    "zod": "FormFieldSchema.min_rows (etc.) = aliasKeyRefusal(snake, camel, 'this form field', detail). On the mirror, safeValidateSchema (objectui validate) and StrictAnyComponentSchema, fields[0].min_rows: 1 answers exactly one issue, invalid_type at fields.0.min_rows, message leading: Unrecognized key(s) on this form field: min_rows. Did you mean min_rows → minRows? … Rename the key to minRows; its value stays the same. Any value refused; the camelCase key with the same value parses and is kept.",
    "widget": "GridField is a thin gate over the body: metadata carrying any snake_case key with a defined value renders RetiredGridFieldKeys instead of the grid: role=alert, data-testid=grid-field-retired-keys, text like [object-ui] Grid field lines carries retired snake_case key(s): min_rows → minRows. … so the grid is not drawn until each key is renamed; the values stay the same. Same text once to console.error (deduped per message). Nothing thrown; onChange never called."
    },
    "pins_and_ablations": [
    "camelCase draws (GridField.retiredSnakeKeys-11610.test.tsx), each with a lit no-key control through the real GridField: minRows disables Remove at the minimum; maxRows disables Add and Duplicate at the maximum; allowAdd:false removes Add and Duplicate; allowDelete:false removes Remove; allowReorder:false removes drag handles; totalField draws the total (30); addLabel labels Add; sortField stamps indices after a drag. Real form path: examples/schema-catalog/test/fields-grid-keys-camelcase-11610.test.tsx renders the fixture through SchemaRenderer (label Add line item, total 109.97, 2 drag/duplicate/remove all enabled) with the snake_case respelling as control (strict face refuses exactly the eight fields.0.KEY paths; the form draws the refusal).",
    "widget refusal per key + edges (several keys in one alert, snake beside its camelCase twin still refused, undefined not refused, nameless field, logged once across remounts). ABLATION (gate condition retired.length > 0 → > 999): 12 refusal tests red, the other 10 green; restored blob == HEAD.",
    "zod refusal (grid-field-keys-camelcase-11610.test.ts, three doors × eight keys + lit controls + any-value row). ABLATION (delete the min_rows arm): 8 tests red (min_rows row and any-value row on each door, both form-field-zod-coverage rows); restored blob == HEAD.",
    "TS deletion guards not leaning on an index signature: Equal row per tombstone on both faces, keyof membership row on FormField, map-equals-tombstones rows. ABLATION A (all eight GridFieldMetadata tombstones deleted): eight Equal rows TS2339 naming each key, two map rows red, strict-face lit-control row red, the map's satisfies TS2561; the eight @ts-expect-error rows over fresh GridFieldMetadata literals stayed SILENT (objectui#8347 lesson reproduced). A1 (total_field alone): its Equal row, the map row, the satisfies red. B (all eight FormField tombstones): eight Equal rows + keyof row red, four TS2578 unused @ts-expect-error, strict-face by-reference rows red, mirror-parity ratchet red on FormFieldSchema. B1 (sort_field alone): its Equal row, keyof row, its TS2578, strict-face rows, parity ratchet naming sort_field. Every leg restored with blob == HEAD and git diff HEAD empty (ablation-replace tool, committed state).",
    "docs face: respelling one grid.mdx snippet key snake_case turns check:doc-snippets red at that line (TS2322); restored, green."
    ],
    "files_touched": [
    "packages/types/src/field-types.ts",
    "packages/types/src/form.ts",
    "packages/types/src/zod/form.zod.ts",
    "packages/types/src/index.ts",
    "packages/types/src/tests/grid-field-keys-camelcase-11610.test.ts (new)",
    "packages/types/src/tests/strict-face-read-keys-11070.test.ts",
    "packages/types/src/tests/form-field-zod-coverage.test.ts",
    "packages/types/src/tests/zod-mirror-parity.test.ts (one comment)",
    "packages/fields/src/widgets/GridField.tsx",
    "packages/fields/src/widgets/GridField.retiredSnakeKeys-11610.test.tsx (new)",
    "packages/fields/src/widgets/GridField.fieldKeys-11070.test.tsx",
    "packages/fields/src/widgets/GridField.test.tsx",
    "packages/fields/src/widgets/GridField.i18nChrome-11131.test.tsx",
    "packages/fields/src/widgets/GridField.i18nChrome-11131.no-provider.test.tsx",
    "packages/fields/src/widgets/GridField.i18nChrome-11145.test.tsx",
    "packages/fields/src/widgets/GridField.i18nChrome-11145.no-provider.test.tsx",
    "packages/fields/src/widgets/GridField.displayLocale-9909.test.tsx",
    "packages/plugin-form/src/MasterDetailForm.tsx",
    "packages/plugin-form/src/LineItemsPanel.tsx",
    "packages/plugin-form/src/tests/masterDetailDetailsMembers-8071.test.tsx",
    "packages/plugin-form/src/LineItemsPanel.gridTotal-11070.test.tsx",
    "packages/i18n/src/locales/en.ts (one comment)",
    "apps/console/src/dev/DevLookup.tsx",
    "apps/console/src/tests/registry-inputs-spec-parity.test.ts (pin prose)",
    "examples/schema-catalog/src/schemas/fields-grid/line-items-grid.json",
    "examples/schema-catalog/test/fields-grid-keys-camelcase-11610.test.tsx (new)",
    "content/docs/fields/grid.mdx",
    "content/docs/rfcs/0001-clipboard-paste.md",
    ".changeset/11610-grid-keys-camelcase.md"
    ],
    "adr_rfc": {
    "adr_reported_not_edited": "docs/adr/0001-master-detail-subform.md names the keys in three sentences: 'Honors min_rows / max_rows / allow_add / allow_delete from the …', 'Drag reorder of lines (allow_reorder), grouping/subtotal rows.', and '… drag-to-reorder (a sort_field …'.",
    "rfc_edited": "content/docs/rfcs/0001-clipboard-paste.md (status Draft) stated max_rows 'from GridFieldMetadata' and wired field.allow_add / field.max_rows as the current API, so its four references moved to maxRows / allowAdd."
    },
    "tests": "All at tree 82b400f (types/fields/plugin-form vitest measured a working tree byte-identical to it: its two later-committed files, the changeset and the catalog test, were already on disk). TYPE-CHECK (package + test program, under os-verify-lock, VERDICT command-exit 0): @object-ui/types, @object-ui/fields, @object-ui/plugin-form, @object-ui/i18n, @object-ui/example-schema-catalog, @object-ui/console (after building @object-ui/plugin-tree, a prerequisite its import graph needs; first run's TS2307s were only that). fields and plugin-form test programs list the touched test files (--listFilesOnly). VITEST (repo-root form, --maxWorkers=2): packages/types/ Test Files 353 passed, Tests 9482 passed; packages/fields/ 233 passed + 1 skipped, Tests 3647 passed + 7 skipped; packages/plugin-form/ 163 passed, Tests 1889 passed + 1 skipped; examples/schema-catalog/ + apps/console registry-inputs-spec-parity + packages/i18n/ 121 passed, Tests 3807 passed + 13 skipped (121 = 41 catalog + 1 + 79 i18n files, so the new catalog test ran); targeted verbose run of the five key test files 175 passed. LINT: root eslint config over the 25 touched TS/TSX files, --format json: 0 errors; the only finding on an added line is the pre-existing as any warning on GridField.test.tsx's fixture. Narrowing proof: population = files of the touched packages under the one root eslint.config.js; file count 25 from the JSON; no type-aware linting (no projectService / parserOptions.project) and no custom rule reads the filesystem ⇒ the diff cannot move a verdict on an untouched file. pnpm lint itself declared to CI. GATES exit 0: check:doc-snippets (777 blocks, 0 failed), check:doc-examples, check:readme-exports, check:new-line-citations (0 new), check:control-bytes, check:spec-symbols, check:designer-field-key-parity, check:prompt-keys, check:handler-key-reads, check:unreferenced-sources, check:phantom-deps, check:self-import, check:test-path-roots, check:doc-types, check:doc-example-ids, check:doc-fences, check:doc-example-readers, check:i18n-drift, check:i18n-keys, check:esm-specifiers, check:side-effects-array; changeset checkers presence/no-major/fixed/overwrite/claims/pending-literals. Gate list derived by hand from .github/workflows (objectui has no dispatch-gates.mjs). Governed guard --test: NOT GOVERNED. ABLATIONS: see pins_and_ablations; after every restore, types pnpm run type-check at 82b400f exit 0 and the three ablated test files 87/87 passed. CI on 82b400f: in_progress at report time (15 completed / 15 in progress).",
    "mcp_calls": "0",
    "api_writes": "3 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]: (1) pr_create → POST /repos/objectstack-ai/objectui/pulls (draft #11614, body read back 14373 bytes identical); (2) label-write --assign → POST /repos//issues/11614/assignees (os-project-manager; no label written, labeler.yml set the path labels); (3) this os-dev-report → POST /repos//issues/11610/comments. Plus two git push (not REST).",
    "deviations": [
    "Surface beyond the claim's list, each a census hit: apps/console registry-inputs-spec-parity.test.ts (pin prose describing the old snake_case renames), packages/i18n en.ts (one comment naming add_label; #11612 also edits en.ts), packages/types/src/index.ts (the new GRID_FIELD_RETIRED_KEYS export), a new catalog test in examples/schema-catalog/test, and the RFC (edited under the dispatch's conditional).",
    "Changeset declares @object-ui/types and @object-ui/fields only: plugin-form's adapters changed source but draw the same output, so its surface does not move (the changeset body says so).",
    "objectstack read-only access used git fetch origin main:refs/os-dev/issue-11610/os-main in /home/user/objectstack (a local ref in its shared .git; no file there edited)."
    ],
    "open_questions": [
    {
    "question": "The mechanical camelCase of total_field is totalField, but on the spec's own surfaces (master-detail subform, record:line_items) totalField is the PARENT field the sum is saved to, while the grid's key names the CHILD column summed (the value the spec calls amountField). Should the spec's runtime form field declare the grid key under this homonym?",
    "options": [
    "A — keep totalField as ruled and dispatched; every declaration, grid.mdx and the changeset state the difference, and the spec seat describes it as the child column when it declares the key",
    "B — rename the grid key to amountField (the spec's child-column word) in a follow-up; costs a second breaking rename and reverses objectui#11070 round 8, which retired amountField on the widget"
    ],
    "recommendation": "A, because the maintainer's ruling and the claim fix the eight camelCase names (裁决区不重开), no measured writer authors the key (axis 实际业务需求: zero pull), and B is a second rename with no producer asking for it (axis 不扩散); the AI-error axis is served by stating the meaning on every face. Raised so the spec seat words the declaration deliberately."
    }
    ],
    "out_of_scope_findings": [
    "carrier: the objectstack spec seat's stage on objectstack-ai/objectstack#21704 · noted, not filed — three packages/spec component.zod.ts comments still name the grid's snake_case keys (the customFields fork note says 'eight of them are the grid widget's snake_case keys'); they move when the spec declares the camelCase keys.",
    "carrier: 承接者:无 · noted, not filed — docs/adr/0001-master-detail-subform.md names min_rows/max_rows/allow_add/allow_delete/allow_reorder/sort_field (governed, dated record; reported in the PR body).",
    "carrier: 承接者:无 · noted, not filed — apps/console DevLookup.tsx still hands the grid as any (dev harness only; key renamed)."
    ]
    }

  5. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat answer to the open question in dev report 5980586583 (2026-10-04T13:40Z). Session session_01CPvhwGcirXqBGEdPSb72TZ, domain:spec seat.

    Q: the totalField homonym. Answer: A, keep totalField.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT: PR #11614 at head 8b56ef26 (2026-10-04T14:44Z)

    Seat domain:spec @ objectui (objectui#10217), session session_01CPvhwGcirXqBGEdPSb72TZ.

    Contract review of record: 5981193754 PASS on head 8b56ef2638e30772f5c758f79d17b8115e3ba627, at CONTRACT_REVIEW_TIER. That head merges main at b403bb36, which is the claim's serial step after #11612 and #11607 landed. The record reads all 29 per-file hunks as byte-identical to those reviewed by the earlier record 5980764277 (PASS on 82b400f9). It also judges the coupling with #11607: GridFieldMetadata never carried BaseSchema's signature, and FormField keeps its own, so the tombstones and their deletion guards mean what they did.

    Checklist, read by the seat at this head:

    • Draft against main. Body line 1 is Fixes #11610, the only closing keyword in the body. Line 2 is Clause-②: yes (narrowing), matching the changeset's line.
    • No content/docs/releases/ path.
    • A changeset is present: @object-ui/types and @object-ui/fields, both minor.
    • Every file is a census hit under the claim's file-surface clause.
    • check-governed-merges --pr objectstack-ai/objectui#11614: NOT governed, 0 of 29 paths. 1,477 changed lines, under the human-merge threshold.
    • Check-runs on the head: 43 completed, 40 success, 3 skipped by design, 0 failed. Lint and Type Check are success.

    Changeset sentences checked against the diff (.changeset/11610-grid-keys-camelcase.md):

    • the BREAKING banner, and the eight FROM → TO lines;
    • the "Why" paragraph: no alias window, no dual read, no stored producer outside the migrated fixtures;
    • the migration's totalField meaning: the CHILD column summed, not the spec's master-detail parent field;
    • the per-face paragraphs: the TS never members; the zod narrowing and widening on the tolerant and strict faces, with the Did you mean message; the widget's alert drawn instead of the grid;
    • the GRID_FIELD_RETIRED_KEYS export;
    • the plugin-form adapters' change with no output change.

    Doc sentences checked against the diff:

    • content/docs/fields/grid.mdx: the camelCase example, the key list with the totalField homonym stated, the new "Retired snake_case keys" section, and the comparison table.
    • content/docs/rfcs/0001-clipboard-paste.md (Draft): four references moved to maxRows / allowAdd.

    Open question answered: 5980610524 (A, keep totalField, with its meaning stated on each face). Verified by both records.

    Acceptance notes (read, not filed):

    Landing: not governed, so this seat lands it now: pr_ready + automerge_enable through the relay, then the post-merge duties and the report on objectstack#21704.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lanepriority:p3tech-debt

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions