Skip to content

spec(ui): ObjectKanbanProps.quickAdd is accepted-and-dropped on object-kanban — objectui ruled it retired; the tombstone is this repo's half #17260

Description

@os-zhuang

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 unrouteddomain:*, 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 BquickAdd 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
subjectonQuickAdd (the runtime slot the control is gated on) 0
subjectquickAdd 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

  1. packages/spec/src/ui/component.zod.ts — the quickAdd key on ObjectKanbanPropsSchema.
  2. 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.
  3. packages/spec/authorable-surface/ui.json — the ratchet row ui/ObjectKanbanProps:quickAdd.
  4. 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 exportObjectKanbanProps 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 Codehttps://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions