docs(api): stop teaching quickAdd and allowCollapse on the object-kanban table - #9353
docs(api): stop teaching quickAdd and allowCollapse on the object-kanban table#9353os-sam wants to merge 1 commit into
quickAdd and allowCollapse on the object-kanban table#9353Conversation
…ban table
`content/docs/api/schema-reference.md`'s `object-kanban` section listed two
keys an object-bound board does not honour, and one of them sat inside the
copy-paste JSON example.
Re-measured against the installed `@objectstack/spec` artifact, not inherited:
- `allowCollapse` is not in `ComponentPropsMap['object-kanban'].shape`, and
`safeParse({ allowCollapse: true })` fails with `unrecognized_keys` naming
the key. The strict map refuses it BY NAME, so a document written from that
row does not merely go unread, it fails validation. Control: the other ten
rows all parse green on the same probe, so the refusal is a reading.
`@object-ui/plugin-kanban/src` has zero occurrences of the key, against
non-zero for every other row key.
- `quickAdd` parses -- the strict map does declare it -- but the board never
honours it: the Quick Add control is gated on an `onQuickAdd` runtime slot,
`ObjectKanban.tsx` has zero occurrences of it against six for the control
`onCardClick`, and it is absent from `OBJECT_KANBAN_INPUTS`. The wording is
aligned with the retirement ruling rather than invented.
Deleting the example's line required dropping the now-dangling comma on the
`cardFields` line; the fenced block still compiles under the snippet gate.
A note in the shape the section already uses records why both keys are absent,
so the rows are not restored from the mirror, which still declares them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L5xpA5q533BgTTNADibEFt
CI red — established as NOT this PR's, and ⛔ not ported. Standing down with reasons.Two checks are red on head The failures, and what they actually name
Why it is not this PR's — measured, ⛔ not assertedI checked the content on ⇒ the offending fences are already on Both halves are already carded — dedupe first, and it hit
⇒ ⛔ No new card filed. Filing a third would be the duplicate this lane keeps carding. ⛔ Why I am NOT porting a fix into this PRThe standing rule is to port an existing fix rather than wait. I am declining here, deliberately, for two reasons that the rule does not cover:
⇒ this PR waits for ⛔ What was NOT done, and will not be⛔ No re-run (this is not a flake — it is a reproducible type error with a named cause). ⛔ No test skipped, disabled or quarantined. ⛔ No gate weakened. ⛔ No empty commit. This PR's own gates are green
Seat: Generated by Claude Code |
Chain update: objectui#9369 now fixes both halves of the
|
Fixes #9247
content/docs/api/schema-reference.md'sobject-kanbansection listed two keys an object-bound board does not honour, and one of them sat inside the copy-paste JSON example. This is the face an AI generator copies from, so a wrong row produces wrong metadata at scale rather than one confused author.One file changed, 3 insertions and 4 deletions.
What changed
"quickAdd": truedeleted.cardFieldsline, which would have made the fenced block invalid JSON; that comma is dropped in the same edit. The snippet gate was run rather than assumed, and it compiles (below).allowCollapsetable row — deleted, not reworded.quickAddtable row — deleted, not reworded. The wording was not free: the retirement ruling governs it, and no description was invented.groupField, recording why both keys are absent. Without it the next reader finds both keys still declared on@object-ui/types' mirror and restores the rows, which is the same defect coming back.Zone 2 — the second-hand readings, re-measured here
Neither triage nor the PM could measure the spec side:
@objectstack/specis not installed in either container. It is installed in this worktree, so both claims were re-derived from the artifact rather than inherited. Both hold.ComponentPropsMap['object-kanban']refusesallowCollapseby name.shape;safeParsereturnsunrecognized_keyswhosekeysarray namesallowCollapse, and the message names it in prosequickAddparses but is droppedonQuickAddruntime slot and nothing on theobject-kanbanpath supplies oneLine addresses were re-derived by content, never by line number, as instructed. They happened to still be
:929,:942and:944, but nothing in this change depends on that.The ruling was verified on its own card rather than assumed: objectui#8285 is open, and the batch-91 ruling recorded on it stands — option B, the key retires from
object-kanbanand stays on theKanbanRenderercomponent where a React host can supply the function. Its spec half is filed cross-repo and has not landed, which is exactly why the key still parses today.⭐ Every row re-measured, not just the two named
Two of eleven rows being wrong is not evidence the other nine are right, so all eleven were probed. Instruments:
ComponentPropsMap['object-kanban']from the installed artifact for the contract half;OBJECT_KANBAN_INPUTSinpackages/plugin-kanban/src/index.tsxplus occurrence counts in that package's sources for the honoured half.OBJECT_KANBAN_INPUTSobjectNamegroupBycolumnstitleFieldcardFieldsfilterlimitquickAddcoverImageFieldallowCollapseconditionalFormattingControls, so the two zeroes are readings rather than broken probes. On the parse probe, ten of eleven rows returned green against the single refusal — a dead probe returns no greens. On the occurrence probe,
allowCollapsehas zero mentions anywhere underpackages/plugin-kanban/srcwhile every other row key has non-zero, andonQuickAddhas zero occurrences inObjectKanban.tsxagainst six foronCardClickin the same file on the same query.Two rows carried claims specific enough to be worth checking separately, and both survived:
columnspromises a{ id, title }array or a bare-string array. Both arms parse green, as does a lane carrying the full member set.conditionalFormattingpromises a native{ field, operator, value }dialect or a spec{ condition, style }one. Both parse green.OBJECT_KANBAN_INPUTSspells the second dialect differently in its own description; the document's spelling is the one the mirror declares and the one the renderer's tests exercise, so the document is right here and no change is owed.⇒ Nine rows correct, two wrong, and the two wrong ones are exactly the two the card named. Nothing outside that table was touched.
The other face, deliberately untouched
@object-ui/typesstill declares both keys on its mirror of this face (packages/types/src/objectql.ts,packages/types/src/zod/objectql.zod.ts). That half is objectui#8801 and is out of scope here by dispatch: its files collide with in-flight PR #9348, so it serialises behind that one. This change deliberately leaves the mirror alone, and the note added to the section points a reader at that card so the two faces stay visible to each other. Related history for the same key: objectui#7742 and objectui#8802.⛔ The renderer is untouched. Both keys' runtime behaviour is correct and owned elsewhere.
Gates
Derived from the per-gate workflow files, not from⚠️ Deviation worth recording: the dispatch said to derive the doc gates from
package.json..github/workflows/lint.yml's step list. They are not there —lint.ymlrunspnpm lint, the entry-guard check, the upstream-port pin, the bash floor andpnpm check. The doc gates each own a separate workflow file, and that is where this list comes from. Exit codes were captured by redirect before any pipe.check-doc-snippet-types.mjscheck-doc-example-types.mjscheck-doc-component-types.mjstypeliterals — every documented component type is registeredcheck:doc-fencescheck-doc-example-ids.mjscheck-doc-links.mjscheck:docs-route-closurecheck-prompt-component-keys.mjscheck-control-bytes.mjscheck-new-cross-file-line-citations.mjscheck-changeset-presence.mjsPRECONDITION NOT MET— their own words: "I could not run", NOT "I ran and found errors", because the packages they resolve against were unbuilt. That is not a red gate and is not recorded as one. The scoped build the gate itself prescribes was run first (35 turbo tasks, all successful), and the numbers above are from the re-run after it.Tests: every test in the tree that reads this document as its input was run — eleven files found by scanning for readers of the path, which is the same method
scripts/markdown-test-inputs.mjsuses to decide whether markdown-only changes must run the shards. 11 files, 413 tests, all passing. All heavy runs went through the shared verify lock; its verdict line readscommand-exit 0with the parts joined by and-and, so the number covers every part.Acceptance notes
cardTitle,swimlaneField,groupinganddataare read by the board but absent from the table. That is an omission, not a wrong row — nothing here teaches a key the runtime refuses — so it is out of this card's defect class. Noted, not filed.titleFieldis documented as the card title field; the registry ledger calls it the legacy spelling ofcardTitle, which wins when both are authored. The row is true as far as it goes and the key is honoured, so it is not in the defect class either. Noted, not filed.Delivery posture
Draft, and it stays draft from this seat. Nothing here is flipped ready, enqueued, armed for auto-merge or merged. No
needs:contract-reviewcarrier: this change has no contract increment —@objectstack/specuntouched, the mirrors untouched, the renderers untouched.Session, as a code span so it survives a body rewrite:
session_01L5xpA5q533BgTTNADibEFt.🤖 Generated with Claude Code
https://claude.ai/code/session_01L5xpA5q533BgTTNADibEFt
Generated by Claude Code