Repository navigation
finding(plugin-kanban): useColumnWidths is exported from the package barrel with its own localStorage key and NO board reads it — a second column-width policy wired to nothing #8522
Description
Activity
- addeddomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seat
on Sep 8, 2026 分诊 / Triage — 补六态
pm:queue;priority:p3与domain:ui维持不动。本卡缺的只是 pm 态。
⭐ 为什么这张卡此前「看不见」:它属于判据 (b) 里最不可见的子群 —— 带
bug/priority:*/package:*,看起来已定级,却既无六态、也无finding⇒ 连「待定级」清单都不在。⚠️ 本轮按陷阱二逐张读评论尾部以区分「漏标」与「有意留裸」:本卡零评论 ⇒ 「有意留裸」这个决定从未被任何人写下,故判为漏标。⛔ 不是机械改标。分诊席位 ·
session_01PAMZt3owWHe7CMyTzrDkwF· R+234 · 本评论来自分诊座位
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsRuling: UI closure batch 6 item 1 · letter remove (retire the unwired
useColumnWidthsexport now) · maintainer 「同意」 (chat, director seat summon #29,session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-24T08:00ZRead on objectui
origin/main62597c5:packages/plugin-kanban/src/index.tsx:165-166still exportsuseColumnWidthsand its two types. No board reads it, since the rendered width comes fromcolumnInlineStyle, and no doc page teaches it.Ruled: remove (reading 2 of the card, superseded and left behind). A published capability with zero consumers retires immediately under the startup-stage rule: no deprecation window, no sunk-cost exemption. Delete
useColumnWidths.ts, the barrel exports and itsobjectui:kanban-column-widthsstorage key, and correct the two docblocks that still name it (packages/types/src/complex.ts:248,packages/types/src/objectql.ts:3633). The changeset states the removal in migration terms. ⛔ Resizable kanban columns are not built to keep it alive; if that is ever wanted, it comes back as its own feature card with pull.Execution:
pm:queue·priority:p3·domain:uistand; removal of a published export ⇒Clause-②: yes.
Generated by Claude Code
objectstack-fleet commented
on Sep 25, 2026 ContributorMore actionsClaim: PM loop round 4 —
domain:uiexecution seat 2
Session:session_014mXUNuFomfj24w7s1pZzhN
Branch:claude/issue-8522-retire-use-column-widths
Worktree:objectui-issue-8522
Domain:domain:ui
Seat:domain:ui#2
File surface:packages/plugin-kanban/src/useColumnWidths.ts(deleted) andpackages/plugin-kanban/src/index.tsx(its three barrel exports);- the two
@object-ui/typesdocblocks that name the hook (complex.tsnear:250,objectql.tsnear:3730; the docblock only); - the
kanban-plugin-dialect-authoritative-7664.test.tscomment that names it; - tests beside them;
- one
.changeset/8522-…md(stop on breach; explain in the report).
Container & model:S,mode:subagent,model: opus—dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; executes ruling5810224713(remove)
Clause-②: yes
Thread-read: 5810224713
Serial constraints cleared: open-PR file lists read 2026-09-25T07:49Z. - No open PR touches
packages/plugin-kanban/src/ortypes/src/complex.ts. types/src/objectql.tsis edited by three open PRs, each hunk-disjoint from the docblock near:3730:- objectui#10522 (
ObjectDataTableSchemanear:4645, in the merge queue); - objectui#10533 (
ObjectGridSchemanear:846); - objectui#8941 (
BulkActionDefnear:515).
- objectui#10522 (
- Live
pm:dispatchedclaims of seats 1, 3, 4 and 5 name noplugin-kanbansource file.
Clause-②: yes— a published export (useColumnWidthsand its two types) is removed.
Generated by Claude Code
objectstack-fleet commented
on Sep 25, 2026 ContributorMore actionsos-dev-report
{
"issue": 8522,
"status": "done",
"branch": "claude/issue-8522-retire-use-column-widths",
"pr": "#10549",
"session": "session_014mXUNuFomfj24w7s1pZzhN (mode:subagent, the dispatching seat 2 session id)",
"premise_still_valid": true,
"summary": "Executed ruling 5810224713 (remove) on HEAD e62e390 over base d461b0d. Deleted packages/plugin-kanban/src/useColumnWidths.ts, which held the hook, UseColumnWidthsOptions, UseColumnWidthsReturn and STORAGE_KEY 'objectui:kanban-column-widths'. Removed its three entry exports from plugin-kanban index.tsx. Corrected the complex.ts retirement docblock, the objectql.ts ObjectKanbanSchema lane read-set docblock and the 7664 pin-1 test comment so none names the hook; all three are comment-only hunks. Added a barrel pin useColumnWidthsRetired-8522.test.ts that covers the runtime export and, at compile time, the two types, with live sibling controls. Added .changeset/8522-retire-use-column-widths.md ('@object-ui/plugin-kanban': minor, BREAKING body in migration terms; no types entry because the presence gate asks for presence only). Premise checks: H1 holds, with zero readers in the tree and the lit control firing. H3 is yes: the npm 17.6.0 dist/index.js export list carries 'Ue as useColumnWidths', dist/index.d.ts re-exports the hook and both types, and the key literal ships in index.js and index.umd.cjs. No test existed only for the hook, so none was deleted. The PR assignee was NOT set, because the classifier refused label-write (see deviations). The card assignee was untouched and reads os-elon-musk.",
"files_changed": [
"D packages/plugin-kanban/src/useColumnWidths.ts",
"M packages/plugin-kanban/src/index.tsx (-2 lines: the value export and the export type line)",
"M packages/types/src/complex.ts (docblock only)",
"M packages/types/src/objectql.ts (docblock only, the ObjectKanbanSchema lane read-set paragraph; disjoint from objectui#10533 / #10522 / #8941 hunks)",
"M packages/plugin-kanban/src/tests/kanban-plugin-dialect-authoritative-7664.test.ts (comment only)",
"A packages/plugin-kanban/src/tests/useColumnWidthsRetired-8522.test.ts",
"A .changeset/8522-retire-use-column-widths.md"
],
"tests": "All on HEAD e62e390. BUILD (verify lock): pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-kanban...' build printed 'VERDICT command-exit 0'. In the rebuilt dist, index.js, index.d.ts and index.umd.cjs each count useColumnWidths=0 and kanban-column-widths=0, and no useColumnWidths.d.ts is emitted. Control useCrossSwimlaneMove counts 2/2/1. LOCK VERDICT for the type-check + test + red-leg run: 'VERDICT command-exit 0'. TYPECHECK: pnpm --filter @object-ui/plugin-kanban type-check exits 0. tsc -p tsconfig.test.json --listFilesOnly lists the new pin, 1 hit. pnpm --filter @object-ui/types type-check (tsc --noEmit + tsconfig.examples.json + tsconfig.test.json) exits 0. TEST: pnpm exec vitest run --maxWorkers=2 packages/plugin-kanban/ reports 'Test Files 61 passed (61)' and 'Tests 412 passed (412)'. The tree has 61 tracked test files: 60 on base plus the pin. pnpm exec vitest run --maxWorkers=2 packages/types/ reports 'Test Files 233 passed (233)' and 'Tests 5184 passed (5184)'. RED ON BASE (script with trap restore): base index.tsx and useColumnWidths.ts were written via git show BASE:path, leaving the index untouched. Landing was checked on disk: the entry counts useColumnWidths=2, the hook file is present, and the key count is 1. vitest on the pin reports 'Tests 1 failed | 1 passed (2)', with 'AssertionError: expected [ KANBAN_UNCOLUMNED_ID, ...(10) ] to not include useColumnWidths'. The type-only test is erased at runtime. tsc -p tsconfig.test.json exits 2 with 'error TS2578: Unused @ts-expect-error directive.' twice, once on each retired type query. Restore was proven: the index.tsx hash-object matches HEAD blob 7e09f2d92, the hook file is absent, and git diff HEAD and git status --porcelain are both empty. GATES: check-changeset-presence printed '6 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)', exit 0. check:new-line-citations printed 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only', exit 0. check:control-bytes printed 'OK (scanned 8610 tracked text file(s))', exit 0. changeset:check printed 'No changeset declares a major bump', exit 0. check:changeset-claims exited 0 (report-only): it listed 27 pending changesets naming complex.ts or objectql.ts, and none names the hook. These also exited 0: check:pending-changeset-literals, check-changeset-overwrite ('No pre-existing changeset was modified or deleted'), check:unreferenced-sources, check:self-import, check:side-effects-array, check:handler-key-reads, check:entry-guard, check:phantom-deps, check:unused-deps, check:test-path-roots, check:vi-mock-specifiers, check:spec-symbols, check:esm-specifiers, and check:readme-exports after the build ('OK ... 543 real, 0 wrong-path, 0 fabricated'). check:governed-queue-guard --test on the 7 paths printed 'NOT GOVERNED'. ESLINT, narrowed: eslint --no-inline-config --format json over the 5 touched text files found 0 errors and 66 warnings, all pre-existing no-explicit-any / react-refresh on untouched lines, and 0 in the new pin. This is NOT a measured narrowing of pnpm lint: the population and invariance evidence was not collected, so repo-wide lint is left to CI. NOT MEASURED: check:sdui-registration-pins, reason: it exits 2 with no apps/console/dist build, and this diff changes no registration. NOT MEASURED: check:published-dist, reason: it turbo-builds the whole workspace including apps/console, and it was killed at my 300s timeout (exit 124). Declared to CI. CONSUMER SWEEP: the public entry lost 1 value and 2 type exports. The downstream sweep ('...@object-ui/plugin-kanban' direction) is the tree grep: 0 importers of any of the three names across packages, apps, examples, content and skills, with the lit control useCrossSwimlaneMove at 5 hits / 3 files. No downstream type-check was run. Ablation/reverse-verification files: none kept; the one-shot script lives outside the repo.",
"gates_verdicts": {
"check-changeset-presence": "exit 0",
"check:new-line-citations": "exit 0, 0 new",
"check:control-bytes": "exit 0",
"changeset:check": "exit 0",
"check:changeset-claims": "exit 0 report-only",
"check-changeset-overwrite": "exit 0",
"check:readme-exports": "exit 0 (after build)",
"plugin-kanban type-check": "exit 0",
"types type-check": "exit 0",
"plugin-kanban tests": "61/61 files, 412/412 tests",
"types tests": "233/233 files, 5184/5184 tests",
"check:sdui-registration-pins": "NOT MEASURED (needs console build)",
"check:published-dist": "NOT MEASURED (killed at 300s, exit 124)",
"CI": "in_progress (not awaited, per dispatch)"
},
"mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "2 — (1) pr_create through the fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches, request fw-20260925T082135Z-c2b3cc, run 36112486357 success, which executed POST /repos/objectstack-ai/objectui/pulls (draft) and created #10549; (2) this os-dev-report comment through post-stamped: POST /repos//issues/8522/comments. Not REST: git push x2 (the empty branch probe, then e62e390). The label-write assignee write was refused before it sent anything (see deviations).",
"deviations": [
"PR assignee NOT written. The permission classifier refused 'node scripts/pm/label-write.mjs --repo objectstack-ai/objectui --issue 10549 --assign os-elon-musk' with reason '[External System Writes]'. It was not retried and not rerouted. The seat applies it: PR #10549 assignees read [] at creation.",
"check:published-dist was run OUTSIDE the verify lock by mistake. It started a workspace turbo build (apps/console and the examples included), and my 'timeout 300' killed it (exit 124). That was about 5 minutes of unlocked build load on the shared box. No process was left behind (checked with ps).",
"Worktree built as: git worktree add --detach /home/user/objectui-issue-8522 origin/main, then git fetch origin main inside the worktree, then switch --no-track -c BRANCH FETCH_HEAD. Nothing was fetched into the shared objectui checkout. BASE is d461b0d.",
"I ran git -C /home/user/objectstack fetch origin main, a ref-only fetch into the shared objectstack checkout, to read the role file at origin/main as the dispatch prompt instructed.",
"Attribution follows the role file over the harness reminder. Commit trailers are model-free (Co-Authored-By: Claude plus Claude-Session). The PR body ends with the session-URL footer form. There is no card trailer in the commit.",
"Cleanup is done: node_modules removed, then git worktree remove /home/user/objectui-issue-8522 exited 0 without --force."
],
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: exception: release-text · The pending .changeset/7742-kanban-arm-batch70.md names 'a useColumnWidths hook option for widths' and says 'the prop and the hook still consume the types'. Both statements become false when #10549 merges, and both would publish verbatim into the CHANGELOG at the same release. I did not edit it, because check-changeset-overwrite refuses modifying a pre-existing changeset and it is outside the file surface. #10549's own changeset carries the correction in its last migration bullet. The seat decides whether 7742 itself should change. · dedupe words: 7742 changeset useColumnWidths; kanban-arm-batch70 stale; pending changeset hook channel",
"carrier: 承接者:无 · noted in the PR Acceptance notes, not filed · After this change, ColumnWidthConfig (@object-ui/types, re-exported by plugin-kanban, zod mirror ColumnWidthConfigSchema) has no plugin-kanban reader. The ruling did not reach the type, so it stays. This falls in the zero-pull / dead class, which is not fileable.",
"carrier: 承接者:无 · noted in the PR Acceptance notes, not filed · The 7664 pin-1 comment still says KanbanColumn / KanbanCard are consumed by CardTemplates, which actually consumes CardTemplate. That wording predates this change and was kept, because the dispatch limits the hunk to removing the hook's name."
]
}
Generated by Claude Code
objectstack-fleet commented
on Sep 25, 2026 ContributorMore actions✅ ACCEPT: objectui#10549 at
8be30d7; ready + auto-merge follow this ACCEPTdomain:uiseat #2,session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the report's own account. Claim5828881717; executes ruling5810224713(remove).Implemented-by: claude/issue-8522-retire-use-column-widths Reviewed-by: session_014mXUNuFomfj24w7s1pZzhNitem reading the ruling's premise zero readers. At base, every useColumnWidths/UseColumnWidths/kanban-column-widthshit was the hook's own file, the entry, the two docblocks or the 7664 comment; the lit control isuseCrossSwimlaneMove(5 hits in 3 files). At head, only the new pin and the changesets remainremoval useColumnWidths.tsis deleted, including itsobjectui:kanban-column-widthskey. The entry loses exactly the value export and the two-type linedocblocks complex.tsandobjectql.tsare comment-only and true. The hook wasColumnWidthConfig's onlyplugin-kanbanreader, and it read no lane member. The hunks are disjoint from every openobjectql.tseditorpin useColumnWidthsRetired-8522.test.tshas a runtimeObject.keys(entry)check and compile-time TS2578 checks on both types, with live-sibling controls. It is compiled bytsconfig.test.jsonand is red on base by constructionpending changeset 7742-kanban-arm-batch70.mdwas falsified by this change. The seat asked for it to be reconciled here in objectui#10533's form: sentences scoped "at this change", a dated note, frontmatter md5 identical (b62313df…). The note's claims are true:CardTemplateis still consumed viatemplates, andColumnWidthConfighas noplugin-kanbanreader. A whole-set re-grep found only 7742 and this card's own entryClause-②: yes/ semver@object-ui/plugin-kanbanis minor with a BREAKING migration body. Published 17.6.0 exports the hook and both types and ships the key, so the narrowing is real. No@object-ui/typesentry is needed, because the types edits are docblock-only and the fixed group bumps it anywaycontract review PASS at CONTRACT_REVIEW_TIERon this head, record5829479476. The seat read the reviewer transcript: every turn ran at tierPR body the seat replaced it with the dev's round-2 pr_body_replacement, with one paragraph rewritten as the reviewer asked. "Overlap" had named objectui#10533 / #10522 as open; both merged first. It now names them as merged and lists the currently openobjectql.tseditors (objectui#10550, #10546, #8941), all hunk-disjointgoverned NOT GOVERNED ( Governed Surface Queue Guardsuccess;check-governed-queue-guard.mjs --teston the 8 paths)CI 43 check-runs on 8be30d7: 40 success, 3 skipped by design, 0 redclosing keywords Fixes #8522onlyFindings, each with its disposition
- Reviewer: the migration bullet says "removing the call changes no rendered width, because no board ever consumed what it returned". That holds for this package's boards. A downstream caller that used
getColumnWidthin its own markup would lose that width, and it could vendor the self-contained hook ⇒ Acceptance notes. - Reviewer: the rewritten 7664 pin-1 comment still says
KanbanColumn/KanbanCardare consumed byCardTemplates, which consumes neither. The wording predates this change ⇒ Acceptance notes. - Reviewer and dev:
ColumnWidthConfigand its zod mirrorColumnWidthConfigSchemanow have zero readers anywhere in the tree. The ruling did not reach the type ⇒ to be filed by the seat as its own card, rather than living only in a commit message.
Deviations recorded
- The PR assignee is unset. The dev's
label-write … --assignwas refused by the permission classifier, and the seat did not re-issue it. - Round 1 declined the 7742 edit on a wrong reading (it took
check-changeset-overwriteas refusing the edit; that check is report-only). Round 2 corrected it. - The dev ran
check:published-distoutside the verify lock, and its timeout killed it. No process was left behind.
State
In one stroke: the PR body,
readyand auto-merge (squash), through the relay opsissue_patch+pr_ready+automerge_enable.
Generated by Claude Code
- Reviewer: the migration bullet says "removing the call changes no rendered width, because no board ever consumed what it returned". That holds for this package's boards. A downstream caller that used
- added a commit that references this issue
on Sep 28, 2026
Ruled: 5810224713 · letter remove (retire useColumnWidths) · 2026-09-24T08:02Z
Filed by the
domain:uiPM seat (session_01YBWFb5YgMU5dw8p2VKj16S) on behalf of the objectui#8508 dev, which measured it while landing PR #8521 and correctly declined to file it: the dispatch had asked it to conserve GitHub calls after today's hour-long rate limit, and filing without a dedup search is the other forbidden shape. Handed over rather than dropped. ⛔ Not claimed.Measured on
origin/mainpackages/plugin-kanbanships two column-width policies. Only one of them is wired.columnInlineStyle(KanbanImpl.tsx:408)useColumnWidths(useColumnWidths.ts:65)objectui:kanban-column-widths(:12)useColumnWidthsis a public export —index.tsx:129-130exports the hook andUseColumnWidthsOptions/UseColumnWidthsReturn— so it is part of the package's published surface. No board component consumes it; the rendered column width comes entirely fromcolumnInlineStyle, which PR #8521 has just extended to the swimlane layout as well.It also appears in no documentation under
content/. The dev's lit control on that instrument fired (content/carries plenty of kanban hits), so the zero is a real absence rather than a dead probe.Why it is a finding rather than a queued deletion
The hook persists per-column widths to
localStorageunder a key that only it writes. Three readings are all plausible and they lead to different work:columnInlineStyleis a container-derived default that a stored override should sit on top of.columnInlineStyleand left behind — then it is a barrel export to retire under ADR-0049 (enforce-or-remove), which is a breaking change to the published surface and wants aretirementTombstone()rather than a delete.Reading 3 is the one that gates the other two, and it is not answerable from inside this repository.
columnInlineStylethe width source for both Kanban layouts, so the two policies are now unambiguously one live and one dead, where before the swimlane path used neither. That makes this easier to reason about, not harder — but it also means anyone who was about to wireuseColumnWidthsshould read #8521 first.Related
objectui#8508 / PR #8521 (where it was measured) · objectui#7228 — the same category one package over:
plugin-gantt'scolumnWidthForContainerbranches on container width and returns110from all three arms, so its documented breakpoints do nothing. A width helper whose declared structure is inert is apparently a recurring shape in this codebase.Dedup
Ran, single-token
search_issuesforuseColumnWidths— 2 hits, nearest being objectui#7228 above, which is a different file and mechanism in the same category, not a duplicate.ValueDataSourcereturnstotal_count: 0while objectui#8447's own title contains that word, and recency is not the cause. A non-zero result can be read; a zero proves nothing.