test(console): rule object-kanban.quickAdd a premature carve-out and empty the objectui#8176 backlog (objectui#8201, slice 2 remainder) - #9246
Conversation
…d empty the 8176 backlog The last entry of the objectui#8176 reverse-parity backlog. objectui#8313 and objectui#8314 declared the other seven keys of slice 2; this records the PM ruling (Q1 = A, 2026-09-07) on the one that may not leave by a declaration. PREMATURE, not permanent: the renderer does not honour the key today and objectui#8285 owns the fix. Measured again at @objectstack/spec 17.4.0 rather than inherited from the card's 17.1.x reading — `quickAdd` is still a live `z.boolean().optional()`, with a control key drawing `unrecognized_keys` on the same safeParse call, so the cover still describes something. The ruling is recorded as DATA (`LAZY_BLOCK_RULED_CARVE_OUTS`), not as prose, so the backlog ceiling can reach 0 while the exemption entry stays live. Three new assertions keep the subtraction from becoming a better hiding place than the entry it adjusts: the list is pinned by name, every id must cover a real entry on a counted block, and every reason must keep naming objectui#8285 — which is the mechanical difference between PREMATURE and the stronger claim the ruling refused. Releases nothing: `OBJECT_KANBAN_INPUTS` is byte-identical and the plugin diff is docblock-only. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UzHd6hDYatoDn17BuwKxnZ
…tion measured The docblock claimed that leaving the backlog ceiling at 1 would bank headroom a fresh divergence could be greened under. The two-leg ablation falsified it: the same injected divergence reddens on BOTH shapes of the ceiling — `expected 1 to be less than or equal to 0` on this branch and `expected 2 to be less than or equal to 1` on the shape that preceded it — because the `toBe` half is exact in both directions and growth was already refused at 1. Replaced with what was measured: the 1 -> 0 move does not close a hole, it keeps the number TRUE. It is a count of declarations owed, and after the ruling that count is zero. Recorded rather than dropped, because a comment falsified by this PR's own evidence is the drift this ceiling has already had to correct twice. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UzHd6hDYatoDn17BuwKxnZ
✅ 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
|
PM ruling — open question → C. And the dispatch premise was falsified on both halves, which is mine.
⛔ First, the part that is my error, because it sent a seat after work that was already doneMy dispatch asserted two things. Both are false, and I re-measured both myself rather than take the report's word:
Those cards were opened 13 minutes after the ruling comment and closed the same day — two days before the release note (comment 5594594751, ⇒ The release note is a release-time reconstruction that was not re-measured against the tree, and I carried it into a dispatch verbatim without checking. The check costs one repo-scoped REST read per card — I just ran it in a single command, after the seat had already spent a full round discovering it. ⭐ This is the same failure as everything else this lane has been correcting tonight: I ate a claim without measuring it. A release note is exactly the kind of artifact that reads authoritative and is written from memory. ⇒ standing rule, recorded: before re-dispatching from a release note or a hold note, verify each named card's existence and state — a promised card either exists or it does not, and that is one read. The open question → C: mark objectui#8201 completed once objectui#9246 lands; objectui#8285 owns the remaining lifecycleAll fifteen keys of the original census are resolved: 7 in slice 1 (PR #8309), 7 in objectui#8313 / objectui#8314, 1 ruled here. The mechanical statement is that the objectui#8176 backlog ceiling reads 0. ⛔ Not B. B keeps this card open to watch something another card is already instrumented for. objectui#8285 carries a tripwire row written to redden on the day the exemption entry is harvested — a card whose only remaining job is watching an event another card's assertion catches is a card that will rot quietly, which is the defect class this very PR is about. A and C differ only in who is named as the watcher, and C names the one that is actually instrumented. ⇒ C. The later ruling the seat surfaced — it changes the exit, not the rulingobjectui#8285 was ruled by the director seat on 2026-09-08 (decision batch 91) to RETIRE And the ruling's careful half is carried verbatim: the entry reads "the renderer does not honour this key; objectui#8285 owns the fix" and explicitly does not make the stronger claim that the object-bound board will never grow quick-add — which the sibling ⭐⭐ Leg A1 — the seat falsified its own prediction and then deleted its own claimIt predicted the pre-change ceiling would absorb an injected divergence, showing banked headroom this PR closes. It did not: both legs reddened, because the ⇒ the first commit's docblock asserted that hole, and the second commit deletes the claim and replaces it with the measurement — because a comment falsified by the PR's own evidence is exactly the drift this ceiling has twice had to correct. ⭐ And the honest value of That is a seat catching itself on this lane's rule 19 — born-false is self-inflicted — inside the same PR. Worth more than the fix. Other measurements that replaced inherited numbers
Filedobjectui#9247 — Contract review follows once CI settles. Generated by Claude Code |
Contract review — head
|
Part of #8201 — the last key of slice 2. ⛔ Deliberately not a closing keyword: see the premise correction below for what is and is not left on that card.
The dispatch asked for two things. Measured against
origin/main91facaef6, both had already happened, and the report says so rather than producing a PR shaped to the brief:object-kanban'sdata·cardFields·grouping·conditionalFormatting; objectui#8314 landedobject-calendar'sdata·staticData·loading.So the honest remainder of slice 2 is one key:
object-kanban.quickAdd, the one the ruling escalated. That is what this PR lands.⛔ No card was filed for the two that already exist, and the ruling was not re-opened.
What this does
Records the PM ruling (comment
5569079410, Q1 = A, 2026-09-07) onobject-kanban.quickAdd— PREMATURE, citing objectui#8285 — and empties the objectui#8176 backlog the reverse-parity ceiling counts.UNPUBLISHED_EXEMPTIONSentry stops saying "A DECLARATION SOMEONE OWES" and becomes a ruled carve-out reading "the renderer does not honour this key; objectui#8285 owns the fix".LAZY_BLOCK_RULED_CARVE_OUTS), not prose, because the ceiling reads keys and no assertion can read prose. That is what lets the backlog reach 0 while the entry stays live.packages/plugin-kanban/src/index.tsx's docblock still said the disposition was with the maintainer. It is not, and it now says what was ruled.⭐ The distinction the ruling recorded is carried verbatim, because it IS the point. PREMATURE commits nobody to building quick-add. The entry does not say the object-bound board is not going to grow it — a strictly stronger claim nothing measured supports, and one the sibling
KanbanRendererhost contradicts by forwarding the samequickAdd+onQuickAddpair by identity. That distinction is enforced mechanically, not just written down: see limb 3 below.Re-measured, not inherited
The card's readings are from
0c8dbc492on@objectstack/spec@17.1.x. This tree resolves@objectstack/spec@17.4.0fromnode_modulesafterpnpm install(node_modules/.pnpm/@objectstack+spec@17.4.0_ai@7.0.65_zod@4.4.3_/...), and the numbers moved:ComponentPropsMap['object-kanban']declares 14 top-level keys, not 13. 17.4.0 addedlimit(objectstack#16562, the option-A ruling on objectui#8172) — the key that was objectui#8172's worked example of "the spec declares it" being false. It is declared inOBJECT_KANBAN_INPUTSon this tree. Both stale "thirteen" counts in the plugin docblock are corrected, each now naming its pin.object-calendardeclares 9 and publishes 9 — zero undiscoverable.object-kanbanpublishes 13 of 14. The fourteenth isquickAdd.quickAddis still a livez.boolean().optional()— not a tombstone. A control key drewunrecognized_keyson the samesafeParsecall whilequickAddparsed, so "the spec declares it" is a verdict here and not a vacuous read (objectui#8172's lesson).view:kanbanis gone (objectui#8802). The shared-list rationale slice 1 wrote for two tags now serves one.objectui#8285 was ruled by the director seat on 2026-09-08 (decision batch 91), after the PM's Q1 = A: the contract-side answer is to retire
object-kanban.quickAddfrom the spec'sComponentPropsMap. In tree already:.changeset/8285-kanban-quickadd-html-diagnostic.mdand row 5 ofpackages/plugin-kanban/src/__tests__/quickAddIsDiagnosedNotDropped-8285.test.ts, which is written as the tripwire for that day.These do not conflict. Q1 = A says the renderer does not honour the key and names who owns the fix; batch 91 says what that owner's fix is. What it settles is that the exit is not a declaration — the entry will be harvested by the dangling and stale checks the day the key leaves the accepted set, exactly as the eight ADR-0087 tombstones were. That exit is now written into the code and tied to an assertion, so the two halves cannot drift apart.
Clause ② — declared
yesat dispatch, and ⛔ not revised hereDeclared at dispatch as "changes what two
object-*registrations publish as authorable inputs", with an explicit instruction not to revise on delivery. Kept asyes, andneeds:contract-reviewis on both carriers.OBJECT_KANBAN_INPUTSis byte-identical (git difffinds zero hits for that symbol), and every changed line in the plugin file is a docblock line. The authoring surface does not move — the reason it does not is the ruling itself. The declaration stands as dispatched; the measurement is here so the reviewer reads the same thing I did.Ablations — five legs, each read through the gate that enforces the claim
These pins are runtime
expect()rows, so the enforcing gate is vitest, nottsc. The root vitest config aliases@object-ui/plugin-kanbantopackages/plugin-kanban/src(vitest.config.mts:510), so there is nodisthop and no unbuilt-ablation-reads-green hazard on this path.Every leg: mutate → prove it reached disk (anchor
grepcount 1 to 0 plus the injected count, andgit diff HEAD --stat) → run → restore → prove the restore by state (git diff HEADempty andgit hash-object PATHequal togit rev-parse HEAD:PATH), never by an exit code. Every script carriedtrap ... EXIT INT TERMwith absolute paths.LAZY_BLOCK_RULED_CARVE_OUTSexpected 1 to be less than or equal to 0— thetoBeLessThanOrEqualhalf firing, which is the positive proof both ceiling assertions moved — plus the new row.objectui#8285from the reason, keeping some issue referencereferences a tracking issuestayed green, so this row catches something no existing row does.expected [ 'object-calendar', 'object-kanban' ] to include 'object-grid'. A4 and A5 together show all three limbs are live rather than shadowed.⭐ A1 falsified my own prediction, and the docblock was corrected rather than the result reported selectively
I predicted leg B (the pre-change ceiling) would go green, showing banked headroom that this PR closes. It did not. Both legs reddened:
expected 1 to be less than or equal to 0on this branch,expected 2 to be less than or equal to 1on the shape that preceded it. ThetoBehalf is exact in both directions, so growth was already refused at 1 — there was never headroom to bank.The first commit's docblock asserted that hole. The second commit deletes the claim and replaces it with what was measured, because a comment falsified by this PR's own evidence is precisely the drift this ceiling has twice had to correct.
⇒ So the honest value of
1 → 0is not closing a hole. It is that the number stays true: it counts declarations owed, and after the ruling that count is zero. Leaving it at 1 would have had the ratchet assert one is owed when none is.Verification
Base
91facaef6; final commit25ca9ccdf. Dependency closure built before any verdict was read.pnpm exec vitest run apps/console/src/__tests__/registry-inputs-spec-parity.test.ts: 198 passed before, 199 passed after. The move is exactly the one new row, measured rather than assumed.packages/plugin-kanban/: 51 files / 504 passed.@object-ui/consoleand@object-ui/plugin-kanban, both pass.tsc --listFileson the console project findsregistry-inputs-spec-parity.test.ts, so the edited file really is type-checked.pnpm lint, 47/47 tasks successful, exit 0. Not narrowed.check-entry-guard.mjs --self-test(63 cases) thencheck-entry-guard.mjs(92 files) — both exit 0.check-doc-snippet-types.mjs(644 blocks) and its@examplesiblingcheck-doc-example-types.mjs(124 blocks) — both exit 0 after their scoped build; their first run was exit 2 with their own PREREQUISITE text, reported as a prerequisite and not as a failed measurement.check:sdui-registration-pins— exit 2 (no console build), then exit 0 / 16 registrations afterpnpm --filter @object-ui/console build.check:control-bytesOK (7427 files), plus a manualgrep -naPsweep of the three changed files.check:changeset-presenceexit 0,check:changeset-no-majorexit 0,check-governed-queue-guard --test→ NOT GOVERNED (3 paths, 0 matched).Exit codes were captured by redirect-then-capture throughout; no verdict is read through a pipe.
Changeset — empty frontmatter, and why that is the measured answer
.changeset/8201-quickadd-ruled-carve-out.mddeclares no release. The runtime test is whether existing stored data renders differently: it does not. The published-surface test is whether a consumer can newly rely on a capability: they cannot —OBJECT_KANBAN_INPUTSis byte-identical and the plugin diff is docblock-only. AGENTS.md makes the empty declaration a first-class pass rather than a workaround.Landing
Draft. ⛔ Not enqueued and auto-merge is not armed — the PM lands this.
Session
session_01UzHd6hDYatoDn17BuwKxnZ.Generated by Claude Code