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 }}
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Repository navigation
Commit fa93c7f
Browse filesBrowse the repository at this point in the historyBrowse files
docs(kanban): make the published docs state the optional groupBy contract (objectui#8990)
Contract review R1 (blocking): four hand-written doc sites still asserted the
pre-change contract, and two of them named THIS card as the pending fix — so the
PR closed the card while leaving the docs telling readers it was still open.
AGENTS.md #2 ("Not done until docs reflect the code") is binding and no CI gate
catches this class.
- content/docs/api/schema-reference.md — the property table said "Required.";
the columns callout said the bare-string arm is "inert on this block" because
"groupBy is required here", and closed with "tracked as objectui#8990".
- content/docs/plugins/plugin-kanban.mdx — same claim, same tracking sentence.
- packages/plugin-kanban/README.md — "type and groupBy are required" and the
inline "// required" comment, plus two further spots the review did not name
that made the same claim.
All now state optional AND the measured lane-less behaviour: lanes drawn from
bare strings and titled by the RAW values (a grouped board shows picklist
LABELS), zero cards, moves inert. Both "tracked as objectui#8990" sentences are
deleted. The record-source rule is called out as separate and unaffected, since
that refusal survives and is easy to conflate with the lane key.
Also from the review:
- Two unqualified sentences ("what made the arm live") now carry the
schema-valid qualifier the groupBy docblock already had. The renderer never
consulted this package's validator, so the arm was always live for a document
that reached it unvalidated; what requiredness prevented was a document being
valid AND getting there.
- The mdx corpus evidence is DOWNGRADED where it was overstated: that fragment
is still refused after this change, at RECORD_SOURCE_REQUIRED, so it shows a
lane-less board is a documented authoring, not a document this change admits.
The ListView evidence carries the argument alone and is strengthened to what
was actually measured: objectDef loads async, so laneField is undefined on
every load until it lands, and stays undefined when detectStatusField finds no
stageField role and no status/stage/state/phase field, or when stageField is
false (ADR-0085 suppression).
- "can only NARROW #8993's reachable set" corrected to UNCHANGED / not widened.
- The six rotted line addresses are no longer restated even as history.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w
Copy file name to clipboardExpand all lines: content/docs/api/schema-reference.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -932,7 +932,7 @@ A drag-and-drop Kanban board. The `object-kanban` type key validates the shape t
932
932
| Property | Type | Description |
933
933
|----------|------|-------------|
934
934
|`objectName`|`string`| Object to fetch records from. |
935
-
|`groupBy`|`string`|**Required.**Field whose values become the lanes (maps to column ids). |
935
+
|`groupBy`|`string`| Field whose values become the lanes (maps to column ids). **Optional** since objectui#8990, matching `@objectstack/spec`. A board that omits it draws whatever lanes `columns` declares — and holds **no cards**, because records are only distributed once a lane key exists. |
936
936
|`columns`|`string[] \| KanbanLane[]`| Swimlane definitions — an array of `{ id, title }` lanes (one per `groupBy` value), **or** an array of bare value strings; never a mix. **Not** a field projection (that is `cardFields`). A lane's `cards` is optional: an object-bound board buckets records into the lane by `groupBy`, and only a static board writes a lane's cards itself. |
937
937
|`titleField`|`string`| Field used as the card title. |
938
938
|`cardFields`|`string[]`| Fields rendered on each card. |
@@ -947,11 +947,11 @@ A drag-and-drop Kanban board. The `object-kanban` type key validates the shape t
947
947
948
948
> `columns` is declared on this face since objectui#8913, as the pair of array shapes `@objectstack/spec` declares — an array of `{ id, title }` lanes, **or** an array of bare value strings. A **mixed** array is refused: the renderer decides which shape it has from the first element alone, so a mix yields a blank lane and mis-bucketed cards. A lane accepts `id`, `title`, `cards`, `limit`, `className` and `collapsed`, which are the members the board implementations read; `id` is a **string** — a non-string lane id makes the board render every card twice, once in its lane and once in "Uncategorized" (objectui#8993). When a lane carries `cards`, each card is judged — a card with no `title` is refused. An undeclared lane key is accepted and dropped, not refused, which is this tolerant face's posture; the strict authoring face refuses it by name.
949
949
>
950
-
> ⚠️ The **bare-string array is accepted but inert on this block.** It is declared so this package does not refuse an authoring the protocol allows. The renderer reads a bare-string lane list only when a board has no `groupBy`, and `groupBy` is required here — so on `object-kanban` the strings are always ignored and the lanes come from the group field's picklist options or from the data. Write the `{ id, title }` array to control the lanes. The requiredness of `groupBy`is tracked as objectui#8990.
950
+
> ⚠️ The **bare-string array applies only to a board with no `groupBy`.** It is declared so this package does not refuse an authoring the protocol allows. The renderer reads a bare-string lane list only when a board has no `groupBy` — so on a board that *does* declare one the strings are ignored and the lanes come from the group field's picklist options or from the data. Since objectui#8990 made `groupBy` optional, a lane-less board is a valid authoring and this arm is live on it: the lanes are drawn, titled by the **raw strings** (a grouped board titles its lanes with the picklist *labels* instead). ⚠️ Such a board holds **no cards** — with no lane key the records are never distributed — and dragging a card writes nothing back. It is lane headings, not a populated board; to control the lanes of a working board, declare `groupBy`and write the `{ id, title }` array.
951
951
>
952
952
> The other keys the retired `kanban` arm alone declared — `cardTitle`, `swimlaneField`, `grouping` and `navigation` — are still undeclared on this face. The renderer reads them, so a board may carry them; they are simply not judged. The board's React host supplies `onCardMove` / `onCardClick` / `onQuickAdd` as props; none of the three is authorable in JSON.
953
953
954
-
> `data` and `bind` are [`BaseSchema`](#baseschema) members, not narrowed here, but this face requires **one of**`bind`, `data`, `objectName` — the renderer's own record-source ladder (an external `data` prop → `bind` via `useDataScope` → this schema's own `data` → a fetch keyed by `objectName`). A purely static board (lanes carrying their own cards, no record source) authors `"groupBy"` and `"data": []`.
954
+
> `data` and `bind` are [`BaseSchema`](#baseschema) members, not narrowed here, but this face requires **one of**`bind`, `data`, `objectName` — the renderer's own record-source ladder (an external `data` prop → `bind` via `useDataScope` → this schema's own `data` → a fetch keyed by `objectName`). A purely static board (lanes carrying their own cards, no record source) authors `"groupBy"` and `"data": []`. ⚠️ The record-source rule is **separate** from the lane key and is unaffected by objectui#8990: omitting `groupBy` is fine, omitting all of `bind` / `data` / `objectName` is still refused, at the refinement rather than at `groupBy`.
0 commit comments