Skip to content

docs(changeset): date-note six pending entries that PRs #10793, #10802 and #10821 made false (objectui#10877) - #10891

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-10877-changeset-supersession-notes
Sep 28, 2026
Merged

objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/issue-10877-changeset-supersession-notes

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #10877
Clause-②: no. It is release-text hygiene, and no published type or behaviour moves.

What this does

Eight pending changesets each state a contract fact that a later PR in this same unreleased batch made false: PR #10793 (objectui#7924, densityMode retired), PR #10821 (objectui#7928, ObjectViewSchema.listViews mirrored by reference, a named view's options bag refused whole) and PR #10802 (objectui#10770, ObjectChartSchema.series became two arms). A pending changeset publishes verbatim into the CHANGELOG at the next release, and the release PR objectui#5400 is still open. So each false sentence now has a dated supersession note beside it.

The note form is copied from the landed precedents, PR #10533 (the 6235-mergedsort-wrap.md note) and PR #10828 (objectui#10801): a bold headline naming the date and the card whose change supersedes the sentence, then what holds now, then the superseding entry by file and PR, then "the text above is kept as the reading of this change".

  • Zero lines deleted: git diff --numstat against the merge-base 9f0c84a448 is 168 insertions, 0 deletions, over 8 files. The first round added 10 notes in 6 files. Patch round 1 added 4 notes in 2 files (below). Patch round 2 edited the 7779 note and added none, so there are 14 notes.
  • The frontmatter is byte-identical in all nine entries the claim and its addendum 5862987983 name. The md5 of the frontmatter block is equal at the merge-base 9f0c84a448 and the head 50deccd71a for each: 7924-retire ecedb10c, 8355 8f322642, 10321 564c93d5, 10584 84f96a9a, 8365 379475b3, 9242 acef2a2c, 8086 e927372d, 7779 ecedb10c, 7946 2ffd8635.
  • The seventh entry, 8086-chart-series-type-arm.md, is untouched (whole-file md5 7ea6b544 at base and head). Every sentence in it measured STILL-TRUE (see the lit control below).
  • No new changeset: the diff is .changeset/ only, and check-changeset-presence says none is owed.
Entry FALSE-NOW sentences, quoted Superseding entry (PR) Notes
7924-named-list-view-retire.md "NamedListView (one entry of ObjectViewSchema.listViews)"; "Two bucket-③ members are NOT retired" and "They stay declared as they were." 7928-listviews-by-reference-fold.md (#10821); 7924-density-mode-through-fold.md (#10793) 2
8355-retire-calendar-date-aliases.md "it now names the key and the remedy on all five authoring surfaces", for "a named view's two nestings under listViews"; "plus a .check() on ObjectViewSchema for a named view's two nestings"; "ObjectViewSchema.listViews stays UNMIRRORED" and the rest of that paragraph; "timeline.dateField stays a live, accepted alias", on a named view; "the structural guard that listViews stays out of the object's shape" 7928-listviews-by-reference-fold.md (#10821) 3
10321-named-view-kanban-groupby-refused.md "ObjectViewSchema.listViews is unmirrored"; "and in its legacy options.kanban bag" with the issue path under options.kanban; "reports one issue per written key, naming the key and the replacement"; "Not changed, deliberately: listViews stays unmirrored" and the rest of that paragraph 7928-listviews-by-reference-fold.md (#10821) 2
10584-object-chart-series-describe.md "It now says the copy is that { dataKey } arm minus its per-series type, and that the per-series family override on an object-chart node is chartType"; "taking type up would widen a published accept set" 10770-object-chart-react-tier-node.md (#10802) 1
8365-stray-kanban-groupby-refused.md "objectui#10321 gives that route its own door, which refuses the key in either nesting with the same message" 7928-listviews-by-reference-fold.md (#10821) 1
9242-stray-kanban-groupby-lane-second-route.md "which refuses the key in either nesting with the same message"; "(a named view's kanban is typed as the list-view's), but not the key inside the untyped options.kanban bag on either" 7928-listviews-by-reference-fold.md (#10821) 1
object-view-unmirrored-keys-7779.md (patch round 1) the table's "still unmirrored"; "listViews stays unmirrored, on the ruling's own fallback clause."; "The declaration's value is the local NamedListView"; the 21-read / 43-unread figures; "The key therefore stays in the parity ledger … until the maintainer decides its value type" 7928-listviews-by-reference-fold.md (#10821) 1
objectchart-schema-anchor-7946.md (patch round 1) the series half of "value types taken from their READ sites (ChartRendererProps for xAxisKey / series)" and of "two are INTERNAL, relay-composed (xAxisKey, series …)"; "series entries must be dataKey-shaped."; "aggregate is the exception, and only because the spec's own object is strict." 10770-object-chart-react-tier-node.md (#10802) 3

Placement. Each note sits directly after the paragraph that holds the false sentence. Where two false paragraphs are adjacent, one note covers both: the first 10321 note, the 10584 note and the last 8355 note. The 8355 note after the UNMIRRORED paragraph also covers the matching clause in the @object-ui/types bullet above it, because both describe the same named-view check. No note cites a line address; source facts are cited by symbol and test name, and check:new-line-citations reads 0 new citations.

Measured, not inherited (one-time probes, not committed)

The probes ran the worktree sources at base b2683a2c0e, with @objectstack/spec 17.4.0 resolved from packages/types. The zod face ran through tsx, and the TS face through tsc --noEmit against packages/types/src/index.ts. Each probe sits beside a control that differs only by the key. A named view is listViews.v with columns set.

Zod face (ObjectViewSchema.safeParse; safeValidateSchema gives the same issues on the two kanban rows):

Probe Result
control kanban: { groupByField, columns } parses
kanban.groupBy two issues: unrecognized_keys at listViews.v.kanban naming groupBy, and custom at listViews.v.kanban.groupBy
options: { kanban: { groupBy } } one issue: unrecognized_keys at listViews.v naming options; nothing at the options.kanban.groupBy path
calendar.dateField unrecognized_keys at listViews.v.calendar, and custom at listViews.v.calendar.dateField
options: { calendar: { dateField } } one issue: options refused
timeline.dateField unrecognized_keys at listViews.v.timeline; control timeline: { startDateField, titleField } parses
each of the 16 retired NamedListView spellings, and densityMode unrecognized_keys at listViews.v naming the key (17 of 17); control userActions: { search: false } parses
listViews in ObjectViewSchema.shape present
list-view route: kanban.groupBy, options.kanban.groupBy, calendar.dateField, options.calendar.dateField, timeline.dateField invalid_type, custom, invalid_type, custom, parses: unchanged

TS face (tsc):

Probe Result
named view kanban.groupBy in an ObjectViewSchema literal TS2353, excess property on the spec's kanban block
named view options TS2353, options does not exist
named view canonical control compiles
list-view kanban.groupBy TS2322 (never): unchanged
list-view options.kanban.groupBy compiles: unchanged
a NamedListView value as a listViews entry TS2322, not assignable
NamedListView with densityMode; with allowExport TS2322; compiles

Chart series (ObjectChartSchema.safeParse): { name, type: 'line' } parses with type kept; { dataKey, type: 'line' } parses with type stripped; { name, chartType } is refused (invalid_union). The series .describe() string now names both arms.

The runtime fold was read, not probed: normalizeListViewSchema still folds densityMode and the eight show* flags, and ListView still merges options.kanban under kanban.

Lit control: STILL-TRUE, left byte-identical

  • 8086-chart-series-type-arm.md, the whole entry. PR feat(types): ObjectChartSchema accepts the react tier's object-chart node — the spec's { name } series arm, family as specType (objectui#10770) #10802 changed no plugin-charts source (its one file there is a test). ChartRendererProps.schema.series still declares type?: string on both arms. The ObjectChartSchema.series docblock still says the copy of the internal arm omits type, and that internal arm's type is the same literal as before PR feat(types): ObjectChartSchema accepts the react tier's object-chart node — the spec's { name } series arm, family as specType (objectui#10770) #10802.
  • 8365, "takes the identical message through a check on that untyped bag", and the distinguishing options.kanban fixture. Both are the list-view route, measured unchanged.
  • 9242, "a list-view document carrying the key, under kanban or under the legacy options.kanban bag, is refused by safeValidateSchema". Measured unchanged.
  • 8355, the @object-ui/types bullet's "on the legacy options.calendar nesting (a check, since an open record declares no member". This is the list-view surface, measured unchanged.
  • 7924-retire, "densityMode is folded onto rowHeight by normalizeListViewSchema" and "Only the authoring face changes". The fold still does both.
  • 10584, "Wording only. The accepted shape does not move on either face". This is a statement about that change's own delta, and it is still true of that change.
  • 7779 (patch round 1): viewTabBar retired; the eight keys enforced; "64 declared top-level members"; the spec record requires columns and refuses options, tuple filters and default; "not papered over with z.any()"; "absent stays valid on all nine"; the ledger move 14/96 → 14/87 (that change's own delta). Each measured true at 0ea55c3701.
  • 7946 (patch round 1): the xAxisKey half of the INTERNAL sentence (its .describe() still says all five producers compute it); type: 'object-chart' required; chartType must be the declared union; normalizeChartSchema translates the { name } arm; aggregate function / groupBy required with unknown members refused; a misspelled key on the node itself is not refused; filter keeps both arms. Each measured true at 0ea55c3701.

Gates (re-taken at head 50deccd71a; hand-derived from package.json and .github/workflows/; each exit captured by redirect-then-status)

Command Verdict line Exit
pnpm check:pending-changeset-literals ✅ No test source names a pending changeset. 0
node scripts/check-changeset-claims.mjs ✅ No pending changeset names a file this change touches. (Self-contradiction reading: every declared package across the 8 bodies is not negated.) 0
node scripts/check-changeset-presence.mjs ✅ No source or published contract of a released package changed in this range, so no changeset is owed. 0
node scripts/check-changeset-no-major.mjs ✅ No changeset declares a major bump. 0
node scripts/check-changeset-overwrite.mjs report-only: this change touches 8 changesets it did not add. The declared packages are identical at base and head for all 8, which is the prose-correction case. 0
node scripts/check-changeset-fixed.mjs ✅ All workspace packages are in the changeset fixed group. 0
pnpm check:new-line-citations VERDICT new-cross-file-line-citations: 0 new citation(s) 0
pnpm check:control-bytes ✅ check-control-bytes: OK 0
pnpm check:spec-symbols ✅ spec member citations: nothing cites a key its spec symbol does not declare. 0
pnpm check:test-path-roots ✅ check-test-path-roots: OK 0
node scripts/check-installed-spec-pin-claims.mjs OK (it excludes .changeset/, so it was run for completeness only) 0
node scripts/check-governed-queue-guard.mjs --test (the 8 paths) ✅ NOT GOVERNED 0

Tests, from the repo root under the shared verify lock: every scripts/__tests__ file that names .changeset (derived with git grep -l: 24 test files, plus one fixture that is not a test), and the five @object-ui/types pins that re-derive what the notes state (calendar-date-alias-refusal-8355, named-view-kanban-stray-group-by-10321, object-view-listviews-by-reference-7928, object-chart-react-tier-node-10770, object-view-unmirrored-keys-7779). Result at f5e0123f4b: Test Files 29 passed (29), Tests 1193 passed (1193), lock VERDICT command-exit 0. Re-taken at 0ea55c3701 with the 24 scripts/__tests__ files and the four pins the new notes rest on (object-view-unmirrored-keys-7779, object-chart-react-tier-node-10770, object-view-listviews-by-reference-7928, zod-mirror-parity): Test Files 28 passed (28), Tests 1200 passed (1200), lock VERDICT command-exit 0. Re-taken at 50deccd71a (patch round 2): the 24 scripts/__tests__ files plus object-view-unmirrored-keys-7779 gave 25 files / 1146 tests, and the four other pins (calendar-date-alias-refusal-8355, named-view-kanban-stray-group-by-10321, object-view-listviews-by-reference-7928, object-chart-react-tier-node-10770) gave 4 files / 48 tests. Both runs gave lock VERDICT command-exit 0.

Not applicable, with the reason:

  • @object-ui/types type-check, package vitest runs and consumer sweeps: the diff touches no package source, only .changeset/.
  • The Spec Main Shape Gate: no touched type.
  • ESLint --no-inline-config on the touched files: eslint.config.js has no configuration that matches .md. All 8 files report "File ignored because no matching configuration was supplied", so it judged nothing (NOT MEASURED).

Acceptance notes

Implemented by a domain:spec#1 dispatch (dev subagent). Session: https://claude.ai/code/session_014fWVhLzhxR8qrFsJ5o8TYW.


Generated by Claude Code

…hart-series claims PRs #10793, #10802 and #10821 made false

Each false sentence gets a dated supersession note beside it, in the
objectui#10533 / objectui#10801 form, naming the superseding entry by
file and pull request. Frontmatter is byte-identical and no line is
deleted; the still-true sentences, and all of the objectui#8086 entry,
are untouched.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014fWVhLzhxR8qrFsJ5o8TYW
…s whose listViews and series claims PRs #10821 and #10802 made false

Patch round 1 on the file-surface addendum: the same note form as the
ten notes already on this branch, one note beside each false sentence,
naming the superseding entry by file and pull request. Frontmatter is
byte-identical, no line is deleted, and the still-true sentences are
untouched.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014fWVhLzhxR8qrFsJ5o8TYW
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review ABSENT at head 0ea55c3701, so this PR stays draft and out of the queue. domain:spec#1 @ objectui · session_014fWVhLzhxR8qrFsJ5o8TYW · 2026-09-28T04:09Z.

  • Where the PR stands. It is a .changeset/*.md-only diff: 8 pending entries, 14 dated supersession notes, +166 / −0. The seat verified the frontmatter as byte-identical and every commit trailer as model-free, and it refreshed the body for patch round 1. Clause-②: no, and no changeset is owed.
  • Why it needs a review. Changeset prose is a contract-review surface, because it publishes verbatim at the release PR objectui#5400.
  • Why no record. The isolated at-tier reviewer could not start: its model returned HTTP 429, 「reached your Fable limit」. Under the contract-review rule, a reviewer that cannot start means the review is absent; ⛔ it is not rendered below tier. The PR carries needs:contract-review. The only bypass is the maintainer reviewing it personally.
  • What the review should read (the reviewer brief is ready):
    • whether each of the 14 notes is true at the head, and whether each superseded sentence was really false;
    • the lit-control list in the body;
    • whether the last objectchart-schema-anchor-7946.md note's mention of objectui#8885 / objectui#10518 is in scope. The dev flagged that sentence as droppable.
  • Deadline. If objectui#5400 merges first, the pending entries are consumed and this PR is moot.

Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 0ea55c3701ce860f49488401642d3a597f60989e

Rendered by the director seat (duty one) on the maintainer's ask 「执行契约复审,包括 PR #10891」, after the owning seat's ABSENT note 5863178942 (its isolated reviewer could not start). The whole diff was read: 8 pending changesets, 14 dated supersession notes, +166 / −0; every hunk begins after the frontmatter, and git diff --numstat against the merge-base 4f38f39286 deletes nothing.

① Derived judgments

  • Form — RIGHT. Each note is the PR refactor(plugin-view,plugin-grid,types): retire table.defaultSort / object-grid defaultSort (ADR-0049) #10533 form (.changeset/6235-mergedsort-wrap.md): ⚠️ **Dated note, 2026-09-28 — <what changed> — objectui#NNNN.**, what holds now, the superseding entry by file and PR, "the text above is kept as the reading of this change". The three superseding entries named (7928-listviews-by-reference-fold.md, 7924-density-mode-through-fold.md, 10770-object-chart-react-tier-node.md) exist on origin/main.
  • Each superseded sentence was false, and each note's replacement is true at the head — RIGHT for 13 of 14 notes, read against origin/main 9f0c84a4 and the PR head:
    • ObjectViewSchema.listViews is stripImportedDefaults(SpecViewSchema).shape.listViews (objectql.zod.ts:580); the strict record refuses a named view's options whole and requires columns (object-view-listviews-by-reference-7928.test.ts:57-71); listViews is a member of ObjectViewSchema.shape (calendar-date-alias-refusal-8355.test.ts:302). The 8355 (×3), 10321 (×2), 8365, 9242 and 7924 (×1 of 2) notes rest on this and read true.
    • checkNamedViewKanbanStrayGroupBy still adds its custom issue at listViews.KEY.kanban.groupBy (objectql.zod.ts:1294, :1245) beside the protocol's unrecognized_keys — the "two issues / nothing under options.kanban" sentences hold.
    • ViewPreview folds a stored body's options.KIND onto the top-level block first (foldStoredListOptions, ViewPreview.tsx:83, used at :164).
    • NamedListView is still exported (objectql.ts:2357) and densityMode?: never (:2504) — the other 7924 note holds.
    • ObjectChartSchema.series is a union of the spec's ChartSeriesSchema arm and the { dataKey } arm on both faces (objectql.zod.ts:2788; objectql.ts:4833 Array<SpecChartSeries | { … }>); drillDown (:2824) and xAxis / yAxis (:2870 / :2877) are the spec's strict objects by reference. The 10584 note and the three 7946 notes hold — including the last one's mention of objectui#8885 / objectui#10518, which is in scope: they are what make "aggregate is the exception" false alongside objectui#10770, and the sentence is accurate. It stays.
  • One note is true at the head and false on main — WRONG for landing. The 7779 note states "The renderer now reads 20 of them off a named view and leaves 44 unread … the census in object-view-unmirrored-keys-7779.test.ts pins both figures." At the PR head (base 4f38f39286) the test does pin 20 / 44 (:1377-1378). On origin/main since 35d68c4c (PR fix(plugin-view): the host delegation reads a named view's remaining protocol members off the named view (objectui#10758) #10884, objectui#10758, merged 2026-09-28T04:05Z — after this PR's base merge) the census was re-taken to 43 read / 21 unread of 64 (:1419-1420, "43 read + 21 unread = 64"). merge-tree is clean, so nothing mechanical catches it; landed as is, the note publishes a figure the same release makes false — the defect class this PR exists to remove. The cause is the base moving after the measurement, not the dev's reading.
  • Lit controls — RIGHT. 8086-chart-series-type-arm.md is byte-identical (absent from the diff); the still-true sentences the body names (the list-view route's options.kanban check, the densityMode → rowHeight fold, "Wording only …", the 7779 ledger move and viewTabBar retirement, the 7946 xAxisKey half) are untouched by any note.
  • Trailers. git log origin/main..head: two docs(changeset) commits and one base merge; no model identifier.
  • Merge. git merge-tree --write-tree origin/main (9f0c84a4) is clean.
  • CI at the head: 38 success, 3 skipped by design (dependabot, the two coverage rows), 0 failures; Changeset Overwrite Report is report-only and green.

② Semver level

None: the diff is .changeset/ prose only; every frontmatter is byte-identical (no hunk touches lines 1–4 of any file); no changeset is owed (check-changeset-presence green). Clause-②: no — right.

③ Boundary flags

  • Ask for the patch round (one commit). In .changeset/object-view-unmirrored-keys-7779.md, restate the note's figures as they will publish: the renderer reads 43 of the 64 declared members off a named view and leaves 21 unread, since objectui#10758 (PR fix(plugin-view): the host delegation reads a named view's remaining protocol members off the named view (objectui#10758) #10884) moved the host delegation's reads onto the named view — or drop the two numbers and keep "the census in object-view-unmirrored-keys-7779.test.ts pins the current figures". Merge origin/main in the same round so the head carries 35d68c4c. Nothing else in the diff needs to move; a delta record at the new head follows, and needs:contract-review stays on until then.
  • NOT GOVERNED: .changeset/** is not in the governed path list; no approval click is required.
  • Deadline stands (the seat's own): if the release PR objectui#5400 merges first, the pending entries are consumed and this PR is moot.
  • Observed, filed separately: the two source docblocks the dev named — the ObjectChartSchema.series TS docblock's "excess property" sentence and the zod docblock's "listViews is unmirrored" — are stale prose in packages/types/src, a hygiene card for domain:spec @ objectui, not this PR.

Implemented-by: claude/issue-10877-changeset-supersession-notes
Reviewed-by: session_01AsCNgFBs8HCjwhyHQsFbx3

VERDICT: FAIL

…9 dated note

Patch round 2. The note stated the census split as 20 read and 44 unread,
which objectui#10758 (PR #10884) moved on main after this branch's
measurement. The note now says the renderer reads some of the declared
members off a named view and leaves the rest unread, names the two changes
that moved the split away from the entry's own 21 and 43, and points at the
census in object-view-unmirrored-keys-7779.test.ts for the current figures
instead of restating them. No other note, sentence or frontmatter moves.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014fWVhLzhxR8qrFsJ5o8TYW
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Patch round 2 done: head 50deccd71a is ready for the delta record. domain:spec#1 @ objectui · session_014fWVhLzhxR8qrFsJ5o8TYW · 2026-09-28T06:32Z. This answers the FAIL 5864532186 and follows REWORK 5864543090; the dev report is on card #10877.

  • The one fix. Only the dated note in .changeset/object-view-unmirrored-keys-7779.md changed (50deccd71a, +6 / −4). It no longer states a read / unread figure. It says the split is no longer the 21 / 43 the entry counted, names both changes that moved it (objectui#7928, objectui#10758), and cites the census pin in object-view-unmirrored-keys-7779.test.ts. That pin reads 43 read + 21 unread = 64 at this head.
    • The phrases 20 of them, 44 unread and pins both figures are gone (0 hits).
    • No other note moved: git diff 0ea55c3701 50deccd71a over the 8 paths shows only this hunk.
  • Base. origin/main 9f0c84a448 was merged as bade176fff, which carries 35d68c4c (merge-base --is-ancestor exits 0). There was no rebase and no force-push. That merge moved probed sources, so the round-1 probes were re-run at the new head; their output is byte-identical.
  • Invariants, seat-checked. Against the merge-base 9f0c84a448: 8 files, +168 / −0. The frontmatter is byte-identical in all 8. The commit trailers are model-free.
  • Gates at the head, all exit 0:
    • check:pending-changeset-literals, check-changeset-claims, -presence, -no-major;
    • check:new-line-citations (0 new), check:control-bytes;
    • the governed guard (NOT GOVERNED);
    • 25 test files / 1146 tests (the 24 .changeset readers plus the 7779 pin), and 4 / 48 on the other note pins.
  • CI on 50deccd71a is running (28 success, 9 in progress, 0 red when read).
  • PR body. It is refreshed for patch round 2.

The PR stays draft with needs:contract-review until the delta record. The deadline is still the release PR objectui#5400.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 50deccd71a48fc185561d4b327fc1b61e59a3757

Round 2, the delta after the FAIL record 5864532186 at 0ea55c3701. Written by the director seat (duty one). The delta is two commits: bade176f (merge of origin/main 9f0c84a4, which carries 35d68c4c — PR #10884, objectui#10758 — no rebase, amend or force-push) and 50deccd7 ("drop the read / unread figures from the objectui#7779 dated note"), which touches one file, .changeset/object-view-unmirrored-keys-7779.md, +6 / −4 inside the dated note only.

① Derived judgments

  • The one FAIL item is closed — RIGHT. The note no longer states a figure: "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." Each clause is true on origin/main 7ea8118f and at this head: the census pins 43 read / 21 unread of 64 (:1419-1420), the options bag left the read set with objectui#7928, and objectui#10758 (35d68c4c, which this head carries) moved the delegation's reads onto the named view. Nothing in the note can be falsified by the release tree as it stands.
  • The other 13 notes are byte-identical to the round-1 head (git diff --numstat against the new merge-base: the same 8 files, 166 → 168 insertions, 0 deletions; the only hunk that moved is the one above). Every ① judgment of 5864532186 on them holds, including the 7946 last note's mention of objectui#8885 / objectui#10518 (in scope).
  • Frontmatter of all 8 entries is still untouched (no hunk touches lines 1–4 of any file).
  • Trailers. git log 0ea55c3701..head --format=%B: the merge line and the fix commit; no model identifier.
  • Merge. git merge-tree --write-tree origin/main (7ea8118f) is clean; main did not touch object-view-unmirrored-keys-7779.md in 35d68c4c (no hunk), so the note sits beside the same paragraph.
  • CI at the head, read at 2026-09-28T06:33Z: 28 success, 9 in progress, 3 skipped by design (dependabot, the two coverage rows), 0 failures. Auto-merge is armed with this record; the queue takes the head only when the remaining checks complete, and a red check on this head voids this record.

② Semver level

None, unchanged: .changeset/ prose only, no changeset owed, Clause-②: no.

③ Boundary flags

  • NOT GOVERNED (.changeset/**); no approval click. needs:contract-review is stripped with this record; pr_ready + automerge_enable via the relay in the same act.
  • Deadline (the seat's own): if the release PR objectui#5400 merges first, the pending entries are consumed and this PR is moot; the queue decides the order.
  • The two stale source docblocks the round-1 record observed are objectui#10905.

Implemented-by: claude/issue-10877-changeset-supersession-notes
Reviewed-by: session_01AsCNgFBs8HCjwhyHQsFbx3

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review September 28, 2026 06:35
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Sep 28, 2026
Merged via the queue into main with commit 733fd5a Sep 28, 2026
43 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-10877-changeset-supersession-notes branch September 28, 2026 06:51
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Sep 28, 2026
…ts name 41 objectui issues that answer 404 (objectui#10803, batch 5) (objectstack-ai#10892)

Part of objectstack-ai#10803
Clause-②: no

Dispatched implementation of the `domain:ui` seat 2 claim (comment
`5862515185`) on objectui#10803, batch 5, session
`https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN`. Citations
only: no sentence's claim moves, and every edited pending changeset's
frontmatter is byte-identical. The runtime text that moves loses its
dead pointer and nothing else, all in `@object-ui/types`: the six
`ChatbotSchema` tombstone guidance strings open `RETIRED (ADR-0049) —`
(rulings `5861129870` and `5861311219`), the `page` node's `actions`
refusal, an ADR-0049 tombstone too, cites `(ADR-0049)` in place of its
dead card (ruling `5861129870`, as measured in patch round 1), and the
`ChartDataSeriesSchema.variant` description drops its pointer (amendment
`5860244997`, Q1 = A). Two tests that pin changed text follow it, anchor
only (ruling `5861900779`, route a).

**Patch round 1** answers the contract review's one FAIL item on
`afed8aa6b`: Special cases 7 had read the `actions` refusal as not
ADR-0049 from a proxy (the `breadcrumbs` changeset, which only says the
2026-09-09 RULING is not borrowed). Measured from the retirement itself,
it is an ADR-0049 tombstone, so under the seat's option (a) its string
now reads "never was (ADR-0049): no renderer reads it". The
runtime-strings changeset follows, and the sweep changeset notes that
`@object-ui/types`' runtime text is declared separately. One text-only
commit, `8255f14f4`; no merge, no force-push.

## Why `Part of`, not a closing line

The card stays open for the other 23 numbers of the family remainder
(seat amendment `5860244997`, Q2 = A), listed in **Acceptance notes** 1,
and for the bare sister-repo numbers the C0 census below lists.

## Premise, re-measured

- REST `GET /repos/objectstack-ai/objectui/issues/N` for each of the 41:
all 41 answer 404, and a second read of each answers 404 again (41 of
41). `GET .../pulls/N` answers 404 for all 41 too. Lit controls:
objectui#10533 and objectui#7714 answer 200. No number was dropped from
the batch.
- The same 41 in objectstack all answer 200. Three of them are the
sites' real subject, read not guessed, and are re-qualified (Zone 1 item
5):
- objectstack#3720 "列表行级 edit/delete 与批量删除未接入服务端 effective 操作集": the
five `[objectstack-ai#3720]` sites in `ObjectGrid.tsx`, `rowCrudAffordances.ts` and
`ListView.tsx` describe that gate, and their landing `ba4514511` is
titled "gate list row Edit/Delete and bulk delete on the effective
operation set (objectstack#3720)".
- objectstack#5506, the "five more hardcoded English chrome strings"
card: `useDetailTranslation.ts` wrote "the SAME key objectstack-ai#5506 gave
NavigationOverlay's identical handle", and nine sibling in-scope lines
already cite `objectstack#5506` for those strings.
- objectstack#6936, the metadata-admin predicate fail-CLOSED card:
`predicate.ts` wrote "objectstack-ai#6936's `true` verdict" one line below
"objectstack#6936's unresolved-path ruling".
- Every other site names an objectui card or pull request, confirmed by
its landing commit below (for example objectstack#7853 is a
`driver-memory` finding, while objectui#7853 is the cite-by-content
ruling AGENTS.md objectstack-ai#11 names).
- Every edited changeset is pending: it is present in `.changeset/` on
`main`.
- Branch point: `b2683a2c0`. `main` is now `4f8b7f86a`; its census still
reads 215, and the merge of this head with it reads 0. Not a shallow
checkout.

## C0: the bare-number remainder (measurement only)

The instrument of PR objectui#10875, at the branch point:

```
git grep -hoP '(?:^|(?<=[^\w#&/.\-]))#\d+(?![0-9A-Za-z_])' b2683a2 -- '.changeset/*.md' 'packages/*/src/**' ':!**/__tests__/**' ':!**/*.test.*' ':!**/*.spec.*' ':!**/test/**' ':!**/tests/**' | sort -u | wc -l
```

- **998 distinct bare numbers** at `b2683a2c0` (1002 at batch 4's
`e32dae160`): the eight batch 4 re-pointed are gone, and four are new
since: objectstack-ai#10321, objectstack-ai#8365 and objectstack-ai#9242 (at or below 10900, each read once: 200)
and #20051.
- **Above 10900: 23**, batch 4's 22 plus #20051. Each was read once with
REST `GET .../issues/N`: **23 answer 404**, and each answered 404 again
on a second read (23 of 23); `GET .../pulls/N` answers 404 for the 18
that are not colours.
- None of them is an objectui citation, and none sits in a sentence or
hunk this batch edits, so **nothing is folded here**:
  - **5 are CSS colours:** #334155, #336699, #475569, #737373, #953800.
- **18 are objectstack numbers**, 16 of which answer 200 there with the
sites' own subject. #13033 and #13413 answer 404 in objectstack too.
Sites (lines / files, at `b2683a2c0`) are listed in **Acceptance notes**
2 for later batches.

## Census (the enumeration pin for this batch)

The instrument PR objectui#10854 printed and PRs objectui#10869 / objectstack-ai#10875
reused, with this batch's 41 numbers substituted (REF = a commit or
tree):

```
git grep -nE '(objectui#|#|issues/)(7091|7097|7108|7177|7612|7620|7623|7658|7666|7667|7669|7678|7681|7682|7703|7704|7708|7804|7844|7853|7869|7874|7877|7926|7959|7967|7979|7980|8058|8060|3720|5420|5503|5506|5737|6467|6936|6945|7622|7662|7684)([^0-9]|$)' REF -- '.changeset/*.md' 'packages/*/src/**' ':!**/__tests__/**' ':!**/*.test.*' ':!**/*.spec.*' ':!**/test/**' ':!**/tests/**' | grep -v 'objectstack#' | wc -l
```

- REF = `b2683a2c0` (branch point, and `main` now): **215** lines, 74
changeset lines in 55 files and 141 src lines in 47 files.
- REF = `8255f14f4` (this head): **0**. Round 0's head `afed8aa6b` also
read 0.
- This head merged with a fresh `main` (`4f8b7f86a`, `git merge-tree
--write-tree`, clean, tree `08f80168a`): **0**. REF = `4f8b7f86a` alone:
215.
- **The filter hid nothing this time.** The 18 branch-point lines the
`grep -v 'objectstack#'` drops name only objectstack#6936 or
objectstack#5506; with those tokens deleted, none of them matches the
instrument (0). Unfiltered, this head reads **26**, all live
`objectstack#` lines: the 18, the seven re-qualified here, and the same
spelling in the new sweep changeset.
- Lit control, the same printed instrument over live objectui#7714 at
this head: 17 lines. Hex-colour false positives (a number followed by a
hex letter) at the branch point: 0.
- **Out of scope, as it stands** (the instrument with the 41 numbers,
unfiltered, whole tree at this head): 367 test lines in 98 files, 23
scripts lines in 5 files, 0 `.github`, 5 governed lines in 4 files
(`AGENTS.md` and three `skills/objectui` files), and 51 other lines in
18 files: published `CHANGELOG.md` history (21 lines in 8 files),
`content/docs` (11 in 4), `apps/console` (7 in 3), `eslint-rules` (8 in
2) and `eslint.config.js` (4). See **Acceptance notes** 4.

## Citation form

- The 9-character backticked sha of the commit on `main` that landed the
change the sentence rests on, as in PRs objectui#10707 / objectstack-ai#10766 / objectstack-ai#10797
/ objectstack-ai#10854 / objectstack-ai#10869 / objectstack-ai#10875. All 40 distinct shas in the mapping are
ancestors of `main`: `git merge-base --is-ancestor`, exit 0 each.
Control leg in the same checkout: the head of PR objectui#10714
(`d2afdb6bf`) answers exit 1, and a known ancestor, `5f789538d`, answers
exit 0. `git rev-parse --short=9` returns the same 9 characters for
each.
- A changeset's pointer to its OWN card is dropped, not replaced:
`@changesets/changelog-git` prefixes each released entry with the hash
of the commit that added the file, which is that landing. Where dropping
it left a dangling word, the clause was minimally repaired (**Special
cases** 5).
- Where the sentence rests on a RULING, the ruling is cited by its date
(**Special cases** 4).
- Where a dead card sits beside a live pull request that IS its landing,
the dead card is dropped and the live pointer stays (**Special cases**
1).
- Where the claim lived only on the dead card (a finding, a ruling, a
scope, a comment), the sha only locates it: "the card behind SHA", "the
ruling behind SHA" (**Special cases** 3). Review `5861306588`'s lesson:
a sha must carry what the sentence cites it for.
- Where nothing answers, the pointer is dropped and the sentence names
the card by role (objectstack-ai#7612, objectstack-ai#7666, objectstack-ai#7682, objectstack-ai#7844, and the open objectstack-ai#7804
parent).
- Runtime text carries no sha: see **Special cases** 7.

## Mapping (number to resolution)

Lines / files are the branch-point census for that number. "Method" is
how the landing was found. The last column is why that commit carries
what the sentence cites it for.

| dead number | resolution | method | lines / files | why the commit
carries it |
|:--|:--|:--|:--|:--|
| objectstack-ai#7091 (a pull request) | `969ba84f4` | `git log --grep`: its squash
subject ends "(objectstack-ai#7091)" | 1 / 1 | it registers the console `app:launcher`
renderer, which is what made the "not a page" clause false |
| objectstack-ai#7097 | `3cab5703b`; own-card pointer dropped | changeset's adding
commit | 3 / 3 | it adds the `2xl` read arm and the literal
`GRID_COLS_2XL` class map, the value-level fix both sentences name |
| objectstack-ai#7108 | `1267508ea`; own-card pointer dropped | changeset's adding
commit | 3 / 2 | it tombstones a deleted record reference in the
approvals inbox, the platform-flagged class the sentences name |
| objectstack-ai#7177 | own-card pointer dropped (landing `ebc05b4d6`) | changeset's
adding commit | 1 / 1 | the only site is its own changeset's pointer |
| objectstack-ai#7612 | "the 2026-09-20 ruling"; the card by role | `git log --grep`
finds only `2ca238075`, the objectui#10150 record of the ruling; the
switch, PR objectui#10054, closed unmerged | 3 / 2 | nothing landed: the
ruling was "no". See **Special cases** 3 and 4 |
| objectstack-ai#7620 | `c15d7eca6`; "ruling A behind `c15d7eca6`" where the sentence
cites the ruling; own-card pointer dropped | changeset's adding commit,
`git log -S` | 13 / 10 | it moves `data-table`'s date-only fallback onto
`formatDate`'s default face, and its message records the two-faces fact
pattern the sentences cite |
| objectstack-ai#7623 | `5d0876c5c`; own-card pointer dropped | changeset's adding
commit | 3 / 3 | it retires the inert dashboard-root `title` declaration
|
| objectstack-ai#7658 | `90c6d090d`; own-card pointer dropped | changeset's adding
commit | 2 / 2 | it keeps code-span content out of `extractToc`'s HTML
strip |
| objectstack-ai#7666 | nothing answers: the card by role ("already-filed defect") |
`git log -S` finds only `a472b0716`, which records it as an
already-filed defect | 1 / 1 | see **Special cases** 3 |
| objectstack-ai#7667 | `a472b0716`; own-card pointer dropped | changeset's adding
commit | 2 / 2 | it gives `extractToc`'s emphasis rules the flanking
rule that keeps `SCREAMING_SNAKE` underscores |
| objectstack-ai#7669 (a pull request) | `a3eb5d07a` | `git log --grep`: its squash
subject ends "(objectstack-ai#7669)" | 2 / 2 | it retires
`FloatingChatbotConfig.triggerIcon` as the tombstone both sentences name
|
| objectstack-ai#7678 | `5f8190c8c` ("in its amended form"); own-card pointers dropped
| changeset's adding commit; its body opens "Part of objectstack-ai#7678" | 21 / 14 |
it brings every statement of the retire-vs-remove discriminator to the
amended form, the surviving-carrier precondition included. See **Special
cases** 6 |
| objectstack-ai#7681 | `01c27c431`; own-card pointer dropped | changeset's adding
commit | 6 / 4 | it routes a `dataKey`-shaped series through
`normalizeSeries`, removing the fast path, so its `type` override is
honoured |
| objectstack-ai#7682 | nothing answers: "a separate card"; runtime pointer dropped |
`git log -S` finds only `8fe8e5c16`, which defers that decision to it |
3 / 3 | see **Special cases** 3 |
| objectstack-ai#7703 | `a4611b3e2`; runtime text `RETIRED (ADR-0049) —`; own-card
pointer dropped | changeset's adding commit | 15 / 3 | it retires the
six dark `ChatbotSchema` keys as ADR-0049 tombstones |
| objectstack-ai#7704 | `20316bac3`; "the card behind `20316bac3`" for the scope note;
own-card pointer dropped | changeset's adding commit | 3 / 2 | it adds
`chatbot-enhanced` and `chatbot-floating` to `SchemaRegistry` |
| objectstack-ai#7708 | `d3499b315`; PR objectstack-ai#8077 kept where it stands beside the dead
card; "the card behind `d3499b315`" for the ruling; own-card and runtime
pointers dropped | changeset's adding commit, `git log --grep` | 13 / 6
| it fences `chatbot-floating`'s raw props spread through `toDomProps`
at the head of the element |
| objectstack-ai#7804 (the handler-key parent) | per slice, by `git blame`:
`75fca9669` (data-table), `7ca6ddd4b` (detail), `f1cd29032` (list-view),
`5a41ce733` (object-kanban), `8d50bc2bf` (objectql.ts), `604476d97`
(tree-view); own-card pointers dropped; "the handler-key parent card"
where the sentence means the open parent | each slice changeset's adding
commit, and `git blame` per line | 49 / 17 | each commit declares
exactly the handler keys the site's arm or face names |
| objectstack-ai#7844 | nothing answers: "their own card" | `git log -S` finds only
`c4a1d39fe`, which leaves both sub-shapes dark | 1 / 1 | see **Special
cases** 3 |
| objectstack-ai#7853 | "the card behind `fa7d66c45`" | AGENTS.md objectstack-ai#11 names
`fa7d66c45` as its landing | 3 / 3 | the ruling lived on the card;
`fa7d66c45` is its one-site landing |
| objectstack-ai#7869 | "the finding objectui#8344 discharged" / "the finding this
card discharges" (landing `841dd2b7e`) | `841dd2b7e`'s message; the live
objectui#8344's body, "Discharges the finding objectstack-ai#7869" | 2 / 2 | the
measurement lived on the dead finding, and the live card that discharged
it restates it |
| objectstack-ai#7874 | `d9580f464`; PR objectstack-ai#7887 kept beside the dead card; own-card
pointer dropped | changeset's adding commit | 3 / 3 | it retires the
five dead `timeline.relative.*` rows |
| objectstack-ai#7877 | `7dcda9cd4` | `git log -S` on the heading | 1 / 1 | it moves
the hand-rolled-table data into `hand-rolled-tables.json`, the heading's
subject |
| objectstack-ai#7926 | `12b599219`; "the 2026-09-09 ruling"; "the `actions` refusal"
by role beside PR objectstack-ai#8870; runtime text `(ADR-0049)`; own-card pointer
dropped | changeset's adding commit | 15 / 6 | it refuses `actions` by
name on the `page` node, measures `breadcrumbs` at 1 site and leaves it
parsing, and pins that |
| objectstack-ai#7959 | `36fc74629`; "the card behind `36fc74629`" for its scope
restraint | the tests it added are headed "objectui#7959" | 8 / 6 | it
adds `readEnvelopeFailureText`, the userMessage-first rule on
`PackagesPage`, and the load-failure testid |
| objectstack-ai#7967 | own-card pointer dropped (landing `0544ae958`) | changeset's
adding commit | 1 / 1 | the only site is its own changeset's pointer |
| objectstack-ai#7979 | own-card pointer dropped (landing `bfa4fe728`) | changeset's
adding commit | 1 / 1 | the only site is its own changeset's pointer |
| objectstack-ai#7980 | `a810bb2ae`; "the card behind `a810bb2ae`" for its surface and
its comment; own-card pointer dropped | changeset's adding commit | 4 /
3 | it publishes `readEnvelopeFailureText` from the package entry |
| objectstack-ai#8058 | `3f4b45886` | `git log -S storedRelationshipTarget` | 5 / 2 |
it adds `storedRelationshipTarget`, the read door under both spellings,
and rewrites the "costs nothing" claim |
| objectstack-ai#8060 | `7dc31bb8d`; "step 1 of the card behind `7dc31bb8d`" | `git
log --grep`: its subject names "(objectstack-ai#8060)" | 8 / 3 | it carries a stored
type the designer cannot author through verbatim
(`partitionStoredFields`) instead of flattening it to `text` |
| objectstack-ai#3720 (C0) | re-qualified `objectstack#3720` | `ba4514511`'s subject;
objectstack#3720's subject | 5 / 3 | see **Premise** |
| objectstack-ai#5420 (C0) | own-card pointer dropped (landing `b470e9150`) | the
adding commit's subject names "(objectstack-ai#5420)" | 1 / 1 | the only site is its
own changeset's heading |
| objectstack-ai#5503 (C0, a pull request) | `6f017e99c` | its squash subject ends
"(objectstack-ai#5503)" | 1 / 1 | it puts the chart min-height floor on the element
Recharts measures |
| objectstack-ai#5506 (C0) | re-qualified `objectstack#5506` | nine sibling in-scope
lines already cite it for the same strings | 1 / 1 | see **Premise** |
| objectstack-ai#5737 (C0, "PR objectstack-ai#5737") | `d1ab06f0f` | its squash subject ends
"(objectstack-ai#5737)" | 4 / 4 | it declares `record.*` the row-predicate canon and
warns on the two deprecated spellings, which is Phase 1 |
| objectstack-ai#6467 (C0) | own-card pointer dropped (landing `5ad0641e0`) | its
subject names "(objectstack-ai#6467)" before its own "(objectstack-ai#7332)" | 1 / 1 | the only site
is its own changeset's pointer |
| objectstack-ai#6936 (C0) | re-qualified `objectstack#6936` | the line above already
cites it | 1 / 1 | see **Premise** |
| objectstack-ai#6945 (C0, "PR objectstack-ai#6945") | `2c45966ff` | its squash subject ends
"(objectstack-ai#6945)" | 1 / 1 | it declares the 13 renderer-read keys the sentence
says objectui#6150 declared first |
| objectstack-ai#7622 (C0, "PR objectstack-ai#7622") | `1cca678ba` | its squash subject ends
"(objectstack-ai#7622)" | 1 / 1 | it retires the dashboard-root `title` read on all
five surfaces |
| objectstack-ai#7662 (C0, "PR objectstack-ai#7662") | `bc640ec56` | its squash subject ends
"(objectstack-ai#7662)" | 1 / 1 | it is the change to `SchemaRegistry`'s kanban entry
the sentence ascribes to objectui#7645 |
| objectstack-ai#7684 (C0, "PR objectstack-ai#7684") | "the contract review of `8fe8e5c16`'s pull
request" | its squash subject ends "(objectstack-ai#7684)" | 2 / 2 | the review lived
on the dead pull request; the sha only locates it |

## Special cases (the judgement calls)

1. **A dead card beside its own live landing.**
- `defaults-table-scan.ts`: "rows of objectui#7874 at all (retired in
objectstack-ai#7887)" becomes "rows at all (retired in objectstack-ai#7887)". PR objectstack-ai#7887 answers 200
and is `d9580f464`'s pull request.
- `7703-chatbot-dark-keys-retired.md`: "**after** objectui#7708's fence
landed as PR objectstack-ai#8077" becomes "**after** the fence landed as PR objectstack-ai#8077". In
the same file "until objectui#7708 the `chatbot-floating` registration
ended…" becomes "until PR objectstack-ai#8077 the…", and the next sentence's "That
card was ruled **fence**, not declare, and landed as PR objectstack-ai#8077" becomes
"Its card was ruled **fence**, not declare, and landed as that PR", so
it keeps an antecedent.
- `8871-page-node-refuses-breadcrumbs.md` and `layout.zod.ts`: "corrects
objectui#7926's "1 site"", beside "(PR objectstack-ai#8870)", becomes "corrects the
`actions` refusal's "1 site"". The changeset's "objectui#7926's `patch`
does not transfer here" becomes "The `actions` refusal's `patch` does
not transfer here".
2. **The sister-repo numbers.** `[objectstack-ai#3720]` becomes `[objectstack#3720]`
at five sites; "objectstack-ai#5506" and "objectstack-ai#6936's" become `objectstack#5506` and
`objectstack#6936`'s. See **Premise**.
3. **The card named by role.**
- **objectstack-ai#7612**, `clientValidation.ts`: "The switch was then put to the
maintainer on objectui#7612" becomes "…on its own card". Nothing landed:
the ruling said no, and the switch PR closed unmerged. The verbatim
ruling quote 「7612 只需要服务端校验」 stays as the maintainer wrote it; it
carries no `#`.
- **objectstack-ai#7666**, `7667-toc-emphasis-flanking.md`: "(objectui#7666, a heading
`extractToc` lists…)" becomes "(a heading `extractToc` lists…)". The
sentence already calls it "a different, already-filed defect".
- **objectstack-ai#7682**: "objectui#7682 owns that decision" becomes "a separate card
owns that decision" (`7546-chart-series-keys-declared.md`), and
"objectui#7682's decision" becomes "a separate card's decision"
(`data-display.ts`).
- **objectstack-ai#7844**, `8754-…` changeset: "the two further sub-shapes
objectui#7844 records" becomes "the two further sub-shapes recorded on
their own card".
- **objectstack-ai#7804 as the open parent**: "whose disposition is still open on
objectui#7804" becomes "…on the handler-key parent card" (`9447-…`);
"both are ledgered to objectui#7804, which owns it" becomes "…to the
handler-key parent card" (`handler-key-reads-follow-cast-receivers.md`);
`crud.zod.ts`'s "objectui#7804's rows are the handler keys" becomes "the
handler-key parent card's rows…".
- **"The card behind SHA"**, where the sentence rests on something that
lived only on the card:
- objectstack-ai#7620's ruling A: "following the maintainer's ruling A on
objectui#7620" becomes "…ruling A behind `c15d7eca6`" in four
`@object-ui/fields` widgets, and `GridField`'s "the split objectstack-ai#7620 ruled
on" becomes "the split ruling A settled". `RelatedList.tsx`:
"objectui#7443 and objectui#7620 spent two cards" becomes "objectui#7443
and the card behind `c15d7eca6` spent two cards".
- objectstack-ai#7708's ruling: "objectui#7708 ruled FENCE" becomes "The card behind
`d3499b315` ruled FENCE", and "That ruling was FENCE" after it becomes
"The ruling behind it was FENCE" (`complex.ts`).
- objectstack-ai#7853: "objectui#7853 ruled…" becomes "The card behind `fa7d66c45`
ruled…" in both objectstack-ai#8875 changesets and in `defaults-table-scan.ts`'s list.
- objectstack-ai#7959's scope restraint: "objectui#7959 kept/left it off the public
entry as scope restraint — that card's file surface was…" becomes "The
card behind `36fc74629` …" (`7980-…` changeset, `app-shell` `index.ts`).
- objectstack-ai#7980: "see objectui#7980 comment 5583988475" becomes "as the card
behind `a810bb2ae` records" (a comment on a dead card resolves nowhere);
`PackageFormDialog.tsx`'s "is objectui#7980's surface" becomes "is the
surface of the card behind `a810bb2ae`".
- objectstack-ai#7704's scope note (`registry.ts`) and objectstack-ai#8060's "step 1"
(`MetadataFieldsPage.tsx`) take the same form.
- objectstack-ai#7869: the finding card is dead, and the live objectui#8344 discharged
it and restates the measurement, so `base.zod.ts` reads "That is the
finding objectui#8344 discharged: an off-spec `size`…" and objectstack-ai#8344's own
changeset reads "the finding this card discharges measured…".
4. **Rulings by date.**
- objectstack-ai#7612: the `AUTHOR_SHAPE_ONLY_TYPES` heading ends "(the 2026-09-20
ruling)"; `10150-author-shape-header-ruling.md` reads "the switch was
put to the maintainer, and the 2026-09-20 ruling was option A". Its last
sentence, "requires the docblock to name the ruling's card", becomes
"…to name the ruling", because the pin it describes now anchors on the
ruling (**Special cases** 8).
- objectstack-ai#7926: "objectui#7926's maintainer ruling covers `actions`" becomes
"The 2026-09-09 maintainer ruling covers `actions`", and "objectui#7926
does not rule on it" becomes "the 2026-09-09 ruling does not cover it"
(`layout.zod.ts`).
5. **Own-card pointers that needed a word.**
- `7097-grid-2xl-breakpoint.md`: the pointer sat on its own line, so the
period moved up with it.
- `7678-tombstone-discriminator-agreement.md`: "the site objectui#7678
was filed about" becomes "the site this card was filed about", the
file's own wording two lines earlier.
- `7804-object-kanban-handler-keys-judged.md`: "its
`KNOWN_UNDECLARED_READS` row naming objectui#7804, which stays open and
stays the parent" becomes "its `KNOWN_UNDECLARED_READS` row, which names
the parent card".
- The six `7804-*` slice changesets keep "(the … slice)" once the
pointer goes, as batch 4 kept "(slice 2)".
6. **The discriminator form (objectstack-ai#7678).** "in the form objectui#7678
amended it to" becomes "in its amended form (`5f8190c8c`)" at every
site; "as amended by objectui#7678" and "amended by objectui#7678" take
the same wording; a bare "objectstack-ai#7678" in a precedent list becomes
`5f8190c8c`. `mobile.ts`'s "without the precondition objectui#7678
added" becomes "without the precondition the amendment added", whose
antecedent is the preamble's "amended form" two sentences up.
`9684-discriminator-cited-once.md`: "objectui#7678's amendment had to be
applied by hand" becomes "the amendment (`5f8190c8c`) had to be applied
by hand", which is what that commit did.
7. **The runtime strings.** Only the listed text moves in each.

| file | member | before | after |
|:--|:--|:--|:--|
| `types/src/zod/complex.zod.ts` | `ChatbotSchema.loading`,
`.showAvatars`, `.userAvatar`, `.assistantAvatar`, `.markdown`,
`.height` (tombstones) | "RETIRED (objectui#7703, ADR-0049) — …" |
"RETIRED (ADR-0049) — …" |
| `types/src/zod/complex.zod.ts` | `ChatbotSchema.showAvatars`
(tombstone) | "… unfiltered props spread — was fenced by objectui#7708.
Delete the key: …" | "… unfiltered props spread — was fenced. Delete the
key: …" |
| `types/src/zod/layout.zod.ts` | `PageNodeSchema.actions` refusal |
"`actions` is not a key of the `page` node and never was
(objectui#7926): no renderer reads it, …" | "`actions` is not a key of
the `page` node and never was (ADR-0049): no renderer reads it, …" |
| `types/src/zod/data-display.zod.ts` | `ChartDataSeriesSchema.variant`
`.describe()` | "… the renderer-internal `current` spelling is not a
member (objectui#7682)" | "… the renderer-internal `current` spelling is
not a member" |

**The ADR-0049 condition, measured from the retirement itself** (Zone 1
item 4): the six tombstones already cited `ADR-0049` beside the dead
card; the zod comment above them opens "ADR-0049 retirement tombstones";
their landing `a4611b3e2` is titled "retire six dark ChatbotSchema keys
as ADR-0049 tombstones"; and the pending
`7703-chatbot-dark-keys-retired.md` says "ADR-0049 retirement
tombstones". The `actions` refusal is an ADR-0049 tombstone too,
measured the same way: its arm is
`retirementTombstone(PAGE_ACTIONS_REFUSAL)`, its landing `12b599219`
calls it "an ADR-0049 `retirementTombstone` arm", and
`7926-page-node-refuses-actions.md` calls it "an ADR-0049 refusal arm".
Its string has no `RETIRED` opener, so its own parenthetical becomes
`(ADR-0049)`, the spelling its `breadcrumbs` sibling already uses. The
TypeScript twins in `complex.ts` read "ADR-0049 RETIREMENT TOMBSTONE —
`loading` (`a4611b3e2`)", the comment form.
8. **What follows the text, and nothing else in it** (ruling
`5861900779`, route a; ruling `5861129870`).
- `chatbot-dark-keys-retired-7703.test.ts` pins the six guidance strings
as full literals. Their openings follow to `RETIRED (ADR-0049) — `, the
`showAvatars` literal follows "was fenced.", its `prescriptive` anchor
`'was fenced by objectui#7708'` becomes `'was fenced.'`, and
`toContain('RETIRED (objectui#7703')` becomes `toContain('RETIRED
(ADR-0049) —')`. Its test names and `@ts-expect-error` comments still
read "RETIRED (objectui#7703)"; they describe the `?: never` TypeScript
face and are out of class (**Acceptance notes** 6).
- `clientValidation.authorShapeRuling-10150.test.ts` pins that the
`AUTHOR_SHAPE_ONLY_TYPES` header names the ruling and
`extractDraftBody`. Its subject `'objectui#7612'` becomes `'the
2026-09-20 ruling'`; its message and title are unchanged.
- No test, doc or changeset quotes the `actions` refusal or the
`variant` description verbatim: a whole-tree search for the old strings
returns only the source lines.
9. **The anchor sweep (PR objectui#10875 Special cases 10 shape).**
- **Instrument:** every string, template, numeric and regex literal in
all 3822 test and script files under `packages/` and `scripts/`,
enumerated with `git ls-tree` at head and parsed with TypeScript (113091
distinct literals).
- **Test applied to each literal:** does its occurrence count DROP
between `b2683a2c0` and head in any file this PR changes, in raw text or
in a comment-flattened form?
- **Run 1, on `8c267051f`** (the sweep commit, before any test moved):
336 distinct literals drop. Read against the files they sit in, the
specific anchors are the two pins in item 8 (the six literals, the
`prescriptive` anchor and the `toContain` in the first;
`'objectui#7612'` in the second). Also listed and read: the
`'objectui#7804'` values of `check-handler-key-read-sites`'s
`KNOWN_UNDECLARED_READS` ledger and its test, which assert over the
script's own data and never read a changed file, and
`tombstone-discriminator-agreement-9684`'s `/RETIRED \(objectui#/`,
which it applies to `mobile.ts` alone, untouched here.
- **Everything else** is a generic token (whitespace, punctuation,
single letters and digits, `objectui#`, character-class regexes of
whole-tree scanners), none an assertion over text this PR changed.
- **Run 2, on round 0's head `afed8aa6b`:** 327 distinct literals; the
nine literals the two pins moved are gone from the drop set, nothing new
appears, and the only one left naming a batch number is that ledger
value.
- **Run 3, patch round 1, over the delta `afed8aa6b..8255f14`:** 18
(literal, file) drops, every one a generic token (`' is'`, `'dropped'`,
a `/(\w+):/g` scanner); no test pins the changed refusal text.

## Held

**By the serial rule: nothing.** Patch round 1 re-read: 8 open besides
this PR (objectui#10896, objectstack-ai#10891, objectstack-ai#10890, objectstack-ai#10889, objectstack-ai#10888, objectstack-ai#10777, objectstack-ai#10278
and the release PR objectstack-ai#5400; objectstack-ai#10886 and objectstack-ai#10714 have left the open list).
New since round 0, objectui#10896 shares
`plugin-grid/src/ObjectGrid.tsx` and `plugin-list/src/ListView.tsx`;
trial merges of this head with every open head are clean except objectstack-ai#10278
(conflicts identical against `main` alone) and the release PR objectstack-ai#5400,
which regenerates. The round's one source edit, in `layout.zod.ts`, is
held by no open PR.

Round 0, re-read before its push: 11 open besides this PR. They are
objectui#10890, objectstack-ai#10889, objectstack-ai#10888, objectstack-ai#10886, objectstack-ai#10884, objectstack-ai#10852, objectstack-ai#10780, objectstack-ai#10777,
objectstack-ai#10714, objectstack-ai#10278 and the release PR objectstack-ai#5400.
- Five of them hold files this PR edits:
  - objectui#10890: `types/src/ai.ts`;
  - objectui#10888: `.changeset/8344-node-recursion-point-redirect.md`;
- objectui#10886: `types/src/objectql.ts` and
`types/src/zod/objectql.zod.ts`;
- objectui#10714: `types/src/data-display.ts`, `types/src/layout.ts`,
`types/src/zod/data-display.zod.ts` and `types/src/zod/layout.zod.ts`;
  - objectui#10278: `plugin-grid/src/ObjectGrid.tsx`.
- Each one's hunks were read against its merge-base, with 3 lines of
context. **None of the 47 lines this PR changes in those files appears
inside or beside any of their hunks.**
- Trial merges of each open PR head with this head (`git merge-tree
--write-tree`) are clean for objectstack-ai#10890, objectstack-ai#10889, objectstack-ai#10888, objectstack-ai#10886, objectstack-ai#10884,
objectstack-ai#10852, objectstack-ai#10780, objectstack-ai#10777 and objectstack-ai#10714.
- objectstack-ai#10278 (`eab4c8e52`) conflicts in `ObjectGrid.tsx`,
`plugin-grid/README.md` and `content/docs/plugins/plugin-grid.mdx`, and
conflicts identically against `main` alone.
- PR objectstack-ai#5400 (Version Packages) regenerates and is not a hold.

## Changesets

- `.changeset/10803-dead-citation-sweep-fifth-batch.md`, EMPTY
frontmatter: the comment-only edits in 15 released packages and the
private `@object-ui/test-support`. No published behaviour changes
through them. It marks `@object-ui/types` as the package "whose runtime
text is declared separately below" (patch round 1) and points at the
second file for it.
- `.changeset/10803-fifth-batch-runtime-strings.md`,
`'@object-ui/types': patch`: the six tombstones open `RETIRED (ADR-0049)
—` with everything after the dash unchanged except the `showAvatars`
pointer; the `actions` tombstone cites `ADR-0049` in place of its dead
card; and the `variant` description loses its pointer. No key, path,
issue code, accept set, refusal or severity moves.

## Proof of prose-only (C4), against `b2683a2c0`, on this head
`8255f14f4`

- **Source.** Each of the 49 touched `.ts` / `.tsx` files (47 non-test
sources and the two pins) was parsed at `b2683a2c0` and at this head
with TypeScript's `createSourceFile` and re-printed by `createPrinter({
removeComments: true })`.
  - 44 of 49 prints are identical.
- The other 5 are equal once exactly the 19 listed substitutions are
applied to the base print, each matched once: `complex.zod.ts` 7 (six
openings and the fence pointer), `layout.zod.ts` 1 (the pointer becomes
`(ADR-0049)`), `data-display.zod.ts` 1,
`chatbot-dark-keys-retired-7703.test.ts` 9 (the same seven, the
`prescriptive` anchor and the `toContain` anchor),
`clientValidation.authorShapeRuling-10150.test.ts` 1.
  - 0 parse diagnostics.
- Lit controls on the same instrument: dropping "(ADR-0049)" from the
`loading` string moves the print; re-spacing the "ADR-0049 retirement
tombstones" comment does not.
- **Changesets.** The frontmatter block of every one of the 55 edited
changesets is byte-identical at `b2683a2c0` and this head (55 of 55, by
md5). The overwrite gate below agrees.
- **Scope of the diff:** 106 files: 55 edited and 2 new changesets, 47
non-test source files, and 2 tests.

## Gates, on this head `8255f14f4`

Each line is the gate's own verdict and exit code, captured by
redirect-then-`$?`.

- `node scripts/check-changeset-presence.mjs`, exit 0: "48 source
file(s) of 15 released package(s) changed, and this change declares 2
changeset(s): .changeset/10803-dead-citation-sweep-fifth-batch.md,
.changeset/10803-fifth-batch-runtime-strings.md." (48 = the 46 released
sources and the 2 tests under released packages' `src/`; `test-support`
is under a package changesets ignores.)
- `pnpm changeset:check`, exit 0: "All workspace packages are in the
changeset fixed group." / "No changeset declares a `major` bump."
- `node scripts/check-changeset-overwrite.mjs` (report-only), exit 0: "2
changeset(s) added, 55 modified, 0 deleted". `declared at base` equals
`declares now` for 55 of 55.
- `pnpm check:changeset-claims` (report-only), exit 0:
- born-false: "Every one of those 2 address(es) either names the tree it
was read from, or points at a line this change does not move";
- self-contradiction: "Every package declared across those 45 body(ies)
is either not negated in its own prose, or negated only in an ASPECT of
it that may legitimately hold still";
- the standing notice "103 pending changeset(s) describe a file this
change touches".
- Read against the diff: a pending changeset quoting a replaced pointer
would itself carry the dead number and so sit in the census, which reads
0. No pending changeset quotes a changed runtime string.
- `pnpm check:control-bytes`, exit 0: "check-control-bytes: OK (scanned
9145 tracked text file(s); skipped 85 binary)."
- `pnpm check:new-line-citations`, exit 0: "VERDICT
new-cross-file-line-citations: 0 new citation(s), enforcement
report-only -> exit 0".
- Also run: `pnpm check:pending-changeset-literals`, exit 0: "No test
source names a pending changeset."; the governed-surface predicate over
the 106 paths, exit 0: "NOT GOVERNED — 106 path(s) checked against 5
governed surface(s); none matched." (lit control `AGENTS.md`: exit 3).

**Tests**, through the shared verify lock.
- **Red, reproduced first.** The branch-point copies of the two pins
were written over the committed sweep tree and run: `Test Files 2 failed
(2)`, `Tests 13 failed | 29 passed (42)`, for example "expected 'RETIRED
(ADR-0049) — never read: chat…' to contain 'RETIRED (objectui#7703'".
Both files were then restored with `git checkout HEAD --`, each checked
by blob hash against `HEAD`, and `git diff HEAD` came back empty.
- **Patch round 1, on this head `8255f14f4`:**
`page-actions-refusal-7926` (it pins the message's remedy words
`actions`, `children` and `page:header` and that it is not zod's generic
text, never the pointer; verified by reading it),
`page-breadcrumbs-refusal-8871`, `guide-layout-page-buttons-7926`,
`zod-mirror-parity`, `chatbot-dark-keys-retired-7703`,
`clientValidation.authorShapeRuling-10150` and
`tombstone-discriminator-agreement-9684` give `Test Files 7 passed (7)`,
`Tests 134 passed (134)`, under `VERDICT command-exit 0`. A whole-tree
search for "never was: no renderer" finds no test or doc quoting it
(only the source line and the runtime-strings changeset, both updated);
an anchor sweep over the round's delta finds only generic tokens.
- **Green, round 0, on `afed8aa6b`:** `chatbot-dark-keys-retired-7703`,
`clientValidation.authorShapeRuling-10150`,
`tombstone-discriminator-agreement-9684`, `page-actions-refusal-7926`,
`page-breadcrumbs-refusal-8871`, `chart-series-keys-7546`,
`zod-mirror-parity`, `chatbot-display-mode-retired` and
`schema-registry-chatbot-keys-7704` give `Test Files 9 passed (9)`,
`Tests 173 passed (173)`, under `VERDICT command-exit 0`.

**Declared narrowing (per the dispatch: the named checks, not wider
sweeps).** NOT MEASURED locally: the full suites and type-check of the
15 touched packages, and eslint. Reason: the comment-stripped syntax
tree of 44 of the 49 touched files is identical to `main`, and the other
5 differ only by the listed literal edits. Every test that anchors on a
changed string or comment was found by the anchor sweep (**Special
cases** 9) and run above. CI runs the full farm.

## Acceptance notes

1. **The remainder rides this card, unchanged (seat amendment
`5860244997`, Q2 = A).** Of the 53 numbers PR objectui#10875's
Acceptance notes 1 lists, this PR carries the first 30 in ascending
order, plus the 11 C0 404s of its Acceptance notes 2. The other **23**
are: objectstack-ai#8072 objectstack-ai#8127 objectstack-ai#8137 objectstack-ai#8204 objectstack-ai#8229 objectstack-ai#8248 objectstack-ai#8307 objectstack-ai#8408 objectstack-ai#9231 objectstack-ai#9241 objectstack-ai#9244
objectstack-ai#9365 objectstack-ai#9373 objectstack-ai#9375 objectstack-ai#9542 objectstack-ai#9553 objectstack-ai#9585 objectstack-ai#10117 objectstack-ai#10119 objectstack-ai#10120 objectstack-ai#10129 objectstack-ai#10132
#14026. None of them occurs in any hunk of this diff.
2. **The C0 bare numbers above 10900, for later batches** (sites at
`b2683a2c0`, lines / files). Each answers 404 as an objectui issue, and
none is an objectui citation, so the fix is a re-qualification to
objectstack, not a landing sha:
- written with a word that names the repository but not in `repo#N` form
("objectstack PR #N", "upstream #N", "framework #N", "spec #N"): objectstack-ai#11289
(2 / 2), objectstack-ai#11662 (1 / 1), objectstack-ai#12616 (1 / 1), objectstack-ai#12718 (1 / 1), #13033 (1 / 1),
#13413 (1 / 1), #13733 (1 / 1), #13906 (6 / 3), #14274 (1 / 1), #15469
(2 / 2), #20160 (2 / 2);
- written bare: #13337 (1 / 1), #13632 (3 / 3), #13855 (1 / 1), #14945
(1 / 1), #15948 (1 / 1), #17493 (1 / 1), #20051 (1 / 1);
   - #13033 and #13413 answer 404 in objectstack as well;
- not citations: #334155, #336699, #475569, #737373, #953800 (CSS
colours).
3. **A live-but-wrong bare number beside a re-qualified one.**
`rowCrudAffordances.ts` cites "(`/me/permissions` `apiOperations`,
objectstack-ai#3391)" at the two sites that now read `[objectstack#3720]`.
objectui#3391 answers 200 with an unrelated subject (a record-header api
action placeholder), while objectstack#3391 is the apiMethods whitelist
contract card that objectstack#3720's own title names. It is not a 404,
so it is outside the family pin and was not touched. Carrier: none.
4. **Published or shipped text outside the two in-scope classes still
names some of these numbers** (counts in **Census**). It is untouched by
scope, as another class the triage split did not scope here: published
`CHANGELOG.md` history (never re-addressed), `content/docs` (for example
the chatbot and layout guides), `apps/console` (the approvals inbox and
the agent-connect section), `eslint-rules` and `eslint.config.js`, three
`skills/objectui` files and `AGENTS.md` (governed). Carrier: none.
5. **Filenames are not citations.** Pending changeset and test FILENAMES
carry several of these numbers. They stay, as in PRs objectui#10707,
objectstack-ai#10797, objectstack-ai#10854, objectstack-ai#10869 and objectstack-ai#10875.
6. **Test comments left as they are.**
`chatbot-dark-keys-retired-7703.test.ts`'s test names and
`@ts-expect-error` comments still read "RETIRED (objectui#7703)", and
`clientValidation.authorShapeRuling-10150.test.ts`'s header, title and
message still name objectui#7612. Only anchors moved (ruling
`5861900779`).

---
_Generated by [Claude
Code](https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Sep 28, 2026
…ts name 23 objectui issues that answer 404, and re-qualify 19 bare objectstack numbers (objectui#10803, batch 6) (objectstack-ai#10914)

Part of objectstack-ai#10803
Clause-②: no

Dispatched implementation of the `domain:ui` seat objectstack-ai#1 claim (comment
`5864334310`) on objectui#10803, batch 6, session
`https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk`. Citations
only: no sentence's claim moves, and every edited pending changeset's
frontmatter is byte-identical. The one runtime string that moves is
`InputSchema.wrapperClass`'s zod `.describe()` text in
`@object-ui/types`, which loses its dead pointer and nothing else
(amendment `5860244997`, Q1 = A; `patch` changeset). No test pins any
changed text: the literal-anchor sweep below finds no specific anchor,
so no test file is edited.

This batch carries the release note `5863776648`'s three lists:
- the last **23 family numbers**;
- the **18 bare objectstack numbers above 10900** from PR
objectui#10892's C0 census, plus **#13086**, a 404 the C0 instrument
cannot see because it shares a token with #13337 (**Premise**);
- the live-but-wrong bare `objectstack-ai#3391` at the two `rowCrudAffordances.ts`
sites beside `objectstack#3720`.

## Why `Part of`, not a closing line

The order says `Part of`. With this PR the family list (all 115 numbers
of amendment `5860244997` Q2) and the C0 above-10900 list both read 0.
Whether the card now closes, or carries the dead `objectstack#N` class
measured in **Acceptance notes** 1, is the seat's call.

## Premise, re-measured on `origin/main` `9f0c84a44` (the branch point)

- **The 23 family numbers.** REST `GET
/repos/objectstack-ai/objectui/issues/N`: 23 of 23 answer 404, and a
second read of each answers 404 again. `GET .../pulls/N` answers 404 for
all 23. Lit controls: objectui#10533 and objectui#7714 answer 200.
- **No new family member.** The distinct `objectui#N` citations in the
two in-scope classes at the branch point, less those at batch 1's head
`6c3ad7c80`, are 24 numbers. Each was read once: 24 of 24 answer 200. So
the family list is still batch 5's 23.
- **#14026 was a sister-repo card written as objectui's.**
objectui#14026 answers 404 as an issue and as a pull. objectstack#14026
answers 301 to objectui#10102, the card it was transferred to. That
card's measurement-round claim (branch
`claude/issue-14026-import-mapping-selector-probe`) is the session of
`ecf14190e`, the commit that added `14026-list-import-mappings-pin.md`,
and six sibling in-scope lines already write `objectstack#14026` for the
same card.
- **C0, the bare-number census** (the instrument of PRs objectui#10875
and objectstack-ai#10892, at the branch point):

```
git grep -hoP '(?:^|(?<=[^\w#&/.\-]))#\d+(?![0-9A-Za-z_])' 9f0c84a -- '.changeset/*.md' 'packages/*/src/**' ':!**/__tests__/**' ':!**/*.test.*' ':!**/*.spec.*' ':!**/test/**' ':!**/tests/**' | sort -u | wc -l
```

- 984 distinct at `9f0c84a44`, against 998 at batch 5's `b2683a2c0`. The
14 that batch 5 re-pointed are gone, and none is new.
- Above 10900 there are 23: the same 5 CSS colours and the same 18
numbers. Each of the 18 answers 404 as an objectui issue and as an
objectui pull on two reads.
- In objectstack, 16 of the 18 answer 200 with the sentence's own
subject (the **C0 mapping** below). #13033 and #13413 answer 404 there
too, as issues and as pulls. Their squash commits exist in objectstack's
history (a full, not shallow, clone): `c459da6bc` "narrow the per-option
`default` key out of the form-view options vocabulary … (#13033)" and
`89448a52b` "remove the inert AUTH_SSO_PROVIDER_SCHEMA export (#13413)".
Both are ancestors of objectstack `main` (`git merge-base
--is-ancestor`, exit 0).
- **The C0 instrument's blind spot.** Its lookbehind refuses a `#`
preceded by `/`, `-`, `.` or `&`. That form (`#A/#B`, `-#N`) carries 109
distinct numbers at the branch point. The 17 that no earlier batch read
were each read once. 16 answer 200. **#13086 answers 404**, as an issue
and as a pull, in objectui and in objectstack. It sits in
`6985-wizard-card-r-alignment.md` as "the #13337/#13086 fence", in the
same token as #13337, so it rides here. objectstack's
`check-yaml-examples.ts` header, at its landing `2ebfe7e9f` (PR
objectstack#13267, which answers 200), reads "Check YAML Examples
(anti-drift for the AUTHORING format, #13086)" and "Ruled 2026-08-29
(#13086)".
- **objectstack-ai#3391.** objectui#3391 answers 200 with an unrelated subject (a
record-header api action placeholder). objectstack#3391 answers 200 as
the apiMethods whitelist contract card ("跟踪:UI 操作按钮与 apiMethods
白名单一致性契约落地"), and objectstack#3720's own title calls itself "objectstack-ai#3391
遗漏的第四个面".
- Every edited changeset is pending: it is present in `.changeset/` on
`main`. The checkout is not shallow.

## Census (the enumeration pin for this batch)

The instrument PR objectui#10854 printed and PRs objectui#10869 / objectstack-ai#10875
/ objectstack-ai#10892 reused, with this batch's 23 numbers substituted (REF = a
commit or tree):

```
git grep -nE '(objectui#|#|issues/)(8072|8127|8137|8204|8229|8248|8307|8408|9231|9241|9244|9365|9373|9375|9542|9553|9585|10117|10119|10120|10129|10132|14026)([^0-9]|$)' REF -- '.changeset/*.md' 'packages/*/src/**' ':!**/__tests__/**' ':!**/*.test.*' ':!**/*.spec.*' ':!**/test/**' ':!**/tests/**' | grep -v 'objectstack#' | wc -l
```

- REF = `9f0c84a44` (branch point): **104** lines.
- One more line is hidden by the `grep -v 'objectstack#'` filter:
`9943-viewtype-totals-page-row-retired.md` names objectui#8127 beside an
`objectstack#` citation.
- So the true population is **105** lines: 28 changeset lines in 26
files, and 77 src lines in 42 files.
- Unfiltered, REF reads 111. The other 6 lines are live
`objectstack#14026` lines.
- REF = `2b3d2061a` (this head): **0**. Unfiltered it reads 7, all live:
the six `objectstack#14026` lines and the re-qualified one.
- This head merged with a fresh `main` (`8522396c0`, `git merge-tree
--write-tree`, clean, tree `f19d17884`): **0**. REF = `8522396c0` alone:
104.
- **C0**, the 19 numbers, bare and not `objectstack#`-qualified: 28
lines in 23 files at the branch point; 0 at this head. At this head C0
reads 966 distinct numbers, and above 10900 only the five CSS colours
are left.
- Lit control, the printed instrument over live objectui#7714 at this
head: 17 lines. Hex-colour false positives (a number followed by a hex
letter) at the branch point: 0.
- **Out of scope, as it stands** (the 23 numbers, filtered, whole tree
at this head):
  - 94 test lines in 36 files;
  - 5 `.github` lines in 1 file (`ci.yml`, objectui#9241);
  - 2 `apps/console` lines in 1 file (`FormPage.tsx`, objectui#8408);
  - 1 line of the root `vitest.config.mts`;
  - 0 scripts, 0 governed, 0 `CHANGELOG.md`.
- For the 19 C0 numbers: 13 test lines in 10 files, and 1 line of
`packages/plugin-tree/README.md`.

## Citation form

- **Landing shas.** The 9-character backticked sha of the commit on
`main` that landed the change the sentence rests on, as in the earlier
batches. All 15 distinct objectui shas below are ancestors of `main`:
`git merge-base --is-ancestor`, exit 0 each. Control legs in the same
checkout: the head of PR objectui#10902 (`496c63c06`) answers exit 1,
and the known ancestor `5f789538d` answers exit 0. `git rev-parse
--short=9` returns the same 9 characters for each.
- **Own-card pointers** in a changeset are dropped, not replaced. The
configured changelog generator (`@changesets/cli/changelog`, per
`.changeset/config.json`) prefixes each released entry with the hash of
the commit that added the file, which is that landing.
- **The claim lived only on the card.** Where the sentence rests on
something that lived only on the dead card, the sha only locates it:
"the card behind SHA".
- **Nothing answers.** The pointer is dropped and the sentence names the
card by role (objectstack-ai#9553 only).
- **Sister-repo numbers.**
- A bare sister-repo number becomes `objectstack#N` after reading it
there.
- "objectstack PR #N" becomes "PR objectstack#N", since the qualifier
now carries the repository. "framework #N", "upstream #N" and "spec #N"
keep their word, as batch 4 kept "framework PR objectstack#6942".
- Where the objectstack pull request itself answers 404, the sentence
cites its commit in that repository as objectstack `SHA`, the spelling
the tree already uses for an objectstack commit ("Measured on
objectstack `9bd4344e4`").
- **Runtime text** carries no sha: see **Special cases** 6.

## Mapping, the 23 family numbers

Lines / files are the branch-point census for that number. "Method" is
how the landing was found; for every source site, `git log -S
'objectui#N' -- FILE` names the commit that wrote the citation, and it
is the landing below unless the row says otherwise.

| dead number | resolution | method | lines / files | why the commit
carries it |
|:--|:--|:--|:--|:--|
| objectstack-ai#8072 | `c974edf14`; own-card pointer dropped; runtime pointer dropped
| changeset's adding commit, subject "(objectui#8072)" | 5 / 3 | it
mirrors `wrapperClass` on `InputSchema`, which is what both comments and
the `7722` changeset say happened |
| objectstack-ai#8127 | `ca3942729`; "the card behind `ca3942729`" twice (**Special
cases** 2) | `git log -S` names `ca3942729` for the first citation in
all 10 source files; `05a49f2ee` (objectui#9880) and `8a7e09fa1` (the
`9943` changeset's landing) wrote three later sentences that cite the
same fix | 17 / 11 | it derives `ViewType` from `@objectstack/spec`
instead of re-declaring it, and its message records the
`page`-degrades-like-a-typo measurement the sentences cite |
| objectstack-ai#8137 | own-card pointer dropped (landing `0fa7a9c83`) | changeset's
adding commit | 1 / 1 | the only site is its own changeset's pointer |
| objectstack-ai#8204 | own-card pointer dropped (landing `580b0fdf4`) | changeset's
adding commit | 1 / 1 | the pointer opened a paragraph as its own
sentence |
| objectstack-ai#8229 | "a separate finding" (changeset); "the finding `8b7ea3945`
reconciled" (`flex.tsx`) | `8b7ea3945`'s message: "Reconciles the third
face objectui#8229 found" | 2 / 2 | the finding lived on the dead card;
`8b7ea3945` is the commit that reconciled it, and it is the `7735`
changeset's own landing |
| objectstack-ai#8248 | own-card label dropped from the second list item (landing
`d02942b0e`) | changeset's adding commit; its message covers
objectui#8458 and objectui#8248 | 1 / 1 | the changeset lists the two
cards its one landing closed |
| objectstack-ai#8307 | `5591f03bd`; own-card pointer dropped | changeset's adding
commit | 11 / 4 | it makes a lane header over a windowed fetch say
`77+`, and it wrote every comment that cites the card |
| objectstack-ai#8408 | own-card pointer dropped; "seam 2 of the card behind
`8241a4400`" | changeset's adding commit; `8241a4400`'s message names no
seams | 2 / 2 | the seam list lived on the dead card |
| objectstack-ai#9231 | `383502b23`; own-card pointer dropped | changeset's adding
commit | 3 / 2 | it gives the create dialog's confirm control its own
accessible name, the rule both `i18n.ts` comments state |
| objectstack-ai#9241 | own-card pointer dropped (landing `250429c8f`) | changeset's
adding commit | 1 / 1 | the only site is its own changeset's heading |
| objectstack-ai#9244 | `bd0995738` | `git log --grep`: its message names the card; it
wrote all three comments | 3 / 2 | it emits one col-span class per
breakpoint tier, not one for the widest |
| objectstack-ai#9365 | own-card pointer dropped (landing `0970a0e00`) | changeset's
adding commit | 1 / 1 | the only site is its own changeset's pointer |
| objectstack-ai#9373 | `c1006ed8e`; own-card pointer dropped | changeset's adding
commit | 2 / 2 | it resolves the inline locale map before the
interpolation options, the `ListView` comment's subject |
| objectstack-ai#9375 | own-card pointer dropped (landing `e427e9c00`) | changeset's
adding commit | 1 / 1 | the only site is its own changeset's pointer |
| objectstack-ai#9542 | `43c0d1710`; own-card pointer dropped; "filed as a separate
card" (**Special cases** 3) | changeset's adding commit; `git log -S`
names it for the `action-button` / `action-icon` comments too | 9 / 6 |
it accepts and resolves an inline `I18nLabel` on `resultDialog` and
makes `ResultDialogSpec` derive its label members |
| objectstack-ai#9553 | nothing answers: "a separate card carried that census" | `git
log --grep` finds only `40f34b4ba`, which points at the card; no commit
lands it | 1 / 1 | see **Special cases** 4 |
| objectstack-ai#9585 | "`ee70287e4`'s pin measures it NOT GATED"; in its own
changeset, "a pin in this change measures it" | no commit names it;
`ee70287e4` adds the test "NOT GATED: the renderer paints the very node
the mirror refuses, without parsing it" | 2 / 2 | see **Special cases**
5 |
| objectstack-ai#10117 | `4c6f549ef`; own-card pointer dropped | changeset's adding
commit | 3 / 2 | it resolves a lookup title candidate in `page:header`
and adds the record-key safety net both comments describe |
| objectstack-ai#10119 | `73a3c89af`; own-card pointer dropped | changeset's adding
commit | 4 / 2 | it makes a nav ancestor's gates reach its subtree and
stops a group outliving its children |
| objectstack-ai#10120 | `80c54122e`; own-card pointer dropped | changeset's adding
commit; for each file `git log -S` names it, or a later commit that
cites its gate: `e0f820246` (objectui#10563) or `b809375ac`
(objectui#10163) | 16 / 13 | it makes a form neither submit nor offer a
field the caller may read but not edit, the FLS half every site names |
| objectstack-ai#10129 | `6cc910b6d`; own-card pointer dropped | changeset's adding
commit | 10 / 5 | it routes a field-backed action param to its record
picker and refuses an unreadable one |
| objectstack-ai#10132 | `061f5e829`; own-card pointer dropped | changeset's adding
commit | 8 / 4 | it makes the two declared-translatable dashboard
surfaces resolve, including the axis `title` forward |
| #14026 | re-qualified `objectstack#14026` | see **Premise** | 1 / 1 |
it is the card the pin's measurement answered |

## Mapping, the 19 bare sister-repo numbers

| number | resolution | what objectstack says | lines / files |
|:--|:--|:--|:--|
| objectstack-ai#11289 | `objectstack#11289` ("upstream") | "record:details sections
cannot survive an empty record: `hideEmpty` / `collapsible` /
`showBorder` are honoured by the renderer but undeclared" | 2 / 2 |
| objectstack-ai#11662 | PR `objectstack#11662` | "feat(spec): declare hideEmpty /
collapsible / showBorder on record:details sections" | 1 / 1 |
| objectstack-ai#12616 | PR `objectstack#12616` | "feat(spec): declare record:details
section headerColor as a closed six-token enum" | 1 / 1 |
| objectstack-ai#12718 | PR `objectstack#12718` | "feat(spec): retire preview mode —
the RuntimeMode 'preview' value and the whole PreviewModeConfig block" |
1 / 1 |
| #13033 | objectstack `c459da6bc` | the pull request answers 404; its
squash commit narrows the per-option `default` key out of the form-view
options vocabulary, the ruling `form-spec.ts` says was executed upstream
| 1 / 1 |
| #13337 | `objectstack#13337` | "docs(objectui): layout-dsl teaches
only shapes the live schemas accept" | 1 / 1 |
| #13086 | `objectstack#13267` | the card answers 404; PR
objectstack#13267 landed its ruled YAML-examples gate (see **Premise**)
| the same line |
| #13413 | objectstack `89448a52b` | the pull request answers 404; its
squash commit removes an inert schema export and leaves a note recording
the absence as a choice, the shape the `base.zod.ts` note cites as
precedent | 1 / 1 |
| #13632 | `objectstack#13632` | "[spec] `FieldSchema` accepts a
`lookup`/`master_detail` with no `reference` target …", the card
17.3.0's refinement answered | 3 / 3 |
| #13733 | PR `objectstack#13733` | "feat(spec): wizard view v1 —
declaration-and-refusal tightening of FormViewSchema type:'wizard' (Card
S)" | 1 / 1 |
| #13855 | `objectstack#13855` | the field-grouping decision card whose
option B is a section `group` reference, landed by `39404f3d9` (#13897)
"a layout section can reference a declared field group" | 1 / 1 |
| #13906 | `objectstack#13906` ("framework") | "two more
`computeExecCtx` seams read "failed" and "not wired" as one value …" | 6
/ 3 |
| #14274 | PR `objectstack#14274` | "fix(sdui-parser): refuse an
authored `type` attribute on the html tier …" | 1 / 1 |
| #14945 | `objectstack#14945` | "A flow cannot REFUSE with per-record
text …", honoured by `cca699149` "the flow `end` node honours `outcome:
'refused'`" | 1 / 1 |
| #15469 | `objectstack#15469` ("spec") | "`GanttConfigSchema` is
`strictObject(...).passthrough()` …", landed as `9c270bba0` "close the
gantt/tree config .passthrough() windows … (#15469)" | 2 / 2 |
| #15948 | `objectstack#15948` | "fix(plugin-auth)!: session payload
`positions[]` is the security axis, not the better-auth role scalar" | 1
/ 1 |
| #17493 | `objectstack#17493` | "three residues of #17322's node-door
refusal …", landed as `2c1011b01` "refuse a blank string in a flow
node's predicate slot" | 1 / 1 |
| #20051 | `objectstack#20051` | "judge a flattened view overlay's
top-level `options.KIND` …", whose door half is `6a4aec71d` | 1 / 1 |
| #20160 | PR `objectstack#20160` | "fix(spec): a joined report refuses
a top-level dataset / rows / columns / values, pointing each onto
blocks[]" | 2 / 2 |

The live-but-wrong number: "(`/me/permissions` `apiOperations`, objectstack-ai#3391)"
becomes "… `apiOperations`, objectstack#3391)" at the two
`rowCrudAffordances.ts` sites.

## Special cases (the judgement calls)

1. **#14026 is re-qualified, not dropped as an own-card pointer.** The
card behind `14026-list-import-mappings-pin.md` was never an objectui
card: it was objectstack#14026, now objectui#10102. Dropping the pointer
would lose which hypothesis the pin refuted. Re-qualifying it matches
the six sibling lines.
2. **objectstack-ai#8127, the card by role twice.**
- `CreateViewDialog.tsx`: "one of the sites the card records as
"drifted, …"" becomes "one of the sites the card behind `ca3942729`
records as …". That record lived on the card.
- `plugin-list` `ViewSwitcher.tsx`: "objectui#8127 was filed against the
two in `@object-ui/types`, and the maps below were described there as
total …" becomes "the card behind `ca3942729` was filed against …".
- `normalize-list-view.ts`: "The bug objectui#8127 records" becomes "The
bug `ca3942729` records". That commit's message carries the measurement:
`page` resolved "to exactly what it resolved a typo to".
3. **objectstack-ai#9542 in `8648-ui-action-four-undeclared-keys.md`.**
- The superseded paragraph keeps its pre-landing voice: "so it is filed
as a separate card and ⛔ not guessed at here".
- The superseding paragraph reads "`43c0d1710` landed the derivation".
- "(Noted here by the objectui#9542 seat, …)" becomes "(Noted here by
the seat that landed `43c0d1710`, …)".
4. **objectstack-ai#9553, nothing answers.** `base.zod.ts` said "No count of authored
`events` keys is stated here — objectui#9553 carries that census." No
commit landed that card. `40f34b4ba` only points at it, and the
`AGENTS.md` fix `7550728a6` names a different card. So the sentence now
reads "— a separate card carried that census". The census is not
restated, per AGENTS.md objectstack-ai#9.
5. **objectstack-ai#9585, the measurement's instrument.** The card measured the render
path NOT GATED, and no commit names it. But the commit that wrote both
citing sentences, `ee70287e4`, adds a pin that re-measures exactly that:
"NOT GATED: the renderer paints the very node the mirror refuses,
without parsing it".
- `disclosure.ts` now reads "(`ee70287e4`'s pin measures it NOT GATED)".
- Its own changeset, `8236-collapsible-open-intercept-retire.md`, whose
landing is `ee70287e4`, reads "(a pin in this change measures it NOT
GATED)".
6. **The runtime string.** Only the listed text moves.

| file | member | before | after |
|:--|:--|:--|:--|
| `types/src/zod/form.zod.ts` | `InputSchema.wrapperClass` `.describe()`
| "Classes on the wrapper div around the input and its label
(objectui#8072)" | "Classes on the wrapper div around the input and its
label" |

No test, doc or changeset quotes it: a whole-tree search for the old
string returns only the source line.
7. **objectstack-ai#8229 in `flex.tsx`.** "(objectui#8229, folded into objectui#7735's
ruling)" becomes "(the finding `8b7ea3945` reconciled, folded into
objectui#7735's ruling)". objectui#7735 answers 200 and stays.
8. **#13413's sentence.** "Precedent of the same shape:
objectstack#12009 / PR #13413." becomes "… objectstack#12009 /
objectstack `89448a52b`." objectstack#12009 answers 404 too, but it is a
qualified sister-repo number outside this batch's lists, so it is left
and listed (**Acceptance notes** 1).
9. **#20160 across a line break.** In
`10746-joined-report-clears-binding.md`, "(objectstack PR" ends one line
and "#20160: …" opens the next. They become "(PR" and
"objectstack#20160: …".

## The literal-anchor sweep (both test-pin classes, ruling `5861900779`)

- **Instrument.** Every string, template, numeric and regex literal in
all 4068 tracked test and script files (119016 distinct literals),
parsed with TypeScript.
- **Candidate filter.** A literal is a candidate only if it matches the
diff's removed lines with two lines of context, raw or
comment-flattened. That leaves 2839.
- **Test applied to each candidate.** Does its occurrence count DROP
between `9f0c84a44` and `2b3d2061a` in any of the 92 files this PR
changes, in raw text or in a comment-flattened form? 229 distinct
literals drop.
- **Every one is a generic token.** Digits and short numbers,
punctuation, single letters, `objectui#`, `objectui#1`, and whole-tree
scanners such as `/#\d+/` and `/objectui#\d+/`. The three `objectui#\d+`
matchers (`ActionRunner.disabledGate`, `registry-inputs-spec-parity`,
`catalog-gallery-render`) assert over their own test data and read no
changed file.
- **No specific anchor.** None is a batch number, a changed phrase, or
the changed `.describe()` string. So no test pins changed runtime text
(class one), and no source-reading test pins a changed comment or
docblock citation (class two).
- Test titles and comments that name these numbers are out of the card's
classes and stay (**Census**, out of scope).

## Held

**By the serial rule: nothing.** Re-mapped before the push, on 9 open
PRs: objectui#10910, objectstack-ai#10908, objectstack-ai#10907, objectstack-ai#10906, objectstack-ai#10901, objectstack-ai#10891, objectstack-ai#10777,
objectstack-ai#10278 and the release PR objectstack-ai#5400 (objectstack-ai#10902 and objectstack-ai#10904 had merged since the
claim).

Two of them share files with this PR. Their hunks were read against
their merge-bases; each file is identical at its merge-base and at
`9f0c84a44`, so the lines map directly.
- **objectui#10907, `types/src/zod/form.zod.ts`.** It inserts a refusal
constant before `InputSchema`, two tombstone members further down
`InputSchema`, and a comment in the `InputShorthandSchema` arm. This
PR's three edited lines (the `wrapperClass` comment and description, and
the arm's "shrank that row" comment) sit outside every one of its hunks
and their 3-line context.
- **objectui#10906, `metadata-admin/i18n.ts` and
`previews/ViewPreview.tsx`.** Its `i18n.ts` insertions are far from the
two `createDraft` comments, and its `ViewPreview.tsx` hunks are far from
the `options` fold docblock.

Trial merges with this head (`git merge-tree --write-tree`):
- clean for objectstack-ai#10910, objectstack-ai#10908, objectstack-ai#10907, objectstack-ai#10906, objectstack-ai#10901, objectstack-ai#10891 and objectstack-ai#10777;
- objectstack-ai#10278 (`eab4c8e52`) conflicts in `ObjectGrid.tsx`,
`plugin-grid/README.md` and `content/docs/plugins/plugin-grid.mdx`, and
conflicts identically against `9f0c84a44` alone;
- objectstack-ai#5400 (Version Packages) regenerates and is not a hold.

objectui#10891 shares no file with this PR.

## Changesets

- `.changeset/10803-dead-citation-sweep-sixth-batch.md`, EMPTY
frontmatter. It covers the comment-only edits in 15 released packages;
no published behaviour changes through them. It points at the second
file for `@object-ui/types`' runtime text.
- `.changeset/10803-sixth-batch-runtime-strings.md`,
`'@object-ui/types': patch`: the `wrapperClass` description loses its
pointer. No key, path, issue code, accept set, refusal or severity
moves.

## Proof of prose-only (C4), against `9f0c84a44`, on this head
`2b3d2061a`

- **Source.** Each of the 53 touched `.ts` / `.tsx` files was parsed at
`9f0c84a44` and at this head with TypeScript 6.0.3's `createSourceFile`,
and re-printed by `createPrinter({ removeComments: true })`.
  - 52 of 53 prints are identical.
- `form.zod.ts` is equal once the one listed substitution (**Special
cases** 6) is applied to the base print, matched once.
  - 0 parse diagnostics.
- Lit controls on the same instrument: editing a string literal moves
the print; re-spacing a comment does not.
- **Changesets.** The frontmatter block of every one of the 37 edited
changesets is byte-identical at `9f0c84a44` and this head (37 of 37, by
md5). The overwrite gate below agrees.
- **Scope of the diff:** 92 files, +175 / −140. That is 37 edited and 2
new changesets, and 53 non-test source files in 15 released packages. No
test file.

## Gates, on this head `2b3d2061a`

Each line is the gate's own verdict and exit code, captured by
redirect-then-`$?`.

- `node scripts/check-changeset-presence.mjs`, exit 0: "53 source
file(s) of 15 released package(s) changed, and this change declares 2
changeset(s): .changeset/10803-dead-citation-sweep-sixth-batch.md,
.changeset/10803-sixth-batch-runtime-strings.md."
- `pnpm changeset:check`, exit 0: "All workspace packages are in the
changeset fixed group." / "No changeset declares a `major` bump."
- `node scripts/check-changeset-overwrite.mjs` (report-only), exit 0: "2
changeset(s) added, 37 modified, 0 deleted". `declared at base` equals
`declares now` for 37 of 37.
- `pnpm check:changeset-claims` (report-only), exit 0:
- "Every one of those 1 address(es) either names the tree it was read
from, or points at a line this change does not move";
- "Every package declared across those 31 body(ies) is either not
negated …";
- the standing notice "75 pending changeset(s) describe a file this
change touches".
- Read against the diff: a pending changeset quoting a replaced pointer
would itself carry the dead number and sit in the census, which reads 0.
No pending changeset quotes the changed description.
- `pnpm check:control-bytes`, exit 0: "check-control-bytes: OK (scanned
9178 tracked text file(s); skipped 85 binary)."
- `pnpm check:new-line-citations`, exit 0: "VERDICT
new-cross-file-line-citations: 0 new citation(s), enforcement
report-only -> exit 0".
- `pnpm check:pending-changeset-literals`, exit 0: "No test source names
a pending changeset."
- Also run over the touched comments:
  - `pnpm check:installed-pin-claims`, exit 0 ("OK");
- `pnpm check:comment-mask-corpus`, exit 0 (1 disagreeing file, within
the ceiling objectui#7882 holds open);
- `pnpm check:handler-key-reads`, exit 0 ("every judged read is a
declared member of it").
- The governed-surface predicate over the 92 paths, exit 0: "NOT
GOVERNED — 92 path(s) checked against 5 governed surface(s); none
matched." Lit control `AGENTS.md`: exit 3.

**Tests**, through the shared verify lock, on `2b3d2061a`. Each is
`VERDICT command-exit 0`.
- `scripts/__tests__/`, the whole directory, whose whole-tree scanners
read the touched files: `Test Files 177 passed | 2 skipped (179)`,
`Tests 5322 passed | 2 skipped (5324)`. The two skipped files are the
network-escape fixtures that run only as a child.
- `packages/types/`, the whole package, whose runtime text moved: `Test
Files 264 passed (264)`, `Tests 5854 passed (5854)`. `pnpm --filter
@object-ui/types type-check`, exit 0.
- **The pins nearest the re-pointed text:**
- in `types`: `input-wrapper-class-mirrored-8072`, `zod-mirror-parity`,
`wrapper-class-declared-7722`, `zod-mirror-authors-no-defaults-7735`,
`collapsible-open-refusal-8236`, `tree-view-config-readers-8253` and
`layout-default-jsdoc-7361`;
- in `components`: `collapsible-open-intercept-8236`,
`registration-defaults-match-renderer-8229` and
`action-undeclared-keys-8648`;
- in `plugin-view`: `ViewSwitcher` and
`ViewSwitcher.viewTypeTotalsBothLegs-9943`;
  - in `plugin-kanban`: `laneCountHonesty-8307`;
  - in `plugin-grid`: `rowCrudAffordances` and `rowCrudEffectiveOps`.
  - Result: `Test Files  15 passed (15)`, `Tests  381 passed (381)`.
- No red leg: the sweep found no anchor to move, so there is no pin
whose old copy should fail.

**Declared narrowing.** NOT MEASURED locally:
- the full suites and type-check of the 14 other touched packages, and
eslint.
- Reason: the comment-stripped syntax tree of 52 of 53 touched source
files is identical to `main`, and the 53rd differs only by the listed
literal.
- CI runs the full farm.

## Acceptance notes

1. **A sister-repo class of the same defect: 30 `objectstack#N`
citations answer 404 in objectstack.**
- **Measurement.** Every distinct `objectstack#N` in the two in-scope
classes at the branch point is 359 numbers. Each was read once: 328
answer 200, 1 answers 301 (objectstack#14026 to objectui#10102), and 30
answer 404, each confirmed by a second read.
- **The 30:** objectstack-ai#5970 objectstack-ai#5976 objectstack-ai#6038 objectstack-ai#6124 objectstack-ai#6281 objectstack-ai#6331 objectstack-ai#6450 objectstack-ai#6483 objectstack-ai#6515
objectstack-ai#9933 objectstack-ai#9934 objectstack-ai#10354 objectstack-ai#10485 objectstack-ai#10695 objectstack-ai#11330 objectstack-ai#11507 objectstack-ai#11513 objectstack-ai#11658 objectstack-ai#11703
objectstack-ai#11753 objectstack-ai#11846 objectstack-ai#12009 objectstack-ai#12868 #13117 #13670 #16126 #17147 #17762 #17987
#18012.
- **Sites at this head:** 82 lines in 63 files, 26 of them changeset
lines.
- **Three of them sit in sentences this PR edits, and are left as they
are:**
- objectstack#11846, "(objectstack#11846, landed as PR
objectstack#12718)" in `6748-preview-mode-provenance-ratchet.md`;
     - objectstack#12009, in `base.zod.ts`'s precedent line;
- objectstack#12868, in `form-spec.ts`'s "RULED 2026-08-28
(objectui#6263 / objectstack#12868, …)".
- **Why left.** They were not in this batch's lists, and the class is
the seat's to scope. objectstack's own card for dead tracker citations
in its tree is objectstack#19123, whose landing `66e266c93` counts
objectstack-ai#12868 among the dead numbers it measured. Triage item 3 would put a
dead number in these classes on this card. The fix shape measured here
for such a number is the objectstack commit, as with `c459da6bc`.
2. **The rest of the bare `objectstack-ai#3391` population.** Only the two sites the
claim names were re-qualified. 28 more in-scope lines in 10 files write
the apiMethods whitelist card as a bare `objectstack-ai#3391`, which resolves to the
unrelated objectui#3391:
   - `ObjectDataPage.tsx`, `ObjectView.tsx` (app-shell);
   - `managedBy.ts`;
- `MePermissionsProvider.tsx`, `PermissionContext.ts`,
`PermissionProvider.tsx`;
   - `fieldWriteGate.ts`;
   - `ImportWizard.tsx`, `ObjectGrid.tsx`;
   - `ListView.tsx`.

It is live, not a 404, so it is outside the family pin. Two of those
lines pair it with a bare 3546 that means objectstack#3546 ("detail/form
面的 edit/delete 按钮接入服务端 effective 操作集"), while objectui#3546 is an
unrelated i18n card. Carrier: none.
3. **A stale claim beside a re-pointed sentence.** The same
`base.zod.ts` paragraph says "AGENTS.md's abridged protocol sketch shows
`events?: Record…` and its action-system commandment authors one".
`7550728a6` removed both from `AGENTS.md`, so that sentence is now
false. It is not a citation, and this PR does not touch it. Carrier:
none.
4. **The C0 blind spot, for any later census.** The bare-number
instrument's lookbehind hides a number written after `/`, `-`, `.` or
`&` (`#13337/#13086`, `-objectstack-ai#2231`). This batch read the 17 such numbers no
batch had read, and #13086 was the only 404. A later census can narrow
the lookbehind to refuse only a word character, `#` or `&` before the
`#`, and drop URL fragments by hand.
5. **Filenames are not citations.** Pending changeset and test FILENAMES
carry several of these numbers. They stay, as in PRs objectui#10707,
objectstack-ai#10797, objectstack-ai#10854, objectstack-ai#10869, objectstack-ai#10875 and objectstack-ai#10892.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk)_

Co-authored-by: Claude <noreply@anthropic.com>
huangyiirene pushed a commit that referenced this pull request Sep 29, 2026
…nce this PR made false (objectui#4356)

W4 (claim addendum 5866346457), authorised by the maintainer's 2026-09-29
ruling 「Allow the appended note (Recommended)」 (card comment 5883360525): a
dated note in the PR #10891 form is appended to
.changeset/7759-dashboard-header-global-filters-spec.md, whose pending
paragraph "The runtime is unchanged too: @object-ui/core still converts a
STORED bare-string option into a pair when it reads the document, and logs a
deprecation warning" would publish in the same release as this PR's "no longer
lifted" entry. Append only: frontmatter byte-identical, 16 insertions, 0
deletions, no existing line edited.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Oct 7, 2026
… family D input slice) (objectstack-ai#10907)

Part of objectstack-ai#9256
Clause-②: yes

**Clause-② `yes`, as the claim declared:** `input` accepted an authored
`children` on both published faces and rendered nothing, with no
render-time error or warning and no element; only the parser tier's
`not-a-container` warning (objectui#9910) noticed it. It now refuses it
by name. A published accept set narrows, so a contract review is owed
before landing.

This is the family-D slice that release `5864147075` on objectui#9256
lists, and nothing else: `input`, the family-D test header's superseded
remarks, and `PartialSchema`'s docblock claim about generic `Omit`
re-spellings. `br`, `hr` and `img` are not touched. objectui#9256 stays
open.

## What changed

- **`input` narrowed** in the family-D shape PRs objectui#9589 and
objectui#10897 used:
- TypeScript face (`InputSchema` in `packages/types/src/form.ts`):
`body?: never` and `children?: never`, each with a docblock saying what
the renderer reads and what it renders instead.
- zod mirror (`InputSchema` in `zod/form.zod.ts`): two
`retirementTombstone` members fed one string, `INPUT_NEITHER_CHANNEL`,
built by `neitherContentChannelGuidance`. Both stay MEMBERS, so
`zod-mirror-parity`'s key sets stay equal.
- `body` was already refused on both faces by `BaseSchema`
(objectui#6771). It is restated because that refusal names `children` as
the remedy, and `input` does not read `children` either.
- **`email` / `password` (`InputShorthandSchema`)**: no type or
accept-set change. See "The shorthand's own pair" below.
- **Texts (comments only):**
- The family-D test header: 「family E, frozen」 (the `InputSchema`
bullet), 「unattributable」 (the `DetailViewSchema` bullet) and the two
`ui:calendar` remarks that still said plain `Omit` (the header bullet on
the six bare-name hold-outs, and the comment above the slice-2 rows) now
say what is true. No assertion in that file moved.
- `PartialSchema`'s docblock in `packages/types/src/index.ts`: the
sentence reading every generic re-spelling as collapsing is marked
false, with `OmitDeclared` named as the counter-example.
- **Bounded in-place fix, declared:**
`partial-schema-collapse-pin.test.ts`'s header carried the same false
claim, and even named the key-remapping spelling as one that collapses.
It is corrected the same way, comment only. See "Texts" below for the
four conditions and the evidence.
- **New pin file**
`packages/types/src/__tests__/content-channel-input-9256.test.ts`.
- **One changeset** `.changeset/9256-input-content-channels.md`:
`@object-ui/types` `minor` with an explicit BREAKING note and a
migration line, the spelling PRs objectui#9589 and objectui#10897 used
under this repo's no-major rule.
- **Four pending changesets are corrected, prose only.**
- Round 2 added a dated note to `6397-partial-schema-collapse-pin.md`,
`9256-content-channel-family-d.md` and
`8499-node-slot-registered-arms.md`.
- Round 3 added a second note to the family-D entry and reworded the E3
entry's render claim in place.
- Each carries a sentence a later change in this same release made
false, or an overstatement, and each ships verbatim into the CHANGELOG.
Every frontmatter block is byte-identical. See "Round 2" and "Round 3"
below.

## Measurement, taken on `origin/main` `244d516df` before any edit

**Instrument.** The TypeScript compiler API (6.0.3), ⛔ not grep. It
builds one program per `tsconfig.json`: the 40 workspace packages,
`apps/console` and the three examples, 44 programs over 2015 non-test
source files. It ran on a BUILT tree (`turbo run build` 43/43, 0 cached)
with 0 unresolved-module diagnostics. It files every `.body` /
`.children` read (property access, string element access, object
destructuring) under the declared type of its receiver: 520 channel
reads were filed.

- **`InputSchema`: 0 `body` / 0 `children` reads.**
`InputShorthandSchema` is never a receiver: the `email` / `password`
wrappers are `any`-typed and hand the node to the `input` renderer,
which reads it as `InputSchema`.
- **Lit controls fire in the same run:** `ButtonSchema` 1, `DivSchema`
1, `CardSchema` 1, `ContainerSchema` 1 (each `children`).
- **Receiver reachability:** the same programs see `InputSchema` as the
receiver of 23 reads over 17 keys: `defaultValue`, `description`,
`error`, `id`, `inputType`, `label`, `max`, `maxLength`, `min`, `name`,
`pattern`, `placeholder`, `readOnly`, `required`, `step`, `value`,
`wrapperClass`. Neither channel is among them, so the zero is a reading,
not blindness.

**Every registration that claims `input`, bare and namespaced**
(`check:registry-bare-names --json`, 1657 files, 424 claims, 0
contested):

- `input`: sole claimant `ui:input`, a literal
`ComponentRegistry.register('input', InputRenderer, …)` in
`renderers/form/input.tsx`. The hop is typed (`InputRenderer` takes
`schema: InputSchema`), not `any`. No `field:input` or other claimant
exists; `ai:input` is a different key, a guarded protocol placeholder.
- `email` / `password`: `ui:email` / `ui:password` own the bare keys;
`field:email` / `field:password` stand down with `skipFallback: true`.

**Does any path pass the node's content through? No.**

- `SchemaRenderer` destructures `children` and `body` out of the props
bag before the spread.
- The only pass-through `InputRenderer` gives the native element is
`toFormControlDomProps(inputProps)`, a whitelist pick of
`SDUI_DOM_PASS_THROUGH_KEYS` plus `name` / `disabled`; `children` is not
on it.
- The `email` / `password` wrappers only spread `props` and
`props.schema` into `InputRenderer`.
- The registration declares no `children` slot input (objectui#9910).
- No in-source host builds an `input` node by spreading another node.
The literal `input` nodes in `form.tsx`, `cli`'s `init` scaffold and the
dashboard / designer config panels are assembled key by key, and none
carries a channel.
- **The 75 `any`-typed channel reads were attributed file by file.**
None can receive an `input` node's channel:
- app-shell nav / search trees, and HTTP request, error or email `body`
payloads;
- React `children` destructured off component props (`view:simple`'s
renderer, `react-page`'s wrapper), which `SchemaRenderer` never fills
from a node;
- the metadata-admin preview canvases, which read a page block's
`properties.children` or a page draft's root `children` to list and
append blocks for selection, not to render a node's channel;
- the page-container and sectioning registrations in `containers.tsx`,
`page.tsx` and `semantic.tsx`, and the html-elements factory, whose tag
list excludes `input` by name (its own comment lists `input` among the
tags it never registers);
- `core`'s schema builder (card / grid / flex builders; `InputBuilder`
has no children setter);
- `record:alert`'s own `props.body`, the runner's nav items, and the
vscode validator.
- **Generic traversers** (`validateChildren` in core, `sdui-parser`'s
parse / validate, `cli validate`) walk children to validate. They render
nothing and are node-agnostic, as for every family-D row already landed.

**Producers.** `pnpm census:body-dialect --keys
input,email,password,ui:input,ui:email,ui:password,div,card,page,button`
read 9016 files. The key population is printed by the tool itself, so
objectui#9545's blindness does not apply.

- Nodes on the six input keys: `input` 321, `email` 75, `password` 60,
`ui:email` 1, `ui:password` 17, `ui:input` 0. **0 author `body`, 0
author `children`.**
- The controls fire in the same pass: `children` on `div` 172, `card`
183, `page` 51, `button` 5.
- Real producers: 0. Nothing was migrated.

## The shorthand's own pair: type-redundant now, kept on purpose

`InputShorthandSchema` inherits `InputSchema` through `OmitDeclared` on
the TypeScript face and `.omit()` on the mirror, so it now inherits the
new pair. It already declared its own (PR objectui#10897).

- **Redundant as a type:** on the built d.ts both are the same `?:
never`, and the new `Eq` pin makes `tsc` hold that.
- **Not redundant as text.** The repo's rule for a restated tombstone is
the one `neitherContentChannelGuidance`'s docblock gives for restating
`body` over `BaseSchema`: restate when the inherited message misdirects
this node's author. The helper's contract spells the node and its route
into the message. The inherited string names `input` and the `ui:input`
route; the shorthand's names `email` / `password` and the wrapper route.
- **Decision:** keep both members and rewrite their docblocks (TS) and
comment (zod) to say they are type-redundant and why they stay. The
shorthand's old `body` docblock gave a reason that became false with
this change (that the inherited refusal names `children` as the remedy),
and it is replaced.
- **Pinned:** a CONTROL row asserts that an author of `email` /
`password` reads the message naming those two nodes and not the `input`
one, so deleting the restatement turns it red.
- Counter-precedents, noted: `UiCalendarSchema` restates nothing and
inherits `calendar`'s message, which names it. objectui#8072 deleted the
shorthand's `wrapperClass` restatement once `InputSchema` carried the
key; that was a live key with one description, not a refusal message
naming a node.

## The `OmitDeclared` propagation, measured on the BUILT d.ts

A compiler-API probe over `packages/types/dist/form.d.ts` reads the
heritage of `InputShorthandSchema` on its own: the base type the checker
gives for `OmitDeclared` of `InputSchema` minus `type` / `inputType`,
before the interface's own members.

| built d.ts | `InputSchema.children` | heritage `.children` | shorthand
face `.children` |
|---|---|---|---|
| base `244d516df` | `SchemaNode \| SchemaNode[]` | `SchemaNode \|
SchemaNode[]` | `undefined` (its own restated tombstone) |
| this branch | `undefined` | `undefined` | `undefined` |

A consumer-side probe resolves `@object-ui/types` the way
`packages/components` does (`--traceResolution`:
`packages/types/dist/index.d.ts`). There, `input` + `children`, `input`
+ `body` and `email` + `children` each answer their `@ts-expect-error`,
and a lit control (`const n: number = 'x'`) fires.

## Red on base, then green — one-shot, the restore proven by state

The predictions were written to a file BEFORE the mutation. The mutation
was `git checkout 244d516` of the two declaration files (`form.ts`,
`zod/form.zod.ts`), with every test at HEAD. It was proven by both blob
hashes equal to BASE and by anchor counts: `INPUT_NEITHER_CHANNEL` 0,
the new TS docblock marker 0. The run sat under `trap … EXIT INT TERM`
with absolute paths.

| reader | mutated (BASE declarations) | restored (HEAD `72dba894a`) |
|---|---|---|
| vitest, `content-channel-input-9256.test.ts` | **RED** exit 1: 6
failed / 13 passed | **GREEN** 19 / 19 |
| `tsc -p packages/types/tsconfig.test.json` | **RED** exit 2: TS2578 on
the `inputChildren` pin, TS2322 on the `Eq` pin for `children`; 0
elsewhere (`zod-mirror-parity` included) | **GREEN** exit 0 |
| built d.ts probe (types rebuilt; dist markers 0 then 2) |
`InputSchema` and heritage `children` accepted | refused |

- **The 6 red rows:** `input.children` refused at its path, its message,
`.describe()` equality, every-value, and the root + nested
`AnyComponentSchema` row; plus the `input.body` message row. The base
message is `BaseSchema`'s `Did you mean` pointer.
- **Green on base, by design:** `input.body` refused at its path,
every-value and `AnyComponentSchema` (`BaseSchema` already refused
`body`), and the shorthand message CONTROL (its own pair is unchanged).
- **One prediction was recorded as uncertain and read, not assumed:**
`input.body` `.describe()` equality is GREEN on base, because
`BaseSchema`'s alias refusal also describes with its own message.
- ⚠️ `?: never` is erased before vitest runs: the TypeScript half is
read by `tsc` alone. `tsc --listFiles` counts the new pin file 1 under
`tsconfig.test.json` and 0 under `tsconfig.json`, so it is a real
assertion under the `type-check` script.
- **Restore:** proven by both blob hashes equal to HEAD, `git diff HEAD`
empty and `git status` clean.

## Texts

- **Family-D test header.** The `InputSchema` bullet now records the
plain-`Omit` hold-out ground in the past tense, the E3 slice's
`OmitDeclared` repair, and this slice's narrowing, pinned in the new
file. The `DetailViewSchema` bullet records that the E3 slice attributed
the `any` hop directly and narrowed it there. The two `ui:calendar`
remarks name `OmitDeclared` for the TS face, `.extend()` for the mirror,
and say which file pins which half. The third `ui:calendar` remark (the
old TRIPWIRE note) was already in the past tense and is unchanged.
- **`PartialSchema`'s docblock.** The triage's reading is kept as the
triage's. The re-spelling claim is marked FALSE, with `OmitDeclared` as
the counter-example. The docblock now says that re-spelling the alias
would narrow a published type, a contract change not made in a comment
correction, and that objectui#6397 is closed. The alias itself is
unchanged.
- **Bounded in-place fix: `partial-schema-collapse-pin.test.ts` header**
(comment only; its assertions are about the alias as written and do not
move). All four conditions hold:
1. It is the same defect as the carried item: the same sentence, one hop
away. The corrected docblock points readers at this file.
2. The fix is mechanical, and its shape is pinned by the carried
correction.
  3. No open PR touches the file.
4. Same gate family: types `tsc` and vitest, no new verification
surface.

**Evidence, a one-shot probe against the built d.ts (not shipped):** the
exact spelling the header named as collapsing, `{ type } & { [K in keyof
T as K extends 'type' ? never : K]?: T[K] }`, declares 62 properties at
`ObjectGridSchema` and 28 at `ButtonSchema`, where the shipped
`PartialSchema` declares 1 at each. It refuses `label: 42` on
`ButtonSchema` and `objectName: 42` on `ObjectGridSchema` (both
`@ts-expect-error` used; tsc exit 0).

## Gates at HEAD `72dba894a` (round 1; round 2's are above) (exit codes
captured by redirect-then-capture; heavy runs through the shared verify
lock)

| gate | result |
|---|---|
| `@object-ui/types` build (tsc + vite + dist completeness) | exit 0,
134 emitted files verified |
| `@object-ui/types` `type-check` (`tsc --noEmit` + examples +
`tsconfig.test.json`) | exit 0 |
| `pnpm exec vitest run packages/types/` (parity, the family-D / E3 /
input pins, the 8072 and 8762 shorthand pins) | 265 files / 5873 tests,
exit 0 |
| `pnpm exec vitest run scripts/` (every `scripts/__tests__` gate suite,
a superset of those whose corpus holds a touched file) | 177 passed + 2
skipped of 179 files / 5322 tests, exit 0 |
| downstream consumer type-check: the packages naming `InputSchema`
(`components`, `core`) plus those authoring `input` nodes or configs
(`cli`, `plugin-dashboard`, `plugin-designer`) and `fields`, `react`,
`types`, against the rebuilt `dist` | 8 × `type-check: Done`, exit 0 |
| `@object-ui/types` lint (`eslint .`, JSON) | 338 files, 0 errors; the
9 `form.ts` warnings sit outside every added hunk |
| `check:handler-key-reads` | exit 0; 128 arms, 50 / 50 reads judged, 0
unjudged |
| `check:control-bytes` · `check:new-line-citations` (0 new) ·
`changeset:check` · `check-changeset-presence` ·
`check:changeset-claims` · `check:pending-changeset-literals` | exit 0
each |
| `check:spec-symbols` · `check:component-surface-parity` ·
`check:readme-exports` · `check:registry-bare-names` ·
`check:prompt-keys` · `check:doc-types` · `check:test-path-roots` ·
`check:esm-specifiers` · `check:vi-mock-*` · `type-check:coverage` |
exit 0 each |
| `check:doc-snippets` (678 / 678) · `check:doc-examples` ·
`check:skill-examples` · `check:doc-fences` · `check:doc-example-ids` ·
`check:sdui-registration-pins` · `pnpm check` (CLI self-check) | exit 0
each |
| governed guard `--test` over the 7 paths | NOT GOVERNED (lit control
`AGENTS.md`: exit 3) |

- **The gate list was derived by hand.** objectstack's
`dispatch-gates.mjs` refuses an objectui answer by design (exit 2), so
the list comes from objectui's `package.json` and `.github/workflows/`.
- `check:changeset-claims` is report-only. It names 18 pending
changesets that mention a touched file; each was read, and none is
falsified as a record of its own change. The two that carry a claim this
slice bears on are in the Acceptance notes.
- **NOT MEASURED, left to CI:** the 8-way `pnpm test` shards beyond
`packages/types` and `scripts/`, `test:dist`, and E2E.
`check:sdui-registration-pins` read the console built at base; this diff
touches no registration and no `sideEffects` array.

## Round 2: four prose edits, head `6eb3397b4`

These come from contract review `5865087439` ③. The seat took them into
this PR because each ships verbatim into the CHANGELOG. They are prose
only: no code, no test logic, and every frontmatter block is
byte-identical (the `name: bump` lines at base and head compare equal).

1. **`.changeset/9256-input-content-channels.md`, and the Clause-②
sentence above.**
- Old: "an authored child list on it rendered nothing: no error, no
warning, no element."
- New: "an authored child list on it rendered nothing, with no
render-time error or warning and no element; only the parser tier's
`not-a-container` warning (objectui#9910) noticed it."
- Measured with a one-shot probe, not committed. It built the manifest
from the live registry the way `container-declaration-ratchet.test.tsx`
does, then ran `validateTree` and `compile`.
- `input`, `ui:input`, `email` and `password` carrying `children`: each
draws exactly `not-a-container`.
     - The same four without `children`: none.
     - `div` carrying `children` (control): none.
- The JSX `input` tag with a child: `not-a-container`, severity
`warning`.
2. **`.changeset/6397-partial-schema-collapse-pin.md`.** A dated note
follows the "Why a pin and not a repair or a retirement" paragraph: a
generic re-spelling of this `Omit` does not collapse, objectui#9256.
- Spelling: `OmitDeclared` is spelled exactly as quoted, in
`packages/types/src/form.ts`.
- Counts: the re-spelled alias declares 28 properties at `ButtonSchema`
and 62 at `ObjectGridSchema` on this head and on `main` `733fd5ac6`. The
shipped alias declares 1 at each.
- "Not true when written": at that entry's own commit (`c8ea8af9c`),
under the same TypeScript 6.0.3 its lockfile pins, the same spelling
declares 27 and 61. Those are the source counts in that entry's own
table. Both re-spellings refuse `label: 42` (the `@ts-expect-error` is
used), and a lit control on the shipped alias admits it.
- "Later in this same release": the E3 entry and the 6397 entry are both
pending on `main` (`git cat-file -e` exit 0 for each; control on an
absent path: exit 128).
3. **`.changeset/9256-content-channel-family-d.md`.** A dated note
follows the AMENDED paragraph, in that file's own convention, naming the
hold-outs this card later narrowed in this release.
   - Six of the nine names, in `nine-holdouts-six-narrow.md`.
- `list` and `timeline`, in `9256-list-timeline-content-channels.md`.
This is one more than the reviewer's draft, measured.
   - `DetailViewSchema` and the shorthand faces, in the E3 entry.
   - `InputSchema`, in this PR.
- A compiler-API probe over the source reads `body` / `children` as
`undefined` with their own `?: never` members on `TextSchema`,
`ImageSchema`, `IconSchema`, `TabsSchema`, `AccordionSchema`,
`CalendarSchema`, `ListSchema`, `TimelineSchema`, `DetailViewSchema`,
`InputShorthandSchema` and `InputSchema`. The zod faces are pinned in
the family-D, E3 and input pin files.
- `ButtonSchema` and `AppComponentSchema` still resolve `children` to
`SchemaNode | SchemaNode[]` (`ButtonSchema`'s zod mirror declares its
own `children` union; `AppComponentSchema`'s extends `BaseSchema`, which
declares one). That is the note's "still accept `children`" sentence.
4. **`.changeset/8499-node-slot-registered-arms.md`.** "`inputType` is
deliberately NOT declared on this arm" is false on `main`.
- `form.zod.ts` declares `inputType:
retirementTombstone(SHORTHAND_INPUT_TYPE_REFUSAL)` on
`InputShorthandSchema`, and `form.ts` declares `inputType?: never`. Both
files are identical on `main` and at the base.
- A runtime probe: `inputType` is a member of the mirror shape. `{ type:
'password', inputType: 'text' }` is refused with `invalid_type` at path
`inputType`, the message opening with the objectui#8762 guidance. Bare
`{ type: 'password' }` (control) parses.
- objectui#8762's entry landed a day after 8499's (2026-09-10 against
2026-09-09), and both are pending on `main`.
- A dated note in the file's own form follows the `InputShorthandSchema`
bullet, the same place its objectui#10756 note sits under the
`HtmlElementSchema` bullet.

| gate at `6eb3397b4` | result |
|---|---|
| `check-changeset-overwrite` | exit 0 (report-only), "1 changeset(s)
added, 3 modified, 0 deleted". Each of the three modified entries prints
the same declaration at base and now (`@object-ui/types: patch`,
`minor`, `minor`), so no declaration is lost: its case 2, a correction
on purpose. |
| `changeset:check` · `check-changeset-presence` ·
`check:changeset-claims` · `check:pending-changeset-literals` ·
`check:control-bytes` · `check:new-line-citations` | exit 0 each |
| the 24 `scripts/__tests__` suites that name `.changeset` (the
changeset gates' own suites, the polarity census, control bytes, pending
literals, docs and workflow suites) | 24 files / 913 tests, exit 0 |

## Round 3: two more prose edits, head `876f6d7ea`

These come from delta review `5865466392` ③ flags 2 and 3. They are
prose only, and both frontmatter blocks are byte-identical.

1. **`.changeset/9256-content-channel-family-d.md`: a second dated note,
directly after the AMENDED paragraph** and before round 2's note. The
headline is "the two twins no longer take `body` — objectui#6771".
- Old, still in the AMENDED paragraph: "The two twins are unchanged and
go on inheriting `body` as the content slot".
- New note: objectui#6771 retired `body` on `BaseSchema` itself, so both
twins refuse `body` on both faces. The TypeScript face does it through
`BaseSchema`'s `body?: never`; each mirror does it by name, pointing at
`requestBody`.
- Measured, TypeScript: a compiler-API probe over the source gives
`BaseSchema` its own `body?: never`. `ChatbotEnhancedSchema` and
`ChatbotFloatingSchema` resolve `body` to `undefined` and declare only
`children?: never` themselves.
- Measured, zod, with a one-shot runtime probe (deleted): each twin's
mirror refuses `body` with `invalid_type` at path `body`, and the
message names `requestBody`. `requestBody` parses (control).
- Provenance, from `git log -S`: `BaseSchema`'s `body?: never` and both
twins' mirror tombstones were introduced by `2acd8e109` (objectui#6771,
2026-09-19). The AMENDED paragraph was written on 2026-09-17
(`c42554e94`), and `6771-retire-body-child-list-dialect.md` is pending
on `main`. So "later in this same release" holds.
- The reviewer's draft also cited objectui#9659. That card did not
introduce the twin refusals, so the note cites objectui#6771 alone.
- Round 2's note opens "most of the hold-outs above have since been
narrowed". It is still true beside the new one: it names what this card
narrowed, and it ends with `button` and `AppComponentSchema`, which
still accept `children`.
2. **`.changeset/9256-e3-residual-content-channels.md`, in place.**
- Old: "an authored child list on them rendered nothing: no error, no
warning, no element."
- New: "an authored child list on them rendered nothing, with no
render-time error or warning and no element; only the parser tier's
`not-a-container` warning (objectui#9910) noticed it."
- Measured for all twelve keys, not just the two in round 2. A one-shot
runtime probe (deleted) loaded every plugin registration (`plugin-grid`,
`-form`, `-kanban`, `-map`, `-tree`, `-view`, `-gantt`, `-calendar`,
`-charts`, `-detail`, and `components`). It built the manifest from the
live registry and ran `validateTree`.
- Each of the twelve is known to the registry, and none declares a
`children` input.
- Carrying `children`, each draws `not-a-container` (severity
`warning`). Without it, none does. `div` carrying `children` (control)
draws nothing.
- `object-chart`, `email` and `password` also draw one `unknown-prop` in
both legs, from the probe's own `objectName` fixture key. It is not part
of the difference.

| gate at `876f6d7ea` | result |
|---|---|
| `check-changeset-overwrite` | exit 0 (report-only), "1 changeset(s)
added, 4 modified, 0 deleted". Each modified entry prints the same
declaration at base and now, so no declaration is lost. |
| `changeset:check` · `check-changeset-presence` ·
`check:changeset-claims` · `check:pending-changeset-literals` ·
`check:control-bytes` · `check:new-line-citations` | exit 0 each |
| the 24 `scripts/__tests__` suites that name `.changeset` | 24 files /
913 tests, exit 0 |

## Serial constraints

- **Re-mapped at branch time (`244d516df`), before each round's push,
and again before round 3's edits.** At round 3 the open PRs are
objectui#10921, objectstack-ai#10915, objectstack-ai#10914, objectstack-ai#10912, objectstack-ai#10911, objectstack-ai#10910, objectstack-ai#10908, objectstack-ai#10906,
objectstack-ai#10901, objectstack-ai#10777 and objectstack-ai#10278. objectstack-ai#10904, objectstack-ai#10902 and objectstack-ai#10891 have merged since
the first map.
  - None touches any of the five changesets this PR adds or edits.
- One touches a source path here: PR objectui#10914 edits
`packages/types/src/zod/form.zod.ts`, in two comment / `.describe()`
hunks on the `wrapperClass` key (in `InputSchema` and in the
`InputShorthandSchema` restatement note). Neither overlaps or touches
this PR's hunks, and `git merge-tree` of this head (`876f6d7ea`) against
objectstack-ai#10914's head is clean.
- PR objectui#10908 edits `zod-mirror-parity.test.ts` and
`zod/index.zod.ts`, neither of which this PR touches.
- **The release PR objectui#5400** (1732 files, enumerated to the end,
last updated 2026-09-18) touches none of the source paths. As release
consumption it deletes pending changesets, three of the four edited here
among them (not the E3 entry); that is not a hunk overlap.
- **`origin/main` moved four commits since the base** (`9f0c84a44`,
`7ea8118f7`, `8522396c0`, `733fd5ac6`). None touches `packages/types` or
the changesets edited here, and `git merge-tree` of this head
(`876f6d7ea`) against `733fd5ac6` is clean. `main` has not moved since.

## Acceptance notes: out of scope, not fixed here

- **The `PartialSchema` docblock and its pin file still sequence the
alias's repair on objectui#5155.** That card is closed as a duplicate of
objectui#5250, whose ruling keeps the tolerant face on renderer props.
objectui#8347 (open) is the card on removing the index signature from
the authoring face. "Once objectui#5155 removes the root index
signature" therefore names a card that will not do it. Noted, not
edited: rewriting the sequencing is a judgement about objectui#5250 /
objectstack-ai#8347, not a comment correction. Carrier: none.
- **The same "no error, no warning, no element" sentence lives in
published refusal messages and docblocks,** not only in changesets.
Examples: the family-D `retirementTombstone` strings on the zod mirrors
(the chatbot twins' included) and the matching TypeScript docblocks.
Wherever the node's registration declares no `children` input, the
parser tier's `not-a-container` warning did fire. Correcting those
strings is a published-message change, not prose, and it is not this
PR's. Noted, not edited. Carrier: none.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Oct 7, 2026
…bjectui#4356) (objectstack-ai#10930)

Fixes objectstack-ai#4356

Clause-②: yes — published runtime behaviour is removed (the bare-string
lift, and the exported `resetDashboardFilterWarnings` if it retires with
its memo), per the execution parameters in `5511028727`.

The claim's "if" resolved to **stays**: the memo survives (it now
dedupes the dropped-member warning, see "The audible-skip question"), so
`resetDashboardFilterWarnings` keeps its job and its export; the
changeset names no removed export.

Final head `a890654027a69911412efbcb146e326da8476256`. Commits on this
branch since the branch point `733fd5ac6`: `bc4ea976e` (the retirement),
`98623a24d` (rework round 1: W1–W3), `e0647486b` (patch round 2: W5),
the two merges of `origin/main` (`1daf7edf7` at `29c76e573`, `a1058f90e`
at `2eaf5be27`), and `a89065402` (W4, the dated note). Implemented in
session `session_012UwY3ahMixEFkfTUxMVkYm`.

## What changed

Phase 2 of objectui#4356 — the runtime bare-string
`globalFilters[].options` lift retires.

- `packages/core/src/utils/dashboard-filters.ts` — in
`normalizeFilterOptions`, the non-object arm no longer pushes `{ value:
String(o), label: String(o) }`. A member that is not an object (string,
number, boolean) yields NO option: a shorthand-only filter resolves with
no `options`, a mixed array keeps only its object members. The nullish /
value-less skips are unchanged. The Phase 1 deprecation warning
(`warnShorthandOptions`, whose text said "Still lifted here") is
deleted; a dev-mode, once-per-filter `warnDroppedShorthandOptions` names
the filter, the dropped members and the rewrite, and promises no lift.
The `DashboardFilterDef.options` JSDoc, the `normalizeFilterOptions`
docblock, the memo docblock and the `resetDashboardFilterWarnings`
docblock stop describing a lift. No lift, alias, fallback or migration
is added anywhere.
- `packages/core/src/utils/__tests__/dashboard-filters.test.ts` — every
lift-pinning test is flipped to pin the new contract (red-first, quoted
under Tests): `normalizes options: spec {value,label} objects AND
bare-string shorthand` became `normalizes spec {value,label} objects,
and DROPS a bare-string member rather than lifting it`; the `[objectstack-ai#4356]`
describe is `retired: dropped, not lifted` — a shorthand-only filter
yields no `options`; a mixed array keeps only its object members; a
number and a boolean are dropped too; warn ONCE across renders while
dropping on every render; a different filter warns separately; canonical
`{ value, label }` options and an `I18nLabel` map are untouched and
silent; `resetDashboardFilterWarnings` re-arms the memo. The stale Phase
1 header above the block is removed (W3).
- `content/docs/guide/dashboard-filters.md` — the "Deprecated: … still
lifted by the runtime" callout became false and now reads "Not
accepted": refused at publish, no longer lifted, a bare-string member
yields no option, rewrite `"X"` as `{ "value": "X", "label": "X" }`. No
fenced block changed.
- `packages/types/src/zod/complex.zod.ts` — the JSDoc of the exported
`GlobalFilterSchema` said the runtime "still LIFTS a stored bare-string
option on read"; that sentence ships in `@object-ui/types`' emitted
declarations and is corrected in place. Outside the claim's original
surface; accepted by the seat's addendum, see "Deviations".
- `packages/plugin-dashboard/README.md` (W1, ships in that package's
`files`) — the `globalFilters` example's `options` comment no longer
says a stored bare string "is still lifted at runtime, and warns"; it
says NOT accepted, the runtime no longer lifts it (objectui#4356), a
bare member yields no option, a dev-mode warning names it, rewrite each
X as `{ "value": X, "label": X }`.
- Three test docblocks state the retirement instead of the lift (W2):
`packages/types/src/__tests__/dashboard-global-filters-spec-binding.test.ts`,
`packages/types/src/__tests__/report-chart-query-spec-parity.test.ts`
(its header docblock only — nothing near objectui#10916's
`JoinedReportBlock` pin, which PR objectstack-ai#10934 rewrote and this branch has
merged),
`packages/plugin-dashboard/src/__tests__/DashboardRenderer.filters.test.tsx`.
A fourth (W5),
`packages/plugin-dashboard/src/__tests__/DashboardFilterBar.i18nLabel.test.tsx`,
no longer says the shorthand "is deprecated and now warns" nor names the
renamed lift pin; it names the current DROP pin. No assertion moved in
any of the four.
- `.changeset/retire-options-shorthand-lift-4356.md` — `@object-ui/core:
minor`, opening with the ruled wording: "bare-string
`globalFilters[].options` is no longer lifted; use `{ value, label }`
objects, the spec's form". Never `major` (AGENTS.md §9 version policy:
the break is stated in the body, the bump stays `minor`);
`check-changeset-no-major` exit 0.
- `.changeset/7759-dashboard-header-global-filters-spec.md` (W4) — a
dated note appended, nothing else touched. That pending entry says "The
runtime is unchanged too: `@object-ui/core` still converts a STORED
bare-string option into a pair when it reads the document, and logs a
deprecation warning. That conversion keeps its own retirement schedule
(objectstack#7917)." — a sentence this PR makes false in the same
release. The note (PR objectstack-ai#10891 form, dated 2026-09-29) says which
sentences no longer hold and what ships. Authorised by the maintainer's
ruling of 2026-09-29, option 「Allow the appended note (Recommended)」,
recorded on the card as `5883360525`; the option reads, verbatim: "You
allow developers to append dated correction notes to pending .changeset
files (appended only, no existing line or frontmatter edited). The
objectstack-ai#10930 developer adds the W4 note inside that PR, then it merges main,
gets a final review, and merges." Measured: 16 insertions, 0 deletions;
frontmatter md5 `ac1bfd0472c0d0b981d923c32d435f18` before and after;
whole-file md5 `94edd5855709afe137f9184c630f298c` →
`5c8f0508bed5ed6f5b76254bb74d622d`; 0 angle-bracket characters; `diff`
against `origin/main` shows only the appended block.

Untouched on purpose:
`examples/schema-catalog/test/plugin-dashboard-global-filters-spec.test.ts`
(the `GlobalFilterSchema` catalog guardrail from PR objectstack-ai#4601 — the positive
control; its docblock narrates history and spec facts only, and stays
true); the assertions of the two `packages/types` tests that pin the
SPEC's refusal of `options: ['EMEA']` (rejection pins, not lift pins);
`@objectstack/spec`; `content/docs/releases/**`; `skills/**` (no file
there becomes false — measured below).

## Rulings executed

- objectstack-ai/objectstack#7917, maintainer 2026-08-12, verbatim 「7917
②」 — the spec stays strict; the runtime bare-string lift retires.
- Maintainer, 2026-09-02, verbatim 「objectstack#7917 不考虑现有数据」 (director
release `5511028727` on objectui#4356) — Phase 2 on release cadence
alone; no live-tenant survey, no migration entry.
- Maintainer direct dispatch to the `domain:spec @ objectui` seat,
verbatim 「这个你也接管继续
objectstack-ai#4356」.
- Maintainer, 2026-09-29, 「Allow the appended note (Recommended)」 (card
comment `5883360525`) — authorises the W4 append in exactly the form
landed here.

## The audible-skip question — governing text found

The dispatch asked whether any governing text requires the post-removal
skip to be audible. What was read, verbatim:

- objectstack `AGENTS.md`, "Degradation log levels — `warn` vs `error`":
"**Functional degradation → `warn` / `info`.** A screen is missing, a
trigger is not armed, a capability is not enabled … The system is
*visibly* smaller than it should be, and the next person to use the
missing thing finds out." and "**prefer failing to falling back**, and
when you must fall back, say what was lost." — A `select` filter whose
members were all bare strings now renders with an empty option list
(`DashboardFilterBar`: `const authored = def.options?.length ?
def.options : (dynamicOptions ?? [])`): visibly smaller, functional,
`warn`-level — and "say what was lost" is the operative sentence.
- objectstack `docs/adr/0078-no-silently-inert-metadata.md`, §4
"Loud-not-silent at the runtime seam": "Where the runtime *skips* an
inert instance … it emits a **dev-mode diagnostic** at registration
rather than swallowing it silently. This is the only layer that is
**authoring-tool-agnostic**". The ADR's completeness gate (§1) is about
Zod-VALID instances and a bare string is Zod-invalid, but §4 is exactly
the case here: a STORED dashboard is the one document no author-time
gate re-reads.
- objectui `AGENTS.md`: no clause on audibility; #0.1 (contract-first,
no lenient fallback) is honoured — a diagnostic is not a fallback, and
nothing is lifted.
- The module's own convention, same file: `buildFilterCondition` —
"anything else → skipped with a console warning, never silently
downgraded"; `buildWidgetScopedFilter` skips an unknown default field
"with a console warning instead of emitting a query".

Conclusion: yes, at `warn`, dev-mode, deduped — the smallest audible
path consistent with the ruling. Implemented as
`warnDroppedShorthandOptions`: same `isDev()` gate and memo key as Phase
1 (no per-render flood), new sentence (DROPPED, "no longer lifted", the
rewrite), no lift. Consequence: the memo and therefore
`resetDashboardFilterWarnings` stay. The contract review (`5866198610`)
judged this RIGHT; dev-only rather than always-on is the same review's
answer for this PR.

## Measurements against the dispatch's mechanism assumptions

1. Lift live on `origin/main` `733fd5ac6` — confirmed: the `else` arm
pushed `{ value: String(o), label: String(o) }` and called
`warnShorthandOptions` for EVERY non-nullish primitive. Pinned now in
`drops EVERY non-object member — a number and a boolean, not only a
string`.
2. `resetDashboardFilterWarnings` — `git grep` repo-wide: importers are
`dashboard-filters.test.ts` only (plus a `packages/core/CHANGELOG.md`
paragraph); it clears only `warnedShorthandOptions`. The inference "with
the memo gone it has no job" is falsified by (4): the memo does not go.
It stays, with a docblock saying why.
3. Fixture recount, repo-wide over every file containing `globalFilters`
(tests included; positive control: the same matcher found the callout it
was meant to find): lift-pinning bare-string members existed only in
`dashboard-filters.test.ts` — six members across five tests (the
dispatch's list lacked the bare `'lost'` of the mixed-array test; the
director's "three" and the dispatch's "five" were both stale). All six
retired or flipped. The two `packages/types` occurrences pin the spec's
REFUSAL and keep their assertions.
4. Skip audibility — see the section above.
5. Teaching sites — swept at the final head with `git grep -n -i -E
'lift' -- ':!**/CHANGELOG.md' ':!content/docs/releases/**'
':!pnpm-lock.yaml' | grep -i -E 'shorthand|bare[- ]string|4356'` over
the whole tracked tree (a superset of every package's `files[]`,
`content/docs`, `skills/`, `examples/`): 20 hits on `bc4ea976e` with
`packages/plugin-dashboard/README.md`'s "still lifted at runtime" line
as the found positive control; 18 on `a89065402` — every hit either
states the retirement (this PR's changeset, source, docs and test text)
or is the unrelated `data`-array shorthand in `plugin-grid` /
`plugin-map`. The first-round sweep's `option|filter` post-filter is
what hid the README line (W1) and the `i18nLabel` comment (W5); the
rework sweep has no post-filter. When the sweep runs on a ref, the ref
prefix is stripped before the second grep — this branch's name contains
both "shorthand" and "lift". Three other sites author `options: ['…']`
on `select` FIELDS (form / object field schemas:
`content/docs/guide/expressions.md`,
`content/docs/guide/schema-playground.md`,
`skills/objectui/guides/project-setup.md`) — a different contract, out
of this card, untouched; the governed `skills/**` file does not become
false.
6. Release — `packages/core/package.json` is `17.6.0`;
`.changeset/config.json` has `@object-ui/core` in the `fixed` group; a
`minor` changeset makes the next release ≥ 17.7.0; release PR objectstack-ai#5400 is
open (not touched).
7. Pending changesets — swept on the merged tree (2326 pending entries)
with `git grep -n -i -E 'normalizeFilterOptions|bare[-
]string|shorthand|lift' -- '.changeset/*.md'` filtered to option /
`globalFilters` / 4356 / 7917 context: exactly ONE pending sentence this
PR makes false, the `7759` paragraph quoted above (W4). Its earlier
sentence "the bare-string option shorthand (`options: ['EMEA']`) is
refused with `invalid_type`" stays true. Every other hit is a different
contract (export-options bare array, object-map / gantt `data` arrays,
kanban `columns`, picklist / field `options`, widget shorthand). The
nine entries the `changeset-claim-re-read` comment `5865883972` lists
were re-read: none says anything about the options lift; all still true.

## Merges of `main`

- `1daf7edf7` — `origin/main` `29c76e573` (PR objectstack-ai#10934, objectui#10916).
No conflicts; `report-chart-query-spec-parity.test.ts` auto-merged
(disjoint hunks); both sides verified — my header-docblock correction
present, PR objectstack-ai#10934's pin text byte-for-byte as `main` has it.
- `a1058f90e` — `origin/main` `2eaf5be27` (70 commits, among them PR
objectstack-ai#10914's citation edits in `dashboard-filters.ts` and three
`complex.zod.ts` commits). No conflicts; after the merge the files
differing from `origin/main` are exactly this PR's ten, and `git diff
origin/main` on `complex.zod.ts` and on the parity test is exactly this
PR's docblock hunks.

No rebase, no amend, no force-push at any point; every push was a plain
`git push`.

## Tests

Red-first (at `bc4ea976e`, the new pins against the UNTOUCHED source,
`pnpm exec vitest run
packages/core/src/utils/__tests__/dashboard-filters.test.ts`, exit 1):

```text
× normalizes spec {value,label} objects, and DROPS a bare-string member rather than lifting it (objectui#4356)
× DROPS a bare string: a shorthand-only filter resolves with no `options`, and says so
× keeps ONLY the object members of a MIXED array, and names only the dropped ones
× drops EVERY non-object member — a number and a boolean, not only a string
× warns ONCE per offending filter across repeated renders, and drops on every one of them
AssertionError: expected [ …(2) ] to be undefined
AssertionError: expected [ Array(2) ] to deeply equal [ { value: 'won', label: 'Won' } ]
AssertionError: expected [ { value: '42', label: '42' }, …(2) ] to deeply equal [ { value: 'gold', label: 'Gold' } ]
 Test Files  1 failed (1)
      Tests  5 failed | 44 passed (49)
```

The three that stayed green on the old code are the ones the block
labels as non-discriminating (different-filter memo, canonical silence,
memo reset). Green after the source change, same command: `Tests 49
passed (49)`.

Final head `a89065402`, one `pnpm exec vitest run` from the repo root
under the shared verify lock over `packages/core/` plus the two
`packages/types` global-filter tests and the two `plugin-dashboard`
dashboard-filter tests this PR touched: `Test Files 188 passed (188)` ·
`Tests 3725 passed | 27 skipped (3752)`, exit 0. The changeset script
tests (`check-changeset-{presence,no-major,fixed,overwrite,claims}`,
`check-pending-changeset-literals`, `changeset-polarity-census`): `Test
Files 7 passed (7)` · `Tests 292 passed (292)`, exit 0.

Consumer sweep at `bc4ea976e` (`resolveDashboardFilterDefs` consumers
re-derived by `git grep`: `core`, `types`, `plugin-dashboard`,
`plugin-designer`, `app-shell`, `examples/schema-catalog`), exit 0:
`packages/core` 182 files / 3643 tests; `packages/plugin-dashboard` 147
/ 1346 (6 pre-existing skips); `packages/types` 3 / 58;
`packages/plugin-designer` (`DashboardDesignPage.presetAlias`) 1 / 4;
`packages/app-shell` (`DashboardWidgetInspector.test.tsx`) 1 / 19;
`examples/schema-catalog` (the guardrail) 1 / 9 — totals `335 passed
(335)` · `5073 passed | 6 skipped (5079)`. No consumer fixture asserted
the old lift. The code has not changed since that head (every later
commit is prose or a merge), and the final-head run above re-covers
`core`, `types` and the touched `plugin-dashboard` tests.

## Gates on the final head `a89065402` (hand-derived from root
`package.json` and `.github/workflows/`; exit codes captured before any
pipe)

| gate | exit | note |
|---|---|---|
| `pnpm --filter '@object-ui/core^...' build` then `pnpm --filter
@object-ui/core build` | 0 / 0 | dependency closure first, so the
type-checks read rebuilt declarations |
| `pnpm --filter @object-ui/core type-check` · `pnpm --filter
@object-ui/types type-check` | 0 / 0 | |
| `pnpm --filter @object-ui/core lint` · `pnpm --filter @object-ui/types
lint` | 0 / 0 | 0 errors; the warnings are pre-existing
`no-explicit-any` — on the touched files the `as any` counts equal the
base (2 / 10 / 0), unchanged since `bc4ea976e` |
| vitest `packages/core/` + the four touched dashboard-filter tests
(under the lock) | 0 | 188 files, 3725 passed, 27 skipped |
| vitest changeset script tests ×7 | 0 | 292 passed |
| `node scripts/check-changeset-presence.mjs` | 0 | 11 files changed vs
merge-base `2eaf5be27`, 7 published source files of 3 released packages,
1 changeset added |
| `node scripts/check-changeset-no-major.mjs` ·
`check-changeset-fixed.mjs` · `check-changeset-claims.mjs` ·
`check-changeset-overwrite.mjs` | 0 ×4 | claims and overwrite are
report-only; the W4 append is overwrite's documented "correcting a
declaration on purpose" case |
| `pnpm check:pending-changeset-literals` | 0 | "No test source names a
pending changeset" |
| `node scripts/check-control-bytes.mjs` | 0 | 9331 tracked text files |
| `node scripts/check-new-cross-file-line-citations.mjs` | 0 | 0 new
citations (the W4 note cites by quoted sentence) |
| `node scripts/check-governed-queue-guard.mjs --test` (every touched
path) | 0 | NOT GOVERNED |
| `pnpm check:doc-fences` · `check:doc-types` · `check:doc-example-ids`
· `check:spec-symbols` · `node scripts/check-doc-links.mjs` ·
`check:test-path-roots` · `check:vi-mock-specifiers` ·
`check:phantom-deps` | 0 ×8 | measured at `bc4ea976e` / `98623a24d`; the
files they read have not changed since |
| `pnpm check:doc-snippets` · `pnpm check:readme-exports` | 2 / 1 | NOT
MEASURED locally — both `PRECONDITION NOT MET` (unbuilt packages); CI's
Doc Snippet Type Check and README Exports are the readings. The docs
hunk changes no fenced block; the README hunk is a JSON comment with no
import binding |

Not run locally, CI-owned: repo-wide `pnpm lint`, `pnpm test`, `pnpm
type-check` (the public type face is unchanged — no export added or
removed, no signature changed; emitted declarations differ in JSDoc text
only), `pnpm check`, the i18n gates, `plugin-dashboard`'s own type-check
(comment-only hunks in two test files).

## Deviations

- `packages/types/src/zod/complex.zod.ts` was outside claim
`5865368364`'s original file surface; edited under the bounded
in-place-fix exemption (same defect class; mechanical; no other open PR
on the file; inside core's type-checked closure) and accepted by the
seat's addendum `5865980488`. The later addenda `5866223135`,
`5866346457`, `5866480991` added the W1–W5 files and the `7759`
changeset.
- The first-round teaching sweep under-reported (W1, W5) because of its
`option|filter` post-filter; corrected above.
- The W4 append was first refused by the auto-mode classifier ("Modify
Shared Resources", record `5866443287`), held and not re-routed; it
landed only after the maintainer's 2026-09-29 ruling.

## Acceptance notes

- `warnDroppedShorthandOptions` is dev-only, exactly as the Phase 1
warning was; the module's other skip warnings are not dev-gated.
Always-on is a one-line product decision the review left to the
maintainer; not this PR's.
- Field-level `select` schemas teaching `options: ['…']` are a different
contract and were not judged here — observation only, not filed.
- `packages/core/CHANGELOG.md` and
`packages/plugin-dashboard/CHANGELOG.md` narrate the lift as history;
published record, not re-addressed (the CHANGELOG clause under AGENTS.md
objectstack-ai#11: never re-address a paragraph in a published CHANGELOG).
- PR objectstack-ai#10914 (objectui#10803 batch 6) has landed on `main` and is merged
into this branch; no other open PR touches this PR's files.

---
_Generated by [Claude
Code](https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant