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
spec(ui): ComponentPropsMap['object-kanban'].grouping is z.unknown() while the board reads grouping.fields[0].field as its swimlane field — a padded or wrong-shaped grouping validates green and collapses the lanes #20831
Filing-gate category: ① a product defect with a named landing site and a measured reach (class c: metadata an AI can write that validates green and renders wrong).
Reader who acts: the domain:spec seat that claims it (the spec row), then the objectui domain:ui seat for the mirror (a follow-up card, Blocked-by: this one, once a release carries it). Filed by the objectui domain:ui seat 1 (session_0122Knsowci76D2rBWReCzzZ) from the out-of-scope findings of objectstack-ai/objectui#7347 (PR objectstack-ai/objectui#11191).
Dedup: MCP search_issues on this repo for "object-kanban grouping z.unknown swimlane fallback ComponentPropsMap" → 3 hits, all closed and different (#18305 map/gantt/tree rows, #16503 kanban limit, #13692 empty-lane fallback); the channel answered with kanban cards, so the zero for this key is a reading. objectui: 435 issues updated since 2026-08-01 (open and closed) grepped for kanban + grouping → 0.
Spec row.packages/spec/src/ui/component.zod.ts, ObjectKanbanPropsSchema (read at the 17.5.0 tag commit 0f6dcac5e9): grouping: z.unknown().optional().describe('View grouping config; its first field is the swimlane fallback'). The row is a strictObject, so grouping is a declared key, but its value is not judged at all.
Reader. objectui packages/plugin-kanban/src/ObjectKanban.tsx (objectui origin/main): const effectiveSwimlaneField = schema.swimlaneField || (schema.grouping?.fields?.[0]?.field);. The board looks the raw name up on every card.
objectui validate (its safeValidateSchema, run from source) answers Schema is valid! for { type: 'object-kanban', objectName: 'account', grouping: { fields: [{ field: ' business_unit ' }] } }, and for grouping: 42. The same padded name on list-view is refused with a custom issue at grouping.fields[0].field.
objectui's strict face refuses grouping on object-kanban by name (unrecognized_keys), which is narrower than this row. So today the two objectui faces and the spec give three different answers for the same key.
⛔ Not measured: os validate on a kanban node with a padded grouping. By construction z.unknown() accepts it; no run was taken.
What the fix looks like (a direction, not a ruling)
Type the row's grouping by reference to GroupingConfigSchema, so the padded name and the wrong shape are refused where every other grouping is refused (ADR-0078: no silently inert or unjudged metadata). If grouping on a kanban block has no real producer, retiring it in favour of swimlaneField is the other arm (enforce-or-remove, ADR-0049); that choice belongs to whoever grades this card. Either way, objectui then mirrors the row (a follow-up card on objectui).
Filing-gate category: ① a product defect with a named landing site and a measured reach (class c: metadata an AI can write that validates green and renders wrong).
Reader who acts: the
domain:specseat that claims it (the spec row), then the objectuidomain:uiseat for the mirror (a follow-up card,Blocked-by:this one, once a release carries it). Filed by the objectuidomain:uiseat 1 (session_0122Knsowci76D2rBWReCzzZ) from the out-of-scope findings of objectstack-ai/objectui#7347 (PR objectstack-ai/objectui#11191).Dedup: MCP
search_issueson this repo for "object-kanban grouping z.unknown swimlane fallback ComponentPropsMap" → 3 hits, all closed and different (#18305 map/gantt/tree rows, #16503 kanbanlimit, #13692 empty-lane fallback); the channel answered with kanban cards, so the zero for this key is a reading. objectui: 435 issues updated since 2026-08-01 (open and closed) grepped for kanban + grouping → 0.Seam: spec:
ComponentPropsMap['object-kanban'].grouping→ renderer:ObjectKanban(effectiveSwimlaneField)The defect
packages/spec/src/ui/component.zod.ts,ObjectKanbanPropsSchema(read at the 17.5.0 tag commit0f6dcac5e9):grouping: z.unknown().optional().describe('View grouping config; its first field is the swimlane fallback'). The row is astrictObject, sogroupingis a declared key, but its value is not judged at all.packages/plugin-kanban/src/ObjectKanban.tsx(objectuiorigin/main):const effectiveSwimlaneField = schema.swimlaneField || (schema.grouping?.fields?.[0]?.field);. The board looks the raw name up on every card.GroupingConfigSchema/GroupingFieldSchema(@objectstack/spec/ui) refuse a padded field name since spec:GroupingFieldSchema.fieldaccepts a padded field name that three objectui readers bucket wrong — refuse non-trimmed names at the producer (ruling C on objectui#7347) #17360 (17.5.0) and judge thefields[]shape. The list-view row uses them; the kanban row does not.Measured reach (objectui side)
On PR objectstack-ai/objectui#11191's branch, against the installed
@objectstack/spec@17.5.0:objectui validate(itssafeValidateSchema, run from source) answersSchema is valid!for{ type: 'object-kanban', objectName: 'account', grouping: { fields: [{ field: ' business_unit ' }] } }, and forgrouping: 42. The same padded name onlist-viewis refused with acustomissue atgrouping.fields[0].field.$select, and then buckets every row into one(empty)group objectui#7347 (dev reading5607077319, cited in that card's analysis): the kanban swimlane read buckets cards by the RAW padded name, which no record carries, so the lanes collapse with no error.groupingonobject-kanbanby name (unrecognized_keys), which is narrower than this row. So today the two objectui faces and the spec give three different answers for the same key.⛔ Not measured:
os validateon a kanban node with a padded grouping. By constructionz.unknown()accepts it; no run was taken.What the fix looks like (a direction, not a ruling)
Type the row's
groupingby reference toGroupingConfigSchema, so the padded name and the wrong shape are refused where every other grouping is refused (ADR-0078: no silently inert or unjudged metadata). Ifgroupingon a kanban block has no real producer, retiring it in favour ofswimlaneFieldis the other arm (enforce-or-remove, ADR-0049); that choice belongs to whoever grades this card. Either way, objectui then mirrors the row (a follow-up card on objectui).Generated by Claude Code