You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 27c0cf3
Browse filesBrowse the repository at this point in the historyBrowse files
fix(spec): the object-kanban quickAdd retirement prescribes "delete the key", not the unregistered kanban-ui block (#21141)
Fixes#21017
Clause-②: no
The `object-kanban` `quickAdd` retirement told authors the control "is
unchanged on the `kanban-ui` block". objectui retired that block
(objectui#8257) and this spec never declared it as a component type, so
a node written there saves clean and resolves no renderer. Every
author-facing copy of the remedy now says one sentence: **Delete the
key; `object-kanban` offers no quick-add control.** The refusal itself
is unchanged: same key, same `invalid_type` code at path `quickAdd`,
same accept set. Prose only.
## The copies
| Copy | File | Change |
|:--|:--|:--|
| tombstone message (shown at the save door and in the generated
reference) | `packages/spec/src/ui/component.zod.ts` | the sentence |
| D2 conversion `object-kanban-quick-add-removed` `summary` |
`packages/spec/src/conversions/registry.ts` | the sentence |
| D3 entry `object-kanban-quick-add-retired`: `replacement`, `reason`,
`acceptanceCriteria` (what `os migrate meta` prints) |
`migrations/entries/semantic/18.object-kanban-quick-add-retired.ts`,
generated copy in `migrations/registry.ts` | the sentence; the second
way out "move the board to a host that renders the `kanban-ui` block" is
dropped |
| step 18 `rationale` fragment (the paragraph the upgrade guide prints)
| `migrations/registry.ts`, the hand-written region outside the
generated markers | the sentence. A sixth copy the card did not list,
found by the `git grep` of the order's H2 |
| docblocks: two in `component.zod.ts`, two in
`conversions/registry.ts`, the retired-key entry's header, the pin
test's header | same files | the ruling is still quoted, now with what
objectui did to the block it named |
| generated | `migrations/registry.ts` (`gen:migration-registry`),
`content/docs/references/ui/component.mdx` (`gen:docs`) | regenerated,
never hand-typed |
## Measured before writing
- **H1, is there a rendering route.** objectui at the pin `e420df310f5b`
and at main `770cc5ba4d15`: 0 code lines naming `kanban-ui` under
`packages` and `apps` outside tests and CHANGELOGs; 22 comment lines in
6 files, all recording the retirement. No `register` call carries the
key. `ObjectKanban` passes neither half of the pair to
`KanbanBoardCore`; objectui's own docblock there says "An
`object-kanban` board draws no Quick Add control, whatever its document
carries". The pair is read only by the exported `KanbanRenderer` React
component, which a host mounts directly, so no metadata node reaches it.
No route to name, so triage's sentence stands.
- **H2, every copy.** Base `git grep` of `kanban-ui` under
`packages/spec/src` lists the files in the order plus the step 18
rationale fragment above. After this PR no author-facing text names the
block; the remaining mentions are docblocks and comments that explain
why it is not named.
- **H3, what PR #20990 already did.** It added the "Re-read at
`e420df310`" qualification to the second docblock. That qualification is
kept, re-wrapped, with the same facts and citations. The sentence just
above it still said the control "stays on `kanban-ui`", contradicting
it; that sentence is the one rewritten.
- **The dead-node claim.** Probe on this branch:
`PageComponentSchema.safeParse` of a node with type `kanban-ui` succeeds
(true), and `ComponentPropsMap['object-kanban'].safeParse({ objectName:
'task', quickAdd: true })` fails with one issue, code `invalid_type`,
path `quickAdd`.
## Pin
`ui/component.test.ts` (`ObjectKanbanPropsSchema quickAdd is retired`):
the existing refusal test now pins "Delete the key" in place of the
block name, and one new test asserts that the refusal still carries
`invalid_type` at `quickAdd`, that the tombstone carries the sentence,
and that none of the tombstone, the D2 summary, the D3 entry's three
texts and the step 18 rationale contains `kanban-ui`. The generated
copies are held to their sources by `check:migration-registry`.
Ablation, each leg through `scripts/ablation-replace.mjs` in wrap mode
against the committed fix: the tool printed anchor 1 to 0 and the blob
hash changing before the run, and `blob == HEAD` with an empty `git diff
HEAD` after it. Direction in every leg was red, exactly one failing
test: leg 1 the tombstone sentence reverted (assertion on the sentence),
leg 2 the D2 summary reverted, leg 3 the generated semantic copy
reverted, leg 4 the step 18 rationale reverted (each of the last three
on `not.toContain('kanban-ui')`). The test imports the sources by
relative path, so no `dist/` is in the resolution path and no rebuild is
owed between legs.
## Verified at head `83d99268a`
- `pnpm --filter @objectstack/spec build` exit 0; `check:generated` all
15 artifacts up to date, with `check:migration-registry`,
`check:spec-changes`, `check:upgrade-guide`, `check:docs`,
`check:authorable-surface` and `check:api-surface` green. `check:docs`
was stale after the tombstone edit and was regenerated: the diff of
`content/docs/references/ui/component.mdx` is the one sentence.
- `dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` over
the actual diff: 112 commands. `--ran` verdict: "112 derived famil(ies)
accounted for — 112 run, 0 NOT-MEASURED", every recorded exit 0. The
four artifact-roster gates whose roster sits under the touched paths
(`check:meta-url-spelling`, `check:authz-resolver`,
`check:error-code-casing`, `check:filter-alias-parity`) also exit 0. The
seven gates that first answered exit 3 (workspace not built) were re-run
after `turbo run build` of the closure and exit 0.
- `pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui
src/conversions src/migrations scripts/step18-rationale-merge.test.ts
scripts/conversions-major18-merge.test.ts`: 114 files, 4190 tests
passed. `pnpm --filter @objectstack/spec typecheck` exit 0.
- `origin/main` was merged with `scripts/pm/os-regen-merge.sh` (main at
`8368f1c00`); regenerating the migration registry afterwards changed
nothing. The repo-wide lint union and the rest of the farm are CI's.
## Acceptance notes
- `packages/spec/CHANGELOG.md`, the 17.5.0 entry for the retirement
(about lines 1580-1629), carries the same prescription ("It stays on the
`kanban-ui` block ...", and "live `kanban-ui` spelling"). It is
release-owned and published, so it is not touched here; it needs an
amendment in a dedicated docs-only PR. Carrier: none.
- `.changeset/objectui-pin-citations-e420df310f5b.md` already says the
block was retired in objectui and is correct; untouched.
- No governed surface is touched (no `.claude/**`, `skills/**`, ADR or
AGENTS.md). The claim records that the at-tier contract review of the
`packages/spec/src/**` face is owed before enqueue.
- Changeset: `patch` for `@objectstack/spec`, `Clause-②: no`. The diff
widens no accept set and no public surface.
---
_Generated by [Claude
Code](https://claude.ai/code/session_017VaLJnYwhPsanVCe9dMCJU)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
fix(spec): the `object-kanban``quickAdd` retirement no longer sends authors to the `kanban-ui` block, which objectui does not register
6
+
7
+
Clause-②: no
8
+
9
+
- The refusal of `quickAdd` on `object-kanban` now ends "Delete the key; `object-kanban` offers no quick-add control." It used to say the control "is unchanged on the `kanban-ui` block". objectui retired that block (objectui#8257), so a node of that type saves clean and renders nothing. The refusal itself is unchanged: the same key is still refused, with the same code and path.
10
+
- The same sentence replaces the old one in the `os migrate meta --from 17` output (the `object-kanban-quick-add-retired` entry) and in the summary of the `object-kanban-quick-add-removed` conversion. That entry no longer offers "move the board to a host that renders the `kanban-ui` block" as a second way out.
11
+
- No author action beyond the existing one. `quickAdd: true` on an `object-kanban` is still a parse error. Delete the key.
Copy file name to clipboardExpand all lines: content/docs/references/ui/component.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -822,7 +822,7 @@ Sort field and direction pair
822
822
|**cardFields**|`string[]`| optional | Fields rendered on each card |
823
823
|**swimlaneField**|`string`| optional | Field for horizontal swimlanes (in addition to columns) |
824
824
|**grouping**|`{ fields: object[] }`| optional | View grouping config; its first field is the swimlane fallback |
825
-
|**quickAdd**|`never`| optional |[REMOVED]`object-kanban` property `quickAdd` was removed in @objectstack/spec 17 (ADR-0049) — the board forwarded it, but the per-column affordance is gated on both `quickAdd` and `onQuickAdd`, and `onQuickAdd` is a host-supplied function JSON cannot carry and no producer ever put on an `object-kanban` node, so authoring it was a parse-clean no-op. Delete the key. The quick-add control is unchanged on the `kanban-ui` block, where a React host supplies the `onQuickAdd` slot the control needs. Run `os migrate meta --from 17` to list the mechanical edits for existing sources; apply them by hand. |
825
+
|**quickAdd**|`never`| optional |[REMOVED]`object-kanban` property `quickAdd` was removed in @objectstack/spec 17 (ADR-0049) — the board forwarded it, but the per-column affordance is gated on both `quickAdd` and `onQuickAdd`, and `onQuickAdd` is a host-supplied function JSON cannot carry and no producer ever put on an `object-kanban` node, so authoring it was a parse-clean no-op. Delete the key; `object-kanban` offers no quick-add control. Run `os migrate meta --from 17` to list the mechanical edits for existing sources; apply them by hand. |
826
826
|**coverImageField**|`string`| optional | Image field rendered as the card cover |
|**navigation**|`{ mode: Enum<'page' \| 'drawer' \| 'modal' \| 'split' \| 'popover' \| 'new_window' \| 'none'>; preventNavigation: boolean; openNewTab: boolean; size: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }`| optional | Card-click navigation config — the same block `ListViewSchema.navigation` declares (`{ mode, size, openNewTab, preventNavigation }`). The renderer's own default is `{ mode: 'drawer' }` when the key is absent; it is documented rather than declared, so a parsed board carries the key only when the author wrote it |
0 commit comments