Filed by the domain:ui @ objectui PM seat (Claude Code, session session_01611D6ZaRaMmwTNQmSbk8MH) as the cross-repo half that objectui#8285's ruling assigns to it. ⛔ Ungraded and unrouted — domain:*, priority and type are this repo's triage's. Filed unassigned.
Why this card exists at all
objectui#8285 recorded a director-seat ruling (comment 5583979207, decision batch #91, 2026-09-08, standing maintainer delegation), whose Execution paragraph reads verbatim:
Execution: domain:ui seat files the objectstack spec card citing this ruling; this card blocks on it after C lands.
This is that card. The ruled option was B — quickAdd is retired from the object-kanban board, and stays only on the kanban-ui block, where a React host can supply the runtime function the control actually needs.
⛔ This card does not re-open A vs B. It carries the spec-side execution of a ruling already made, and the open questions below are about how the spec tombstones a key, not about whether to.
The defect, re-measured on both sides rather than relayed
objectstack side — measured by me on origin/main 470746a. ObjectKanbanPropsSchema in packages/spec/src/ui/component.zod.ts declares:
quickAdd: z.boolean().optional().describe('Show the per-column quick-add affordance'),
objectui side — re-measured by me on objectui origin/main 4fa0eb9c4, with the control lit, rather than quoting the filing seat's transcript:
probe, all git grep -c on packages/plugin-kanban/src/ObjectKanban.tsx |
hits |
subject — onQuickAdd (the runtime slot the control is gated on) |
0 |
subject — quickAdd itself |
0 |
control, same probe shape, same file — onCardClick |
6 |
⇒ the zeros are readings, not a broken pattern: the same instrument returns 6 on a sibling handler in the same file. The board's own source never names either half of the pair; quickAdd reaches the renderer only by the spread of the authored bag.
The renderer gates the affordance on both quickAdd and onQuickAdd being truthy. onQuickAdd is a host-supplied function, refused by name in objectui's own JSON tier because JSON has no function value. A whole-tree scan finds onQuickAdd only in the renderer chain (KanbanImpl, KanbanEnhanced, index.tsx) and in type declarations and their tests — no producer puts it on an object-kanban node.
⇒ An author who follows this spec and writes quickAdd: true on an object-kanban gets nothing, with no diagnostic. This is the accepted-and-dropped class — the spec publishes it, the renderer accepts it, and nothing happens.
The carriers in this repo — three, and a fourth thing that is also wrong
packages/spec/src/ui/component.zod.ts — the quickAdd key on ObjectKanbanPropsSchema.
- The same file's
ObjectKanbanPropsSchema docblock, which lists quickAdd among the board's read points reached "via the forwarded schema". ⚠️ That sentence is true about the forward and false about the read — the value is forwarded and then dropped at a gate the docblock does not mention. Whoever takes this should fix the docblock's claim in the same stroke, or it will keep re-authorizing the key.
packages/spec/authorable-surface/ui.json — the ratchet row ui/ObjectKanbanProps:quickAdd.
- ⭐ Measured negative, with the same instrument that found the positives:
quickAdd appears nowhere else under packages/ — not on a kanban schema, not on a kanban-ui schema. So the spec surface to be retired is exactly the one key plus its ledger row. The ruling's phrase "kept on kanban-ui" describes an objectui-side block that this spec does not declare a quickAdd for; ⛔ nothing needs adding there.
The mechanism already exists — ⛔ do not invent one, and ⛔ do not just delete the key
The ledger's own description states the contract:
A key that disappears without a tombstone fails gen:schema, because these schemas are not .strict() and Zod would silently strip it. "[RETIRED]" marks a tombstoned key that still rejects with an upgrade prescription. See #3855, ADR-0059 §5.
Measured breadth of the precedent on 470746a: 207 tombstoned keys across the 14 authorable-surface/ shards, of which 55 are in ui.json (e.g. ui/ObjectListView:bordered [RETIRED], ui/Action:execute [RETIRED]). This is a well-worn path, not a new one.
The sibling in-file precedent for the prescription half is OBJECT_CALENDAR_FLAT_FIELD_GUIDANCE in the same component.zod.ts — a KeySetGuidance that refuses a key set by name and hands back an upgrade sentence. ⚠️ Sketch of the option space, not a design ruling: whoever takes this decides the shape.
⚠️ Two things I am flagging rather than asserting
① The ADR citation in the objectui ruling does not survive my check, and I am not passing it on as fact.
That ruling cites "ADR-0049 enforce-or-remove". ADR-0049 is real and is genuinely titled the enforce-or-remove gate — but its own title and TL;DR scope it to security/access-control properties ("Spec must not declare security properties the runtime does not enforce"; "A spec property that names a security/access-control boundary must be in exactly one of three states"). quickAdd names a UI affordance, not a boundary. ⇒ ADR-0049 is the right spirit and, on my reading, the wrong citation. The discipline that actually governs a tombstone here is the authorable-surface ratchet and ADR-0059 §5 / #3855, per the ledger's own description quoted above. ⛔ Triage should confirm this rather than take my reading either.
② The release disposition is genuinely open, and I am ⛔ not settling it from the objectui seat.
The objectui ruling recorded the disposition as minor + BREAKING + ADR-0087. But ADR-0059 §4 (the freeze contract) says, verbatim:
A spec change that requires editing the fixtures, or that removes an entry from the snapshot, is by definition a breaking change for third parties. […] Removed / renamed / narrowed → restore it, or bump @objectstack/spec to a new major and document the migration.
⚠️ These may not actually be in conflict: §4 governs the api-surface snapshot, which is name+kind of exports, and a tombstoned key removes no export — ObjectKanbanProps still exists and the ledger row survives with a [RETIRED] marker rather than vanishing. So the honest statement is: I do not know whether a tombstone on an authorable key is a §4 removal, and the answer decides minor vs major. ⇒ This repo's triage owns that call, against ADR-0059 §4, ADR-0087 and whatever the 207 existing tombstones actually shipped as. ⛔ Do not inherit minor from the objectui ruling — that ruling had standing over objectui's half, not over this repo's release policy.
⚠️ Whoever takes this: the 207 existing tombstones are a measurable answer to ② sitting in this repo's own history. Read what a previous [RETIRED] row shipped as before designing anything.
⛔ Scope fence
- ⛔ Not the inline record-creation path (objectui#8285's option A). It was ruled against: zero in-repo producers, no measured external puller, and it would open a write path carrying permissions, required-field prompting and rollback.
- ⛔ Not objectui's interim. objectui#8285 slice C — making the silent drop loud at the html tier until this pin moves — is separately in flight on the objectui side and is not blocked on this card. This card is what lets that interim eventually retire.
- ⛔ Not objectui#8201, which owns the declaration question for the board's other keys and stays open.
⚠️ Confidence gap I could not close
Whether any external consuming application already authors quickAdd: true on an object-kanban and believes it works. In-repo producers are zero on both sides, measured. Out-of-repo is unknown to me and unknowable from either seat. ⛔ Do not read the in-repo zero as a global zero — it is what sets the migration prescription's tone, and it is the stated reversal path on the ruling ("a named consumer that wants inline creation reopens this as A with the puller stated").
Related
objectui#8285 (the ruled card, and the ruling itself) · objectui#8201 (the board's other undeclared keys) · objectui#6124 (the runtime-slot class that makes onQuickAdd unauthorable in JSON) · ADR-0059 §4 and §5 · ADR-0087 · ADR-0049 (cited by the ruling; see flag ① above) · #3855 (the tombstone convention)
Generated by Claude Code — https://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH
Filed by the
domain:ui@ objectui PM seat (Claude Code, sessionsession_01611D6ZaRaMmwTNQmSbk8MH) as the cross-repo half that objectui#8285's ruling assigns to it. ⛔ Ungraded and unrouted —domain:*, priority and type are this repo's triage's. Filed unassigned.Why this card exists at all
objectui#8285 recorded a director-seat ruling (comment 5583979207, decision batch #91, 2026-09-08, standing maintainer delegation), whose Execution paragraph reads verbatim:
This is that card. The ruled option was B —
quickAddis retired from theobject-kanbanboard, and stays only on thekanban-uiblock, where a React host can supply the runtime function the control actually needs.⛔ This card does not re-open A vs B. It carries the spec-side execution of a ruling already made, and the open questions below are about how the spec tombstones a key, not about whether to.
The defect, re-measured on both sides rather than relayed
objectstack side — measured by me on
origin/main470746a.ObjectKanbanPropsSchemainpackages/spec/src/ui/component.zod.tsdeclares:objectui side — re-measured by me on objectui
origin/main4fa0eb9c4, with the control lit, rather than quoting the filing seat's transcript:git grep -conpackages/plugin-kanban/src/ObjectKanban.tsxonQuickAdd(the runtime slot the control is gated on)quickAdditselfonCardClick⇒ the zeros are readings, not a broken pattern: the same instrument returns 6 on a sibling handler in the same file. The board's own source never names either half of the pair;
quickAddreaches the renderer only by the spread of the authored bag.The renderer gates the affordance on both
quickAddandonQuickAddbeing truthy.onQuickAddis a host-supplied function, refused by name in objectui's own JSON tier because JSON has no function value. A whole-tree scan findsonQuickAddonly in the renderer chain (KanbanImpl,KanbanEnhanced,index.tsx) and in type declarations and their tests — no producer puts it on anobject-kanbannode.⇒ An author who follows this spec and writes
quickAdd: trueon anobject-kanbangets nothing, with no diagnostic. This is the accepted-and-dropped class — the spec publishes it, the renderer accepts it, and nothing happens.The carriers in this repo — three, and a fourth thing that is also wrong
packages/spec/src/ui/component.zod.ts— thequickAddkey onObjectKanbanPropsSchema.ObjectKanbanPropsSchemadocblock, which listsquickAddamong the board's read points reached "via the forwarded schema".packages/spec/authorable-surface/ui.json— the ratchet rowui/ObjectKanbanProps:quickAdd.quickAddappears nowhere else underpackages/— not on akanbanschema, not on akanban-uischema. So the spec surface to be retired is exactly the one key plus its ledger row. The ruling's phrase "kept onkanban-ui" describes an objectui-side block that this spec does not declare aquickAddfor; ⛔ nothing needs adding there.The mechanism already exists — ⛔ do not invent one, and ⛔ do not just delete the key
The ledger's own description states the contract:
Measured breadth of the precedent on
470746a: 207 tombstoned keys across the 14authorable-surface/shards, of which 55 are inui.json(e.g.ui/ObjectListView:bordered [RETIRED],ui/Action:execute [RETIRED]). This is a well-worn path, not a new one.The sibling in-file precedent for the prescription half is⚠️ Sketch of the option space, not a design ruling: whoever takes this decides the shape.
OBJECT_CALENDAR_FLAT_FIELD_GUIDANCEin the samecomponent.zod.ts— aKeySetGuidancethat refuses a key set by name and hands back an upgrade sentence.① The ADR citation in the objectui ruling does not survive my check, and I am not passing it on as fact.
That ruling cites "ADR-0049 enforce-or-remove". ADR-0049 is real and is genuinely titled the enforce-or-remove gate — but its own title and TL;DR scope it to security/access-control properties ("Spec must not declare security properties the runtime does not enforce"; "A spec property that names a security/access-control boundary must be in exactly one of three states").
quickAddnames a UI affordance, not a boundary. ⇒ ADR-0049 is the right spirit and, on my reading, the wrong citation. The discipline that actually governs a tombstone here is the authorable-surface ratchet and ADR-0059 §5 / #3855, per the ledger's own description quoted above. ⛔ Triage should confirm this rather than take my reading either.② The release disposition is genuinely open, and I am ⛔ not settling it from the objectui seat.
The objectui ruling recorded the disposition as
minor+ BREAKING + ADR-0087. But ADR-0059 §4 (the freeze contract) says, verbatim:ObjectKanbanPropsstill exists and the ledger row survives with a[RETIRED]marker rather than vanishing. So the honest statement is: I do not know whether a tombstone on an authorable key is a §4 removal, and the answer decidesminorvsmajor. ⇒ This repo's triage owns that call, against ADR-0059 §4, ADR-0087 and whatever the 207 existing tombstones actually shipped as. ⛔ Do not inheritminorfrom the objectui ruling — that ruling had standing over objectui's half, not over this repo's release policy.[RETIRED]row shipped as before designing anything.⛔ Scope fence
Whether any external consuming application already authors
quickAdd: trueon anobject-kanbanand believes it works. In-repo producers are zero on both sides, measured. Out-of-repo is unknown to me and unknowable from either seat. ⛔ Do not read the in-repo zero as a global zero — it is what sets the migration prescription's tone, and it is the stated reversal path on the ruling ("a named consumer that wants inline creation reopens this as A with the puller stated").Related
objectui#8285 (the ruled card, and the ruling itself) · objectui#8201 (the board's other undeclared keys) · objectui#6124 (the runtime-slot class that makes
onQuickAddunauthorable in JSON) · ADR-0059 §4 and §5 · ADR-0087 · ADR-0049 (cited by the ruling; see flag ① above) · #3855 (the tombstone convention)Generated by Claude Code — https://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH