## The defect Two guards in `node-override-guard.ts` answered a **role** question with a **column name**: - **`task.column === "in-progress"`** refuses changing a task's node override mid-flight. On a renamed board it never matched, so an operator could re-route a **running** task — precisely what the guard exists to prevent, and the failure is silent because the guard simply returns `allowed: true`. - **`task.column !== "done"`** gates overriding *to* the terminal node. On a renamed board it never matched either, so the override was refused for exactly the tasks that had legitimately reached the end node. Both fail in the direction that looks like normal behaviour rather than an error. ## Why the lanes are injected rather than resolved in place `validateNodeOverrideChange` is **synchronous by design**, and its existing `isTerminalNodeId` option already establishes the pattern: callers with cheap IR access inject, callers without keep a documented literal fallback. **Both production callers now supply the lanes** — `branch-and-pr-entities.ts:594` (which already injected `isTerminalNodeId`) and `task-update.ts:53`. That was the deciding factor: an optional parameter that only tests fill is the inert-injection shape this program keeps finding, where a guard reads as converted, its test passes because the test injects the value, and production keeps the literal. I checked both call sites had a store in scope *before* adding the option. `resolveNodeOverrideLanes` lives beside the guard rather than in the callers, so the two cannot drift about what "executing" and "completed" mean. ## Fallbacks A workflow expressing **no trait on any column** is a v1 upgrade — `synthesizeDefaultColumns` emits `traits: []` everywhere — not a board without these roles, so it keeps the legacy ids. Same for an unresolvable workflow. Both preserve exactly the behaviour the literals already had. ## Verification - **Mutation-verified per guard:** restoring `task.column === "in-progress"` fails a case; restoring `task.column !== "done"` fails a different one. - The suite also pins the paired negative — resolving lanes must not turn the guard into a blanket refusal for a task outside every WIP lane. - `node-override-guard.test.ts` → 27 passed - `pnpm test:gate` → 161 + 487 + 13 + 71 - `--strict` → exit 0; `tsc --noEmit` and `pnpm lint` → 0 errors Census: batch-core scope **45 → 43**; repo total **255**. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Node overrides now correctly recognize workflow-defined in-progress and completed lanes, including renamed columns. - Override validation falls back safely for legacy or unresolved workflows. - Prevented validation from using stale task-column information during updates. - **Tests** - Added coverage for workflow lane resolution, legacy fallbacks, renamed lanes, and override eligibility. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
158 lines
9.2 KiB
JSON
158 lines
9.2 KiB
JSON
{
|
|
"generatedFrom": "node scripts/lifecycle-column-census.mjs --strict --update-baseline",
|
|
"byFile": {
|
|
"packages/engine/src/self-healing.ts": 97,
|
|
"packages/engine/src/scheduler.ts": 12,
|
|
"packages/core/src/task-store/async-comments-attachments.ts": 9,
|
|
"packages/engine/src/executor.ts": 8,
|
|
"packages/engine/src/notification/notification-service.ts": 5,
|
|
"packages/engine/src/restart-recovery-coordinator.ts": 5,
|
|
"packages/engine/src/replan-target.ts": 4,
|
|
"packages/core/src/async-mission-store-queries.ts": 3,
|
|
"packages/core/src/task-store/task-artifacts-ops.ts": 3,
|
|
"packages/dashboard/src/routes/register-task-workflow-routes.ts": 3,
|
|
"packages/engine/src/planner-overseer.ts": 3,
|
|
"packages/core/src/agent-store.ts": 2,
|
|
"packages/core/src/task-store/audit-ops.ts": 2,
|
|
"packages/core/src/task-store/moves.ts": 2,
|
|
"packages/core/src/task-store/project-store-ops.ts": 2,
|
|
"packages/core/src/task-store/reads.ts": 2,
|
|
"packages/core/src/task-store/task-id-integrity.ts": 2,
|
|
"packages/dashboard/app/utils/taskRevert.ts": 2,
|
|
"packages/dashboard/src/github-tracking-state.ts": 2,
|
|
"packages/engine/src/auto-merge-finalization.ts": 2,
|
|
"packages/core/src/eval-automation.ts": 1,
|
|
"packages/core/src/eval-signal-collector.ts": 1,
|
|
"packages/core/src/in-review-stall.ts": 1,
|
|
"packages/core/src/mission-store.ts": 1,
|
|
"packages/core/src/plugin-store.ts": 1,
|
|
"packages/core/src/stalled-review-detector.ts": 1,
|
|
"packages/core/src/task-store/comments-ops.ts": 1,
|
|
"packages/core/src/task-store/lifecycle-ops.ts": 1,
|
|
"packages/core/src/task-store/merge-queue-ops-2.ts": 1,
|
|
"packages/core/src/task-store/merge-queue-ops.ts": 1,
|
|
"packages/dashboard/app/components/ResearchTaskActionModal.tsx": 1,
|
|
"packages/dashboard/app/components/TaskCard.tsx": 1,
|
|
"packages/dashboard/src/task-planner-chat-metrics.ts": 1,
|
|
"packages/engine/src/backlog-pressure-reporter.ts": 1,
|
|
"packages/engine/src/ephemeral-worker-manager.ts": 1,
|
|
"packages/engine/src/merger.ts": 1,
|
|
"packages/engine/src/runtimes/in-process-runtime.ts": 1,
|
|
"packages/engine/src/triage.ts": 1
|
|
},
|
|
"deliberateByFile": {
|
|
"packages/dashboard/src/reliability-metrics.ts\u0000in-review": 4,
|
|
"packages/dashboard/app/components/TaskContextMenu.tsx\u0000in-review": 3,
|
|
"packages/core/src/live-agent-count.ts\u0000in-progress": 2,
|
|
"packages/core/src/live-agent-count.ts\u0000in-review": 2,
|
|
"packages/core/src/store.ts\u0000in-review": 2,
|
|
"packages/core/src/task-merge.ts\u0000archived": 2,
|
|
"packages/core/src/task-merge.ts\u0000done": 2,
|
|
"packages/core/src/task-merge.ts\u0000in-review": 2,
|
|
"packages/dashboard/app/components/TaskCard.tsx\u0000todo": 2,
|
|
"packages/dashboard/app/components/TaskCard.tsx\u0000triage": 2,
|
|
"packages/dashboard/app/components/TaskContextMenu.tsx\u0000archived": 2,
|
|
"packages/dashboard/app/components/TaskContextMenu.tsx\u0000done": 2,
|
|
"packages/dashboard/app/components/TaskDetailModal.tsx\u0000triage": 2,
|
|
"packages/engine/src/cli-agent/state-machine.ts\u0000done": 2,
|
|
"packages/engine/src/scheduler.ts\u0000archived": 2,
|
|
"packages/engine/src/scheduler.ts\u0000done": 2,
|
|
"packages/engine/src/scheduler.ts\u0000in-progress": 2,
|
|
"packages/engine/src/scheduler.ts\u0000in-review": 2,
|
|
"packages/engine/src/usage-limit-detector.ts\u0000archived": 2,
|
|
"packages/engine/src/usage-limit-detector.ts\u0000done": 2,
|
|
"plugins/fusion-plugin-reports/src/store/report-store.ts\u0000archived": 2,
|
|
"packages/cli/src/commands/task.ts\u0000archived": 1,
|
|
"packages/cli/src/commands/task.ts\u0000done": 1,
|
|
"packages/cli/src/extension.ts\u0000archived": 1,
|
|
"packages/cli/src/extension.ts\u0000done": 1,
|
|
"packages/core/src/live-agent-count.ts\u0000archived": 1,
|
|
"packages/core/src/live-agent-count.ts\u0000done": 1,
|
|
"packages/core/src/store.ts\u0000archived": 1,
|
|
"packages/core/src/store.ts\u0000done": 1,
|
|
"packages/core/src/store.ts\u0000in-progress": 1,
|
|
"packages/core/src/store.ts\u0000todo": 1,
|
|
"packages/core/src/task-move-disposer.ts\u0000in-progress": 1,
|
|
"packages/core/src/task-move-disposer.ts\u0000todo": 1,
|
|
"packages/core/src/task-store/archive-lifecycle-2.ts\u0000archived": 1,
|
|
"packages/core/src/task-store/branch-and-pr-entities.ts\u0000archived": 1,
|
|
"packages/core/src/task-store/task-store-helpers.ts\u0000in-progress": 1,
|
|
"packages/core/src/task-store/task-store-helpers.ts\u0000todo": 1,
|
|
"packages/core/src/task-store/task-update.ts\u0000in-progress": 1,
|
|
"packages/core/src/task-store/task-update.ts\u0000in-review": 1,
|
|
"packages/core/src/task-store/update-task-deps.ts\u0000archived": 1,
|
|
"packages/core/src/task-store/update-task-deps.ts\u0000done": 1,
|
|
"packages/dashboard/app/components/command-center/liveSnapshotMetrics.ts\u0000in-progress": 1,
|
|
"packages/dashboard/app/components/command-center/MissionControlPanel.tsx\u0000done": 1,
|
|
"packages/dashboard/app/components/command-center/MissionControlPanel.tsx\u0000in-review": 1,
|
|
"packages/dashboard/app/components/command-center/MissionControlPanel.tsx\u0000todo": 1,
|
|
"packages/dashboard/app/components/DocumentsView.tsx\u0000archived": 1,
|
|
"packages/dashboard/app/components/DocumentsView.tsx\u0000done": 1,
|
|
"packages/dashboard/app/components/RoutineEditor.tsx\u0000triage": 1,
|
|
"packages/dashboard/app/components/ScheduleForm.tsx\u0000triage": 1,
|
|
"packages/dashboard/app/components/ScheduleStepsEditor.tsx\u0000triage": 1,
|
|
"packages/dashboard/app/components/TaskCard.tsx\u0000done": 1,
|
|
"packages/dashboard/app/components/TaskContextMenu.tsx\u0000in-progress": 1,
|
|
"packages/dashboard/app/components/TaskContextMenu.tsx\u0000triage": 1,
|
|
"packages/dashboard/app/components/TaskDetailModal.tsx\u0000archived": 1,
|
|
"packages/dashboard/app/components/TaskDetailModal.tsx\u0000done": 1,
|
|
"packages/dashboard/app/components/TaskDetailModal.tsx\u0000in-progress": 1,
|
|
"packages/dashboard/app/components/TaskDetailModal.tsx\u0000in-review": 1,
|
|
"packages/dashboard/app/components/TaskDetailModal.tsx\u0000todo": 1,
|
|
"packages/dashboard/app/hooks/useTaskDiffStats.ts\u0000done": 1,
|
|
"packages/dashboard/app/hooks/useTaskDiffStats.ts\u0000in-progress": 1,
|
|
"packages/dashboard/app/hooks/useTaskDiffStats.ts\u0000in-review": 1,
|
|
"packages/dashboard/app/utils/columnRoles.ts\u0000todo": 1,
|
|
"packages/dashboard/app/utils/quickAddStart.ts\u0000todo": 1,
|
|
"packages/dashboard/src/github-tracking-comments.ts\u0000done": 1,
|
|
"packages/dashboard/src/github-tracking-state.ts\u0000archived": 1,
|
|
"packages/dashboard/src/github-tracking-state.ts\u0000done": 1,
|
|
"packages/dashboard/src/gitlab-tracking-comments.ts\u0000in-progress": 1,
|
|
"packages/dashboard/src/reliability-metrics.ts\u0000done": 1,
|
|
"packages/dashboard/src/reliability-metrics.ts\u0000in-progress": 1,
|
|
"packages/dashboard/src/routes/register-task-workflow-routes.ts\u0000todo": 1,
|
|
"packages/dashboard/src/routes/register-task-workflow-routes.ts\u0000triage": 1,
|
|
"packages/dashboard/src/server.ts\u0000archived": 1,
|
|
"packages/dashboard/src/task-planner-chat-context.ts\u0000done": 1,
|
|
"packages/dashboard/src/test/mockCoreEngine.ts\u0000in-review": 1,
|
|
"packages/engine/src/agent-heartbeat.ts\u0000archived": 1,
|
|
"packages/engine/src/agent-heartbeat.ts\u0000done": 1,
|
|
"packages/engine/src/cli-agent/task-session.ts\u0000done": 1,
|
|
"packages/engine/src/executor.ts\u0000in-progress": 1,
|
|
"packages/engine/src/hold-release.ts\u0000archived": 1,
|
|
"packages/engine/src/hold-release.ts\u0000done": 1,
|
|
"packages/engine/src/hold-release.ts\u0000in-review": 1,
|
|
"packages/engine/src/project-engine.ts\u0000in-review": 1,
|
|
"packages/engine/src/scheduler.ts\u0000todo": 1,
|
|
"packages/engine/src/triage.ts\u0000triage": 1,
|
|
"plugins/fusion-plugin-even-cards/src/cards/board-cards.ts\u0000archived": 1,
|
|
"plugins/fusion-plugin-even-cards/src/cards/board-cards.ts\u0000done": 1,
|
|
"plugins/fusion-plugin-even-realities-glasses/src/notifications/diff.ts\u0000done": 1,
|
|
"plugins/fusion-plugin-reports/src/store/report-types.ts\u0000archived": 1
|
|
},
|
|
"queryByFile": {
|
|
"packages/engine/src/self-healing.ts": 48,
|
|
"packages/engine/src/project-engine.ts": 7,
|
|
"packages/engine/src/backlog-pressure-reporter.ts": 3,
|
|
"packages/core/src/task-store/async-persistence.ts": 2,
|
|
"packages/core/src/task-store/merge-queue-ops.ts": 2,
|
|
"packages/core/src/task-store/moves.ts": 2,
|
|
"packages/engine/src/executor.ts": 2,
|
|
"packages/engine/src/stale-task-reporter.ts": 2,
|
|
"packages/cli/src/extension.ts": 1,
|
|
"packages/core/src/async-mission-store.ts": 1,
|
|
"packages/core/src/eval-automation.ts": 1,
|
|
"packages/core/src/store.ts": 1,
|
|
"packages/core/src/task-store/archive-lifecycle-2.ts": 1,
|
|
"packages/core/src/task-store/async-archive-lineage.ts": 1,
|
|
"packages/core/src/task-store/async-self-healing.ts": 1,
|
|
"packages/core/src/task-store/task-artifacts-ops.ts": 1,
|
|
"packages/dashboard/src/routes/register-gitlab.ts": 1,
|
|
"packages/engine/src/agent-tools.ts": 1,
|
|
"packages/engine/src/auto-merge-finalization.ts": 1,
|
|
"packages/engine/src/restart-recovery-coordinator.ts": 1,
|
|
"packages/engine/src/scheduler.ts": 1,
|
|
"packages/engine/src/workflow-node-handlers.ts": 1
|
|
}
|
|
}
|