docs(plugin-kanban): stop naming which face declares which kanban key (objectui#9726) - #9740
Conversation
Two docblocks in `ObjectKanban.tsx` asserted in the present tense which published face declares which key. Measured per key against the block of `ObjectKanbanSchema` extracted per symbol from both faces, three of the five they name are declared today (`columns`, `filter`, `cardTitle`) and two still ride `BaseSchema`'s index signature (`swimlaneField`, `grouping`). Repair shape: DELETE the per-key declaration inventory rather than re-date it. A source comment publishes nothing and freezes no reading, so there is nothing a dated construction protects; the inventory restates what `tsc` already answers off `ObjectKanbanSchema`, and its measured half-life in this tree is hours, not releases. Each site keeps a dated, past-tense retirement notice naming what it used to claim and when each half went false, so the two claims that are still true are not swept away with the three that are not. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UanLVj6xvbS6puBCewLr8L
…ng nothing `scripts/check-changeset-presence.mjs` scores any edit under a released package's `src/` as owing a declaration, comment-only included. This is the empty-frontmatter form the gate names as its explicit exemption: no published behaviour moves. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UanLVj6xvbS6puBCewLr8L
|
changeset-claim-re-read
|
✅ Console Performance Budget
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
Size Limits
|
… entry, and the third copy of the filter comparison The count this PR removed from the docblock was still pending one step downstream, in `.changeset/7322-object-kanban-component-props.md`, which publishes verbatim into the CHANGELOG at the next release. Re-measured by binding -- property reads off the component's own `schema` prop, with `resolveKanbanTitleField`'s same-named parameter excluded by region -- the read set is 14 today and was 14 at that entry's own measurement commit `6ca6e12a7`: its bullet list omits `navigation`, which its own "Casts this removes" section names as a read. So "thirteen" was one short when it was written, not rotted afterwards. It is not replaced with 14; both cardinals are retired with a dated note in the register the entry already uses. The entry's frontmatter is byte-identical to the merge-base (sha256 over the fence block, with the whole-file hash as the lit control that the hash is not stuck). Prose only. Same commit repairs a third copy of the born-false comparison inside `ObjectKanban.tsx`: the `navigation` read site said this key rides `BaseSchema`'s index signature "exactly as `filter` does", written in the same commit as the site-2 sentence and false for the same reason. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UanLVj6xvbS6puBCewLr8L
✅ Console Performance Budget
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
Size Limits
|
Fixes #9726
Clause-②: no
Session for this work:
https://claude.ai/code/session_01UanLVj6xvbS6puBCewLr8L(written as prose, because an edited body loses the link form of the footer).Repair shape — decided in one line before either site was touched
DELETE the per-key declaration inventory rather than re-date it. A source comment publishes nothing and freezes no reading, so the dated-reading construction objectui#9713 needs for a
.changesetbody protects nothing here; the inventory restates whattscalready answers offObjectKanbanSchema(AGENTS.md #9 — leave the count to the instrument), and its measured half-life in this tree is hours (timeline below), so a re-dated restatement only schedules the next rot.⛔ What is NOT deleted: each site keeps a dated, past-tense retirement notice naming what it used to claim and when each half went false. That is how the two claims that are still true survive instead of being swept out with the three that are not.
Per-key verdict, re-derived on this branch base
580e5dd94ObjectKanbanSchemain each published face (packages/types/src/objectql.tsand itszod/objectql.zod.tstwin), extracted per symbol. ⛔ Not a grep over the file: the indentation is shared by every schema there, so a file-wide grep answers about the FILE.objectql.tsobjectql.zod.tscolumns:3672declared:2087declaredfilter:3750declared:2103declaredfilteralways has」cardTitle:3786declared:2129declaredswimlaneFieldgroupingobjectName(:3420/:2071) andgroupBy(:3525/:2081) are FOUND ⇒ a declared key is visible to it.zzNoSuchKeyEverreads ABSENT in both blocks ⇒ the two ABSENT rows are a verdict, not a dark instrument. Two zeros on one instrument would have been a broken instrument.BaseSchemastill carries[key: string]: any(packages/types/src/base.ts:523), so the two surviving rows have a live mechanism behind them.KanbanSchemais gone frompackages/types/src/: a grep for its exported declaration returns 0, exit 1, with a [LIT CTRL] on the same instrument and corpus — the same grep forObjectKanbanSchemareturns 2 hits, exit 0.Timeline — ⭐ the claims are three different defects, not one
The repository was deepened (
git fetch --deepen=800; the checkout is shallow, and alog -Son a shallow tree answers 0 without meaning it). Every ancestry leg below isgit merge-base --is-ancestorwith a control leg at least as deep on the same target, both exit codes read.4fa0eb9c42026-09-10T00:34Z (objectui#8308)adf5812782026-09-10T09:59Z (objectui#8802)cardTitle… through the index signature」4fa0eb9c42026-09-10T00:34Z78a9c67442026-09-17T18:36Z (objectui#9606)filteralways has」adf5812782026-09-10T09:59Z (objectui#8802)ee4d19f6c2026-09-09T07:51Z (objectui#8174) — 26h08m EARLIERfilterdoes」 (thenavigationread site)adf5812782026-09-10T09:59Z — the same commitcolumnsrides the index signatureadf5812782026-09-10T09:59Z8693b85692026-09-10T16:32Z (objectui#8913)cardTitlerides the index signatureadf5812782026-09-10T09:59Z78a9c67442026-09-17T18:36ZswimlaneField,groupingadf5812782026-09-10T09:59Z6ca6e12a72026-09-06⇒ this is what decided the shape. The shortest-lived rotted claim was false 6 hours 33 minutes after it was written, by a pull request that was in flight while it was being authored. A re-dated inventory would be a promise to lose the same race again.
Site 3 — the third copy, repaired in place
The
navigationread site in the same file said the key ridesBaseSchema's index signature 「exactly asfilterdoes」. That is the site-2 sentence a third time, written in the same commit, false for the same reason. It is the card's own defect class in the card's own declared file, the repair shape was already fixed, no other branch holds this file, and it adds no verification surface — so it is repaired here rather than filed, with the comparison retired and the reason dated. Everything else in that comment was re-measured and stands:navigationis absent fromObjectKanbanSchema's member list and fromBaseSchema's, so the index-signature claim aboutnavigationitself is true.The pending copy —⚠️ the count was still downstream
.changeset/7322-object-kanban-component-props.md:39-40still carried 「reads thirteen keys offschema」 and 「the two TOGETHER cover twelve」, undated, in a body that otherwise dates every reading. That entry publishes verbatim into the CHANGELOG at the next release, so this is the card's own mechanism one step downstream, with a closing window.A second instrument, built so it does not have the defect the first one had. The earlier census scoped by identifier NAME and so conflated the component's
schemaprop withresolveKanbanTitleField's same-named parameter. This one scopes by binding:ObjectKanban.tsxwith comment spans AND string/template literals blanked by the repo's own scanner (scripts/js-comment-mask.mjs,scanSource), so a key-shaped token in prose or in a string cannot be read as a property access.schemawhere that identifier is the component's prop; the one shadowing binding in the file is excluded by region, and the two keys the resolver reads are re-admitted only because the component measurably hands it its ownschema(2 call sites).09121e4ee)6ca6e12a7)resolveKanbanTitleField(schema)call sitesschemaobjectNameandgroupByare in the set ⇒ real reads are visible.highlightFields, a property read in this same file off a DIFFERENT receiver, is not in the set although its token is present in the masked source ⇒ the instrument discriminates by receiver, not by name.cardTitle/titleFieldenter it from the shadowed binding ⇒ the exclusion is doing work, and the earlier census got the right total by the wrong route.⇒ 「thirteen」 was one short on its own measurement date: the entry's bullet list omits
navigation, which the entry's own 「Casts this removes」 section names as a read ((schema as any).navigationthen,schema.navigationnow — the cast spelling is why a-Ssearch for the dotted form dates it later). Born false, ⛔ not rotted.Disposition — ⛔ the new number is NOT written in. The lead sentence now names WHERE the read set is derived (the bullet list that follows it, which is the set), and both cardinals are retired by a dated note in the register the entry already uses. A cardinal in a body that publishes verbatim is derived once and never again. ⛔ The bullets themselves are left exactly as measured on 2026-09-06 — adding⚠️ The nearby 「it drops four declared reads」 is left alone deliberately: it is anchored to the bullet that enumerates those four, one line above it, so it is not an undated free-floating cardinal.
navigationto them would silently rewrite a dated reading, which is the thing objectui#9713 rules against.Two byte-level proofs
Frontmatter untouched (
check-changeset-overwrite.mjs's documented case 2):580e5dd94bf9e59f9…bf9e59f9…— identical9f62b265…2a495ab9…— differs, so the hash is not stuckThe gate agrees on its own terms:
declared at base: @object-ui/plugin-kanban: minor·declares now: @object-ui/plugin-kanban: minor.Nothing executable moved in⚠️ Recorded because the first projection of this proof reported a false alarm:
ObjectKanban.tsx: the code-only projection (comments removed by the repo's own scanner, blank lines dropped, trailing space normalised) is 639 lines, sha256fd6b7487…, identical at580e5dd94and at this head, while the raw files differ [LIT CTRL] and the projection is non-vacuous [CTRL] (it contains thenavigationread line itself).stripCommentskeeps every newline, so changing the NUMBER of comment lines moves the projection's length without moving any code. The length reading was the wrong projection, not a moved byte.Gates on head
09121e4ee— exit code captured to disk before any pipepnpm --filter @object-ui/plugin-kanban type-checktsc --noEmit && tsc -p tsconfig.test.json, both legs clean (dependency closure rebuilt first, so the compile-time suite judged real.d.tsoutput)pnpm exec vitest run packages/plugin-kanban/(repo-root form, per AGENTS.md)Test Files 57 passed (57)·Tests 365 passed (365)node scripts/check-changeset-overwrite.mjsnode scripts/check-changeset-presence.mjsdeclares 1 changeset(s)— EMPTY frontmatter, the gate's own named exemptionpnpm check:changeset-claimspnpm check:pending-changeset-literalsNo test source names a pending changesetpnpm check:control-bytesOK (scanned 7827 tracked text file(s); skipped 85 binary), plus a direct control-byte scan of both changed files (zero hits)pnpm check:new-line-citationsVERDICT new-cross-file-line-citations: 0 new citation(s)node scripts/check-governed-queue-guard.mjs --test(all three changed paths)NOT GOVERNED — 3 path(s) checked against 5 governed surface(s); none matchedpnpm exec eslinton the changed pathsObjectKanban.tsx, 0 errors, none on a touched line; the other 2 areFile ignored because no matching configuration was suppliedfor the two.mdpathsBoth heavy runs went through the shared verify lock (
OS_VERIFY_LOCK_SLOT=objectui-9726), each printingVERDICT command-exit 0; the second build waited 3m21s behind another holder. The working tree was byte-identical to09121e4eewhen they ran (git statusempty). The repo-widepnpm lintand the full suite are CI's.Serial constraint — re-taken against the live branches before this write
.changeset/7322-object-kanban-component-props.mdandpackages/plugin-kanban/src/ObjectKanban.tsxappear on nobody else's list. Merge-queue pull requests objectui#9734 (plugin-detail+ three other changesets) and objectui#9735 (plugin-detail,plugin-grid,typestests + its own changeset) were read file by file; cards objectui#9629 and objectui#9365 have no open pull request yet, and their local branches were read directly — objectui#9629 holdspackages/types/src/objectql.ts,.changeset/8801-*,.changeset/9629-*and a types test; objectui#9365 holdspackages/types/src/base.tsand a components test. Disjoint at file level. ⛔ Release pull request objectui#5400 was not touched, and neither were the other pending entries that nameObjectKanban.tsx.Why no new test
After the repair there is no per-key claim left in any of the three sites to pin, and a census that forbade one from coming back would redden on the retirement notices that quote them. The pins this file already owes are unchanged and green: the objectui#8308 source census masks comments, so a comment edit is invisible to it (its two anchors, the
KanbanTitleFieldSourcedeclaration and theresolveKanbanTitleFielddefinition, are untouched).Out of scope, noted and ⛔ not filed
packages/types/src/objectql.ts'scardTitledocblock records that the zod-mirror-parity ratchet does not hold the optionality agreement between the two faces, naming objectui#9711 — already the live sibling card objectui#9729's surface. Carrier: objectui#9729.Generated by Claude Code