Skip to content

docs: cite landing commits where pending changesets and source comments name 23 objectui issues that answer 404, and re-qualify 19 bare objectstack numbers (objectui#10803, batch 6) - #10914

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-10803-dead-citations-sixth-batch
Sep 28, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-10803-dead-citations-sixth-batch

Conversation

@objectstack-fleet

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

Copy link
Copy Markdown
Contributor

Part of #10803
Clause-②: no

Dispatched implementation of the domain:ui seat #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 #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 docs: cite landing commits where pending changesets and source comments name 41 objectui issues that answer 404 (objectui#10803, batch 5) #10892, at the branch point):
git grep -hoP '(?:^|(?<=[^\w#&/.\-]))#\d+(?![0-9A-Za-z_])' 9f0c84a44 -- '.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)".
  • [console] 记录详情页头的 api 动作:target URL 的 {field} 占位符从不插值——record_header 执行器不提供 params._rowRecord,literal {id} 被原样发出 #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 "[console] 记录详情页头的 api 动作:target URL 的 {field} 占位符从不插值——record_header 执行器不提供 params._rowRecord,literal {id} 被原样发出 #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 / #10875 / #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 (finding(docs): AGENTS.md documents a BaseSchema.events key that no schema declares and no renderer reads — BaseSchemaCore is passthrough, so a node authored from the instruction file is silently discarded #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
#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
#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
#8137 own-card pointer dropped (landing 0fa7a9c83) changeset's adding commit 1 / 1 the only site is its own changeset's pointer
#8204 own-card pointer dropped (landing 580b0fdf4) changeset's adding commit 1 / 1 the pointer opened a paragraph as its own sentence
#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
#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
#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
#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
#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
#9241 own-card pointer dropped (landing 250429c8f) changeset's adding commit 1 / 1 the only site is its own changeset's heading
#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
#9365 own-card pointer dropped (landing 0970a0e00) changeset's adding commit 1 / 1 the only site is its own changeset's pointer
#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
#9375 own-card pointer dropped (landing e427e9c00) changeset's adding commit 1 / 1 the only site is its own changeset's pointer
#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
#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
#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
#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
#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
#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
#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
#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
#11289 objectstack#11289 ("upstream") "record:details sections cannot survive an empty record: hideEmpty / collapsible / showBorder are honoured by the renderer but undeclared" 2 / 2
#11662 PR objectstack#11662 "feat(spec): declare hideEmpty / collapsible / showBorder on record:details sections" 1 / 1
#12616 PR objectstack#12616 "feat(spec): declare record:details section headerColor as a closed six-token enum" 1 / 1
#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, #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. A spec-valid type: 'page' view silently renders as a grid — ViewType in packages/types/src/views.ts never gained page, so six total maps over it compile green while being incomplete #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. finding(core/app-shell): ResultDialogSpec hand-copies the contract's resultDialog block and has drifted — title / description / acknowledge are string here and I18nLabel in the contract #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. finding(docs): AGENTS.md documents a BaseSchema.events key that no schema declares and no renderer reads — BaseSchemaCore is passthrough, so a node authored from the instruction file is silently discarded #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 完善设计器的每一个细节 #9.
  5. measurement only: does the zod refusal gate the collapsible RENDER path, or only validate? — the binary precondition every route on objectui#8236 depends on #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. #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, #10908, #10907, #10906, #10901, #10891, #10777, #10278 and the release PR #5400 (#10902 and #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):

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.

  2. The rest of the bare #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 #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, -#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, docs: cite landing commits where pending changesets and source docblocks name ten objectui issues that answer 404 (objectui#10771) #10797, docs: cite landing commits where pending changesets and source comments name fourteen objectui issues that answer 404 (objectui#10803) #10854, docs: cite landing commits where pending changesets and source comments name 32 objectui issues that answer 404 (objectui#10803, batch 3) #10869, docs: cite landing commits where pending changesets and source comments name 30 objectui issues that answer 404 (objectui#10803, batch 4) #10875 and docs: cite landing commits where pending changesets and source comments name 41 objectui issues that answer 404 (objectui#10803, batch 5) #10892.


Generated by Claude Code

…ts name 23 objectui issues that answer 404, and re-qualify 19 bare objectstack numbers (objectui#10803, batch 6)

The last 23 family numbers are re-pointed to the commit that landed each
change, or named by role where nothing answers; a changeset's pointer to
its own card is dropped. The 18 bare sister-repo numbers of batch 5's C0
census, plus #13086 that its instrument could not see, are re-qualified
to objectstack#N; where the objectstack pull request itself answers 404
(#13033, #13413) the sentence cites its commit in that repository. Two
bare #3391 beside objectstack#3720 in rowCrudAffordances.ts now read
objectstack#3391. One zod .describe() string in @object-ui/types drops
its dead pointer (patch changeset).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk
@github-actions

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

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

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

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

.changeset/10108-form-payload-server-owned-fields.md

  • names sanitize.ts → packages/plugin-form/src/sanitize.ts — edited by this change

    What it was. The write-side roster in sanitize.ts and the render-side roster in autoLayout.ts were two hand-written copies of the same list, and they drifted. The render copy had learned to drop owner_id; the write copy never did. A form therefore showed the user business inputs only, and sent back every ownership and audit column it had read — owner_id, owning_business_unit_id, created_by, updated_by — while dropping created_at and organization_id from the same payload, because those two happened to be in the write copy.

.changeset/10612-form-arms-managed-lock.md

  • names fieldWriteGate.ts → packages/plugin-form/src/fieldWriteGate.ts — edited by this change

    Clause-②: no. No exported symbol, type or prop changes. The shared step lives in fieldWriteGate.ts, an internal module that index.tsx does not re-export. What changes is which inputs the drawer, modal, tabbed, split and wizard layouts draw enabled.

.changeset/10864-app-shell-spec-floor.md

  • names packages/app-shell/src/views/metadata-admin/previews/simulator/flow-sim-validate.ts → packages/app-shell/src/views/metadata-admin/previews/simulator/flow-sim-validate.ts — edited by this change

    packages/app-shell/src/views/metadata-admin/previews/screen-spec.ts imports predicateSlotRefusal from @objectstack/spec/automation; packages/app-shell/src/views/metadata-admin/previews/simulator/flow-sim-validate.ts imports structuralConditionRefusal from the same subpath plus EVALUATED_EXPRESSION_SOURCE_REQUIRED and EvaluatedExpressionSchema from @objectstack/spec/shared. @objectstack/spec was declared as ^17.3.0, so any resolution landing on 17.3.0 (which the range allows) gets a module that names exports its own declared spec dependency does not have.

.changeset/5905-componentinput-inputtype-tombstone.md

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

    The write was measured as a no-op before it was deleted, and re-measured on this branch's base rather than inherited from the card. A structural census over every inputs: array in the repository (211 regions, all tracked TS/TSX/JS sources) scores inputType at exactly ONE authoring site — the plugin-markdown registration — against name 953, type 969, label 966, description 194, enum 119, required 86 and binding 4 in the same pass over the same regions, so the instrument was not blind. The other 192 in-repo inputType hits are a DIFFERENT face: FormField.inputType (zod/form.zod.ts), the text-input renderer's prop, and SchemaBuilder.inputType, none of which sit on a ComponentInput. The publication path is unchanged and was re-confirmed: packages/sdui-parser/src/index.ts forwards exactly seven keys per input — name, type, of, required, enum, binding, description — so an authored inputType could not reach the published sdui.manifest.json even in principle.

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

    Stale wording corrected in the same pass, because this change falsifies it: base.ts and zod/base.zod.ts both said the fork was "recorded for a ruling; until then this stays a live, writable key", and widget.ts called it "the open fork". All three now record the ruling. A reader who greps the source instead of the card thread was meeting an open fork that no longer existed.

.changeset/5905-componentinput-retire-constraint-keys.md

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

    The retirement kit: ?: never on the interface (packages/types/src/base.ts), so authoring one is a tsc error at the registration site; retirementTombstone() on the Zod mirror (packages/types/src/zod/base.zod.ts), so an authored value is REFUSED at parse time with code: 'invalid_type', the key named in the issue path, and the migration note as the message. Deleting the members outright was the option NOT taken: ComponentInputSchema is a non-strict z.object, which strips an undeclared key silently — one silent no-op traded for another. Pinned in packages/types/src/__tests__/component-input-retired-constraint-keys.test.ts.

.changeset/5920-flow-runner-translation-overlay.md

  • names flow-sim-validate.ts → packages/app-shell/src/views/metadata-admin/previews/simulator/flow-sim-validate.ts — edited by this change

    ⚠️ Dated note, 2026-09-28 — the declared floor has since moved again — objectui#10864. At this change @object-ui/app-shell declared ^17.3.0, and the paragraph above is kept as the reading of that change: 17.3.0 was in fact the first release exporting the resolver family this fix uses. Later in this same release the floor was raised again, to ^17.4.0, because two other shipped app-shell sources (screen-spec.ts, flow-sim-validate.ts) import four symbols (predicateSlotRefusal, structuralConditionRefusal, EVALUATED_EXPRESSION_SOURCE_REQUIRED, EvaluatedExpressionSchema) that 17.3.0 does not export — a defect this changeset's own range did not introduce and did not need to guard against. @object-ui/app-shell now declares ^17.4.0.

.changeset/6172-markdown-kanban-one-authority.md

  • names KanbanImpl.tsx → packages/plugin-kanban/src/KanbanImpl.tsx — edited by this change

    KanbanCard / KanbanColumn — the three in-package copies converged to one. KanbanImpl.tsx and KanbanEnhanced.tsx each redeclared both names. A TypeScript-AST comparison found them strict-SUBSET copies of ./types with nothing typed differently, so their extra members moved onto the one declaration and, at this change, both files re-pointed at it.

.changeset/6237-wizard-step-config-split.md

  • names WizardForm.tsx → packages/plugin-form/src/WizardForm.tsx — edited by this change

    WizardStepConfig is now declared independently in WizardForm.tsx, which is simply what SplitFormSectionConfig, ModalFormSectionConfig and DrawerFormSectionConfig already do: each layout owns its group shape, documents className / gridClassName in its own terms, and declares visibleWhen only where its renderer honours it. The derivation flips from subtractive to additive — a key is authorable on a wizard step only if someone writes it there.

.changeset/6306-action-icon-type-resolution.md

  • names action-button.tsx → packages/components/src/renderers/action/action-button.tsx — edited by this change

    Scope is this one renderer. type: schema appears in exactly two files under renderers/action/ — action-button.tsx (already correct) and action-icon.tsx; action:group and action:menu compose their members differently and are untouched.

  • names action-icon.tsx → packages/components/src/renderers/action/action-icon.tsx — edited by this change

    Scope is this one renderer. type: schema appears in exactly two files under renderers/action/ — action-button.tsx (already correct) and action-icon.tsx; action:group and action:menu compose their members differently and are untouched.

.changeset/6309-delete-object-fields-bridge.md

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

    Removing it is not the whole change. Three comments — in types/src/designer.ts, types' designer-field-types.test.ts (twice) and fields' richtext-cell-renderer-5452.test.tsx — cited the bridge as a live corroborating source. Left behind, they would have swapped dead code for false documentation: three in-repo pointers telling a future reader that this bridge mediates between the framework field record and FieldDesigner, and nothing telling them it is unreachable. The two that named it as the consumer deriving an editable-subset check from DESIGNER_FIELD_TYPES now name MetadataFieldsPage, which does exactly that with the same idiom and the same objectui#3017 anchor. The third cited the bridge's richtext → html mapping as one of three corroborations that richtext stores HTML; the other two (the showcase seed and the field-type decision tree) are live and carry the point on their own, so that clause is dropped rather than repointed.

.changeset/6310-designer-formula-key-retired.md

  • names packages/app-shell/src/views/metadata-admin/i18n.ts → packages/app-shell/src/views/metadata-admin/i18n.ts — edited by this change

    Not touched: designer.field.formula ('Formula (CEL)') in packages/app-shell/src/views/metadata-admin/i18n.ts, a different and live key belonging to metadata-admin's ObjectFieldInspector — the surface that still authors formula expressions.

.changeset/6349-name-authority-batch-3.md

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

    @object-ui/components — ComboboxOption now IS @object-ui/types' declaration. The component declared its own { value, label }, a strict subset of the ComboboxOption that @object-ui/types declares for ComboboxSchema.options and mirrors in form.zod.ts ({ value, label, disabled? }). The component now re-exports the types declaration (through the @object-ui/types/form subpath — the root barrel does not publish the name), so the name ComboboxOption exported from @object-ui/components gains the optional disabled?: boolean member. Every value that type-checked before still does — nothing narrows and no key changes type; the one thing that moves is keyof ComboboxOption, so a consumer that EXHAUSTS the type (a Record over its keys) will need the new key. Note that the Combobox component itself does not read option.disabled — that member was already declared on the @object-ui/types face and is now visible on this one too; it is recorded as a separate finding, not changed here.

.changeset/6396-previous-values-dom-leak.md

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

    Scope is the runtime leak only. The declared key stays exactly as declared (packages/types/src/form.ts, packages/types/src/zod/form.zod.ts are untouched): it has a live consumer, so there is nothing here for the enforce-or-remove channel.

.changeset/6473-metadatatypeactions-param-dialog-close.md

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

    The pre-reset paramState.resolve?.(null) is dropped as well, on an enumeration rather than on "resolving twice is a no-op": onOpenChange is reachable from exactly three places, all inside ActionParamDialog, and every one settles the promise before asking for the close — handleSubmit, handleCancel, and the Radix root handler that delegates to handleCancel (the single route Escape, an overlay click and the header close button all take). All four routes are driven in the new test, with a census over ActionParamDialog.tsx so a later call site that skipped the settle is red there instead of leaving a promise pending forever.

.changeset/6519-retired-field-key-strip.md

  • names plugin-designer/src/MetadataFieldsPage.tsx → packages/plugin-designer/src/MetadataFieldsPage.tsx — edited by this change

    Unifying the three retired-key lists on this seam is deliberately not part of this change: it spans plugin-designer/src/MetadataFieldsPage.tsx, which objectui#6489 owns in flight.

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

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

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

.changeset/6771-retire-body-child-list-dialect.md

  • names renderers/layout/containers.tsx → packages/components/src/renderers/layout/containers.tsx — edited by this change

    Non-rendering readers keep their arm on the same rule, and none of them renders anything: while a renderer still reaches stored body content, a reader that must see the SAME content keeps its arm, or the renderer draws what the reader cannot find. Those are the two tab-subtree walkers in renderers/layout/containers.tsx, app-shell's pageSchemaIntrospect (CONTAINER_KEYS) and PageBlockInspector (STRUCTURAL_PROP_KEYS, the inspector half of a stored properties.body), and the CLI's OBJECTUI_STRUCTURAL_KEYS — a file-IDENTIFICATION marker, where keeping body is what lets an old file still be recognised as an ObjectUI node and therefore refused, instead of silently not judged.

.changeset/6938-checkbox-wrapper-class.md

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

    packages/components/src/renderers/form/checkbox.tsx:36 reads cn("flex items-center space-x-2", schema.wrapperClass) — classes on the wrapper div around the box and its label — and neither the TypeScript interface in packages/types/src/form.ts nor the zod mirror in zod/form.zod.ts declared the key. It compiled through BaseSchema's index signature and parsed through .passthrough(), admitted unexamined. The same key, on the same class of read, is declared on FileUploadSchema and FilterBuilderSchema (objectui#6150); the checkbox was left out only because its doc page's schema block is a six-line summary.

.changeset/6939-kanban-column-cards.md

  • names KanbanImpl.tsx → packages/plugin-kanban/src/KanbanImpl.tsx — edited by this change

    Breaking, deliberately. KanbanColumn declared its card list as items in complex.ts and in the zod mirror complex.zod.ts. Every board reads cards. Measured on origin/main 78a3cc238: KanbanImpl.tsx reads .cards on 12 lines, KanbanEnhanced.tsx on 8, and bucketCardsIntoColumns twice more as col.cards || []; .items had zero read sites in either board (a same-shaped .title control on the same two files returns 8 and 3, so those zeros are readings and not a mis-shaped probe). Both catalog entries, the plugin docs and content/docs/api/schema-reference.md all author cards.

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

  • names plugin-list/src/ListView.tsx → packages/plugin-list/src/ListView.tsx — edited by this change

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

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

.changeset/7087-disabled-twin-symmetry.md

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

    Those 18 redeclarations are removed, on both faces. The interfaces inherit BaseSchema.disabled the way they always inherited visible; the zod mirrors inherit base.zod.ts's z.union([z.boolean(), z.string()]) through .extend()'s merged .shape, so there is no second spelling of the union to drift from — the route ChatbotSchema took in objectui#6169.

.changeset/7113-chart-data-model.md

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

    .extend() with a NEW key still works and preserves the fold and the refinement; .optional(), z.discriminatedUnion, z.toJSONSchema and safeValidateSchema are all unaffected. Nothing in this repository calls the throwing combinators on either const, and the published surface already ships refined mirrors (objectql.zod.ts, complex.zod.ts, form.zod.ts, app.zod.ts), so the class is not new — but it is a real behaviour change on a published export and it belongs in the release note rather than in a reviewer's file.

.changeset/7125-dashboard-empty-state-keys-retired.md

  • names packages/app-shell/src/views/metadata-admin/i18n.ts → packages/app-shell/src/views/metadata-admin/i18n.ts — edited by this change

    Not touched: table.noRows ('No rows to display') and engine.form.noRows (packages/app-shell/src/views/metadata-admin/i18n.ts, read at widgets.tsx) — two different, same-named keys in different namespaces. Nor the comments in WidgetEmptyState.tsx, DatasetWidget.tsx, ObjectDataTable.tsx and PivotTable.tsx that record WHY three widgets with three strings became one shared empty state; the packs' own comment keeps that rationale and now names the retirement instead of a row that is gone.

.changeset/7182-declared-action-ids-one-rule.md

  • names containers.tsx → packages/components/src/renderers/layout/containers.tsx — edited by this change

    New on @object-ui/types, beside actionRendersAt: the pure resolveDeclaredActionIds(elements, registeredActions), with the DeclaredActionsResolution / DeclaredActionsRefusal result types (the shape classifier stays module-internal: called with no registry, the function already returns the registry-independent verdict a renderer needs before its lookup). Both renderers call it; the whole-array switch in record-quick-actions.tsx and the per-element normalisation in containers.tsx are gone. The rule is closed: a string is an id, a non-null non-array object is an inline definition, and any other element (null, a number, a nested array) is refused at its index too. An all-id array resolves by name in authored order, first registration winning on a duplicate name; ids that name nothing are reported back with their index for the caller to warn about once its lookup has settled.

.changeset/7287-resolve-title-field-shared-ladder.md

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

    def.primaryField — a DetailViewSchema key (@object-ui/types views.ts), read off an OBJECT def and ranked ABOVE the canonical nameField ADR-0079 Phase 2 made the pointer (AGENTS.md Commandment #0.1). No producer can put it there: @objectstack/spec's object schema is a strictObject that answers unrecognized_keys: ['primaryField'], and ObjectSchema.create() throws — which is why objectstack#6326 deleted the identical read from two lint rules. A census across both repos found zero object payloads carrying it (the only writers are three test fixtures), and primaryField appears in zero files of the shipped @objectstack/spec@17.2.0 dist against 68 for nameField. Same shape as the undeclared objectDef.titleField read objectui#6531 measured and Five more consumer-side reads of the undeclared object-level titleField survive #6531 — in ObjectView view-config fallbacks and a useRecordSearch memo key #6557 removed. DetailViewSchema.primaryField is untouched and still honoured by DetailView's own header — it is a view key, and on a view it is legitimate.

.changeset/7322-object-kanban-component-props.md

  • names ObjectKanban.tsx → packages/plugin-kanban/src/ObjectKanban.tsx — edited by this change

    Inside ObjectKanban.tsx, three schema-key reads drop their as any: titleField (two sites, now honest because the object-kanban arm declares it) and cardFields / cardTitle (already declared; the casts were redundant). (schema as any).navigation stays — navigation is declared on neither face, so removing the cast would change nothing but the spelling of an index-signature read.

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

  • names packages/plugin-kanban/src/ObjectKanban.tsx → packages/plugin-kanban/src/ObjectKanban.tsx — edited by this change

    What was measured, on this branch's base (53ded82b). packages/plugin-kanban/src/ObjectKanban.tsx reads schema.groupBy at thirteen sites (lane materialisation at :601 / :625 / :640, card moves at :747 / :865, and their effect deps) and schema.limit at two (:264, $top: schema.limit ?? DEFAULT_KANBAN_LIMIT, and the effect deps at :291). groupField has ZERO read sites anywhere under packages/plugin-kanban/ — against a control of those thirteen groupBy reads in the same query, so the zero is a reading, not a blind grep. Yet the declaration REQUIRED groupField and declared neither groupBy nor limit. Measured from source: the documented, tested, working shape — { type: 'object-kanban', objectName, groupBy, limit } — failed ObjectKanbanSchema.safeParse and safeValidateSchema on the missing groupField, and only ever reached the renderer through BaseSchema's [key: string]: any and .passthrough(), admitted unexamined. An author who followed the declaration wrote groupField and got a board that grouped nothing, with no diagnostic on either face.

  • names packages/core/src/utils/normalize-list-view.ts → packages/core/src/utils/normalize-list-view.ts — edited by this change

    Who is NOT affected. The VIEW-LEVEL kanban config is untouched: kanban.groupField there is a live legacy alias of the spec's groupByField (packages/core/src/utils/normalize-list-view.ts maps it; plugin-list's ListView and plugin-view's ObjectView still read it). groupField is dead only on the object-kanban NODE. The declarative kanban node (KanbanSchema) is untouched, BaseSchema's unknown-key policy is byte-identical (an undeclared key still passes through), and the renderer is unchanged — boards authored the documented way rendered before and render now. One in-repo fixture authored groupField on this node (packages/types/src/__tests__/kanban-conditional-formatting.test.ts); it now authors groupBy. No doc snippet, catalog entry, skill or app in this repository authored groupField on an object-kanban node.

.changeset/7344-handler-string-any-mirrors.md

.changeset/7493-componentinput-retire-label-defaultvalue-advanced.md

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

    The retirement kit: ?: never on ComponentInput (packages/types/src/base.ts), so authoring one is a tsc error at the registration site; retirementTombstone() on ComponentInputSchema (packages/types/src/zod/base.zod.ts), so an authored value is REFUSED at parse time with code: 'invalid_type', the key named in the issue path, and the migration note as the message (one string, both channels). Pinned in packages/types/src/__tests__/component-input-retired-keys-7493.test.ts, which also holds a tree-scoped absence census over every inputs: array under packages/** and apps/**.

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

  • names plugin-list/src/ListView.tsx → packages/plugin-list/src/ListView.tsx — edited by this change

    • plugin-list/src/ListView.tsx — the object-gantt render branch. - plugin-view/src/ObjectView.tsx — generateViewSchema, the authored object-view element route, which bypasses ListView entirely.
  • names plugin-view/src/ObjectView.tsx → packages/plugin-view/src/ObjectView.tsx — edited by this change

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

.changeset/7530-predicate-envelope-declared.md

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

    • ExpressionWire (type, main entry) — the TypeScript wire union, in packages/types/src/expression.ts. - ExpressionWireSchema (@object-ui/types/zod) — its runtime twin, hoisted out of zod/form.zod.ts (where it was module-private) into zod/expression.zod.ts and imported by both base.zod.ts and form.zod.ts. One envelope type, reused by reference; no second spelling.
  • names base.zod.ts → packages/types/src/zod/base.zod.ts — edited by this change

    • ExpressionWire (type, main entry) — the TypeScript wire union, in packages/types/src/expression.ts. - ExpressionWireSchema (@object-ui/types/zod) — its runtime twin, hoisted out of zod/form.zod.ts (where it was module-private) into zod/expression.zod.ts and imported by both base.zod.ts and form.zod.ts. One envelope type, reused by reference; no second spelling.
  • names form.zod.ts → packages/types/src/zod/form.zod.ts — edited by this change

    • ExpressionWire (type, main entry) — the TypeScript wire union, in packages/types/src/expression.ts. - ExpressionWireSchema (@object-ui/types/zod) — its runtime twin, hoisted out of zod/form.zod.ts (where it was module-private) into zod/expression.zod.ts and imported by both base.zod.ts and form.zod.ts. One envelope type, reused by reference; no second spelling.

.changeset/7586-primary-field-consumer-reads.md

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

    primaryField is a DetailViewSchema key (@object-ui/types views.ts) — a view key, which DetailView.resolveDisplayTitle reads off schema and is welcome to. Read off an object def it is undeclared: @objectstack/spec's object schema is a strictObject answering unrecognized_keys: ['primaryField'], and ObjectSchema.create() throws. primaryField appears in zero files of the shipped @objectstack/spec@17.2.0 dist, against 68 for the canonical nameField. objectstack#6326 removed the identical read from two lint rules; objectui#7287 / PR fix(plugin-detail): resolveTitleField delegates to the shared ADR-0079 ladder #7585 removed it from resolveTitleField. These two survived it — and three of this repo's own changelogs already called the probe "not a spec property — always undefined" while the code kept honouring it.

.changeset/7712-kanban-calendar-filter-input.md

  • names ObjectKanban.tsx → packages/plugin-kanban/src/ObjectKanban.tsx — edited by this change

    ObjectKanban.tsx sends the authored key to the query as $filter: schema.filter and ObjectCalendar.tsx does the same, and @objectstack/spec's ComponentPropsMap declares filter on both blocks (measured: safeParse accepts it, and refuses an undeclared key by name on the same call). But none of the four registrations that publish those two renderers listed filter in inputs, and sdui-parser's validateTree reports unknown-prop for every key no inputs entry claims. So an author writing the one spelling that WORKS was told it was unknown — objectui#6678's shape, where a correct write draws the same diagnostic as a write that does nothing. That is worse than an inert key: it actively punishes the correct behaviour, and the honest response to it is to delete working metadata.

.changeset/7772-page-block-kanban-group-by-control.md

  • names ObjectKanban.tsx → packages/plugin-kanban/src/ObjectKanban.tsx — edited by this change

    What was measured, on this branch's base (0c8dbc49). BLOCK_CONFIG['object-kanban'] offered exactly four controls — objectName / groupField / titleField / cardFields. ObjectKanbanSchema.groupBy is REQUIRED on both published faces (objectql.ts:2765 groupBy: string, no ?; objectql.zod.ts:1001 groupBy: z.string(), no .optional()) and had no control at all, while groupField — the only control able to set grouping — has been a retirementTombstone() on the Zod face and ?: never on the TS face since objectui#7322. ObjectKanban.tsx reads schema.groupBy at thirteen sites and groupField at zero (control: those same thirteen hits in the one query, so the zero is a reading).

  • names core/src/utils/normalize-list-view.ts → packages/core/src/utils/normalize-list-view.ts — edited by this change

    The view-level kanban.groupField alias (core/src/utils/normalize-list-view.ts) is live and untouched — node-level retirement and the view-level alias are different things.

.changeset/7773-kanban-adapter-groupfield-write.md

  • names ObjectKanban.tsx → packages/plugin-kanban/src/ObjectKanban.tsx — edited by this change

    The object-kanban renderer never read it: groupField has ZERO hits anywhere under packages/plugin-kanban/, against a control of thirteen schema.groupBy read sites in ObjectKanban.tsx from the same query — so the zero is a reading, not a blind grep. The write was inert; the board grouped by groupBy and groupField rode along unread.

  • names normalize-list-view.ts → packages/core/src/utils/normalize-list-view.ts — edited by this change

    Who is NOT affected — the boundary is node-local. Every VIEW-LEVEL groupField read is untouched and still live: it is a legacy alias of the spec's groupByField on the kanban view config, mapped by normalize-list-view.ts, and both adapters still resolve lanes through it (ObjectView.tsx's kanbanCfg.groupField ||, ListView.tsx's groupByField || groupField). Authoring options.kanban.groupField on a list-view or object-view keeps working exactly as documented in packages/plugin-list/README.md. groupField is dead only on the generated object-kanban NODE.

  • names ListView.tsx → packages/plugin-list/src/ListView.tsx — edited by this change

    Who is NOT affected — the boundary is node-local. Every VIEW-LEVEL groupField read is untouched and still live: it is a legacy alias of the spec's groupByField on the kanban view config, mapped by normalize-list-view.ts, and both adapters still resolve lanes through it (ObjectView.tsx's kanbanCfg.groupField ||, ListView.tsx's groupByField || groupField). Authoring options.kanban.groupField on a list-view or object-view keeps working exactly as documented in packages/plugin-list/README.md. groupField is dead only on the generated object-kanban NODE.

.changeset/7780-object-kanban-record-source.md

  • names packages/plugin-kanban/src/ObjectKanban.tsx → packages/plugin-kanban/src/ObjectKanban.tsx — edited by this change

    packages/plugin-kanban/src/ObjectKanban.tsx resolves a board's rows in four steps: the pre-fetched data PROP a parent passes (hasExternalData), then bind through useDataScope(schema.bind), then the inline ROW ARRAY on schema.data, and only then a fetch keyed by schema.objectName — rawData = (hasExternalData ? externalData : undefined) || boundData || schema.data || fetchedData, with the fetch itself gated on schema.objectName && !boundData && !schema.data. Every objectName read is guarded. Both published faces nevertheless REQUIRED objectName, so a bind-only or data-only board — one that renders correctly today — was refused by the shipped validator and could not be annotated with its own type.

  • names ListView.tsx → packages/plugin-list/src/ListView.tsx — edited by this change

    groupBy is untouched and stays REQUIRED (objectui#7322, PR feat(types): declare ObjectKanbanSchema.groupBy and .limit, retire groupField on both faces (objectui#7322 item 1) #7774). A record source and a lane key are different questions: every lane-less document above is still refused at groupBy, and the two readings PR feat(types): declare ObjectKanbanSchema.groupBy and .limit, retire groupField on both faces (objectui#7322 item 1) #7774 excluded from counting as a lane-less mode — the dataSource json fragment in content/docs/utilities/data-objectstack.mdx and ListView.tsx's runtime-generated node — are asserted still-refused in the new pin. The retired groupField tombstone is likewise still refused by name.

.changeset/7918-zod-lazy-getter-identity.md

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

    The card that found this did not claim the ten were wrong. It asked whether the spelling was buying a temporal-dead-zone dodge, and that check is what shipped. Each of the ten was rewritten in place to const inner = ANGLE-BRACKETS(body); z.lazy(() => inner), the package rebuilt, and the built barrel imported in a fresh process. Eight refuse to load. Seven name the very const being declared (children: z.array(TreeNodeSchema) sits inside TreeNodeSchema's own initialiser); SchemaNodeSchema names BaseSchemaCore, which base.zod.ts declares below it. For those eight the z.lazy is load-bearing, so ActionSchema, AppMenuItemSchema, FilterGroupSchema, MenuItemSchema, NavLinkSchema, NavigationMenuItemSchema, SchemaNodeSchema and TreeNodeSchema keep the spelling they have. The two that loaded clean are memoised: FilterBuilderConditionSchema is not recursive at all, and NavigationItemSchema already defers its self-reference through an inner z.lazy(() => NavigationItemSchema) on children.

.changeset/7997-detail-view-related-retired.md

  • names renderers/record-details.tsx → packages/plugin-detail/src/renderers/record-details.tsx — edited by this change

    Why it retired. @objectstack/spec declares no DetailView schema at all — every DetailView occurrence in packages/spec/src is prose about this repo's own RecordDetailView.tsx — so this array mirrored no protocol schema and drifted freely: it declared columns as TableColumn[] while the renderer it fed also accepted bare field names, { field, label } and legacy { name, label } spellings. The axis that carried the ruling was measured zero pull: no application code authored the member, both internal producers of a detail-view node (RecordDetailDrawer, renderers/record-details.tsx) synthesize it without related, and the only in-tree authorings carrying real columns were two documents — both rewritten here.

.changeset/8155-app-root-residue-swept.md

  • names containers.tsx → packages/components/src/renderers/layout/containers.tsx — edited by this change

    Swept as a class, not as two coordinates. Every other place in this tree that stated app was a bound expression-scope root is corrected in the same change — the diagnostic copy and its byte-pin, the ambient-scope docblocks in @object-ui/react (SchemaRenderer, useExpression), @object-ui/core (ActionRunner.ParamDef.visible, RowPredicateOptions.scope), @object-ui/components (form.tsx, containers.tsx), @object-ui/plugin-detail, @object-ui/plugin-form (docblock and README), @object-ui/app-shell and the console app, plus fourteen test fixtures that transcribed the old bag with an app key. The fixtures in @object-ui/app-shell now call buildExpressionScope instead of transcribing it, so that pair cannot drift again.

.changeset/8174-kanban-calendar-filter-sort.md

  • names ObjectKanban.tsx → packages/plugin-kanban/src/ObjectKanban.tsx — edited by this change

    filter had four declaration faces and only three of them named it: @objectstack/spec declares it (ComponentPropsMap['object-kanban'] and ['object-calendar']), both plugins' registration inputs publish it, and both renderers read it — ObjectKanban.tsx lowers schema.filter onto $filter, ObjectCalendar.tsx lowers schema.filter onto $filter and schema.sort onto $orderby through convertSortToQueryParams. This package's own published faces (the TypeScript interface and its zod mirror) named none of them, so an authored value reached the renderer only through BaseSchema's index signature and the mirror's .passthrough() — admitted, never examined. That is the same reasoning finding(types,plugin-kanban): ObjectKanbanSchema requires groupField (zero read sites) and declares neither groupBy nor limit — no working object-kanban node is assignable to any declared type #7322 used to move groupBy and limit into this same interface.

.changeset/8318-jsdoc-default-tag-corrections.md

  • names core/src/actions/ActionRunner.ts → packages/core/src/actions/ActionRunner.ts — edited by this change

    • CRUDDialogSchema.size / .closeOnOutsideClick / .closeOnEscape / .showClose — there is no register('crud-dialog' anywhere, so no node of that type ever reaches a renderer. Recorded once on the interface. Per key, the name census differs: two spellings occur nowhere outside the declaration and its zod twin, and showClose's one other occurrence (renderers/overlay/drawer.tsx:38) belongs to DrawerSchema. - ActionSchema.level — type: 'action' is not a rendered node type, and core/src/actions/ActionRunner.ts, which is what makes method / chainMode / reload / close live, does not read level. - CardSchema.variant — card IS registered, twice, and neither registration reads it: the ui route forwards the key to ui/card.tsx, which spreads onto a div and mentions variant nowhere, and the page route forwards only its designer props. - PageNodeSchema.isDefault — page IS registered, and PageRenderer neither reads the key nor forwards it: the wrapper element gets toDomProps(props), an allow-list that does not carry it.

.changeset/8344-node-recursion-point-redirect.md

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

    Two mechanical notes for anyone editing the wiring. AnyComponentSchema is built in zod/index.zod.ts from all 13 category modules and 14 modules import zod/base.zod.ts, so the arm cannot be an import — z.lazy defers evaluation, not the module graph. It is a written option slot that index.zod.ts fills inside AnyComponentSchema's own initializer, and it is a z.union option rather than a z.lazy holder because z.lazy memoises its getter: a holder would let whichever module graph parsed first decide the accept set for the whole process. Both constraints are measured, and the reasoning lives on defineNodeComponentUnion in zod/base.zod.ts.

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

    ⛔ It is NOT closed here, and the reason is measured rather than argued. The route that closes it by binding the union inside SchemaNodeSchema's z.lazy getter was implemented and pushed, and CI refused it: Build Docs failed with ReferenceError: Cannot access 'BaseSchema' before initialization out of packages/types/dist/zod/app.zod.js, because that import makes base.zod.ts depend on the barrel and a bundler is free to evaluate the resulting cycle category-module-first. Reproduced locally in one line — importing dist/zod/app.zod.js throws with the binding in place and loads clean without it. The other three candidates were measured too: a narrowed sideEffects array is not a legal declaration for this package (one gate requires every entry form to be named, another refuses a named entry with no load-time effect, and this package's entry forms are pure), a bare top-level call is dropped by the same flag, and dropping the flag costs 16,078 gzipped bytes on the console framework chunk and moves a workspace census a guard pins.

.changeset/8400-kanban-name-field-skip-set.md

  • names record-details.tsx → packages/plugin-detail/src/renderers/record-details.tsx — edited by this change

    Deliberately one rung, unlike the same dedupe in record-details.tsx, which also carries deriveTitleField: that ladder filters a synthesized field list, whereas this one filters an author-declared cardFields, where dropping a field the author asked for is a worse failure than a repeated title. A regression test pins both directions, including an object whose declared and derived pointers disagree.

.changeset/8478-describe-line-addresses.md

.changeset/8478-zod-pins-form-layout.md

.changeset/8499-node-slot-registered-arms.md

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

    • SemanticElementSchema (zod/layout.zod.ts) — the seven HTML sectioning tags renderers/layout/semantic.tsx registers: aside main header nav footer section article. - HtmlElementSchema (zod/layout.zod.ts) — the 37 safe flow/inline tags renderers/basic/html-elements.tsx registers (h1…h6, p, a, ul, img, …), plus the per-tag keys that module forwards to the DOM (href, target, rel, title, src, alt, width, height, dateTime, cite). ⚠️ Dated note, 2026-09-27 — that set has since gained code — objectui#10756. At this change TAGS and this arm both named 37 tags; both now name 38, and the parity pin counts 38. The rest of this entry is kept as the reading of this change. - InputShorthandSchema (zod/form.zod.ts) — email / password, the two aliases renderers/form/input.tsx registers onto the input renderer with inputType pinned. inputType is deliberately NOT declared on this arm: the wrapper spreads its own value last, so an authored one is overwritten. - UiCalendarSchema (zod/form.zod.ts) — ui:calendar, the date-picker primitive renderers/form/calendar.tsx registers under exactly that key (skipFallback, because bare calendar belongs to the plugin-calendar view).

.changeset/8632-malformed-picklist-option-loud.md

  • names views/metadata-admin/i18n.ts → packages/app-shell/src/views/metadata-admin/i18n.ts — edited by this change

    Two new strings land in the designer's own en / zh tables — the metadata-admin console owns its strings in views/metadata-admin/i18n.ts and is deliberately outside the ten locale packs (packages/i18n/README.md, "Scope — the engine.* carve-out").

.changeset/8649-detail-renderer-undeclared-keys.md

  • names record-details.tsx → packages/plugin-detail/src/renderers/record-details.tsx — edited by this change

    @object-ui/plugin-detail — the annotation-erasing destructure default is gone from three renderers. record-details.tsx, record-highlights.tsx and record-related-list.tsx each annotated schema correctly and then wrote schema = {} as any. A destructuring default's type joins the annotated property type at the binding, so any erased the annotation for every read site in the file — declared keys and undeclared ones alike read any. No published surface moves: the exported annotations were always correct.

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

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

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

.changeset/8738-object-form-fields-description.md

  • names ObjectForm.tsx → packages/plugin-form/src/ObjectForm.tsx — edited by this change

    The registration declared { name: 'fields', type: 'array' } with no description, so an author had nowhere to read that this key's members are bare field names — a different vocabulary from sections[].fields, which also accepts the spec FormFieldSchema object (identity key field, e.g. { field: 'note', colSpan: 2 }). Moving one of those objects to the top-level fields resolves to no name and is skipped by SimpleObjectForm (ObjectForm.tsx) and by buildFlatFields (flatFields.ts, shared by the drawer/modal presentations). Behaviour is unchanged by this entry; it only adds the description text an author would need to avoid the drop before writing it.

.changeset/8827-kanban-empty-state-settled.md

  • names ObjectKanban.tsx → packages/plugin-kanban/src/ObjectKanban.tsx — edited by this change

    A genuinely empty board still paints DataEmptyState. The reverse regression — "gating on a truthy definition would leave those boards empty forever", named in ObjectKanban.tsx itself — is what the settle contract exists to prevent, and every exit settles: the query succeeding, the query throwing, no readable source, the non-fetch record sources (external, bound and inline data are settled from the first frame), and the schema-only kanban-ui entry, which has no ObjectKanban and therefore no provider and so takes the context's settled default. Lanes, headers, counts and drop targets keep rendering while the rows are in flight; only the claim is withheld.

.changeset/8871-page-node-refuses-breadcrumbs.md

  • names layout/src/NavigationRenderer.tsx → packages/layout/src/NavigationRenderer.tsx — edited by this change

    What was measured, on this branch's base 93127bd6f. Zero readers, with a point-access probe rather than a bare word: on that base \.breadcrumbs scores 0 tree-wide (exit 1) against \.breadcrumb\b's 12 files tree-wide (10 under packages/) as the lit control. At head the same two probes read 16 and 13 and \.breadcrumbs is exit 0 over 4 files — every hit one of this branch's own four files (this changeset, the refusal pin, layout.ts, zod/layout.zod.ts) quoting the probe string, and the pin's own exclusions put head back at exit 1. The base reading is the measurement; the head reading is this branch's echo of it. The bare word would have lied — it also names Sentry's own unrelated concept (app-shell/src/observability/sentry.ts) and appears in two comments listing UI surfaces (core/src/utils/record-title.ts, layout/src/NavigationRenderer.tsx), so a bare probe reports five readers that do not exist.

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

  • names packages/plugin-list/src/ListView.tsx → packages/plugin-list/src/ListView.tsx — edited by this change

    • packages/plugin-list/src/ListView.tsx generates the node as groupBy: laneField. objectDef loads asynchronously, so laneField is undefined on every load until it lands, and stays undefined whenever the object offers no stageField hint and none of status / stage / state / phase. The renderer serves that node; both published faces refused it. - content/docs/utilities/data-objectstack.mdx documents an object-kanban node that is exactly { type, dataSource }, with no groupBy. ⚠️ This one is weaker and is cited for what it is: that fragment is still refused after this change, at RECORD_SOURCE_REQUIRED, because dataSource is not a rung of the record-source ladder. It shows a lane-less board is a documented authoring; it is not a document this change admits.
  • names ObjectKanban.tsx → packages/plugin-kanban/src/ObjectKanban.tsx — edited by this change

    What a lane-less board does, measured rather than assumed. Every schema.groupBy read in ObjectKanban.tsx is a guarded early-return, so the board degrades instead of breaking: with no lane key and no columns it renders an empty board; with bare-string columns it draws those lanes, titled by the raw strings; card moves are inert (persistCardMove and the move callback both open if (!groupBy) return). ⚠️ Every lane-less board holds zero cards — bucketCardsIntoColumns returns before distributing records when there is no lane key — so omitting groupBy is not a way to configure a board, it is a board that groups by nothing.

.changeset/9067-zod-barrel-named-arms.md

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

    • InputShorthandSchema (zod/form.zod.ts) — the email / password shorthand arm. - UiCalendarSchema (zod/form.zod.ts) — ui:calendar, the date-picker primitive renderers/form/calendar.tsx registers, a different component from the calendar plugin view that owns the bare literal.

.changeset/9162-node-slot-guard-class-closure.md

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

    What leaked. {schema.footer && ANGLE-BRACKETS(CardFooter)…ANGLE-BRACKETS(/CardFooter)} does not evaluate to false when the slot is falsy — it evaluates to the slot, and React renders numbers. A node slot's published zod face carries a z.number() arm (nodeUnionOptions, packages/types/src/zod/base.zod.ts), so footer: 0 is legal authored input, and it painted a stray 0 into the DOM. NaN painted three characters. The && also short-circuits, so renderChildren's own if (!children) return null first leg was never reached — which is why the objectui#8908 bridge repair could not cover any of these sites.

.changeset/9174-interpolate-fastpath-trim.md

  • names packages/components/src/renderers/layout/containers.tsx → packages/components/src/renderers/layout/containers.tsx — edited by this change

    At this change page:header's title/subtitle (and the record-title titleFormat) all went through interpolate() in packages/components/src/renderers/layout/containers.tsx. When the template contained a {token} the function collapsed and trimmed whitespace before returning; when it contained no { at all it returned the raw string untouched. A whitespace-only authored title (e.g. ' ') has no token, so it came back unchanged — truthy — and PageHeaderRenderer's {explicitTitle && ANGLE-BRACKETS(h1)} gate drew a blank h1. Because literalTitleText (page.tsx), which decides whether PageRenderer delegates its own heading to the authored header, already trimmed and correctly read "no title", PageRenderer also drew its own implicit heading — two ANGLE-BRACKETS(h1) elements on one document, the broken outline objectui#3434 closed, arriving through a different door.

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

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

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

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

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

.changeset/9659-node-recursion-point-inert-clause.md

.changeset/9880-undrawable-view-kinds-both-legs.md

  • names normalize-list-view.ts → packages/core/src/utils/normalize-list-view.ts — edited by this change

    Compiled both ways rather than argued. With the published pin @objectstack/spec@17.4.0 installed, turbo run type-check --filter=@object-ui/core exits 0 before and after this change. With a spec built from objectstack main injected in its place, the same command reported the TS2353 in normalize-list-view.ts before and does not report it after; the diagnostics that remain on that leg come from other files, are reproduced against the pristine source, and are not this change's.

.changeset/action-keys-warning-text-5642.md

  • names ActionRunner.ts → packages/core/src/actions/ActionRunner.ts — edited by this change

    Both halves of the message's tail had outlived the change they described. It told the author the key was warned about rather than rejected because ActionDef "still carries [key: string]: any" — objectstack#4075 step 3 deleted that index signature, and actionKeys.pin.test.ts pins the deletion in the opposite direction ({ ActionDef: false, ActionContext: true }), while actionDef-closed-surface.test.ts pins that tsc now rejects exactly such a key at the construction site. And it prescribed promoting the key to an explicit field on ActionDef "(packages/core/src/actions/actionKeys.ts)" — that file holds the INVENTORY (ACTION_DEF_KEYS); the interface is in ActionRunner.ts. The wrong pointer had teeth: an author who followed it edited the inventory alone, which is precisely the half-change the pin test reddens on, since it re-derives the inventory from the interface's AST.

.changeset/component-meta-converge-and-deprecate-alias-5893.md

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

    Either side had already moved. base.ts declared eleven keys; the plugin-scoped copy declared nine — the same nine, minus tags and description. So a plugin author typing against the plugin-facing declaration could not write two keys the main surface advertises, and which the runtime validator already accepted: ComponentMetaSchema in zod/base.zod.ts declares all eleven, so two of the three authorities agreed and the plugin-facing one did not. resizeConstraints' six members were identical in both, so the delta was exactly those two keys.

.changeset/console-form-field-spec-one-declaration-5542.md

  • names views/metadata-admin/form-spec.ts → packages/app-shell/src/views/metadata-admin/form-spec.ts — edited by this change

    objectui#5040 was not a missing key. It was that two hand-written descriptions of one contract drifted, and nothing could notice, because each was only ever checked against itself. PR metadata-admin: FormFieldSpec declares dependsOn, one declaration for both halves #5537 converged the two app-shell descriptions into views/metadata-admin/form-spec.ts. A third survived in apps/console: FormPage.tsx declared its own nine-key interface FormFieldSpec, under the same name, in a different package — so the same failure mode stayed fully available.

  • names form-spec.ts → packages/app-shell/src/views/metadata-admin/form-spec.ts — edited by this change

    @object-ui/app-shell therefore re-exports FormFieldSpec from its package root (type-only, erased at build — nothing is added to the bundle), and FormPage.tsx imports it and deletes the local declaration. Reachability is the load-bearing half: a type that cannot be imported is a type that gets retyped, and retyped copies drift. form-spec.ts itself is untouched.

.changeset/console-formpage-visible-predicates-5594.md

.changeset/dashboard-config-aria-retired-5852.md

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

    Both spellings are named verbatim above so a host can grep its own sources: the retired member is aria, on the TypeScript interface DashboardConfig (@object-ui/types, designer.ts) and on its Zod mirror DashboardConfigSchema (@object-ui/types/zod). It declared { label?: string; description?: string }.

.changeset/formfieldspec-dependson-5040.md

  • names views/metadata-admin/form-spec.ts → packages/app-shell/src/views/metadata-admin/form-spec.ts — edited by this change

    No runtime behaviour changes: MetadataField already handed dependsOn through and both widgets already read it. What changes is the type face — it now admits what the runtime has always accepted. The two descriptions are one declaration, extracted to a leaf module (views/metadata-admin/form-spec.ts) that both halves import, because SchemaForm.tsx imports ./widgets.js and a back-edge would close a cycle. SchemaForm.tsx re-exports FormFieldSpec and VisibilityPredicate, so every existing importer is unaffected.

.changeset/issue-9819-operations-ceiling.md

  • names packages/plugin-grid/src/rowCrudAffordances.ts → packages/plugin-grid/src/rowCrudAffordances.ts — edited by this change

    Maintainer ruling of 2026-09-18, ruling batch Complete component documentation coverage for all 76 platform components #162 item 1, letter A, on objectui#9819. rowActions' other ruled power — narrowing INSIDE the ceiling, so naming only edit would withhold an allowed Delete — is NOT part of this change; the section headed "operations is the ceiling" in packages/plugin-grid/src/rowCrudAffordances.ts records what blocks it.

.changeset/layout-default-jsdoc-7361.md

  • names flex.tsx → packages/components/src/renderers/layout/flex.tsx — edited by this change

    The published @default documentation on two layout.ts members now matches the value the renderer actually applies. ContainerSchema.maxWidth documented 'lg' while container.tsx applies schema.maxWidth ?? 'xl', and the shared FlexLayoutProps.align documented 'center' while flex.tsx applies schema.align || 'start' and stack.tsx applies schema.align || 'stretch'. The renderers are unchanged — they are the authority for what runs — so only the docblocks moved; align now states both consumers in prose instead of carrying a single @default, because one member shared by two deliberately divergent component types cannot have one correct default.

.changeset/layout-direction-default-jsdoc-7734.md

  • names flex.tsx → packages/components/src/renderers/layout/flex.tsx — edited by this change

    The published @default documentation on FlexLayoutProps.direction no longer states a value that only one of its two consumers applies. The member is declared once (objectui#6151) but flex.tsx reads schema.direction || 'row' while stack.tsx reads schema.direction || 'col' ("Default to column for Stack"), so the single @default 'row' was correct for flex and wrong for stack — whose own defaultProps.direction is 'col'. The renderers are unchanged — they are the authority for what runs — so only the docblock moved: direction now names both consumers in prose, the same remedy objectui#7361 applied to the sibling align. justify is shared by the same two consumers and both read || 'start', so its tag is correct and stays: the criterion is a DIVERGENT shared member, not a shared one.

.changeset/list-user-actions-collision-5398.md

  • names ListView.tsx → packages/plugin-list/src/ListView.tsx — edited by this change

    The harvest now reads the object block only. Both userActions read sites in ListView.tsx carry a comment naming the collision, and __tests__/ListView.userActionsCollision.test.tsx pins each clause of it: the two shapes, a producer that manufactures the view one, the harvest's blindness to it, and the projection that must keep the object's operand with a toolbar block — or an empty block — present on the view.

.changeset/listview-comment-pair-4559.md

  • names ListView.tsx → packages/plugin-list/src/ListView.tsx — edited by this change

    Two comment corrections in ListView.tsx (objectui#4559, objectui#4966). No runtime behaviour changes and the emitted bundle is byte-identical; the published .d.ts does change, which is why this is a patch rather than an empty frontmatter.

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

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

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

.changeset/plugin-form-readme-classname-quantifier-5131.md

  • names packages/components/src/renderers/form/form.tsx → packages/components/src/renderers/form/form.tsx — edited by this change

    README.md's "Not a FormField key" table said a field-level className is "read on exactly one pseudo-field, type: 'section-divider'". That quantifier holds only for the renderer's explicit read — className={fp.className} on the section-divider branch of packages/components/src/renderers/form/form.tsx. The same renderer forwards every key it did not destructure, and className is not among the names taken off the field config, not among the ones stripRendererOnlyProps removes, and so rides {...fieldProps} into renderFieldComponent, whose built-in input branch spreads it onto ANGLE-BRACKETS(Input). A field-level className therefore lands visibly on ordinary built-in controls, and a reader taking "exactly one" literally concludes the opposite of what the code does (objectui#5131).

.changeset/record-picker-label-placeholder-i18n-5637.md

  • names renderers/layout/containers.tsx → packages/components/src/renderers/layout/containers.tsx — edited by this change

    KNOWN GAP, unchanged by this release: the sibling label read sites in renderers/layout/containers.tsx compose translateLabel(pickLocalized(…), language), and that second helper is not applied here — translateLabel and its KNOWN_LABEL_DICT are module-private to that file. Only the locale-map resolution lands in this change; a plain-English string label is still rendered verbatim in every language, exactly as before.

.changeset/retire-components-action-param-dialog-5685.md

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

    • import { ActionParamDialog } from '@object-ui/components' — no drop-in replacement is published. The surviving implementation is @object-ui/app-shell's ActionParamDialog (src/views/ActionParamDialog.tsx), rendered by app-shell's action runtime (useConsoleActionRuntime, RecordDetailView) rather than exported standalone. A host that needs its own param form builds on @object-ui/fields' shared field widgets (resolveFormWidgetType / getLazyFieldWidget, ADR-0059) — the same seam the surviving dialog renders through.

.changeset/text-input-description-aria-describedby-5735.md

  • names renderers/form/form.tsx → packages/components/src/renderers/form/form.tsx — edited by this change

    Before this the paragraph and the input were siblings with no programmatic relationship: a screen reader moving to the field announced the label and the value and never the helper text. The label half of the same block was already wired (htmlFor against the input's id), which is what made the gap specific to description rather than a general absence of a11y wiring — and the identical key authored on a field INSIDE renderers/form/form.tsx has been announced all along, so one authoring key behaved two ways depending on which container the author reached for. It no longer does.

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

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

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

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

Compared the checked-out tree with 733fd5ac6 (merge-base with origin/main): 53 file(s) changed outside .changeset/, read against 1639 pending declaration(s) that publish a body (2226 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3096.1 KB 3104.5 KB
Main entry chunk (gzip) 148.6 KB 350 KB
Entry file index-CXe0iCYr.js —
Status PASS —

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.58KB 6.17KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.70KB 2.23KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.52KB 3.45KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 557.59KB 133.60KB
core (index.js) 9.93KB 3.94KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 226.46KB 63.00KB
fields (index.js) 261.01KB 66.28KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.32KB 11.09KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 51.96KB 14.83KB
plugin-charts (index.js) 83.99KB 22.86KB
plugin-chatbot (index.js) 197.67KB 46.90KB
plugin-dashboard (index.js) 136.93KB 36.48KB
plugin-designer (index.js) 215.03KB 44.21KB
plugin-detail (index.js) 233.48KB 61.79KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 161.21KB 41.41KB
plugin-gantt (index.js) 170.35KB 42.19KB
plugin-grid (index.js) 228.33KB 62.59KB
plugin-kanban (index.js) 48.43KB 15.11KB
plugin-list (index.js) 115.86KB 28.64KB
plugin-map (index.js) 22.90KB 7.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.17KB 12.20KB
plugin-timeline (index.js) 31.00KB 9.09KB
plugin-tree (index.js) 11.21KB 3.89KB
plugin-view (index.js) 88.55KB 22.21KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 119.16KB 39.05KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.03KB 1.86KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 7.50KB 3.05KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.16KB 2.71KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 18.27KB 6.22KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 3.83KB 1.49KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 17.15KB 6.32KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.27KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 2b3d2061a270b8c626c6fe7016b9587403ed295d

Isolated adversarial re-derivation of PR objectui#10914 (card objectui#10803, batch 6; claim 5864334310, amendment 5860244997, rulings 5861129870 / 5861311219 / 5861900779, release note 5863776648). Read: the card and all 29 comments, PRs objectui#10854 / #10869 / #10875 / #10892 and their six contract-review records, this PR's body, its 92-file diff (git diff origin/main..., +175 / −140, file set equal to REST), the head's check-runs, and the trees at 2b3d2061a, the branch point 9f0c84a44 and origin/main 733fd5ac6. The dev report 5865040563 was treated as a claim; every figure below is my own measurement unless marked REASONED or NOT MEASURED.

CI on the head, final poll: 43 check-runs, 40 success, 3 skipped (coverage shards, dependabot), 0 failed, 0 in progress, polled until settled. REST mergeable_state: clean. Draft, assigned os-steve, one commit whose trailers are the model-free Claude and the session URL.

① Derived judgments

Premise, re-read over REST. The 23 family numbers: 23 of 23 answer 404 on /issues/N; controls objectui#10533, #7714, #8236, #7735, #8648, #9880 answer 200. The 19 sister-repo numbers in objectstack: 16 answer 200 with the subject each sentence cites (#11289 record:details sections, #11662 / #12616 / #12718 / #13337 / #13733 / #14274 / #15948 / #20160 are the PRs named, #13632 the reference refinement, #13855 the field-grouping decision, #13906 computeExecCtx, #14945 the refused-flow card, #15469 the gantt/tree passthrough card, #17493 the predicate-slot residues, #20051 the options-bag door, open); #13033, #13413 and #13086 answer 404 as issues and as pulls, #13086 in objectui too. objectstack#14026 answers 301 to objectui#10102, whose body names GET /api/v1/meta/mapping and targetObject, the hypothesis ecf14190e's message records. #3391: objectui#3391 is the unrelated record-header api card; objectstack#3391 is the apiMethods whitelist card, and objectstack#3720's own title reads "#3391 遗漏的第四个面". No new family member: the distinct objectui#N in the two in-scope classes at 9f0c84a44 less those at 6c3ad7c80 are exactly the 24 the body lists; 24 of 24 answer 200.

Shas. All 28 objectui shas the diff and its mapping name (the 15 landings plus 40f34b4ba, ecf14190e, 7550728a6, e0f820246, b809375ac, 05a49f2ee, 8a7e09fa1 and the four own-card landings) are ancestors of origin/main 733fd5ac6 (git merge-base --is-ancestor exit 0 each) and rev-parse --short=9 returns the same 9 characters. The objectstack checkout here is shallow, so its shas were read over REST: c459da6bc, 89448a52b, 2ebfe7e9f, 39404f3d9, 9c270bba0 and cca699149 each exist, and compare/SHA...main answers behind_by 0 for each (ancestors of objectstack main); 2c1011b01, 6a4aec71d and 66e266c93 are ancestors locally.

Mapping, sampled adversarially (16 of 23 family rows, all 3 stand-ins, #3391), each against git show and the adding commit of the changeset:

Every rewritten sentence read in pairs still reads true and grammatical. No sha is cited for something its commit does not carry (the #5738 / MarkdownSchema class of batches 3 and 4 does not recur).

Runtime text. TypeScript 6.0.2 createSourceFile + createPrinter({ removeComments: true }) over the 53 touched .ts / .tsx files at 9f0c84a44 and at the head: 52 of 53 prints identical, 0 parse diagnostics; form.zod.ts is equal once the one substitution (InputSchema.wrapperClass's describe loses " (objectui#8072)", matched once) is applied to the base print. Lit controls: re-spacing a comment leaves the print unchanged, editing a string moves it. The old string occurs at the head only on the source line and as the quote in the new runtime changeset; no test reads wrapperClass's description, no doc quotes it. Dropping the pointer, not replacing it, is what amendment Q1 = A requires.

Anchors. Two instruments of my own. (a) All 150,373 distinct string and 9,298 regex literals in the tracked test, script, .github and vitest.config files (git grep -o, ERE), filtered to those present in the diff's removed lines with two lines of context (1,717 strings, 657 regexes), then counted per changed file's hunk text at base and head: 96 distinct literals drop, every one generic (objectui#, objectui#1, \d+, #\d+, objectui#\d+|objectstack#\d+, [Mm]easured, carries, name, character classes). The objectui#\d+ scanners live in tests that assert over their own fixtures (ActionRunner.disabledGate, registry-inputs-spec-parity, the check-* script tests). (b) A phrase grep for the removed wording ("seam 2 of objectui", "measured NOT GATED", "carries that census", "objectstack PR", "framework #13906", "#13337/#13086", "spec #15469", "upstream #11289", "PR #13413", "the card records as", "silent wrongness objectui", "17.3.0's #13632", "folded into objectui#7735", "objectui#8127 installed", "objectui#10120 taught", the describe string): the survivors are test docblocks, test titles, one test message string, packages/plugin-tree/README.md and content/docs, none an assertion over a changed file. No test file is in the diff, and the eight test shards are green on this head. "Nothing to move" holds.

Held proofs. C4 as above. The frontmatter block of all 37 edited changesets is md5-identical at 9f0c84a44 and the head (37 of 37); every one of the 37 is present in .changeset/ on origin/main (pending); the two new files carry the frontmatters the body states.

Census, re-run as printed. The 23-number instrument: 104 at 9f0c84a44, 104 at origin/main 733fd5ac6, 0 at the head; 0 on git merge-tree --write-tree origin/main head (tree 2096df60c). Unfiltered: 111 at the base, 7 at the head, all seven live objectstack#14026 lines. The hidden line is real: the filter drops 9943-viewtype-totals-page-row-retired.md:6, whose objectui#8127 sits beside an objectstack# token, so the true population is 105: 28 changeset lines in 26 files and 77 src lines in 42 files, and the per-number line / file counts equal the body's table for all 23 rows. Lit control objectui#7714 at the head: 17. C0 as printed: 984 distinct at the base, 966 at the head; above 10900 the base holds the 18 numbers plus the five CSS colours, the head the five colours only; the 19 bare numbers: 28 lines in 23 files at the base, 0 at the head. Out of scope at the head (the 23 numbers, filtered, whole tree): tests 94 lines / 36 files, .github 5 / 1, apps/console 2 / 1, vitest.config.mts 1 / 1, scripts 0, CHANGELOG.md 0, the body's figures. For the 19 C0 numbers under the printed lookbehind instrument I read 13 test lines in 10 files plus the one plugin-tree/README.md line; the body says 12 test lines in 10 files (see ③).

Clause-②: no is honest. The comment-stripped syntax of 52 files is byte-equal to the base and the 53rd differs by one description literal; no key, path, accept set, refusal, code or type moves.

② Semver level

  • .changeset/10803-sixth-batch-runtime-strings.md, '@object-ui/types': patch: right for a zod description string, the level batches 2 to 5 declared for the same class; @object-ui/types is in the fixed group. Its sentences are true: the string ends with a pointer to a 404 (measured), the pointer is dropped rather than replaced, the quoted resulting text equals form.zod.ts:248 character for character, and "every document that parsed before parses the same way" is the C4 proof.
  • .changeset/10803-dead-citation-sweep-sixth-batch.md, empty frontmatter: right for comment-only edits. Its 15 named packages equal the 15 packages/* roots in the diff (measured); "none of these comment edits changes a code or type token" is C4; the objectstack#3391 and sister-repo-commit sentences describe what the diff does; the frontmatter sentence is (①). "Some of these docblocks reach the emitted .d.ts and .js": REASONED, as in the earlier batches.
  • The 37 edited pending changesets: no sentence made false or ungrammatical; the 8458 list keeps one labelled and one unlabelled item, both true. No changeset declares major.

③ Boundary flags

Implemented-by: claude/issue-10803-dead-citations-sixth-batch
Reviewed-by: session_01DuWo5bdP9SdVebamn99GGk

VERDICT: PASS


Generated by Claude Code

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants