Skip to content

fix(app-shell,data-objectstack,plugin-view,types): the console reads stored view rows by the spec's declared spellings and drops the reads nothing writes (objectui#11013) - #11209

Merged
objectstack-fleet[bot] merged 7 commits into
mainfrom
claude/issue-11013-view-row-declared-spellings
Sep 30, 2026
Merged

objectstack-fleet[bot] merged 7 commits into
mainfrom
claude/issue-11013-view-row-declared-spellings

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #11013

Clause-②: yes

Context

What changed: one commit per work item

  1. Declared spellings for the bound object and the row identity (08a159633)
    • viewItemObjectName (data-objectstack) reads data.object ?? object. The objectName leg is gone.
    • The object page no longer stamps objectName: sv.objectName || sv.object || objectName onto the rows listViews() returns. No reader consumed that stamp; the handlers act on the route's object name. A saved view's whole-body toolbar save wrote the stamp back into the stored row.
    • The Studio view-ref picker now reads object (viewRefCatalog). It used to read objectName ?? object ?? object_name.
    • The Studio view preview reads object (resolveObjectName). It used to read objectName on the body and on the draft. This site was not in the card's census. It is fixed in place as the same defect class and the same gate family, and no open PR touches the file.
    • viewRowId reads name only. A top-level id / _id is no identity.
    • filter[].id / sort[].id and exportOptions needed no change; see the measurements below.
  2. Drop the reads nothing writes; userActions for the toolbar policy (af24d4e7c)
    • Both relays of a view into the list-view node stop reading nine keys off the view: allowExport, wrapHeaders, clickIntoRecordDetails, addRecordViaForm, addDeleteRecordsInline, collapseAllByDefault, fieldTextColor, prefixField, and the editRecordsInline spelling of inlineEdit. The two relays are plugin-view's renderListView composition and the object page's relay over it.
    • The object-view node's own values still reach ListView. That node read is the objectui#5097 host-composition read, and it is untouched.
    • A view's allowExport: false no longer withholds its exportOptions.
    • NamedListView.allowExport becomes a ?: never tombstone. Ruling A on objectui#7924 kept it declared only because both relays read it.
    • Two sites now read the toolbar policy as userActions.search / .sort / .filter. They used to read the bare showSearch / showSort / showFilters flags off the view. The sites are the object-view node the object page builds and plugin-view's non-grid generateViewSchema route.
    • Census and pin updates: the relay census (ObjectView.relayRungCensus-7559.test.ts) declares each dropped rung's absence with its evidence kind; the objectui#7779 census re-points its allowExport pins; the objectui#10694 panel probe edits resizable instead of wrapHeaders.
  3. listViews() record flatten (67048225b)
    • The flattened row now carries the record's object. It also carries the spec's round-trip keys declared on the viewItem member: isDefault, isPinned, sortOrder, visibility, columnState. The set is read off VIEW_CONSOLE_ROUND_TRIP_KEYS, not retyped.
    • app-shell's VIEW_ROW_STATE_KEYS for the view-config save is derived from the same record.
    • A reload round trip per key is pinned against a stub metadata store.

Also in this PR:

  • The changeset (bcd3c6f67) states each dropped key's effect in user terms.
  • c1d3b684a adds dated notes to two pending objectui#7924 changeset entries. Both said "allowExport stays declared", which this change makes false; pnpm check:changeset-claims surfaced them.
  • b2df69071 is a lint tidy with no behaviour change.

PM mechanism assumptions, measured

  1. "Every objectName reader already falls back to object." This is partially falsified. viewItemObjectName did read object before objectName. The other two sites read objectName FIRST, with object as the fallback: the object-page stamp (sv.objectName || sv.object) and the picker (objectName ?? object ?? object_name). A fourth reader, ViewPreview's resolveObjectName, read it third and fifth.
    • Where rows carrying only objectName would come from: no door accepts one. ViewMetadataSchema refuses a flattened overlay bound by objectName alone, and also a ViewItem record bound by it alone. The same bodies bound by object parse; that is the lit control. The test is viewItemObjectName.declaredSpelling-11013.test.ts.
    • Every adapter writer stamps object: createView, updateViewConfig and updateView, all measured in the same file.
    • A row carrying both spellings answers by object at every site, as before.
  2. "No producer for the nine keys." Confirmed: zero producers.
    • Stored rows: no console write path puts any of them on a view. The config save narrows config to the spec's ListViewSchema keys plus the declared row-state keys. The create path goes through the spec-driven inspector. The pin toggle and reorder write isPinned / isDefault / sortOrder. The settings overlay writes rowHeight / sort / hiddenFields / columnState / inlineEdit.
    • Census command, non-test sources of packages/*/src, apps/** and examples/**: git grep for the key as a property. The only hits are the readers, the type declarations, and two React props handed to ListView directly: StudioDesignSurface's addDeleteRecordsInline: true, and InterfaceListPage's list-view node allowExport: false. Neither is a view row or an authored view.
    • Lit control on the same search: isPinned finds the pin toggle's write.
    • Authored views in the sibling objectstack checkout (examples/**, apps/**): 0 files for each of the nine. The control inlineEdit finds 9 files.
    • The spec's strict ListViewSchema refuses all nine with unrecognized_keys; the control exportOptions is accepted.
    • Nothing is raised on spec(ui)+metadata save: judge a flattened view overlay's top-level options.KIND with the strict per-kind schema and persist the PARSED body — the door half of objectui#10380 objectstack#20051.
  3. "The round-trip keys come back only through the loadViewOverrides override merge." This is partially falsified.
    • Confirmed: the flatten kept only config + name / label / isDefault / _draft.
    • The override merge restores isPinned / visibility / columnState onto the TAB. It does so for records that MetadataProvider lists into objectDef.listViews, which is where loadViewOverrides takes its ids.
    • The switcher's sort reads sortOrder off the savedViews row only, so sortOrder never came back through the merge. A reordered record lost its place on reload, wherever the per-browser viewOrder: cache did not mask it.
    • Pinned per key in listViews.roundTripKeys-11013.test.ts.
  4. "No reader keys state by filter[].id / sort[].id across a reload." Confirmed.
    • The search ran over non-test sources of plugin-view, plugin-list, the components custom/ builders and renderers, and app-shell views. It looked for (filter|sort|condition|item|…).id and for localStorage / sessionStorage.
    • The ids are React keys and in-session edit targets in filter-builder.tsx / sort-builder.tsx. view-config-utils.ts mints one when a row has none.
    • No persisted state is keyed by them.

exportOptions needed no change on this end: the only reader outside ListView, ObjectGrid, reads exportOptions.formats. ListView.tsx's bare-array tolerance is untouched. The card retires it after rows are stored parsed, and the file is in PR objectui#10278's area.

Acceptance notes

  • NamedListView.allowExport tombstone. It follows from dropping the read. The alternative, keeping the type declared with no reader, is the declare-and-ignore shape ADR-0049 forbids. The seat's disposition on spec(ui)+objectui: declare the console's round-trip keys on the stored view overlay (#20051 stage ii, ruling 甲) objectstack#20456 is also "no producer, no declared spelling". NamedListView no longer types ObjectViewSchema.listViews (objectui#7928), so the break is on an exported legacy type only.
  • Toolbar reads go through normalizeListViewSchema. This is the one fold the relays' own userActions rung already runs, so no new tolerance is added. A stored view that still carries a bare show* flag keeps its answer, which objectui#7924's changeset states as policy ("that fold stays"). Reading userActions raw would change those rows at these two sites only.
  • MetadataProvider.applyViewItem still flattens a record to config + identity. Its tab gets the round-trip keys back through the override merge. It was noted and not changed; the listViews comment says so.
  • Not changed, noted only:
    • UnifiedViewConfig (types/src/designer.ts) still declares allowExport / addRecordViaForm / show*. Nothing constructs that type. Carrier: none.
    • ResourceEditPage's sourceObjectName falls back to draft.objectName for every metadata type. That is not a view-row read.
  • Overlap with open PRs:
    • PR objectui#11192 edits data-objectstack/src/index.ts, in its import block and filter translation, away from these hunks.
    • PR objectui#10278 edits types/src/objectql.ts at ObjectKanbanSchema, away from NamedListView.
  • File surface beyond the claim's list, each a consequence of the three items:
    • types/src/objectql.ts and its objectui#7779 census, for the tombstone
    • ViewPreview.tsx, the in-place fix above
    • the relay census and the objectui#10694 probe, plus comment refreshes in two plugin-view pins
    • two pending changesets, for the dated notes

Verification

All readings below are at head b2df69071. Exit codes were captured before any pipe. Heavy runs went through os-verify-lock.sh.

Build and type-check

  • pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' run build: exit 0. That closure holds 29 packages, including types, data-objectstack and plugin-view. The build ran at c1d3b684a; b2df69071 changed no exported type.
  • pnpm --filter PACKAGE run type-check: exit 0 for all four packages. types and plugin-view were checked at c1d3b684a and are unchanged since. data-objectstack and app-shell were re-checked at b2df69071.
  • The new and edited tests are in each type-check population, counted with --listFiles:
    • app-shell tsconfig.test.json: 5 of 5
    • types tsconfig.test.json: 1 of 1 (it holds the allowExport @ts-expect-error pin)
    • plugin-view tsconfig.test.json: 2 of 2
    • data-objectstack tsconfig.json: 2 of 2 new tests, 74 test files in all

Tests

  • pnpm exec vitest run packages/data-objectstack/ packages/types/ packages/plugin-view/: exit 0. Test Files 421 passed (421), Tests 8177 passed (8177).
  • pnpm exec vitest run packages/app-shell/ --shard=N/4, N = 1 to 4, each exit 0:
    • shard 1: 229 files passed, 2189 tests passed, 1 skipped
    • shard 2: 228 files passed and 1 skipped, 2074 tests passed and 8 skipped
    • shard 3: 228 files passed, 2743 tests passed
    • shard 4: 228 files passed, 2205 tests passed

Reverse verification

Each ablation was one-off: mutate, run the pin, restore. Every leg went through ablation-replace.mjs in WRAP mode, with the anchor required to hit exactly once and restore proven against HEAD's blob. After the run, git diff HEAD is empty. The predicted direction was red for every leg, and every leg went red:

leg mutation pin result
A1 objectName leg back in viewItemObjectName viewItemObjectName.declaredSpelling-11013 2 failed
A2 id / _id back in viewRowId ObjectView.setDefaultViewIdentity 3 failed
A3 objectName ?? object ?? object_name back in viewRefCatalog ResourceEditPage.pickerLoadFailure 1 failed
A4 objectName back in resolveObjectName ViewPreview.declaredObject-11013 2 failed
A5 activeView?.wrapHeaders back in plugin-view ObjectView.viewRowDeclaredReads-11013 2 failed
A6 activeView?.showSearch back on the object-view node same 1 failed
A7 the allowExport rung and gate back in app-shell relay census, the same file, and the objectui#7779 census 6 failed across 3 files
A8 the round-trip loop emptied in the flatten listViews.roundTripKeys-11013 5 failed
A9 activeView?.showSearch back on plugin-view's non-grid route ObjectView.viewRowDeclaredReads-11013 1 failed

A4's first attempt was a no-op. Its replacement contained the anchor, so the tool refused, the anchor count did not drop, and no test ran. It was redone with a non-overlapping replacement; the row above is the redone run.

Gates

Each exit 0:

  • node scripts/check-changeset-presence.mjs: "21 source file(s) of 4 released package(s) changed, and this change declares 1 changeset(s)"
  • pnpm check:control-bytes
  • check-changeset-no-major, check-changeset-fixed
  • check-changeset-overwrite. It is report-only. It names the two dated-note edits, and their front matter is unchanged.
  • pnpm check:new-line-citations: "0 new citation(s)"
  • check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape
  • check:spec-symbols, check:metadata-write-doors, check:test-path-roots, check:pending-changeset-literals
  • check:icon-record-names, check:docs-route-closure
  • check:changeset-claims. It is report-only; its two findings got the dated notes.

Lint, narrowed and proven

  • Population: eslint.config.js lints **/*.{ts,tsx}. All 21 changed or added .ts / .tsx files are in it.
  • Count: pnpm exec eslint --format json over those 21 files reports 21 files and 0 errors, with inline config honoured as pnpm lint honours it.
  • Warnings per file against the merge base are equal, except two. ResourceEditPage.tsx gains one react-refresh/only-export-components hint, for the exported viewRefCatalog. ViewPreview.tsx loses one.
  • Invariance: the config sets no parserOptions.project, so linting is not type-aware. It loads no import plugin, and no rule in eslint-rules/ reads another file. So this diff cannot move an untouched file's verdict.
  • The full pnpm lint is CI's run.

NOT MEASURED

  • check:doc-examples. Reason: PREREQUISITE NOT MET. It needs the app-shell, cli, plugin-ai, plugin-gantt, plugin-map, plugin-markdown and plugin-timeline dists, which are outside the built closure. No doc example writes allowExport on a NamedListView or names another changed symbol. It is declared to CI.

Mergeability

  • Main has moved to 846cec0ef. Of this branch's files, only data-objectstack/src/index.ts changed there, by PR objectui#11192.
  • git merge-tree of HEAD against that main exits 0.

Generated by Claude Code

…identity by the declared spellings

objectui#11013 item 1 (ruling 甲 on objectstack#20051, stage ii).

- `viewItemObjectName` reads `data.object ?? object`; the undeclared
  `objectName` leg is gone. The metadata door refuses a row bound by
  `objectName` alone, and every adapter write path stamps `object`.
- The console no longer stamps `objectName` onto the rows `listViews()`
  returns. No reader consumed the stamp; a saved view's whole-body toolbar
  save wrote it back into the stored row.
- The `view-ref` picker (`viewRefCatalog`) and the Studio view preview
  (`resolveObjectName`) read `object`, not `objectName` / `object_name`.
- `viewRowId` reads `name` only; a top-level `id` / `_id` is no identity.

Filter/sort row ids and `exportOptions` need no change on this end: no
reader keys state by a row id across a reload, and the one reader of the
export formats outside `ListView` (`ObjectGrid`) reads `exportOptions.formats`.

Claude-Session: https://claude.ai/code/session_0122Knsowci76D2rBWReCzzZ
Co-authored-by: Claude <noreply@anthropic.com>
…writes, and read the toolbar policy as userActions

objectui#11013 item 2 (ruling 甲 on objectstack#20051, stage ii).

- Both relays of a view into the `list-view` node stop reading nine keys
  off the view: `allowExport` and the renderer flags `wrapHeaders`,
  `clickIntoRecordDetails`, `addRecordViaForm`, `addDeleteRecordsInline`,
  `collapseAllByDefault`, `fieldTextColor`, `prefixField`, plus the
  `editRecordsInline` spelling of `inlineEdit` on the object page. No
  console surface writes any of them onto a view, no view in this
  repository authors one, and the spec's view schema refuses each by name.
  The object-view node's own value (the objectui#5097 host-composition
  read) still reaches `ListView`.
- A view's `allowExport: false` no longer withholds its `exportOptions`.
- `NamedListView.allowExport` retires as a `?: never` tombstone: ruling A
  on objectui#7924 kept it only because both relays read it.
- The object page's `object-view` node and plugin-view's non-grid route
  read the view's toolbar policy as `userActions.search` / `.sort` /
  `.filter` (through `normalizeListViewSchema`, which folds a stored bare
  `show*` flag), not as the bare flags.
- The relay census declares each dropped rung's absence with its evidence;
  the objectui#7779 census re-points its `allowExport` pins; the
  objectui#10694 panel probe edits `resizable` instead of `wrapHeaders`.

Claude-Session: https://claude.ai/code/session_0122Knsowci76D2rBWReCzzZ
Co-authored-by: Claude <noreply@anthropic.com>
…declared members through the flatten

objectui#11013 item 3 (ruling 甲 on objectstack#20051, stage ii).

`listViews()` flattened a ViewItem record to its `config` plus `name` /
`label` / `isDefault` / `_draft`, so the keys the console writes at the
record's top level (`isPinned`, `sortOrder`, `visibility`, `columnState`)
did not come back on the row the switcher reads. The switcher sorts saved
views by the `sortOrder` it reads off that row, so a reordered record lost
its place on reload wherever the per-browser order cache did not mask it.

The flattened row now also carries the record's `object` and the spec's
round-trip keys declared on the `viewItem` member, read off
`VIEW_CONSOLE_ROUND_TRIP_KEYS` rather than hand-listed. app-shell's
view-config save derives its carried row-state keys from the same record
instead of retyping them. A reload round trip per key is pinned against a
stub metadata store.

Claude-Session: https://claude.ai/code/session_0122Knsowci76D2rBWReCzzZ
Co-authored-by: Claude <noreply@anthropic.com>
…port stays declared

objectui#11013 retires `NamedListView.allowExport` in the same release, so
the objectui#7924 entries' "`allowExport` stays declared" no longer holds.
Each gets a dated note in the form those entries already carry, pointing at
the objectui#11013 entry; their original text is kept as the reading of
their change. Surfaced by `pnpm check:changeset-claims`.

Claude-Session: https://claude.ai/code/session_0122Knsowci76D2rBWReCzzZ
Co-authored-by: Claude <noreply@anthropic.com>
…ead, and `unknown` for the new row types

objectui#11013 follow-up, no behaviour change. The toolbar-policy fold on the
object page is read inline: `activeView` is a fresh object each render while
a draft is open, so the memo bought nothing and drew an exhaustive-deps
warning. `viewRefCatalog` and the `listViews` flatten type their rows
`Record<string, unknown>`. Per-file lint warning counts for the three files
return to the merge base's, except the one `only-export-components` hint for
the exported `viewRefCatalog`.

Claude-Session: https://claude.ai/code/session_0122Knsowci76D2rBWReCzzZ
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 25 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/5903-objectgantt-declared-keys.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    Both halves move together. The TS declaration (packages/types/src/objectql.ts) and its zod mirror (src/zod/objectql.zod.ts) gain the same ten keys at the same requiredness — all optional — and no KnownDrift entry is added. navigation is taken from @objectstack/spec's NavigationConfigSchema by reference rather than restated, matching ObjectGridSchema.navigation.

.changeset/6152-object-form-unmirrored-members.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectFormSchema in @object-ui/types (objectql.ts) declared a set of members that its zod mirror in @object-ui/types/zod had never heard of. Every one of them is read by the object-form renderer (ObjectForm in @object-ui/plugin-form). The two published faces answered differently:

.changeset/6726-find-envelope-records-arms.md

  • names plugin-view/src/ObjectView.tsx → packages/plugin-view/src/ObjectView.tsx — edited by this change

    | module | what it does | | --- | --- | | components/src/hooks/related-count-store.ts | related-list tab badge count | | components/src/renderers/basic/data-list.tsx | element:repeater rows | | components/src/renderers/basic/elements.tsx | element:number client-side aggregate | | components/src/renderers/basic/record-picker.tsx | element:record_picker options | | plugin-detail/src/renderers/record-activity.tsx | record:activity self-fetch | | plugin-detail/src/renderers/record-history.tsx | record:history self-fetch | | plugin-view/src/ObjectView.tsx | non-grid (kanban / calendar / gallery / timeline) fetch |

.changeset/7070-no-invented-gantt-date-fields.md

  • names app-shell/src/views/ObjectView.tsx → packages/app-shell/src/views/ObjectView.tsx — edited by this change

    • app-shell/src/views/ObjectView.tsx — the console object page. The inline branch becomes ganttViewOptions, the sibling of calendarViewOptions and timelineViewOptions: the declared block spread whole, title floored at 'name', no date field invented. - plugin-list/src/ListView.tsx — the render branch AND the capability gate. - plugin-view/src/ObjectView.tsx — generateViewSchema, the authored object-view element route, which bypasses ListView entirely.
  • names plugin-view/src/ObjectView.tsx → packages/plugin-view/src/ObjectView.tsx — edited by this change

    • app-shell/src/views/ObjectView.tsx — the console object page. The inline branch becomes ganttViewOptions, the sibling of calendarViewOptions and timelineViewOptions: the declared block spread whole, title floored at 'name', no date field invented. - plugin-list/src/ListView.tsx — the render branch AND the capability gate. - plugin-view/src/ObjectView.tsx — generateViewSchema, the authored object-view element route, which bypasses ListView entirely.

.changeset/7322-object-kanban-group-by-limit.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    Breaking for authored metadata: ObjectKanbanSchema.groupField is RETIRED (objectui#7322, ADR-0049 enforce-or-remove), and the two keys the object-kanban renderer actually reads — groupBy and limit — are now DECLARED and validated on both published faces: the TypeScript interface in objectql.ts and the Zod mirror in zod/objectql.zod.ts.

.changeset/7363-objectql-union-arms.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectGallerySchema and ObjectDataTableSchema are members of ObjectQLComponentSchema on both faces — the TS union in objectql.ts and the zod union in zod/objectql.zod.ts — so AnyComponentSchema, and with it validateSchema / safeValidateSchema / objectui validate, has an arm for object-gallery and object-data-table nodes (objectui#7363).

.changeset/7499-gantt-non-axis-floors-omitted.md

  • names plugin-view/src/ObjectView.tsx → packages/plugin-view/src/ObjectView.tsx — edited by this change

    • plugin-list/src/ListView.tsx — the object-gantt render branch. - plugin-view/src/ObjectView.tsx — generateViewSchema, the authored object-view element route, which bypasses ListView entirely.

.changeset/7632-shared-record-source-config.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    That ladder is published contract on both faces — packages/types/src/objectql.ts and its zod mirror both ship .describe() strings naming getDataConfig's order (77cb489b4, maintainer ruling 2026-09-02), pinned by objectql-record-source-refinement-6939.test.ts — and it was hand-copied into five plugin components with no gate holding them together. A change to the ruled order had five edit sites and nothing that noticed a missed one; that is the AGENTS.md #0.1 drift class.

.changeset/7804-objectql-handler-key-arms.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    The four plain objectql.ts node faces declare the nine handler keys their registered renderers read (the objectql.ts slice): ObjectFormSchema.onCancel / .onError / .onOpenChange / .onStepChange / .onSuccess, ObjectGallerySchema.onCardClick / .onRowClick, ObjectGridSchema.onNavigate and ObjectViewSchema.onNavigate.

.changeset/7804-tree-view-handler-slot.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    'runtime-slot' and not 'retired', measured at this key's own channel. 'retired' publishes "no renderer reads this key, so nothing could ever run it" — true of the two siblings already tombstoned on this arm (onSelectChange, onExpandChange) and flatly false here, since the read is live and INVOKED. ⚠️ No in-repo host builds a tree-view node carrying the key: the channel is wired end to end and only the supplier is absent, which is the same shape as ObjectFormSchema.onStepChange in this card's objectql.ts slice and is not evidence of a dead read. The TypeScript declaration is unchanged and still callable, so a programmatic host supplies it exactly as before.

.changeset/7963-alert-dialog-footer-keys-retired.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    Nothing else moves. These spellings are overloaded across the tree and every other owner is a live key on a different declaration — FormSchema.cancelLabel, objectql.ts's confirmLabel, plugin-designer's ConfirmDialog React props, plugin-grid's def.confirmLabel, and plugin-form's ModalForm / DrawerForm, which build a local cancelLabel from schema.cancelText. None is an AlertDialogSchema; none is touched, and a pin asserts it. No fixture, catalog schema, example app or doc fence authored any of the three on an alert-dialog node, so no shipped document is stranded.

.changeset/8653-listview-title-retired-rowactiondefs-pinned.md

  • names packages/plugin-view/src/ObjectView.tsx → packages/plugin-view/src/ObjectView.tsx — edited by this change

    title — retired. ListView resolved its export filename through schema.label || (schema as any).title. @objectstack/spec/ui's ListViewSchema refuses title by name (unrecognized_keys: ['title']) while ObjectGridPropsSchema accepts it; packages/types mirrors the platform contract rather than ruling over it, so declaring title on ListViewSchema would have made this repo accept what the platform save gate rejects. That asymmetry is also why objectui#6639 could take the declare branch for ObjectGridSchema.title one package over and this site could not. A parse-based census of apps/ examples/ content/ and packages/ found zero list-view nodes authoring title, so the retirement costs no author a filename. Over that same corpus the instrument reports three object-grid nodes carrying the key: two authored ones, both in content/docs/api/schema-reference.md, plus one that is not authored at all — packages/plugin-view/src/ObjectView.tsx composes title: schema.table?.title onto a grid node it builds, so it is a producer writing the key rather than an author declaring it. ObjectGrid's own title reads are untouched — they remain declared, ruled and read.

.changeset/8767-object-grid-refuses-string-sort.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    Migration. Write the array: sort: [{ field: 'name', order: 'desc' }]. Both keys are required. SortConfig.order carries no ? in @object-ui/types (packages/types/src/objectql.ts) and no .optional() in its zod mirror, and the protocol's own reusable SortItemSchema requires order as well — measured: that schema refuses [{ field: 'name' }] with invalid_value at 0.order. Do not omit it: this block's array arm interpolates whatever is present, so an omitted order lowers to $orderby: 'name undefined' today. That is pre-existing behaviour on the arm this change does not touch, and it is filed as a successor card rather than widened into here.

.changeset/8801-object-kanban-allow-collapse-retired.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    • the declarations retired here — packages/types/src/objectql.ts and its mirror packages/types/src/zod/objectql.zod.ts; - the pins that assert the retirement — object-kanban-allow-collapse-retired-8801.test.ts and bare-kanban-node-key-retired-8802.test.ts; - a comment in packages/types/src/zod/complex.zod.ts, recording that the deleted retiredZeroReadKanbanKey helper once carried this spelling on the SIBLING arm; - one row of content/docs/api/schema-reference.md; - the .changeset/ release notes that discuss it — this one, the two historical entries covering the sibling arm's own spelling, and objectui#9629's note recording the correction to this paragraph.

.changeset/8885-object-chart-drilldown-title-compareto.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectChart.tsx reads all three off schema, and until now neither published copy declared any of them: not the TS interface (packages/types/src/objectql.ts) and not the zod mirror (packages/types/src/zod/objectql.zod.ts). They rode BaseSchema's index signature / .passthrough() and arrived unvalidated. drillDown was the sharpest case — this component's registry inputs advertise it to the designer palette, and @objectstack/spec publishes ChartDrillDownSchema for exactly this carrier, so an author was offered a key that neither published shape mentioned.

.changeset/8913-object-kanban-columns-declared.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    What moved. ObjectKanbanSchema gains columns on both halves that move together — the TypeScript interface (objectql.ts) and its Zod mirror (zod/objectql.zod.ts). Retiring the bare kanban node type key (objectui#8802) removed the only face that judged a lane, and object-kanban had never declared the key, so it rode BaseSchema's [key: string]: any / .passthrough(): read by the renderer at three sites, named by no published face.

.changeset/8990-object-kanban-groupby-optional.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    @objectstack/spec declares the key optional — groupBy: z.string().optional() on ObjectKanbanPropsSchema — while this package required it on the TypeScript declaration (packages/types/src/objectql.ts) and on the Zod mirror (packages/types/src/zod/objectql.zod.ts). objectui was therefore narrower than the protocol on a published key: ObjectKanbanSchema.safeParse and safeValidateSchema refused an object-kanban node the protocol accepts, and such a node could not be annotated with its own type.

.changeset/9092-inline-locale-declared-face.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    • AppComponentSchema.label (app.ts) - ObjectGridSchema.label and .description (objectql.ts) - PageNodeSchema.aria.ariaLabel (layout.ts)

.changeset/9309-object-gallery-filter-destination-typed.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectGallerySchema.filter is typed as the destination its own docblock names — QueryParams['$filter'] — on both faces, the TS interface in objectql.ts and the zod mirror in zod/objectql.zod.ts (objectui#9309).

.changeset/9511-record-id-is-a-string.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    The three authorable keys, each on BOTH faces. ObjectFormSchema.recordId (objectql.ts + zod/objectql.zod.ts), DetailViewSchema.resourceId (views.ts + zod/views.zod.ts) and DetailSchema.resourceId (crud.ts + zod/crud.zod.ts). ⚠️ The crud pair is DetailSchema, not DetailViewSchema, and it reaches the same renderer — not by symbol but by data flow: plugin-detail registers the 'detail' node type onto DetailView. A read that follows TypeScript symbols alone finds two keys and is incomplete.

.changeset/9549-tree-filter-declared.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectTreeSchema.filter is declared on both faces, in the shape objectui#9309 settled for ObjectGallerySchema.filter: QueryParams['$filter'] by indexed access on the TS interface in objectql.ts, and the same two-arm union (array first) on the zod mirror in zod/objectql.zod.ts (objectui#9549).

.changeset/9550-object-tree-root-barrel.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectQLComponentSchema declares the node types an ObjectQL block may be. Every one of its arms was a named export of this package's root barrel except ObjectTreeSchema, which was declared in objectql.ts, applied by the union, and re-exported by the ./zod barrel (objectui#7917) — while no TypeScript consumer could name it. There is no ./objectql subpath to reach around the barrel: the package's exports map is pinned by packages/types/src/__tests__/package-exports-manifest.test.ts, and the root barrel was the only route to this type.

.changeset/9606-object-kanban-card-title.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    Both published faces of the object-kanban arm now name the key: the zod mirror ObjectKanbanSchema in zod/objectql.zod.ts and its TypeScript twin, the ObjectKanbanSchema interface in objectql.ts. Both declare it OPTIONAL, at the same requiredness the other face uses, so the two faces accept and refuse the same documents. (Located and cited by SYMBOL: line addresses in zod/objectql.zod.ts have drifted before, and this change is itself about a drifted mirror.)

.changeset/9628-kanban-column-collapsed-honoured.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    The key was declared on both published faces of the object-kanban arm — the lane element of ObjectKanbanSchema (objectql.ts and its Zod mirror) and the runtime lane KanbanColumn (complex.ts and its mirror) — and read by KanbanEnhanced alone, a module no production source imports. An authored { "id": "todo", "title": "To Do", "collapsed": true } therefore parsed green on both faces and reached a board that did nothing with it: KanbanImpl's only collapse is the SWIMLANE row's, held in viewer state under objectui:kanban-collapsed:ANGLE-BRACKETS(swimlaneField) and never keyed to a lane's declared value. That is the ADR-0049 declared-but-unhonoured shape.

.changeset/object-view-unmirrored-keys-7779.md

  • names packages/plugin-view/src/ObjectView.tsx → packages/plugin-view/src/ObjectView.tsx — edited by this change

    What was measured. Every reading was taken on the object-view node renderer (packages/plugin-view/src/ObjectView.tsx, registered by plugin-view/src/index.tsx) with schema.objectName / schema.layout as the positive controls of the same schema.KEY query, so each zero is a reading; the repo-wide census of viewTabBar finds the key in no source file outside @object-ui/types (two doc tables listed it as authorable and are corrected here). The spec side was read through the installed pin (@objectstack/spec@17.2.0, ui entry, 117 exported object schemas walked; control keys objectName / columns / navigation / listViews hit): the three spec-modelled keys are optional slots on ListViewSchema and ObjectListViewSchema; the six local keys have no spec slot anywhere.

  • names object-view-unmirrored-keys-7779.test.ts → packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts — edited by this change

    ⚠️ Dated note, 2026-09-28 — the value type has since been decided, and listViews is mirrored by reference — objectui#7928. Later in this same release the maintainer's ruling A made ObjectViewSchema.listViews the protocol's own named-view record, by reference: on both faces its value is @objectstack/spec's strict ObjectListViewSchema, and a NamedListView is not assignable to it. The docs have taught that shape since objectui#8255. So "listViews stays unmirrored", "The declaration's value is the local NamedListView", the key "stays in the parity ledger … until the maintainer decides its value type" and the table's "still unmirrored" above no longer hold: the ObjectViewSchema entry has left UnmirroredDeclared. NamedListView stays exported with its 64 declared members. The renderer reads some of them off a named view and leaves the rest unread, and the split is no longer the 21 and 43 this entry counted: objectui#7928 stopped reading the options bag, which the record refuses, and objectui#10758 made the host delegation read a named view's remaining protocol members off the named view. The census in object-view-unmirrored-keys-7779.test.ts pins the current figures. .changeset/7928-listviews-by-reference-fold.md (PR objectui#10821) states what ships; the text above is kept as the reading of this change.

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a born-false claim that spells no line address at all (objectui#9495 coordinated one by ORDINAL — "a grep finds that member first" — and deciding that means reading what the sentence means), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Angle-bracketed names in the quoted prose above are rewritten as ANGLE-BRACKETS(name): GitHub deletes tag-shaped fragments from a stored body, and a quote that silently loses the identifier it is about is worse than a visible repair.

Compared the checked-out tree with 9419df198 (merge-base with origin/main): 21 file(s) changed outside .changeset/, read against 1802 pending declaration(s) that publish a body (2412 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3572.5 KB 3607.4 KB
Main entry chunk (gzip) 149.4 KB 350 KB
Entry file index-BdmxR-ls.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 559.46KB 134.18KB
core (index.js) 9.94KB 3.94KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 228.91KB 63.54KB
fields (index.js) 261.19KB 66.27KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.35KB 9.18KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 40.51KB 11.36KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.58KB 4.90KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.25KB 2.17KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 52.17KB 15.06KB
plugin-charts (index.js) 84.09KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 138.73KB 37.05KB
plugin-designer (index.js) 215.78KB 44.42KB
plugin-detail (index.js) 240.43KB 63.18KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 172.30KB 44.19KB
plugin-gantt (index.js) 172.43KB 42.85KB
plugin-grid (index.js) 230.25KB 63.22KB
plugin-kanban (index.js) 48.43KB 15.11KB
plugin-list (index.js) 115.82KB 28.67KB
plugin-map (index.js) 22.90KB 7.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 32.26KB 9.42KB
plugin-tree (index.js) 11.20KB 3.89KB
plugin-view (index.js) 90.27KB 22.74KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 119.55KB 39.23KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.17KB 2.73KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 22.61KB 7.40KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.82KB 7.15KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Spec Main Shape Gate is red on this head (b2df69071, job 109883053378), and the failure is not this PR's.

  • It compiles objectui against @objectstack/spec built from objectstack main 05a7547c9f40. The four diagnostics are the known drift: packages/app-shell/src/providers/writeWarningToast.ts:119 (TS2741, no computed entry in STRIPPED_LINE, three times) and packages/data-objectstack/src/spec-symbol-batch6.test.ts:242 (TS2344). This PR touches neither file.
  • The cause is objectstack b2805465, which adds computed to DroppedFieldsEvent['reason']; the repair is objectui#11206, PR objectui#11210 (the lane's p0, in review).
  • When it lands, this PR merges main and the gate re-runs; nothing in this diff changes for it.

domain:ui seat 1 · session_0122Knsowci76D2rBWReCzzZ · 2026-09-30T12:32Z


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: b2df69071d168034b7c3477287f99b2b7da77d5b
Local-runs: none

Inputs, and nothing else: card objectui#11013 (body and all seven comments — the ruling quote, claim 5908989184, cross-seat note 5908394824 and its correction 5909173910, the os-dev report 5911251883), PR objectui#11209 (body, the 24-file list, the net diff against main at the head), the 43 check-runs on the head, plus file reads at the head ref and at the 17.5.0 spec tag 0f6dcac5e9 (VIEW_CONSOLE_ROUND_TRIP_KEYS, view.zod.ts:6242-6249). Nothing built, run or re-run; the dev's evidence was re-measured by git grep at the head tree where the record says so.

① Derived judgments

Ruling 甲 on objectstack#20051 (5856781584): objectui aligns its reads to the declared spellings. Each accept-set or public-surface change the diff implies, judged against that and the card body:

  1. viewItemObjectName (@object-ui/data-objectstack, exported) drops the objectName leg and reads data.object ?? object. Right. The 17.5.0 spec declares object on every view member (view.zod.ts:177) and objectName on none (:6223 names it only as the alias the spec strips); the new pin viewItemObjectName.declaredSpelling-11013.test.ts parses the door on both members with a lit object control and shows every adapter writer stamps object. listViews() and listViewOverrides() narrow through this one accessor, so a row bound by objectName alone stops listing — card item 1, and only a legacy row no console writer produces.
  2. viewRowId (app-shell) reads name only; a top-level id / _id is no identity. Right. Card item 1. data-objectstack is the only in-repo adapter and its rows are name-keyed; the setDefaultViewIdentity pins are re-pointed, not deleted, and buildViewTabs skips an identity-less row rather than keying a tab on an undeclared spelling.
  3. The object page no longer stamps objectName onto the listViews() rows it reads. Right. buildPersistedViewBody returns { ...baseViewDef, ...patch } for a saved view (a whole-document PUT), so the stamp rode a toolbar toggle back into the stored row — the changeset's sentence checks out. Removing a reader-minted undeclared key from that echo is read-side alignment, not stage (iv): the save path's shape is untouched.
  4. Studio view-ref picker (viewRefCatalog, now exported) and Studio view preview (resolveObjectName, now exported) read object only. Right. The preview site was outside the card's three-reader census: same defect class (an objectName read off a stored view row), same ruling, same gate family; see ③.
  5. The nine dropped view reads — allowExport, wrapHeaders, clickIntoRecordDetails, addRecordViaForm, addDeleteRecordsInline, collapseAllByDefault, fieldTextColor, prefixField at both relays, and editRecordsInline as a second spelling of inlineEdit at the object page. Right, and the zero-producer evidence holds. Re-run at the head tree over packages/*/src, apps and examples (non-test): the only hits are the two relays' NODE reads, the NamedListView tombstones, objectui's list-view node zod arm (objectql.zod.ts:1653-1667, where the node keeps them), UnifiedViewConfig in designer.ts, and the two React props the dev named (InterfaceListPage.tsx:529, StudioDesignSurface.tsx:2797, both node-side). editRecordsInline: zero. Authored views in objectui apps / examples: 0 files per key; the objectstack checkout's apps / examples: 0 files per key, with the inlineEdit control lighting 9 files. The node's own values still reach ListView (OBJECT_VIEW_HOST_COMPOSITION_KEYS, objectui#5097), which ListView.tsx:1636 and :3279 still read. So the card's rule — zero producers ⇒ drop — is met for all nine, and there is nothing to raise on objectstack#20051.
  6. A view's allowExport: false no longer withholds its exportOptions. Right, the consequence of 5; the node's export gate stays.
  7. NamedListView.allowExport becomes a ?: never tombstone (@object-ui/types, a narrowing on a published type). Right. Ruling A on objectui#7924 kept it declared only because both relays read it; with the reads gone, keeping it would be the declare-and-ignore shape. The objectui#7779 census re-points its pins (a compile-time Expect on the tombstone, a @ts-expect-error on the authored value, source pins on both relays and on ListView's gate), and the list-view NODE arm keeps its own allowExport. Outside the claim's file list, flagged by the dev; judged a consequence — see ③.
  8. Toolbar policy read as userActions.search / .sort / .filter through the existing normalizeListViewSchema fold at two sites (the object page's object-view node; plugin-view's non-grid generateViewSchema route). Right. The fold applies no defaults (normalize-list-view.ts docblock: an absent flag stays absent), so plugin-view's ?? schema.showSearch ?? false leg still fires for a silent view and the object page's !== false default is unchanged; a bare flag folds only when the canonical key is absent. It is the same fold the relays' userActions rung already runs (plugin-view/ObjectView.tsx:2834-2835, app-shell ObjectView.tsx:2889-2890): no new tolerance is minted, and the read names no legacy key.
  9. listViews() flatten carries the record's object plus the viewItem-member keys of VIEW_CONSOLE_ROUND_TRIP_KEYS (isDefault, isPinned, sortOrder, visibility, columnState), derived, not retyped; app-shell's VIEW_ROW_STATE_KEYS is derived the same way. Right. It matches the spec's record at 0f6dcac5e9; _isOverride is listOverlay-only and correctly excluded on both sides. The switcher sort reads sortOrder off this row (ObjectView.tsx:1976-1985), so the dev's partial falsification of card item 3 is real and the fix is at the right reader. isDefault is still coerced to a boolean, _draft preserved, flat rows returned whole, a missing key not invented.
  10. buildViewTabs drops the explicit showSearch / showFilters / showSort picks; the ...sv spread keeps the row's keys, userActions included. Right, no accept-set change.
  11. Untouched, correctly: packages/plugin-list/src/ListView.tsx (the bare-array exportOptions tolerance stays, per the card and the claim's ⛔), view-config-utils.ts (no reader keys persisted state by filter[].id / sort[].id), and nothing persisted changes shape beyond the declared keys now surviving the whole-body save.

Remaining objectName ?? object reads at the head are node reads (nav-target.ts:106, StudioDesignSurface.tsx:1479) or the global-search hit shape (data-objectstack/src/index.ts:3543), not view rows: outside this card.

② Semver level

  • .changeset/11013-view-row-declared-spellings.md: @object-ui/types: minor; data-objectstack, app-shell, plugin-view: patch. Matches what the diff publishes. The one narrowing of a published type (① item 7) is marked BREAKING (TypeScript only) with its migration (a view's allowExport → the list-view / object-view node's allowExport, formats via the view's exportOptions.formats); objectui's rule is breaking ⇒ minor, never major (AGENTS.md, version alignment; Changeset Bump Policy green). All four packages sit in the one fixed group, so the published level is one minor bump group-wide whatever the three patch arms say, and each package still gets the entry in its CHANGELOG. Precedent, noted not faulted: the objectui#7924 density entry took plugin-view: minor for the same class of renderListView-output change; patch here is defensible as a correction (the spec refuses the keys on a view) and moves no version.
  • Prose checked against the diff: the switcher-state paragraph (sortOrder now survives a reload), the nine-key table, the userActions paragraph (a bare flag keeps its answer through the fold — supported by the fold's no-default behaviour), the binding / identity paragraph (door refuses objectName alone; every write stamps object and name; the echo-back sentence, see ① item 3), the tombstone paragraph — each claim is in the diff or pinned by a new test. One observation, not a defect under objectui's gate set: the two 7924 entries carried an explicit ADR-0087 disposition marker; this entry states the stored-document effect per key (inert, or folded) without the marker, and no objectui gate reads one.
  • Dated notes on .changeset/7924-density-mode-through-fold.md and 7924-named-list-view-retire.md: front matter unchanged (Changeset Overwrite Report green), the same ⚠️ dated-note form those entries already use, and each sentence true at this head (neither bucket-③ member stays declared; ListView still gates its export control on the node's own allowExport; the 11013 entry states what ships). Right.
  • Clause-②: yes, at line start in the PR body and in the claim. Consistent: yes takes at least minor, and types: minor is there; the change is a narrowing (the tombstone) and the changeset says BREAKING, so yes is the true reading.

③ Boundary flags

Gate verdicts on the head (43 check-runs, every one concluded before this record was posted): 39 success, 3 skipped, 1 failure, none still in progress. Type Check, Lint, Build & E2E, Test (dist pins), all eight Test (shard N/8) jobs and their Test rollup, every changeset gate (Changeset Declaration, Changeset Bump Policy, Changeset Fixed Group Check, Changeset Overwrite Report, Changeset Claim Re-read), Doc Snippet Type Check (which runs check-doc-example-types.mjs, so CI answers the dev's NOT MEASURED check:doc-examples: green), Line Citation Gate, Governed Surface Queue Guard and the rest are success; dependabot and the two coverage jobs are skipped.

  • Spec Main Shape Gate is red, and it is the known objectstack-main drift tracked as objectui#11206. Its annotations name packages/app-shell/src/providers/writeWarningToast.ts:119 (computed missing from the strip-reason record) and packages/data-objectstack/src/spec-symbol-batch6.test.ts:242, compiled against objectstack 05a7547c9f40; neither file is in this diff, and the job's remaining annotations are the resulting type-check / build step exits for app-shell, data-objectstack and apps/console. Not a finding against this head.

Dev flags and open questions, each answered:

  1. open_questions[0] — the toolbar policy read through the fold at the two sites, or raw. A, the seat's answer: keep the existing normalizeListViewSchema fold. The diff is consistent with A: both sites call normalizeListViewSchema(activeView ?? {}) and read its userActions, pinned by the SAME ANSWER cases in ObjectView.viewRowDeclaredReads-11013.test.tsx. I see no reason against A: the fold is the objectui#7924 changeset's standing policy (that fold stays), the relays' own userActions rung already runs it, it mints no new tolerance, and B would split one row's toolbar answer between two routes.
  2. NamedListView.allowExport tombstone outside the claim's listed surface — accepted (① item 7).
  3. ViewPreview.tsx in-place fix under the bounded exemption — accepted: same defect class, same gate family, 10 / 3 lines plus its own pin; git log --remotes --not origin/main on the file shows no other live branch editing it (the only other hit is a merge of main into the objectui#9853 branch, which carries no edit of its own).
  4. Relay census (relayRungCensus-7559), the objectui#10694 probe (wrapHeaders → resizable), two plugin-view pin comments, three test replicas of the old stamp, the objectui#7779 census — accepted as consequences; each is a test or comment edit.
  5. Two 7924 dated notes — accepted (②).
  6. Not changed, noted by the dev: UnifiedViewConfig (designer.ts) still declares the keys with zero constructors; MetadataProvider.applyViewItem still flattens to config plus identity (its tab regains the keys through the override merge, and the sort reads the listViews() row); ResourceEditPage's sourceObjectName draft.objectName fallback is not a view-row read. Agreed, outside this card; carriers none, as reported.
  7. Cross-seat correction 5909173910, cited in the PR body: objectstack#20051 stage (iv) no longer waits on this card; this card remains the legacy-row read alignment. Nothing here changes what is persisted, so the correction leaves the scope as claimed.
  8. For the seat, not a verdict matter: the PR is a draft and behind main (846cec0ef; PR objectui#11192 touched data-objectstack/src/index.ts away from these hunks, merge-tree clean per the dev), so the queue step will re-run CI on an updated head.

Implemented-by: claude/issue-11013-view-row-declared-spellings
Reviewed-by: session_0122Knsowci76D2rBWReCzzZ

VERDICT: PASS

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3572.7 KB 3607.4 KB
Main entry chunk (gzip) 149.4 KB 350 KB
Entry file index-u9aw1Wce.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 559.46KB 134.18KB
core (index.js) 9.94KB 3.94KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 228.91KB 63.54KB
fields (index.js) 261.19KB 66.27KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.35KB 9.18KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 40.51KB 11.36KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.58KB 4.90KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.25KB 2.17KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 52.17KB 15.06KB
plugin-charts (index.js) 84.09KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 138.73KB 37.05KB
plugin-designer (index.js) 215.78KB 44.42KB
plugin-detail (index.js) 240.43KB 63.18KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 172.30KB 44.19KB
plugin-gantt (index.js) 172.43KB 42.85KB
plugin-grid (index.js) 230.25KB 63.22KB
plugin-kanban (index.js) 48.43KB 15.11KB
plugin-list (index.js) 115.82KB 28.67KB
plugin-map (index.js) 22.90KB 7.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 32.26KB 9.42KB
plugin-tree (index.js) 11.20KB 3.89KB
plugin-view (index.js) 90.27KB 22.74KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 119.55KB 39.23KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.17KB 2.73KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 22.61KB 7.40KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.82KB 7.15KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: aa07a782550386b600d1a1e4913c62a6329f5582
Local-runs: none

Delta record. This head is the GitHub update-branch merge of main into the head that record 5911456894 reviewed; nobody edited a file. Inputs, and nothing else: record 5911456894 (head b2df69071d168034b7c3477287f99b2b7da77d5b); origin/main at 9419df198f06856c3746738c99dd807fd3f7dd04 and the two heads, read after a fetch with git log, git merge-base, git diff, git show --cc and git patch-id --stable at refs, plus git show of packages/data-objectstack/src/index.ts at this head; PR #11209 and its /files at this head; the objectui#11210 merge commit's 14-file stat; this head's check-runs. Nothing checked out, installed, built or run.

① Derived judgments

Carried over from record 5911456894 at head b2df69071d168034b7c3477287f99b2b7da77d5b, the net diff being identical (patch-id 6361c2417f89dba42eff1d2116ca78e780a9435d at both heads). The three measurements that make the carry-over valid:

  1. Parents. aa07a78255 is a merge commit with exactly two parents: first parent b2df69071d168034b7c3477287f99b2b7da77d5b, the reviewed head; second parent 9419df198f06856c3746738c99dd807fd3f7dd04, the tip of origin/main (the merge of objectui#11210). git rev-list --first-parent b2df6907..aa07a782 is the merge commit alone, so no other commit sits between the reviewed head and this one. git show --cc on the merge is empty: an automatic merge with no hand-resolved hunk, including in the one file both sides touched (item 3).
  2. Net diff. merge-base(origin/main, aa07a782) is 9419df198f; merge-base(origin/main, b2df6907) is 81778b955575b61d56c7563ef854fa73b7745ed7. git diff --name-status over the two ranges lists the same 24 paths with the same A / M status each (three .changeset entries, thirteen app-shell paths, three data-objectstack, three plugin-view, two types), and GitHub's /files on the PR at this head lists those same 24. git diff 9419df19 aa07a782 | git patch-id --stable = 6361c2417f89dba42eff1d2116ca78e780a9435d; git diff 81778b95 b2df6907 | git patch-id --stable = 6361c2417f89dba42eff1d2116ca78e780a9435d. Identical hunks.
  3. What main brought in. Nine merges between the two merge bases (objectui PRs test(types): a padded grouping field name is refused on every face that declares grouping (objectui#7347) #11191, feat(types,layout,app-shell): a navigation entry with no label renders its target's current label at render time (objectui#9868) #11186, fix(types): the six held public blocks refuse the content channels no renderer reads (objectui#10872 batch 5) #11193, feat(types,plugin-detail): declare the field-security triple on record:details / record:highlights / record:related_list and read it un-cast (objectui#8649) #11184, feat(types): the object-form zod mirror declares the members its TypeScript twin declared (objectui#6152, round 1) #11125, fix(app-shell): Studio resolves an app's own locale-map label in the designer locale instead of printing [object Object] (objectui#11181) #11194, fix(data-objectstack): the entry-form filter refuses an empty or non-string icontains comparand, reading the spec's own predicate (objectui#9048) #11192, fix(core,plugin-tree): the record-source ladder judges map / gantt / tree against their spec rows; the tree stops honouring an undeclared bare-array data (objectui#8348) #11200, fix(app-shell,i18n,data-objectstack): the computed strip reason is worded, and the table and the batch-6 pin compile against both the pinned spec and objectstack main (objectui#11206) #11210), 100 files. Intersection with this PR's 24 paths: one file, packages/data-objectstack/src/index.ts, changed on main by objectui#11192 (objectui#9048, the entry-form icontains comparand refusal). The two sides of that file are disjoint in both hunks and symbols. main's hunks: one added import from @objectstack/spec/data (isRefusedTextComparand, textComparandRefusalReason), the new describeFilterEntry and refuseTextComparandEntry, the MalformedFilterError constructor, and an index parameter threaded through objectFilterEntryToAST, objectFilterEntriesToAST, translateFilterArray and translateFilterChild, all in the filter-translation region of the file. This PR's hunks in the same file: one added import from @objectstack/spec/ui (VIEW_CONSOLE_ROUND_TRIP_KEYS), the derived VIEW_ITEM_ROUND_TRIP_KEYS, the viewItemObjectName docblock and the dropped objectName leg, and the listViews() flatten. No hunk overlaps, no function is edited by both, neither side calls anything the other side changed, and at this head the file carries both imports, both sets of functions, and the PR's viewItemObjectName body exactly as reviewed. The earlier record's ③ item 8 anticipated exactly this interaction ("objectui#11192 touched data-objectstack/src/index.ts away from these hunks, merge-tree clean per the dev"); it is now measured on the merged head rather than reported. Not a semantic interaction. objectui#11210's two files, packages/app-shell/src/providers/writeWarningToast.ts and packages/data-objectstack/src/spec-symbol-batch6.test.ts, are among the 100 and are not in this PR's file list.

So every judgment in ① of record 5911456894 (the viewItemObjectName and viewRowId declared-spelling reads, the dropped objectName stamp, the Studio picker and preview reads, the nine dropped view reads with their zero-producer evidence, the allowExport consequence and the NamedListView.allowExport tombstone, the toolbar-policy read through the existing fold, the derived round-trip keys on the listViews() flatten, buildViewTabs, and what is correctly untouched) is a judgment on hunks this head carries byte for byte, merged onto a main whose one shared file is touched in a different region. Unchanged.

② Semver level

Carried over from record 5911456894 at head b2df6907: .changeset/11013-view-row-declared-spellings.md and the two dated notes on .changeset/7924-density-mode-through-fold.md and .changeset/7924-named-list-view-retire.md are byte-identical at the two heads (git diff b2df6907 aa07a782 -- .changeset/... over the three is empty), the levels the new entry declares (@object-ui/types minor with the BREAKING (TypeScript only) migration; @object-ui/data-objectstack, @object-ui/app-shell, @object-ui/plugin-view patch; no major) still match what the identical diff publishes, and the PR body's Clause-②: yes is unchanged. The changeset gates on this head (Changeset Declaration, Changeset Bump Policy, Changeset Fixed Group Check, Changeset Claim Re-read, Changeset Overwrite Report) are success.

③ Boundary flags

  • The boundary flags of record 5911456894 carry over as recorded: the answer A on the toolbar-policy fold, the accepted tombstone, the accepted ViewPreview.tsx in-place fix, the accepted census and pin consequences, the two 7924 dated notes, the noted-not-changed items and the cross-seat correction are dispositions on the diff, and the diff is the same; nothing the merge brought touches them.
  • What main brought in: one shared file, packages/data-objectstack/src/index.ts, judged disjoint in ① item 3. Any cross-file effect of the other 99 main files on these 24 is what this head's Type Check, Lint, Build & E2E and test shards measure, listed below.
  • objectui#11210's two files are not in this PR's file list. The Spec Main Shape Gate failure the earlier record attributed to those two files (objectstack-main drift, objectui#11206) is what this update-branch merge was made to pick up; the earlier record's item 8 (behind main, the queue step re-runs CI on an updated head) is answered by this head, whose merge base is the main tip.
  • Check-runs on aa07a78255, read 2026-09-30T13:07Z: 42 runs. 35 success: Action Ref Convention, Build & E2E, Build Docs, Bundle Analysis, Changeset Bump Policy, Changeset Claim Re-read, Changeset Declaration, Changeset Fixed Group Check, Changeset Overwrite Report, Control Byte Scan, Doc Component Type Check, Doc Example Id Check, Doc Fence Language Check, Doc Snippet Type Check, Docs Route Eager Closure Check, Governed Surface Queue Guard, Inert vi.mock Specifier Check, Internal Docs Link Check, label, Line Citation Gate, Lint, Live E2E (informational), Pre-Install Import Graph Check, README Export Check, Shell Escape Residue Scan, Skill Eval Token Check, Skill Example Check, Skill Guide Path Check, Spec Main Shape Gate, Test (dist pins), Test (shard 3/8), Test (shard 6/8), Test (shard 7/8), Test (shard 8/8), Type Check. 3 skipped: dependabot, the coverage-shard matrix job, Test (coverage), which do not run on this event. 0 failure. 4 in_progress, not yet concluded and named here as such: Test (shard 1/8), Test (shard 2/8), Test (shard 4/8), Test (shard 5/8). Spec Main Shape Gate is success on this head (job 109895592039 of run 36717988178). On the reviewed head it was the one failure, attributed to the two objectui#11210 files; this head is the first of this PR to carry those files at their objectui#11210 state, and the gate concludes green on it, so the objectstack-main drift the earlier record set aside as not this contract's no longer stands between the PR and the queue.

Implemented-by: claude/issue-11013-view-row-declared-spellings
Reviewed-by: session_0122Knsowci76D2rBWReCzzZ

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review September 30, 2026 13:15
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Sep 30, 2026
Merged via the queue into main with commit 3c13675 Sep 30, 2026
45 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-11013-view-row-declared-spellings branch September 30, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

2 participants