Files
fusion/scripts/lib/lifecycle-column-census-baseline.json
gsxdsm aa02db5782 fleet: scheduler.ts 28 → 27 + make the column-role predicates reachable from the other 80% of the backlog (#2690)
## Census

**722 → 721**; `packages/engine/src/scheduler.ts` **28 → 27**. Exactly
the one site converted. Baseline re-recorded in the same commit —
`--strict` flagged the stale allowance itself, and `in-progress` went
138 → 137.

## The unblocker (commit 1)

The role helpers live in `packages/dashboard/app/utils/columnRoles.ts`,
a dashboard-**app** module. Measured against the census:

| Location | Guards | Share | Helpers importable? |
|---|---:|---:|---|
| `packages/engine/**` | 316 | 43% | no |
| `packages/dashboard/app/**` | 150 | 20% | **yes** |
| `packages/core/**` | 148 | 20% | no |
| `packages/dashboard/src/**` | 78 | 10% | no |
| `packages/cli/**` | 24 | 3% | no |

**Only 20% of the backlog can call them at all.** #2685 widens the
helper *set* correctly; that is coverage, not location.
`packages/core/src/column-roles.ts` is the same flags-first /
legacy-id-fallback predicate placed where the other 80% can reach it —
core already exports `resolveColumnFlags`, so no new resolution
machinery comes with it.

**Semantics are mirrored from #2685, not invented**, so the two sets
cannot answer the same question differently: `complete` EXCLUDES
`archived`; `wip` keys on `countsTowardWip` (the same flag capacity
arithmetic uses); `review` accepts `mergeBlocker` OR `humanReview`. One
addition — `isTerminalColumnRole` for the `!== "done" && !== "archived"`
union, the most repeated shape in the backlog.

10 tests cover both modes of all 8 predicates, including the **degraded
no-flags fallback** — the half with no coverage when these lived only in
the dashboard app — plus the two cases that prove the predicate does
something rather than nothing: a renamed column carrying the right trait
answers yes, and a legacy id carrying the WRONG trait answers no.

## A trap every fleet worker converting engine code will hit

A new core export must be added to **both** `index.ts` and
`index.gate.ts`.

The `engine-core` gate project resolves `@fusion/core` to a bundle built
from `index.gate.ts` (`scripts/build-engine-core-gate-bundle.mjs`). An
export present only in `index.ts` is `undefined` at runtime under the
gate: 13 `scheduler-workflow-cutover` tests failed with `isWipColumnRole
is not a function`, in a file that does not mock `@fusion/core` at all.
The symptom points at the consumer, the cause is the barrel.

I nearly mis-attributed this. Baseline first:
`scheduler-workflow-cutover` is **42 passed on clean main**, so the 13
were mine — not pre-existing. That measurement is the only reason I
looked at the barrel instead of "fixing" the tests.

## The conversion (commit 2)

`scheduler.ts:1690`'s `isWipColumnTask` was a hand-rolled copy of
`isWipColumnRole` — it stored only `countsTowardWip` as a boolean and
re-implemented flags-first-then-legacy-id inline. It now stores the
resolved flags object and lets the shared predicate decide.

Behaviour is identical in all four states: column present with the flag
true or false (flags win), column absent from a resolved IR, and IR
resolution failed (both defer to the legacy id).

| Check | Result |
|---|---|
| `scheduler-workflow-cutover` | **42 passed** before and after |
| 21 scheduler/capacity/hold-release files | **372 passed** |
| `pnpm test:gate` | **726 passed** |
| `pnpm lint` | clean |

## Flagged and skipped, not guessed

**`scheduler.ts:1736` — a latent legacy-vocabulary defect, not a
conversion.** `if (task.column !== "in-progress") continue;` gates the
file-scope-lease loop on the literal, ~40 lines below capacity
arithmetic that is trait-aware. On a renamed WIP column the loop
silently does nothing while capacity counts the same cards correctly.
Converting it *changes behaviour* on renamed boards (from wrong to
right), which the fleet rules put out of scope — so it is flagged here
for whoever owns that fix. It is the same class as U10's six
legacy-vocabulary defects.

**`hold-release.ts:343`** — already marked `DELIBERATE-LITERAL`. It is
the legacy half of FN-5719's dual-accept pair; converting it would make
both halves compute the same answer, deleting the compatibility signal
*and* its divergence detector while looking like a cleanup. Untouched.

**`task-merge.ts:254`** — the documented fallback for callers that have
not proven lane identity; trait-aware callers pass
`skipColumnIdentityCheck`. Untouched.

**The other 14 `scheduler.ts` sites** have no flags in scope (e.g.
`isLegacyDependencySatisfied(dep: Task | undefined)`,
`shouldHoldActiveFileScopeLease(...)` — task-only pure functions).
Threading an IR in changes signatures and call graphs: behaviour change,
out of scope. This is why the cluster is 28 → 27 and not 28 → 0, and the
reachability measurement behind it is #2687.

No changeset: `@fusion/*` are private and no `@runfusion/fusion`
behaviour changes.
2026-07-30 03:01:36 -07:00

211 lines
10 KiB
JSON

{
"generatedFrom": "node scripts/lifecycle-column-census.mjs --strict --update-baseline",
"totals": {
"column": 721,
"role": 5,
"status": 186,
"deliberate": 17
},
"byColumnId": {
"done": 195,
"in-progress": 137,
"in-review": 200,
"archived": 147,
"todo": 42
},
"byFile": {
"packages/engine/src/self-healing.ts": 110,
"packages/engine/src/executor.ts": 85,
"packages/dashboard/app/components/TaskCard.tsx": 42,
"packages/dashboard/app/components/TaskDetailModal.tsx": 30,
"packages/engine/src/scheduler.ts": 27,
"packages/dashboard/src/routes/register-task-workflow-routes.ts": 20,
"packages/core/src/task-store/moves.ts": 15,
"packages/core/src/store.ts": 12,
"packages/engine/src/project-engine.ts": 12,
"packages/engine/src/mission-execution-loop.ts": 10,
"packages/core/src/task-store/async-comments-attachments.ts": 9,
"packages/dashboard/app/components/TaskContextMenu.tsx": 9,
"packages/dashboard/src/github-tracking-comments.ts": 9,
"packages/dashboard/src/github-tracking-reconciler.ts": 9,
"packages/engine/src/notification/notification-service.ts": 9,
"packages/cli/src/commands/dashboard.ts": 8,
"packages/cli/src/commands/task.ts": 8,
"packages/core/src/default-workflow-hooks.ts": 7,
"packages/core/src/task-store/update-task-deps.ts": 7,
"packages/dashboard/app/components/Column.tsx": 7,
"packages/core/src/live-agent-count.ts": 6,
"packages/core/src/task-merge.ts": 6,
"packages/core/src/task-store/branch-group-ops.ts": 6,
"packages/core/src/task-store/task-artifacts-ops.ts": 6,
"packages/dashboard/app/components/ListView.tsx": 6,
"packages/dashboard/src/reliability-metrics.ts": 6,
"packages/engine/src/runtimes/in-process-runtime.ts": 6,
"packages/cli/src/extension.ts": 5,
"packages/core/src/task-store/merge-queue-ops-2.ts": 5,
"packages/dashboard/app/hooks/useTaskDiffStats.ts": 5,
"packages/engine/src/agent-tools.ts": 5,
"packages/engine/src/merger.ts": 5,
"packages/engine/src/restart-recovery-coordinator.ts": 5,
"packages/core/src/agent-store.ts": 4,
"packages/core/src/blocker-fanout.ts": 4,
"packages/core/src/task-age-staleness.ts": 4,
"packages/core/src/task-store/task-store-helpers.ts": 4,
"packages/dashboard/app/components/TaskReviewTab.tsx": 4,
"packages/dashboard/app/components/taskSorting.ts": 4,
"packages/dashboard/src/gitlab-tracking-comments.ts": 4,
"packages/dashboard/src/routes/register-git-github.ts": 4,
"packages/engine/src/agent-heartbeat.ts": 4,
"packages/engine/src/replan-target.ts": 4,
"packages/engine/src/triage.ts": 4,
"packages/engine/src/usage-limit-detector.ts": 4,
"packages/core/src/async-mission-store-queries.ts": 3,
"packages/core/src/async-mission-store.ts": 3,
"packages/core/src/task-priority.ts": 3,
"packages/core/src/task-store/async-merge-coordination.ts": 3,
"packages/core/src/task-store/task-update.ts": 3,
"packages/dashboard/app/components/DockTaskList.tsx": 3,
"packages/dashboard/app/components/TaskChangesTab.tsx": 3,
"packages/dashboard/app/components/TaskChatTab.tsx": 3,
"packages/dashboard/app/utils/taskActivity.ts": 3,
"packages/dashboard/app/utils/worktreeGrouping.ts": 3,
"packages/dashboard/src/chat.ts": 3,
"packages/dashboard/src/routes/register-chat-routes.ts": 3,
"packages/engine/src/gridlock-detector.ts": 3,
"packages/engine/src/planner-overseer.ts": 3,
"packages/engine/src/worktree-pool.ts": 3,
"packages/cli/src/commands/dashboard-tui/app.tsx": 2,
"packages/core/src/assigned-task-ranking.ts": 2,
"packages/core/src/duplicate-intake.ts": 2,
"packages/core/src/near-duplicate-canonical.ts": 2,
"packages/core/src/node-override-guard.ts": 2,
"packages/core/src/task-move-disposer.ts": 2,
"packages/core/src/task-store/archive-lifecycle-2.ts": 2,
"packages/core/src/task-store/audit-ops.ts": 2,
"packages/core/src/task-store/comments-ops.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/symbol-locks.ts": 2,
"packages/core/src/task-store/task-id-integrity.ts": 2,
"packages/core/src/team-analytics.ts": 2,
"packages/core/src/workflow-analytics.ts": 2,
"packages/dashboard/app/components/Board.tsx": 2,
"packages/dashboard/app/components/DocumentsView.tsx": 2,
"packages/dashboard/app/components/effective-model-resolution.ts": 2,
"packages/dashboard/app/components/WorkflowResultsTab.tsx": 2,
"packages/dashboard/app/utils/prFeedback.ts": 2,
"packages/dashboard/app/utils/taskRevert.ts": 2,
"packages/dashboard/app/utils/taskTiming.ts": 2,
"packages/dashboard/src/github-tracking-state.ts": 2,
"packages/dashboard/src/routes/register-project-routes.ts": 2,
"packages/dashboard/src/routes/register-session-diff-routes.ts": 2,
"packages/dashboard/src/routes/register-system-maintenance-routes.ts": 2,
"packages/dashboard/src/server.ts": 2,
"packages/engine/src/agent-reflection.ts": 2,
"packages/engine/src/auto-merge-finalization.ts": 2,
"packages/engine/src/cli-agent/state-machine.ts": 2,
"packages/engine/src/merger-scope-auto-widen.ts": 2,
"plugins/fusion-plugin-even-cards/src/cards/board-cards.ts": 2,
"plugins/fusion-plugin-reports/src/store/report-store.ts": 2,
"packages/cli/src/commands/pr.ts": 1,
"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/branch-and-pr-entities.ts": 1,
"packages/core/src/task-store/lifecycle-ops.ts": 1,
"packages/core/src/task-store/merge-queue-ops.ts": 1,
"packages/core/src/task-timing.ts": 1,
"packages/dashboard/app/components/ChangesDiffModal.tsx": 1,
"packages/dashboard/app/components/command-center/liveSnapshotMetrics.ts": 1,
"packages/dashboard/app/components/DevServerView.tsx": 1,
"packages/dashboard/app/components/MergeDetails.tsx": 1,
"packages/dashboard/app/components/PrPanel.tsx": 1,
"packages/dashboard/app/components/ResearchTaskActionModal.tsx": 1,
"packages/dashboard/app/components/RoutingTab.tsx": 1,
"packages/dashboard/app/components/TaskPlannerChatTab.tsx": 1,
"packages/dashboard/app/hooks/useExecutorStats.ts": 1,
"packages/dashboard/app/hooks/useTasks.ts": 1,
"packages/dashboard/app/utils/inReviewStallCopy.ts": 1,
"packages/dashboard/app/utils/quickAddStart.ts": 1,
"packages/dashboard/app/utils/stalePausedReviewCopy.ts": 1,
"packages/dashboard/app/utils/taskStuck.ts": 1,
"packages/dashboard/src/github-issue-comment.ts": 1,
"packages/dashboard/src/gitlab-issue-comment.ts": 1,
"packages/dashboard/src/gitlab-source-issue-reconciler.ts": 1,
"packages/dashboard/src/knowledge-index-refresh.ts": 1,
"packages/dashboard/src/planning-board-tools.ts": 1,
"packages/dashboard/src/research-routes.ts": 1,
"packages/dashboard/src/routes/register-agent-core-routes.ts": 1,
"packages/dashboard/src/task-planner-chat-context.ts": 1,
"packages/dashboard/src/task-planner-chat-metrics.ts": 1,
"packages/dashboard/src/test/mockCoreEngine.ts": 1,
"packages/engine/src/auto-recovery-handlers/branch-worktree.ts": 1,
"packages/engine/src/backlog-pressure-reporter.ts": 1,
"packages/engine/src/cli-agent/task-session.ts": 1,
"packages/engine/src/ephemeral-worker-manager.ts": 1,
"packages/engine/src/merger-integration-worktree.ts": 1,
"packages/engine/src/merger-orphan-rehome.ts": 1,
"packages/engine/src/plugin-runner.ts": 1,
"packages/engine/src/pr-comment-handler.ts": 1,
"plugins/fusion-plugin-even-realities-glasses/src/notifications/diff.ts": 1,
"plugins/fusion-plugin-reports/src/store/report-types.ts": 1
},
"deliberateByFile": {
"packages/dashboard/app/components/TaskCard.tsx\u0000triage": 2,
"packages/dashboard/app/components/TaskDetailModal.tsx\u0000triage": 2,
"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/TaskCard.tsx\u0000todo": 1,
"packages/dashboard/app/components/TaskContextMenu.tsx\u0000triage": 1,
"packages/dashboard/app/components/TaskDetailModal.tsx\u0000todo": 1,
"packages/dashboard/app/utils/columnRoles.ts\u0000todo": 1,
"packages/dashboard/src/routes/register-task-workflow-routes.ts\u0000todo": 1,
"packages/dashboard/src/routes/register-task-workflow-routes.ts\u0000triage": 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/triage.ts\u0000triage": 1
},
"properties": {
"query": 83,
"definition": 43
},
"queryByColumnId": {
"todo": 10,
"archived": 7,
"done": 10,
"in-progress": 19,
"in-review": 35,
"triage": 2
},
"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/core/src/task-store/task-store-helpers.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
}
}