triage census — core/live-agent-count.ts: the literal fallback is NOT fixture-only (finding, 2 sites still open) (#2604)

Taking `packages/core/src/live-agent-count.ts` from the shared
triage-guard backlog. **This PR does not convert it** — it corrects a
comment that would have stopped the conversion, and records why the
conversion is not a one-liner.

## Per-file guard count

| File | Before | After | Note |
|---|---:|---:|---|
| `packages/core/src/live-agent-count.ts` | 2 | **2** | not converted —
see below |

Census across `packages/*/src` excluding tests, for the pattern `column
=== "triage"` / `column !== "triage"`:

| File | Sites |
|---|---:|
| `engine/self-healing.ts` | 10 |
| `dashboard/src/routes/register-task-workflow-routes.ts` | 7 |
| `core/task-store/comments-ops.ts` | 3 |
| `dashboard/src/routes/board-workflows.ts` | 2 |
| `core/task-store/task-creation.ts` | 2 |
| `core/live-agent-count.ts` | 2 |
| `engine/spec-staleness.ts`, `engine/replan-target.ts`,
`engine/mission-feature-sync.ts`, `core/types/archive-planning.ts` | 1
each |

## The finding

The comment in this file asserted the literal fallback was unreachable:

> *"The literal fallback is fixture-only; board/store callers always
supply flags/IR."*

**It is false.** `useExecutorStats` resolves
`columnFlagsByTaskId?.get(task.id) ?? columnFlagsById?.get(task.column)`
— `undefined` for any card whose column is absent from the board's flag
map, which is exactly the renamed-or-undeclared column case. So the
literals run in production, on the cards least likely to match them.

**Consequence is under-reporting, not a stall.** A card in a renamed
planner column matches neither `triage` nor `todo`, so
`isWaitingAgentTask` returns false and the footer's queued count
silently omits it. Default-workflow cards still match through the `todo`
arm after the Planning merge, which is why nothing looks broken — the
same "still fires via the todo arm" shape as the executor sites I
audited in #2572, but here with a real observable effect.

## Why I did not convert it

Removing the id guesses means deciding what an **absent flag set**
should mean, and `"not intake"` is as much a guess as `"todo is intake"`
— either choice moves the numbers the operator sees in the footer. Doing
that safely needs the dashboard's flag-map population understood and a
test that pins the queued count, neither of which is a small change.

A comment asserting an untrue invariant is worse than no comment: it is
precisely what would stop the next person converting these two sites,
because they would read it and move on. Correcting it is the useful part
I can land with confidence right now; the census entry stays open.

## Verification

`tsc --noEmit` on `@fusion/core` clean; `pnpm lint` clean. Comment-only
change to production source, so no behaviour change and no changeset.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-07-29 20:47:52 -07:00
committed by GitHub
parent c9df4b9dee
commit 71f64025d8

View File

@@ -83,7 +83,17 @@ export function enrichRunningAgentTaskShapeFromFlags<T extends RunningAgentTaskS
columnTerminalKind: flags?.archived ? "archived" : flags?.complete ? "complete" : "none",
columnIsIntakeOrHold: flags ? flags.intake === true || flags.hold === true : task.column === "triage" || task.column === "todo",
columnCountsTowardWip: flags ? flags.countsTowardWip === true : task.column === "in-progress",
// The literal fallback is fixture-only; board/store callers always supply flags/IR.
/*
FNXC:WorkflowLifecycleColumns 2026-07-29-23:10:
These id fallbacks are REACHABLE, not fixture-only — callers may pass no flags for a column
absent from the board's flag map, which is the renamed or undeclared column case. A card in
such a column then matches no arm and is counted as neither running nor waiting, so the
footer's queued total under-reports it.
Converting them means deciding what an ABSENT flag set should mean, and "not intake" is as
much a guess as "todo is intake"; either choice moves an operator-visible count. Supply flags
rather than relying on these.
*/
columnIsReviewOrMerge: flags ? flags.mergeOrchestration === true || flags.mergeBlocker === true : task.column === "in-review",
};
}