Skip to content

feat(plugin-kanban,types): honour columns[].collapsed on the registered board (objectui#9628) - #9721

Merged
os-sales merged 1 commit into
mainfrom
claude/issue-9628-kanban-column-collapsed
Sep 17, 2026
Merged

os-sales merged 1 commit into
mainfrom
claude/issue-9628-kanban-column-collapsed

Conversation

@os-sales

Copy link
Copy Markdown
Collaborator

Fixes #9628

Clause-②: no

What this is

KanbanColumn.collapsed was declared on both published faces of the object-kanban arm — the lane element of ObjectKanbanSchema (packages/types/src/objectql.ts and its Zod mirror) and the runtime lane KanbanColumn (complex.ts and its mirror) — and read by KanbanEnhanced alone, a module no production source imports. An authored lane { "id": "todo", "title": "To Do", "collapsed": true } parsed green on both faces and reached a board that did nothing with it.

This PR repairs it at the reader (dispatch direction 2). It does not retire the key and does not reopen the PASS verdict this card originates from.

Direction-2 feasibility, measured before any repair

question reading
does the authored value reach the registered board? yes — bucketCardsIntoColumns spreads ...col on both legs, localizeColumn returns { ...col, title }, and KanbanRenderer forwards the whole lane objects as columns={processedColumns}
does honouring move a published accept set? no — both faces already declare the member; nothing that parsed before parses differently
does the protocol declare or refuse the key? neither — @objectstack/spec ObjectKanbanPropsSchema.columns is z.array(z.unknown()).optional(), so the lane element is unconstrained at the protocol level (measured on the installed @objectstack/spec 17.4.0 in this worktree)
would retiring it be cheap? no, and it is not this PR's route — it narrows a published accept set (a maintainer floor) and would strand objectui#8801's tombstone, which names this key as where lane collapse lives

The reproduction, with its firing controls in the same run

packages/plugin-kanban/src/__tests__/columnCollapsedHonoured-9628.test.tsx, run against the unrepaired reader:

Tests  2 failed | 4 passed (6)
FAIL  renders the declared lane collapsed, with its cards withheld
      expected document not to contain element, found the card "Alpha"
FAIL  the viewer can expand it again
      Unable to find an accessible element with the role "button" and name "To Do"

The four that passed in that same run are the controls:

  • both faces accept collapsed: true and keep the value (two legs), while an undeclared sibling key is accepted and dropped — so acceptance is a reading about this key, not about a passthrough;
  • className authored on the same lane reaches the DOM, so the inert collapsed is not a plumbing failure of that lane;
  • limit authored on a sibling lane paints the Full badge, so the board renders authored lane members at all.

What an authored collapsed: true now does

The lane renders narrowed to a title spine with its cards withheld, on both of the board's layouts — the flat lane and the column cells of every swimlane row — and its heading becomes a disclosure the viewer can open. That is the meaning KanbanEnhanced already gave the key, so the platform states one behaviour for it rather than two.

The authored value is the lane's initial state. The board holds the viewer's overrides in a map and resolves them against the current prop, rather than copying the authored flags into state: columns is rebuilt on every data round-trip, so a state seeded from it would re-collapse a lane the viewer had opened on every refetch (AGENTS.md #8), and nothing here depends on the identity of a memoised value (#10).

A board that authors the key nowhere is untouched. The disclosure appears only on a lane that declared collapsed: true, so an omitted key and an authored collapsed: false stay indistinguishable. The one place this had to be defended by construction: LaneHeading returns the bare title where the caller already owns an element, because wrapping it in one more span unconditionally hands laneCountHonesty-8307's count-badge locator the title instead. That was measured, not predicted — the first cut failed those four rows, and the fix is the !collapsible early return rather than a change to that pin.

Prose this change falsified, and repaired

Three sentences asserted that on the board this arm renders, collapse is the viewer's and not the author's. That was true when objectui#8801 retired allowCollapse; this PR makes it false, so it is corrected where it is stated rather than left to publish:

  • the allowCollapse tombstone docblock in objectql.ts and the author-facing refusal message on the Zod mirror — both keep every clause that ruling required of them (KanbanColumn.collapsed, "not a board-level authored toggle", "Delete the key"), and both now steer the author to a key that works. Swimlane-row collapse is still stated as the viewer's alone, because it still is;
  • the pending changeset .changeset/8801-object-kanban-allow-collapse-retired.md, whose body publishes verbatim into the CHANGELOG at the next release — the same release this change lands in. Its "what replaces it: nothing you author" paragraph would have contradicted the entry beside it. pnpm check:changeset-claims is the instrument that put this in front of this seat.

The docblocks and describe text on the declaration itself, the plugin README and content/docs/plugins/plugin-kanban.mdx stop pointing authors at the unregistered board.

Evidence

Every command was run from the repo root in this worktree, through the shared verify lock, with the exit code captured before any pipe.

run verdict
pnpm exec vitest run packages/plugin-kanban/ exit 0 — Test Files 57 passed (57), Tests 365 passed (365)
pnpm exec vitest run packages/types/ exit 0 — Test Files 202 passed (202), Tests 4698 passed (4698)
turbo run type-check (both packages, dependency builds included) exit 0 — Tasks: 15 successful, 15 total
turbo run lint (both packages) exit 0 — Tasks: 3 successful, 3 total, 0 errors
node scripts/check-changeset-presence.mjs exit 0 — 5 published source files of 2 released packages, 1 changeset
pnpm check:control-bytes exit 0 — 7818 tracked text files scanned
pnpm check:new-line-citations exit 0 — 0 new citations
pnpm check:changeset-claims exit 0, report-only — its finding is answered above
pnpm check:pending-changeset-literals exit 0
pnpm check:doc-fences / check:doc-types / check:i18n-keys exit 0
node scripts/check-governed-queue-guard.mjs --test (the six paths) exit 0 — NOT GOVERNED
pnpm check:doc-snippets NOT MEASURED — exit 2 is its prerequisite leg (it wants a scoped 34-package build), not a finding; declared to CI

Ablation of the pin this PR adds

From the committed tree, one leg each way, on packages/plugin-kanban/src/KanbanImpl.tsx:

PRE  anchor=1 inject=0 bytes=64403          anchor: "?? col.collapsed === true,"
POST anchor=0 inject=1 bytes=64400          inject: "?? false /* ABL9628 */,"
MUTATED_BLOB=3b3279af2eedf11b12eaea9b4dbfaf667f8d302a  HEAD_BLOB=6ecfdd141e9464476a89895d2102b7a19e0418eb
ABLATED_TEST_EXIT=1   Tests 3 failed | 4 passed (7)

The three that turned red are the flat lane, the viewer toggle and the swimlane layout; the four that stayed green are the two face legs, the undeclared-key control and the "no disclosure where nothing is authored" row — so the pin fails for the reason it exists and its controls do not move with it. Restored with git checkout HEAD -- on that file's absolute path, proven by blob equality with HEAD, an empty git diff HEAD, a clean git status and the marker at zero occurrences. No ablation artefact remains in the tree.

An earlier attempt at the same leg is recorded rather than hidden: its perl -0pi replacement terminated at the / inside the injected comment, so the anchor went to zero while the intended marker never landed. The reading was voided and the leg re-run through a Python replacement that asserts the anchor count first — the numbers above are from that run.

Acceptance notes

  • Serial constraints hold. The surfaces this touches are packages/types/src/complex.ts, objectql.ts, their two Zod mirrors, plugin-kanban/src/KanbanImpl.tsx, the plugin README, one docs page and two .changeset/ files. Intersection with objectui#7924 (views.ts), objectui#9375 (base.ts) and objectui#9712 (data.ts, useViewData.ts) is empty. Against the queued .changeset/ PRs measured on their own file lists: objectui#9714 holds 8478-describe-line-addresses.md and 8478-zod-pins-form-layout.md, objectui#9715 holds 8499-node-slot-registered-arms.md — none of the three is the file edited here.
  • KanbanEnhanced is untouched. It keeps its own collapsed read and its two test importers (cardPredicateScope.test.tsx, kanban-handler-slots-7664.test.tsx). Whether it should be revived or deleted is objectui#8257's question, not this one's.
  • Noted, not filed: KanbanEnhanced's own collapse toggle is an icon-only Button with no accessible name, so on that board the control is unnamed to a screen reader. The repair here does not copy that shape — its disclosure is named by the lane title. No PR or person is queued on that file today, so the carrier is: none.
  • Noted, not filed: packages/types/src/complex.ts introduces KanbanColumn as "a lane of the registered 'kanban' renderer", a node key retired by objectui#8802. Stale framing in one sentence, not a defect in a declaration.

Generated by Claude Code

…ered board

`KanbanColumn.collapsed` was declared on both published faces of the
`object-kanban` arm and read only by `KanbanEnhanced`, a module no production
source imports. An authored `collapsed: true` parsed green and reached a board
that did nothing with it — `KanbanImpl`'s only collapse is the swimlane row's,
held in viewer state and never keyed to a lane's declared value.

The repair is at the reader, not at the declaration: retiring the key would
narrow a published accept set and strand objectui#8801's tombstone, which names
this key as where lane collapse lives. Honouring it moves no accept set — both
faces already declare the member and `@objectstack/spec` declares the lane
element as `z.unknown()`.

A lane authored `collapsed: true` now renders narrowed to a title spine with its
cards withheld, on both of the board's layouts, and its heading is a disclosure
the viewer can open. The authored value is the initial state; the viewer's own
toggle wins after that and survives the data refreshes that rebuild the lane
objects. A board that authors the key nowhere renders the DOM it rendered
before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UanLVj6xvbS6puBCewLr8L
@github-actions

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 34 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/5903-objectgantt-declared-keys.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    Both halves move together. The TS declaration (packages/types/src/objectql.ts) and its zod mirror (src/zod/objectql.zod.ts) gain the same ten keys at the same requiredness — all optional — so the zod-mirror-parity ratchet stays at zero drift for this pair and no KnownDrift entry is added. navigation is taken from @objectstack/spec's NavigationConfigSchema by reference rather than restated, matching ObjectGridSchema.navigation.

  • names src/zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    Both halves move together. The TS declaration (packages/types/src/objectql.ts) and its zod mirror (src/zod/objectql.zod.ts) gain the same ten keys at the same requiredness — all optional — so the zod-mirror-parity ratchet stays at zero drift for this pair and no KnownDrift entry is added. navigation is taken from @objectstack/spec's NavigationConfigSchema by reference rather than restated, matching ObjectGridSchema.navigation.

.changeset/6172-markdown-kanban-one-authority.md

  • names KanbanImpl.tsx → packages/plugin-kanban/src/KanbanImpl.tsx — edited by this change

    KanbanCard / KanbanColumn — the three in-package copies converged to one. KanbanImpl.tsx and KanbanEnhanced.tsx each redeclared both names. A TypeScript-AST comparison found them strict-SUBSET copies of ./types with nothing typed differently, so their extra members moved onto the one declaration and both files now re-point at it.

.changeset/6687-chatbot-surface-authorable.md

  • names packages/types/src/complex.ts → packages/types/src/complex.ts — edited by this change

    Measured on both declaration faces before the fix, each with a control that had to hit: schema.surface appeared 0 times in renderer.tsx against schema.placeholder at 3 (one per registration) and schema.processVisibility at 1; and ChatbotSchema (packages/types/src/complex.ts) declared 34 keys, not this one. Two faces agreeing is what made the zero a reading rather than a bad query.

.changeset/6939-kanban-column-cards.md

  • names complex.ts → packages/types/src/complex.ts — edited by this change

    Breaking, deliberately. KanbanColumn declared its card list as items in complex.ts and in the zod mirror complex.zod.ts. Every board reads cards. Measured on origin/main 78a3cc238: KanbanImpl.tsx reads .cards on 12 lines, KanbanEnhanced.tsx on 8, and bucketCardsIntoColumns twice more as col.cards || []; .items had zero read sites in either board (a same-shaped .title control on the same two files returns 8 and 3, so those zeros are readings and not a mis-shaped probe). Both catalog entries, the plugin docs and content/docs/api/schema-reference.md all author cards.

  • names complex.zod.ts → packages/types/src/zod/complex.zod.ts — edited by this change

    Breaking, deliberately. KanbanColumn declared its card list as items in complex.ts and in the zod mirror complex.zod.ts. Every board reads cards. Measured on origin/main 78a3cc238: KanbanImpl.tsx reads .cards on 12 lines, KanbanEnhanced.tsx on 8, and bucketCardsIntoColumns twice more as col.cards || []; .items had zero read sites in either board (a same-shaped .title control on the same two files returns 8 and 3, so those zeros are readings and not a mis-shaped probe). Both catalog entries, the plugin docs and content/docs/api/schema-reference.md all author cards.

  • names KanbanImpl.tsx → packages/plugin-kanban/src/KanbanImpl.tsx — edited by this change

    Breaking, deliberately. KanbanColumn declared its card list as items in complex.ts and in the zod mirror complex.zod.ts. Every board reads cards. Measured on origin/main 78a3cc238: KanbanImpl.tsx reads .cards on 12 lines, KanbanEnhanced.tsx on 8, and bucketCardsIntoColumns twice more as col.cards || []; .items had zero read sites in either board (a same-shaped .title control on the same two files returns 8 and 3, so those zeros are readings and not a mis-shaped probe). Both catalog entries, the plugin docs and content/docs/api/schema-reference.md all author cards.

.changeset/6940-rowactions-boolean-mirror.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    The list view's same-named rowActions in zod/objectql.zod.ts — z.array(z.string()), the legacy bare-name action list on ObjectGridSchema — is a different key that is correct as it stands, is in parity with its own TS twin (rowActions?: string[]), and is not touched.

.changeset/7113-chart-data-model.md

  • names objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    .extend() with a NEW key still works and preserves the fold and the refinement; .optional(), z.discriminatedUnion, z.toJSONSchema and safeValidateSchema are all unaffected. Nothing in this repository calls the throwing combinators on either const, and the published surface already ships refined mirrors (objectql.zod.ts, complex.zod.ts, form.zod.ts, app.zod.ts), so the class is not new — but it is a real behaviour change on a published export and it belongs in the release note rather than in a reviewer's file.

  • names complex.zod.ts → packages/types/src/zod/complex.zod.ts — edited by this change

    .extend() with a NEW key still works and preserves the fold and the refinement; .optional(), z.discriminatedUnion, z.toJSONSchema and safeValidateSchema are all unaffected. Nothing in this repository calls the throwing combinators on either const, and the published surface already ships refined mirrors (objectql.zod.ts, complex.zod.ts, form.zod.ts, app.zod.ts), so the class is not new — but it is a real behaviour change on a published export and it belongs in the release note rather than in a reviewer's file.

.changeset/7200-object-form-section-style-keys-undeclared.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    The authored-metadata type now agrees with @objectstack/spec, whose FormSectionSchema is a strict object declaring neither key, and with the ruling's rationale (maintainer 2026-09-01, verbatim): "retire the reads … Declaring the keys was weighed and not adopted: it would formally invite free Tailwind strings into authored metadata, the exact class the boundary exists to keep out." A ?: never tombstone was not used: ObjectFormSection has no zod mirror (ObjectFormSchema in zod/objectql.zod.ts does not declare sections), so there is no parse door to refuse at, and a tombstone is still a declaration in completion and in the published .d.ts.

.changeset/7265-types-user-filter-field-derives.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    zod/objectql.zod.ts declared two schemas under names @objectstack/spec/ui already exports. They were triaged separately, by reading their sites, and went different ways.

.changeset/7295-chat-message-avatar-keys.md

  • names packages/types/src/complex.ts → packages/types/src/complex.ts — edited by this change

    packages/plugin-chatbot/src/index.tsx:173–178 reads message.avatar || userAvatarUrl and message.avatarFallback || userAvatarFallback (and the assistant twins), the authoring-to-runtime seam spreads every unlisted key through (chatMessageAdapter.ts, ...passthrough), and the SDUI renderer feeds the authored messages[] straight in — a per-message avatar override renders, is documented, and no authoring-facing type declared it. ChatMessage in packages/types/src/complex.ts has no index signature (objectui#5155, deliberately — none is added here), so an author annotating ChatbotSchema.messages was told a value that renders is an error (TS2353); the zod mirror ChatMessageSchema is a plain strip-mode z.object, so the value parsed green and was silently DROPPED from the parsed output.

.changeset/7322-object-kanban-group-by-limit.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    Breaking for authored metadata: ObjectKanbanSchema.groupField is RETIRED (objectui#7322, ADR-0049 enforce-or-remove), and the two keys the object-kanban renderer actually reads — groupBy and limit — are now DECLARED and validated on both published faces: the TypeScript interface in objectql.ts and the Zod mirror in zod/objectql.zod.ts.

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    Breaking for authored metadata: ObjectKanbanSchema.groupField is RETIRED (objectui#7322, ADR-0049 enforce-or-remove), and the two keys the object-kanban renderer actually reads — groupBy and limit — are now DECLARED and validated on both published faces: the TypeScript interface in objectql.ts and the Zod mirror in zod/objectql.zod.ts.

.changeset/7352-drill-down-config-mirror.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    DrillDownConfigSchema is the zod mirror of DrillDownConfig, and both declarations that carry drillDown reference it — ChartSchema (zod/data-display.zod.ts) and ObjectDataTableSchema (zod/objectql.zod.ts) — so the published validator under @object-ui/types/zod reads the key for the first time (objectui#7352).

.changeset/7363-objectql-union-arms.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectGallerySchema and ObjectDataTableSchema are members of ObjectQLComponentSchema on both faces — the TS union in objectql.ts and the zod union in zod/objectql.zod.ts — so AnyComponentSchema, and with it validateSchema / safeValidateSchema / objectui validate, has an arm for object-gallery and object-data-table nodes (objectui#7363).

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    ObjectGallerySchema and ObjectDataTableSchema are members of ObjectQLComponentSchema on both faces — the TS union in objectql.ts and the zod union in zod/objectql.zod.ts — so AnyComponentSchema, and with it validateSchema / safeValidateSchema / objectui validate, has an arm for object-gallery and object-data-table nodes (objectui#7363).

.changeset/7632-shared-record-source-config.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    That ladder is published contract on both faces — packages/types/src/objectql.ts and its zod mirror both ship .describe() strings naming getDataConfig's order (objectui#6939, maintainer ruling 2026-09-02), pinned by objectql-record-source-refinement-6939.test.ts — and it was hand-copied into five plugin components with no gate holding them together. A change to the ruled order had five edit sites and nothing that noticed a missed one; that is the AGENTS.md #0.1 drift class.

.changeset/7655-chatbot-registration-authoring-faces.md

  • names complex.ts → packages/types/src/complex.ts — edited by this change

    New published symbol: ChatbotSharedKey, the string-literal union of the twenty keys all three registrations read. It is exported from complex.ts because an exported interface may not extend a Pick over a private name (TS4022), so it is emitted into dist/complex.d.ts and is reachable through the published @object-ui/types/complex subpath (it is not re-exported from the package entry). It is a census, not an authoring face.

.changeset/7703-chatbot-dark-keys-retired.md

  • names packages/types/src/complex.ts → packages/types/src/complex.ts — edited by this change

    Each member goes to ?: never on packages/types/src/complex.ts and to retirementTombstone(...) on packages/types/src/zod/complex.zod.ts — both halves, in lockstep, the convention MarkdownSchema.sanitize (objectui#6972), TimelineSchema.timeScale (objectui#6355) and ObjectViewSchema.viewTabBar (objectui#7779) already carry. Each refusal names the key, says why it is retired, and points at what to write instead; one string feeds both the parse-time message and the .describe() metadata, so the two cannot drift.

  • names packages/types/src/zod/complex.zod.ts → packages/types/src/zod/complex.zod.ts — edited by this change

    Each member goes to ?: never on packages/types/src/complex.ts and to retirementTombstone(...) on packages/types/src/zod/complex.zod.ts — both halves, in lockstep, the convention MarkdownSchema.sanitize (objectui#6972), TimelineSchema.timeScale (objectui#6355) and ObjectViewSchema.viewTabBar (objectui#7779) already carry. Each refusal names the key, says why it is retired, and points at what to write instead; one string feeds both the parse-time message and the .describe() metadata, so the two cannot drift.

.changeset/7804-objectql-handler-key-arms.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    The four plain objectql.ts node faces declare the nine handler keys their registered renderers read (objectui#7804, the objectql.ts slice): ObjectFormSchema.onCancel / .onError / .onOpenChange / .onStepChange / .onSuccess, ObjectGallerySchema.onCardClick / .onRowClick, ObjectGridSchema.onNavigate and ObjectViewSchema.onNavigate.

.changeset/7804-tree-view-handler-slot.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    'runtime-slot' and not 'retired', measured at this key's own channel. 'retired' publishes "no renderer reads this key, so nothing could ever run it" — true of the two siblings already tombstoned on this arm (onSelectChange, onExpandChange) and flatly false here, since the read is live and INVOKED. ⚠️ No in-repo host builds a tree-view node carrying the key: the channel is wired end to end and only the supplier is absent, which is the same shape as ObjectFormSchema.onStepChange in this card's objectql.ts slice and is not evidence of a dead read. The TypeScript declaration is unchanged and still callable, so a programmatic host supplies it exactly as before.

.changeset/7917-export-breadcrumb-object-tree-zod-schemas.md

  • names objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    AnyComponentSchema declares 107 node component types. 105 of them could be named on the ./zod barrel — ButtonSchema.safeParse(node), which is what a designer, a form builder or a targeted test needs. The arms declaring type: 'breadcrumb' (navigation.zod.ts) and type: 'object-tree' (objectql.zod.ts) could not: both were already export const in their own module, but index.zod.ts — the package's only zod entry point — did not re-export them, so the schemas existed, were maintained, and were applied by the union while no consumer could name them.

.changeset/7963-alert-dialog-footer-keys-retired.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    Nothing else moves. These spellings are overloaded across the tree and every other owner is a live key on a different declaration — FormSchema.cancelLabel, objectql.ts's confirmLabel, plugin-designer's ConfirmDialog React props, plugin-grid's def.confirmLabel, and plugin-form's ModalForm / DrawerForm, which build a local cancelLabel from schema.cancelText. None is an AlertDialogSchema; none is touched, and a pin asserts it. No fixture, catalog schema, example app or doc fence authored any of the three on an alert-dialog node, so no shipped document is stranded.

.changeset/8415-filter-builder-condition-id.md

  • names complex.ts → packages/types/src/complex.ts — edited by this change

    Breaking for authored metadata: a filter-builder CONDITION must now declare id (objectui#8415). It is declared on both published faces — the TypeScript interface FilterBuilderCondition in complex.ts and the Zod mirror FilterBuilderConditionSchema in zod/complex.zod.ts — so a key the renderer has always required is finally validated instead of silently discarded.

  • names zod/complex.zod.ts → packages/types/src/zod/complex.zod.ts — edited by this change

    Breaking for authored metadata: a filter-builder CONDITION must now declare id (objectui#8415). It is declared on both published faces — the TypeScript interface FilterBuilderCondition in complex.ts and the Zod mirror FilterBuilderConditionSchema in zod/complex.zod.ts — so a key the renderer has always required is finally validated instead of silently discarded.

.changeset/8478-describe-line-addresses.md

.changeset/8478-zod-pins-complex.md

.changeset/8478-zod-pins-form-layout.md

  • names zod/complex.zod.ts → packages/types/src/zod/complex.zod.ts — edited by this change

    The remaining 6 addresses (zod/complex.zod.ts) stayed out of scope for this PR and returned to the queue rather than riding this PR's scope — the card did not close here.

.changeset/8735-objectql-mirror-docblocks-not-defaulted.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    Correct four zod/objectql.zod.ts docblocks that described the behaviour objectui#8317 removed. Since that change the zod mirrors strip imported @objectstack/spec defaults at this package's import boundary, but the docblocks on HttpRequestSchema, ListColumnSchema, SelectionConfigSchema and PaginationConfigSchema still said, in the present tense, that method, prefix.type, type and pageSize are defaulted on parse — the opposite of what each export does. Each now says the key is declared and accepted but NOT defaulted on parse.

.changeset/8767-object-grid-refuses-string-sort.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    Migration. Write the array: sort: [{ field: 'name', order: 'desc' }]. Both keys are required. SortConfig.order carries no ? in @object-ui/types (packages/types/src/objectql.ts) and no .optional() in its zod mirror, and the protocol's own reusable SortItemSchema requires order as well — measured: that schema refuses [{ field: 'name' }] with invalid_value at 0.order. Do not omit it: this block's array arm interpolates whatever is present, so an omitted order lowers to $orderby: 'name undefined' today. That is pre-existing behaviour on the arm this change does not touch, and it is filed as a successor card rather than widened into here.

.changeset/8802-8257-8008-kanban-gantt-family-retirement.md

  • names complex.ts → packages/types/src/complex.ts — edited by this change

    What each retirement was, measured. Three of the four were registration-only: no schema face in @object-ui/types ever declared kanban-ui, kanban-enhanced or gantt as a component node type, so unregistering is the whole retirement. The bare kanban key was the exception — it had a declared arm on both faces (KanbanSchema in complex.ts and its Zod mirror), and a plain deletion there would have been the objectui#7664 failure: BaseSchema is .passthrough(), so a document naming a dropped key validates green and renders nothing. It therefore retires as a named refusal: the Zod union keeps an arm claiming the literal and answers a { "type": "kanban" } document with a message naming object-kanban as the remedy, while the TypeScript half is the absence of the arm from ComplexSchema and of the key from SchemaRegistry, so tsc refuses it at the authoring site.

  • names content/docs/plugins/plugin-kanban.mdx → content/docs/plugins/plugin-kanban.mdx — edited by this change

    The diagnostic's remedy text moves from a tag to a component. It used to end "render ANGLE-BRACKETS(kanban-ui) from a React host that passes onQuickAdd". That sentence is falsified by this change: kanban-ui is no longer a node type key, so a page written to the old advice draws unknown-component. It now names KanbanRenderer from @object-ui/plugin-kanban — still exported, still forwarding both halves by identity — which is the surviving way to get the pair. content/docs/plugins/plugin-kanban.mdx says the same thing the same way.

.changeset/8885-object-chart-drilldown-title-compareto.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectChart.tsx reads all three off schema, and until now neither published copy declared any of them: not the TS interface (packages/types/src/objectql.ts) and not the zod mirror (packages/types/src/zod/objectql.zod.ts). They rode BaseSchema's index signature / .passthrough() and arrived unvalidated. drillDown was the sharpest case — this component's registry inputs advertise it to the designer palette, and @objectstack/spec publishes ChartDrillDownSchema for exactly this carrier, so an author was offered a key that neither published shape mentioned.

  • names packages/types/src/zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    ObjectChart.tsx reads all three off schema, and until now neither published copy declared any of them: not the TS interface (packages/types/src/objectql.ts) and not the zod mirror (packages/types/src/zod/objectql.zod.ts). They rode BaseSchema's index signature / .passthrough() and arrived unvalidated. drillDown was the sharpest case — this component's registry inputs advertise it to the designer palette, and @objectstack/spec publishes ChartDrillDownSchema for exactly this carrier, so an author was offered a key that neither published shape mentioned.

.changeset/8913-object-kanban-columns-declared.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    What moved. ObjectKanbanSchema gains columns on both halves that move together — the TypeScript interface (objectql.ts) and its Zod mirror (zod/objectql.zod.ts). Retiring the bare kanban node type key (objectui#8802) removed the only face that judged a lane, and object-kanban had never declared the key, so it rode BaseSchema's [key: string]: any / .passthrough(): read by the renderer at three sites, named by no published face.

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    What moved. ObjectKanbanSchema gains columns on both halves that move together — the TypeScript interface (objectql.ts) and its Zod mirror (zod/objectql.zod.ts). Retiring the bare kanban node type key (objectui#8802) removed the only face that judged a lane, and object-kanban had never declared the key, so it rode BaseSchema's [key: string]: any / .passthrough(): read by the renderer at three sites, named by no published face.

.changeset/8990-object-kanban-groupby-optional.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    @objectstack/spec declares the key optional — groupBy: z.string().optional() on ObjectKanbanPropsSchema — while this package required it on the TypeScript declaration (packages/types/src/objectql.ts) and on the Zod mirror (packages/types/src/zod/objectql.zod.ts). objectui was therefore narrower than the protocol on a published key: ObjectKanbanSchema.safeParse and safeValidateSchema refused an object-kanban node the protocol accepts, and such a node could not be annotated with its own type.

  • names packages/types/src/zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    @objectstack/spec declares the key optional — groupBy: z.string().optional() on ObjectKanbanPropsSchema — while this package required it on the TypeScript declaration (packages/types/src/objectql.ts) and on the Zod mirror (packages/types/src/zod/objectql.zod.ts). objectui was therefore narrower than the protocol on a published key: ObjectKanbanSchema.safeParse and safeValidateSchema refused an object-kanban node the protocol accepts, and such a node could not be annotated with its own type.

.changeset/8992-user-actions-collapse-and-docblock.md

  • names objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    objectql.zod.ts's UserActionsSchema read stripImportedDefaults(Spec).extend({ group, hideFields, rowColor }), an extension that existed only because @objectstack/spec did not declare those three keys while normalizeListViewSchema folded objectui's legacy showGroup / showHideFields / showColor onto them. The protocol adopted all three in 17.3.0 (objectui#5435's ruling), so the extension is now a second local copy of a protocol declaration — the shape two faces start drifting from — and it collapses into the plain by-reference re-export its own note always said it would become.

.changeset/9092-inline-locale-declared-face.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    • AppComponentSchema.label (app.ts) - ObjectGridSchema.label and .description (objectql.ts) - PageNodeSchema.aria.ariaLabel (layout.ts)

.changeset/9550-object-tree-root-barrel.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectQLComponentSchema declares the node types an ObjectQL block may be. Every one of its arms was a named export of this package's root barrel except ObjectTreeSchema, which was declared in objectql.ts, applied by the union, and re-exported by the ./zod barrel (objectui#7917) — while no TypeScript consumer could name it. There is no ./objectql subpath to reach around the barrel: the package's exports map is pinned by packages/types/src/__tests__/package-exports-manifest.test.ts, and the root barrel was the only route to this type.

.changeset/9606-object-kanban-card-title.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    Both published faces of the object-kanban arm now name the key: the zod mirror ObjectKanbanSchema in zod/objectql.zod.ts and its TypeScript twin, the ObjectKanbanSchema interface in objectql.ts. Both declare it OPTIONAL, at the same requiredness the other face uses, so the two faces accept and refuse the same documents. (Located and cited by SYMBOL: line addresses in zod/objectql.zod.ts have drifted before, and this change is itself about a drifted mirror.)

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    Both published faces of the object-kanban arm now name the key: the zod mirror ObjectKanbanSchema in zod/objectql.zod.ts and its TypeScript twin, the ObjectKanbanSchema interface in objectql.ts. Both declare it OPTIONAL, at the same requiredness the other face uses, so the two faces accept and refuse the same documents. (Located and cited by SYMBOL: line addresses in zod/objectql.zod.ts have drifted before, and this change is itself about a drifted mirror.)

.changeset/calendar-readme-schema-keys-5045.md

  • names packages/types/src/complex.ts → packages/types/src/complex.ts — edited by this change

    README.md's "Schema API / CalendarView" block described a CalendarViewSchema that does not exist. Measured against the interface itself (packages/types/src/complex.ts) and its zod mirror: events — the schema's only required key besides type — was published as events?, so a reader following the README omits it and TypeScript rejects the node; defaultDate was string where the schema says string | Date; and onDateClick was listed as a schema key when it is a CalendarViewProps component prop, sending readers to a different package's surface for a key calendar-view does not have (the schema's key is onDateChange). The block also listed 6 of the schema's 13 keys with nothing saying it was a summary (objectui#5045).

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a claim that was born false (a changeset this change adds is excluded by construction), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Angle-bracketed names in the quoted prose above are rewritten as ANGLE-BRACKETS(name): GitHub deletes tag-shaped fragments from a stored body, and a quote that silently loses the identifier it is about is worse than a visible repair.

Compared the checked-out tree with 4cf57b6da (merge-base with origin/main): 8 file(s) changed outside .changeset/, read against 1127 pending declaration(s) that publish a body (1637 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3049.2 KB 3104.5 KB
Main entry chunk (gzip) 145.7 KB 350 KB
Entry file index-DnyzLIkC.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 545.93KB 130.69KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 215.98KB 59.97KB
fields (index.js) 249.27KB 62.92KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.22KB 2.26KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.83KB 10.95KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.92KB 14.22KB
plugin-charts (index.js) 71.49KB 19.99KB
plugin-chatbot (index.js) 195.34KB 46.51KB
plugin-dashboard (index.js) 131.44KB 34.65KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 253.29KB 65.88KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.71KB 34.16KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 212.64KB 57.91KB
plugin-kanban (index.js) 48.10KB 14.94KB
plugin-list (index.js) 112.73KB 27.69KB
plugin-map (index.js) 21.48KB 6.99KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.41KB 11.93KB
plugin-timeline (index.js) 30.07KB 8.74KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.04KB 21.01KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 104.82KB 34.67KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.04KB 5.36KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Copy link
Copy Markdown
Collaborator Author

ACCEPT — card objectui#9628, reviewed by the domain:spec @ objectui execution seat at 2026-09-17T19:58Z. Enqueueing.

⛔ Nothing below is taken from the PR body or the dev's report.

① Clause-②: no — verified per file, ⛔ not per declaration

The claim is that no declaration face moves. Measured on the API's own patches:

file changed lines NON-COMMENT what the non-comment lines are
packages/types/src/complex.ts 17 0 —
packages/types/src/objectql.ts 32 0 —
packages/types/src/zod/complex.zod.ts 2 2 a .describe() STRING; collapsed: z.boolean().optional() is byte-identical on both sides
packages/types/src/zod/objectql.zod.ts 9 9 one .describe() string and the allowCollapse refusal MESSAGE; the lane's collapsed: z.boolean().optional() is byte-identical

⇒ no member, requiredness or accept set moves on any of the four faces. The two .zod.ts files read as non-comment because zod carries its prose as a string argument, ⭐ which is exactly why "0 non-comment lines" is the wrong instrument there and the patch had to be read.

② The rewritten refusal message still carries every clause objectui#8801's ruling required

This is the sharpest risk in the diff: the PR rewrites a published refusal message that a prior ruling constrained. Read on the head:

  • KanbanColumn.collapsed — present
  • 「not a board-level authored toggle」 — present
  • 「Delete the key」 — present

⭐ And ⛔ the pin that asserts all three was not touched. object-kanban-allow-collapse-retired-8801.test.ts:146/:147/:148 asserts each clause by regex; that file is untouched by this diff and present on the head (lit control). ⇒ the message was rewritten to satisfy a pin that was not moved to fit it.

⭐ Exactly one test file is in this diff, and it is the new one. Not one existing pin was edited — including laneCountHonesty-8307, which the dev's own report says went red on its first cut. The repair for that was an early return in LaneHeading, ⛔ not a change to the pin. That is the distinction between fixing the code and fixing the instrument, and it went the right way.

③ What the message correction actually says, and why it is a ROTTED repair done right

The old text said lane collapse 「is the VIEWER's rather than the author's」 on the board this arm renders. ⚠️ This PR makes that false — and the PR corrects it rather than publishing a contradiction beside itself. The new text splits the two, which is the distinction the old sentence blurred:

  • LANE collapse becomes the author's, honoured, naming objectui#9628
  • SWIMLANE collapse stays the viewer's alone, KanbanImpl per swimlaneField

The same repair lands in the pending .changeset/8801-… entry — which publishes verbatim — and names objectui#9628 「in this same release」, so the two entries in one CHANGELOG do not contradict each other. Frontmatter untouched: the patch is a single hunk at line 50, so nothing above it moved. ⭐ This is a ROTTED repair, not a BORN-FALSE one: the old sentence was true when written, and it is re-stated with its falsifier named rather than silently overwritten.

④ The new pin has controls, including the no-regression leg

Nine rows. The ones that make its zeros readings:

  • 「CONTROL — an undeclared lane key is dropped rather than kept」 ⇒ the two "both faces accept collapsed" rows are about this key, ⛔ not about a passthrough face
  • the collapsed lane's own authored className reaching the reader ⇒ the inert key was ⛔ not a plumbing failure of that lane
  • a sibling lane's authored member painting ⇒ the board renders authored lane members at all
  • the swimlane layout asserted to be the one on screen before its rows are read
  • 「a board that authors the key nowhere renders no disclosure at all」 ⇒ the no-regression leg, which is what lets every pre-existing pin stay green

⑤ Gates — job conclusions, ⛔ not the aggregate

All 36 check runs on head 4e2236eaf5 complete: 0 pending, 0 non-green. Named: Type Check, Lint, Test (shard 1..4/4), Changeset Declaration, Changeset Bump Policy, Changeset Fixed Group Check, Changeset Overwrite Report, Changeset Claim Re-read, Doc Component Type Check, Doc Snippet Type Check, Doc Example Id Check, Doc Fence Language Check, Governed Surface Queue Guard — each completed: success.

The minor on @object-ui/types for a prose-only change is what Changeset Bump Policy and Changeset Fixed Group Check both accept — every workspace package is in the fixed group, so the level is set by plugin-kanban, which earns it.

⑥ One correction to the report, and one design call worth naming

⚠️ The dev's serial-constraint table names objectui#7924's file surface as packages/types/src/views.ts. It is not: PR objectui#9720 touches no source file at all — one test file and two changesets. The intersection conclusion (empty) is right; the premise was wrong, and this seat re-derived the intersections rather than adopting them. ⭐ Recorded because this board has already spent a round on a wrong-surface reading (objectstack#18755).

⚠️ The disclosure appears only on a lane that authored collapsed: true, so an omitted key and an authored collapsed: false stay indistinguishable. Declared, deliberate, and the right call for a no-regression change — ⛔ but it means collapsed: false is still an unhonoured spelling. ⛔ Not filed: it is one sentence in a docblock away from being a stated limit rather than a defect, and the changeset already states it.

Implemented-by: claude/issue-9628-kanban-column-collapsed
Reviewed-by: session_01UanLVj6xvbS6puBCewLr8L

VERDICT: ACCEPT. Turning ready and enqueueing; card objectui#9628 closes on merge.


Generated by Claude Code

@os-sales
os-sales marked this pull request as ready for review September 17, 2026 19:58
@os-sales
os-sales added this pull request to the merge queue Sep 17, 2026
Merged via the queue into main with commit dea17b4 Sep 17, 2026
38 checks passed
@os-sales
os-sales deleted the claude/issue-9628-kanban-column-collapsed branch September 17, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

2 participants