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 Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(plugin-gantt): taskListWidth_LEGACY_REMOVED is a declared-and-never-read const null left behind by a finished refactor #7421
Found while implementing the task-list width work in packages/plugin-gantt/src/GanttView.tsx (PR #7420). Filed unassigned, not claiming, and deliberately not fixed in that PR — it is outside its scope.
What is there
One line inside the GanttView component body:
consttaskListWidth_LEGACY_REMOVED=null;// taskListWidth now derived from useResizeObserver above
Measured on origin/main24d4a21ff5ea7a4baa5915c0e3701cd06b8f77e9:
the identifier appears exactly once in the whole repo — its own declaration. git grep -n taskListWidth_LEGACY_REMOVED returns one line, so there is no reader anywhere, in plugin-gantt or outside it.
its value is the literal null, so it carries no state and no side effect.
its comment describes a migration that has already happened: the real taskListWidth is derived a few hundred lines above it from the useResizeObserver container width.
Why it is worth a card rather than nothing
It is inert, so nothing is broken today. The cost is that it reads like a live seam: a name with LEGACY_REMOVED in it, inside the component, sitting near the width logic, invites the next reader to believe there is a legacy width path still to be reconciled. The comment is the only documentation of a refactor that is complete, and it documents it in the one place a reader will mistake it for a to-do.
It also sits directly adjacent to the container-sizing helpers that #7228 already covers (columnWidthForContainer branching on width and returning 110 from all three arms). Same file, same class of leftover — a dead arm of a finished change that the compiler and lint have no reason to complain about — so the two may want to be settled in one stroke. That is triage's call, not this card's.
Reproduction
git grep -n 'taskListWidth_LEGACY_REMOVED' # exactly one hit, the declaration
Suggested directions — none proposed as decided
A. Delete the line. Nothing reads it; if the fact that the width now comes from the ResizeObserver is worth recording, the derivation site already carries a comment saying so.
B. Delete the line and fold the surviving intent into the comment already sitting on the taskListWidth derivation, so the note lives where a reader needs it.
C. Leave it. Cheapest, and it keeps costing one confused read at a time.
Related: #7228 (the same file's other dead sizing arm), #7204 / #7224 (the width work this was found under).
Triage — R+118.priority:p3 · pm:queue · domain:ui. ⛔ Not claimed, not dispatched.
Verification (origin/mainac8d523)
Confirmed, and the whole of it is one line — packages/plugin-gantt/src/GanttView.tsx:2323:
consttaskListWidth_LEGACY_REMOVED=null;// taskListWidth now derived from useResizeObserver above
git grep across packages/ returns this single occurrence, so the name is declared once and read nowhere. The card's reading is exact: a finished refactor left its own tombstone behind as a live const.
Why p3, and why it is still worth a card
Zero behavioural effect and zero risk either way. What earns the card is that the name is a false signal: _LEGACY_REMOVED reads as "this is retained deliberately for a reason recorded elsewhere", so the next reader spends time looking for the reason. Deleting the line is strictly cheaper than the next person re-deriving that it is dead.
⛔ One thing not to lose in the deletion: the trailing comment records where the value went (useResizeObserver above). If that fact is not already stated at the useResizeObserver call site, carry it there rather than deleting it with the line.
Anchoring
domain:ui — packages/plugin-gantt is a published library, which the objectui three-stream split routes to domain:ui.
Good first candidate. Self-contained, one line, no contract surface, no decision to make.
Claim. Session session_01EMrWaQw3XS5DxTHxp4yRyC (dispatched by the domain:ui PM seat).
Branch: claude/issue-7421-tasklistwidth-tombstone
Base: a27d153c2c262535569d8271c18c0fef830fa31a (origin/main at claim time)
Clause-②: no — the diff deletes one function-localconst bound to null inside the GanttView component body and adds a comment. It touches no authorable declaration: the identifier is not exported, not a prop, not a type/zod/spec key, and it does not exist outside this one line anywhere in the fleet.
Derived, not assumed (_LEGACY_REMOVED names get the declaration check anyway):
objectui git grep -n 'taskListWidth_LEGACY_REMOVED' → 1 line, packages/plugin-gantt/src/GanttView.tsx:2323, its own const declaration. Read sites (same grep, minus lines matching the binder form) → 0.
objectstack git grep for taskListWidth_LEGACY_REMOVED and for the bare taskListWidth → 0 files / 0 lines for both, in a run where the controls gantt (94 files / 359 lines) and rowHeight (34 / 74) fired. No spec/zod/type declaration of this key exists in the platform repo.
Path limb, for the record: SUSPECT_TIER_GLOBS declares packages/spec/src/**; this diff lands in objectui packages/plugin-gantt/src/.
Note for the seat: the assignee field is empty on this card at claim time. Not writing it (the seat owns it) — recording it as a PM-side half-state.
{
"issue": 7421,
"status": "done",
"branch": "claude/issue-7421-tasklistwidth-tombstone",
"pr": "https://github.com/objectstack-ai/objectui/pull/7511",
"premise_still_valid": true,
"summary": "Deleted `const taskListWidth_LEGACY_REMOVED = null` (and the whitespace-only line under it) from packages/plugin-gantt/src/GanttView.tsx:2323, and carried the one fact its trailing comment held to the useResizeObserver call site at line 875, which had no comment at all — triage asked for exactly that transfer. Plus an empty-frontmatter changeset, since released source moved but nothing releases. Head sha 73ef5ec7a; diff is 2 files, 24 insertions, 2 deletions. TWO CORRECTIONS TO THE BRIEF, both harmless: (1) the brief anchors on packages/plugin-gantt/src/ObjectGantt.tsx and PR #7391 / 7c3df8f0c, but the card and its triage both name GanttView.tsx — a different file; 7c3df8f0c touched only ObjectGantt.tsx and never the file I edited, so the row-ceiling and settled-schema-fetch-gate warning did not apply. (2) the brief says the PM seat has set the assignee; the card's assignees array was EMPTY at claim time and still is. I did not write it. Also correcting the CARD: it says this line is something 'the compiler and lint have no reason to complain about' — ESLint did complain, as @typescript-eslint/no-unused-vars; it just never failed CI because unused vars sit at warning severity here while #7332 lifted only unused imports to error. The card's conclusion is unaffected.",
"tests": "All readings on head sha 73ef5ec7a, in the dedicated worktree /home/user/objectui-7421, heavy runs serialized through scripts/pm/os-verify-lock.sh (slot dev-7421-gantt; one wait of 325s behind the issue-7319 agent, waited in-turn, not ended). LIVENESS PROBE, declaration form and read sites probed separately, never the bare word: declaration `git grep -E '\\b(const|let|var|function|class|interface|type|enum)\\s+taskListWidth_LEGACY_REMOVED\\b'` = 1 hit (GanttView.tsx:2323, its own binding); read sites = the same identifier grep minus lines matching the binder form = 0. CONTROLS THAT FIRED IN THE SAME RUN: identical two shapes on `taskListWidth` = 3 declarations / 20 read sites, on `rowHeight` = 2 / 360. objectstack swept too: 0 files 0 lines for both `taskListWidth_LEGACY_REMOVED` and bare `taskListWidth`, in a run where controls `gantt` (94 files, 359 lines) and `rowHeight` (34, 74) fired — no spec/zod/type declaration of the key exists in the platform repo, which is what makes Clause-② a `no` rather than an assumption. WORD-COUNT TRAP MEASURED: in GanttView.tsx `\\btaskListWidth\\b` goes 21 to 20 across this diff, not 21 to 0, because the tombstone's own comment said `taskListWidth` once; the declaration-form count goes 1 to 0. REVERSE VERIFICATION: committed first, then the pre-fix file restored from base a27d153c2 under `trap ... EXIT INT TERM` with an absolute REPO_ROOT path. Mutation proved on disk — blob 756df02d3 to 96033b44f, deleted-text grep 0 to 1, injected-comment grep 1 to 0. Restore proved BY STATE, never by exit code — blob back to 756df02d3 byte-equal to HEAD's, `git diff HEAD` printed nothing, greps back to 0 and 1. No rebuild leg is owed: both gates read source directly (eslint lints the file; vitest resolves packages/plugin-gantt/src through the root config), so no dist sits between mutation and reading. WHAT MOVED: `eslint .` on the package = 354 problems / GanttView.tsx 17 with the tombstone present, 353 / 16 with it deleted, and the moving row is exactly `2323:9 warning 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used @typescript-eslint/no-unused-vars`. CONTROL THAT STAYED: the `'currentDate' is assigned a value but never used` warning is present in both legs, and the other 353 rows are identical. NO BEHAVIOURAL PIN EXISTS AND NONE WAS INVENTED — the binding was `null` with zero readers, and the suite is 485-green on BOTH sides of the ablation (62 files / 485 tests, mutated and restored alike), which is the measurement of that claim rather than an assertion of it. GATES, each quoted from its own verdict line, dependency closure built first (`pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build`, exit 0, so nothing below is a could-not-run): `pnpm --filter @object-ui/plugin-gantt type-check` exit 0 running `tsc --noEmit && tsc -p tsconfig.test.json` (script name echoed, so not a zero-match no-op); `pnpm --filter @object-ui/plugin-gantt lint` exit 0 with `✖ 353 problems (0 errors, 353 warnings)`, all pre-existing; `pnpm exec vitest run --maxWorkers=2 packages/plugin-gantt/src` from the REPO ROOT (a package-cwd run is refused, objectui#3378) with `Test Files 62 passed (62)` / `Tests 485 passed (485)`; `node scripts/check-changeset-presence.mjs` exit 0 — '1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s) ... Every one of them has an EMPTY frontmatter — declared as releasing nothing, which is the explicit exemption and a complete answer to this gate'; `node scripts/check-changeset-no-major.mjs` exit 0 — 'No changeset declares a major bump'; `node scripts/check-control-bytes.mjs` exit 0 — 'check-control-bytes: OK (scanned 6195 tracked text file(s); skipped 85 binary)'. Every exit code was captured with output redirected to a file FIRST, never read after a pipe. DECLARED NARROWING: the repo lint job is `turbo run lint`, i.e. per-package `eslint .`, and only the one package this diff touches was linted. The three readings that make that a measurement and not a skip — population from ESLint's own config resolution rather than my guess (`eslint . --format json` reports 92 files linted in packages/plugin-gantt), the counts above taken from that run, and `eslint.config.js` configuring no type-aware linting at all (no parserOptions.project, no projectService), so this diff cannot move the verdict of any file it does not contain. CI runs the full farm regardless; per the standing ruling I am not waiting for it.",
"mcp_calls": "5 — issue_read(get #7421), add_issue_comment(claim), create_pull_request(#7511), issue_write(create #7512), add_issue_comment(this report). Every READ went through the zero-quota REST channel, which was probed first and answered 200 for repo-scoped reads (comments, issue, PR readback, label-scoped issue list). REST /search/issues answered 403, so the duplicate check for the new finding switched channel — declared here — to the label-scoped REST LIST endpoint (state=open, labels=finding, one page, 73 results so complete under the 100 cap) plus a local grep, rather than spending an MCP search. No broad table scan was run.",
"open_questions": [],
"out_of_scope_findings": [
"filed as #7512: three more declared-and-never-read residues in the same file — HEADER_HEIGHT=50 (line 43) and COLUMN_WIDTH=100 (line 44), neither exported and both with 0 read sites repo-wide, plus the currentDate/setCurrentDate useState pair (line 873) whose value and setter are both unread. COLUMN_WIDTH is the costly one: the width the gantt actually renders is 110 (from columnWidthForContainer, #7228), so the stale constant states a DIFFERENT wrong number from the live one. Unassigned, labelled finding + domain:ui, not fixed in this PR — same file and same class, but a separate unit of work with its own reverse verification, and #7228 already holds a claim-shaped interest in this file."
]
}
这不是记账瑕疵。CLAUDE.md 对它的判词是逐字的:"an unassigned issue reads as an open invitation: two that start on it burn the same hours twice, then race to land conflicting shapes." 两张卡在整个执行期里对其他 agent 都显示为「无人认领、在队列里」。没有发生碰撞是运气,不是纪律。
Activity
huangyiirene commentedon Sep 3, 2026
Triage — R+118.
priority:p3·pm:queue·domain:ui. ⛔ Not claimed, not dispatched.Verification (
origin/mainac8d523)Confirmed, and the whole of it is one line —
packages/plugin-gantt/src/GanttView.tsx:2323:git grepacrosspackages/returns this single occurrence, so the name is declared once and read nowhere. The card's reading is exact: a finished refactor left its own tombstone behind as a liveconst.Why
p3, and why it is still worth a cardZero behavioural effect and zero risk either way. What earns the card is that the name is a false signal:
_LEGACY_REMOVEDreads as "this is retained deliberately for a reason recorded elsewhere", so the next reader spends time looking for the reason. Deleting the line is strictly cheaper than the next person re-deriving that it is dead.⛔ One thing not to lose in the deletion: the trailing comment records where the value went (
useResizeObserverabove). If that fact is not already stated at theuseResizeObservercall site, carry it there rather than deleting it with the line.Anchoring
domain:ui—packages/plugin-ganttis a published library, which the objectui three-stream split routes todomain:ui.Good first candidate. Self-contained, one line, no contract surface, no decision to make.
Generated by Claude Code
os-project-manager commentedon Sep 3, 2026
Claim. Session
session_01EMrWaQw3XS5DxTHxp4yRyC(dispatched by thedomain:uiPM seat).Branch:
claude/issue-7421-tasklistwidth-tombstoneBase:
a27d153c2c262535569d8271c18c0fef830fa31a(origin/mainat claim time)Clause-②: no — the diff deletes one function-local
constbound tonullinside theGanttViewcomponent body and adds a comment. It touches no authorable declaration: the identifier is not exported, not a prop, not a type/zod/spec key, and it does not exist outside this one line anywhere in the fleet.Derived, not assumed (
_LEGACY_REMOVEDnames get the declaration check anyway):git grep -n 'taskListWidth_LEGACY_REMOVED'→ 1 line,packages/plugin-gantt/src/GanttView.tsx:2323, its ownconstdeclaration. Read sites (same grep, minus lines matching the binder form) → 0.git grepfortaskListWidth_LEGACY_REMOVEDand for the baretaskListWidth→ 0 files / 0 lines for both, in a run where the controlsgantt(94 files / 359 lines) androwHeight(34 / 74) fired. No spec/zod/type declaration of this key exists in the platform repo.SUSPECT_TIER_GLOBSdeclarespackages/spec/src/**; this diff lands in objectuipackages/plugin-gantt/src/.Note for the seat: the assignee field is empty on this card at claim time. Not writing it (the seat owns it) — recording it as a PM-side half-state.
Generated by Claude Code
Generated by Claude Code
os-project-manager commentedon Sep 3, 2026
os-dev-report
{ "issue": 7421, "status": "done", "branch": "claude/issue-7421-tasklistwidth-tombstone", "pr": "https://github.com/objectstack-ai/objectui/pull/7511", "premise_still_valid": true, "summary": "Deleted `const taskListWidth_LEGACY_REMOVED = null` (and the whitespace-only line under it) from packages/plugin-gantt/src/GanttView.tsx:2323, and carried the one fact its trailing comment held to the useResizeObserver call site at line 875, which had no comment at all — triage asked for exactly that transfer. Plus an empty-frontmatter changeset, since released source moved but nothing releases. Head sha 73ef5ec7a; diff is 2 files, 24 insertions, 2 deletions. TWO CORRECTIONS TO THE BRIEF, both harmless: (1) the brief anchors on packages/plugin-gantt/src/ObjectGantt.tsx and PR #7391 / 7c3df8f0c, but the card and its triage both name GanttView.tsx — a different file; 7c3df8f0c touched only ObjectGantt.tsx and never the file I edited, so the row-ceiling and settled-schema-fetch-gate warning did not apply. (2) the brief says the PM seat has set the assignee; the card's assignees array was EMPTY at claim time and still is. I did not write it. Also correcting the CARD: it says this line is something 'the compiler and lint have no reason to complain about' — ESLint did complain, as @typescript-eslint/no-unused-vars; it just never failed CI because unused vars sit at warning severity here while #7332 lifted only unused imports to error. The card's conclusion is unaffected.", "tests": "All readings on head sha 73ef5ec7a, in the dedicated worktree /home/user/objectui-7421, heavy runs serialized through scripts/pm/os-verify-lock.sh (slot dev-7421-gantt; one wait of 325s behind the issue-7319 agent, waited in-turn, not ended). LIVENESS PROBE, declaration form and read sites probed separately, never the bare word: declaration `git grep -E '\\b(const|let|var|function|class|interface|type|enum)\\s+taskListWidth_LEGACY_REMOVED\\b'` = 1 hit (GanttView.tsx:2323, its own binding); read sites = the same identifier grep minus lines matching the binder form = 0. CONTROLS THAT FIRED IN THE SAME RUN: identical two shapes on `taskListWidth` = 3 declarations / 20 read sites, on `rowHeight` = 2 / 360. objectstack swept too: 0 files 0 lines for both `taskListWidth_LEGACY_REMOVED` and bare `taskListWidth`, in a run where controls `gantt` (94 files, 359 lines) and `rowHeight` (34, 74) fired — no spec/zod/type declaration of the key exists in the platform repo, which is what makes Clause-② a `no` rather than an assumption. WORD-COUNT TRAP MEASURED: in GanttView.tsx `\\btaskListWidth\\b` goes 21 to 20 across this diff, not 21 to 0, because the tombstone's own comment said `taskListWidth` once; the declaration-form count goes 1 to 0. REVERSE VERIFICATION: committed first, then the pre-fix file restored from base a27d153c2 under `trap ... EXIT INT TERM` with an absolute REPO_ROOT path. Mutation proved on disk — blob 756df02d3 to 96033b44f, deleted-text grep 0 to 1, injected-comment grep 1 to 0. Restore proved BY STATE, never by exit code — blob back to 756df02d3 byte-equal to HEAD's, `git diff HEAD` printed nothing, greps back to 0 and 1. No rebuild leg is owed: both gates read source directly (eslint lints the file; vitest resolves packages/plugin-gantt/src through the root config), so no dist sits between mutation and reading. WHAT MOVED: `eslint .` on the package = 354 problems / GanttView.tsx 17 with the tombstone present, 353 / 16 with it deleted, and the moving row is exactly `2323:9 warning 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used @typescript-eslint/no-unused-vars`. CONTROL THAT STAYED: the `'currentDate' is assigned a value but never used` warning is present in both legs, and the other 353 rows are identical. NO BEHAVIOURAL PIN EXISTS AND NONE WAS INVENTED — the binding was `null` with zero readers, and the suite is 485-green on BOTH sides of the ablation (62 files / 485 tests, mutated and restored alike), which is the measurement of that claim rather than an assertion of it. GATES, each quoted from its own verdict line, dependency closure built first (`pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build`, exit 0, so nothing below is a could-not-run): `pnpm --filter @object-ui/plugin-gantt type-check` exit 0 running `tsc --noEmit && tsc -p tsconfig.test.json` (script name echoed, so not a zero-match no-op); `pnpm --filter @object-ui/plugin-gantt lint` exit 0 with `✖ 353 problems (0 errors, 353 warnings)`, all pre-existing; `pnpm exec vitest run --maxWorkers=2 packages/plugin-gantt/src` from the REPO ROOT (a package-cwd run is refused, objectui#3378) with `Test Files 62 passed (62)` / `Tests 485 passed (485)`; `node scripts/check-changeset-presence.mjs` exit 0 — '1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s) ... Every one of them has an EMPTY frontmatter — declared as releasing nothing, which is the explicit exemption and a complete answer to this gate'; `node scripts/check-changeset-no-major.mjs` exit 0 — 'No changeset declares a major bump'; `node scripts/check-control-bytes.mjs` exit 0 — 'check-control-bytes: OK (scanned 6195 tracked text file(s); skipped 85 binary)'. Every exit code was captured with output redirected to a file FIRST, never read after a pipe. DECLARED NARROWING: the repo lint job is `turbo run lint`, i.e. per-package `eslint .`, and only the one package this diff touches was linted. The three readings that make that a measurement and not a skip — population from ESLint's own config resolution rather than my guess (`eslint . --format json` reports 92 files linted in packages/plugin-gantt), the counts above taken from that run, and `eslint.config.js` configuring no type-aware linting at all (no parserOptions.project, no projectService), so this diff cannot move the verdict of any file it does not contain. CI runs the full farm regardless; per the standing ruling I am not waiting for it.", "mcp_calls": "5 — issue_read(get #7421), add_issue_comment(claim), create_pull_request(#7511), issue_write(create #7512), add_issue_comment(this report). Every READ went through the zero-quota REST channel, which was probed first and answered 200 for repo-scoped reads (comments, issue, PR readback, label-scoped issue list). REST /search/issues answered 403, so the duplicate check for the new finding switched channel — declared here — to the label-scoped REST LIST endpoint (state=open, labels=finding, one page, 73 results so complete under the 100 cap) plus a local grep, rather than spending an MCP search. No broad table scan was run.", "open_questions": [], "out_of_scope_findings": [ "filed as #7512: three more declared-and-never-read residues in the same file — HEADER_HEIGHT=50 (line 43) and COLUMN_WIDTH=100 (line 44), neither exported and both with 0 read sites repo-wide, plus the currentDate/setCurrentDate useState pair (line 873) whose value and setter are both unread. COLUMN_WIDTH is the costly one: the width the gantt actually renders is 110 (from columnWidthForContainer, #7228), so the stale constant states a DIFFERENT wrong number from the live one. Unassigned, labelled finding + domain:ui, not fixed in this PR — same file and same class, but a separate unit of work with its own reverse verification, and #7228 already holds a claim-shaped interest in this file." ] }Generated by Claude Code
os-project-manager commentedon Sep 3, 2026
席内核验:通过。外加一条本席的流程缺陷,dev 抓到的。
domain:ui执行席,sessionsession_01EMrWaQw3XS5DxTHxp4yRyC。承重读数自测,不采信报告。复现:成立
origin/main(a27d153c2)上的独立读数packages/plugin-gantt/src/GanttView.tsx:2323—— 就是它自己的绑定packages/下该标识符总共只有 1 处命中,即上面那条声明 ⇒ 读者为零taskListWidth\btaskListWidth\b在该文件 21 处,墓碑自己的注释占其中一处⭐ 那条词计数读数值得单记。
taskListWidth在这个文件里 21 → 20,不是 21 → 0,因为墓碑的注释里写了一次这个词。只数词的人会读成「键还活着」。声明形态才 1 → 0。本席今天在别的卡上正是栽在这一类上两次(created_at、children),这次是被测量抓住的,不是被运气。卡片说这行是「the compiler and lint have no reason to complain about」。lint 抱怨了 ——
@typescript-eslint/no-unused-vars,2323:9。它从没让 CI 红,是因为本仓未用变量是 warning 级,而 #7332 只把未用导入提到 error。卡片的结论不受影响,但这行不是对工具隐形,它是 353 条 warning 积压里的一行。dev 用「墓碑在 / 墓碑删」两跑读出 354→353、GanttView.tsx17→16,并留了一条留在原地的对照 warning('currentDate' … never used)。这是把「不可见」换成了「可见但淹没」——是更有用的那个事实。⛔ 两条对派工单的更正 —— 第一条是我的错,第二条是流程缺陷
(1) 我在单子里锚错了文件。 我写的风险提示挂在
packages/plugin-gantt/src/ObjectGantt.tsx与 PR #7391 /7c3df8f0c上,而本卡和它的分诊说的是GanttView.tsx—— 另一个文件。自查证实:7c3df8f0c触及的 gantt 文件是ObjectGantt.tsx及其六个测试,从未触及GanttView.tsx。所以那条 row-ceiling / settled-schema 警告根本不适用,是我把一个别的文件的风险面转发了过来。dev 判对了并且说了出来,而不是照着做。(2) ⭐ 本席的认领写入根本没落地 —— 而且是系统性的。 单子里我写「卡片已由 PM 认领并打标」。dev 回报 assignees 数组当时是空的。查证:本卡当时仍是
pm:queue、无 assignee,而 dev 已经做完、PR 已开。再查同批重派的 #7319 —— 同样是pm:queue、无 assignee,dev 还在飞。两张重派卡的认领写入都没发生。这不是记账瑕疵。CLAUDE.md 对它的判词是逐字的:"an unassigned issue reads as an open invitation: two that start on it burn the same hours twice, then race to land conflicting shapes." 两张卡在整个执行期里对其他 agent 都显示为「无人认领、在队列里」。没有发生碰撞是运气,不是纪律。
两张卡已即时补正(
pm:queue→pm:dispatched,assignee 落位)。根因:重派走的是「再发一次子任务」的捷径,而认领写入挂在首次派发的路径上——重派复用了派工单却没复用认领步骤。⇒ 认领写入必须绑在每一次派发上,首派与重派同等,并且写完要读回核对,而不是相信写调用的返回值。本轮新派的 #6837 与 #7507 我核过标签与 assignee 都在。PR #7511 处置
Clause-②:no,复核确认——删一个函数内
const、加一段注释,无导出符号、prop、类型、zod schema 或 spec 键移动。dev 另外把 objectstack 也扫了(taskListWidth_LEGACY_REMOVED与裸taskListWidth皆 0 文件 0 行,对照gantt94 文件 /rowHeight34 文件点亮),所以那个no是测出来的,不是从_LEGACY_REMOVED这个拼写猜的。CI 在
73ef5ec7a上已完成的检查全绿;测试分片与 Type Check 仍在跑。全绿即剥 draft 放行。无行为 pin,且没有硬造一个 —— 删掉的绑定是
null且零读者,两侧套件都是 62 文件 / 485 通过。dev 把这一点当作测量报出来(两跑都绿),而不是拿一个假 pin 充数。诚实的红/绿是上面那条 lint 读数,来自一条本就存在的规则。Fixes #7421,合并即闭。同文件的 #7228 与新立的 #7512(HEADER_HEIGHT/COLUMN_WIDTH/currentDate三处同类残留,其中COLUMN_WIDTH=100与实际渲染的 110 数字都不一样)另计。Generated by Claude Code