Files
fusion/packages/dashboard/app/components
gsxdsm 3c46ecca14 Drift (unowned): the planner-activity signal was never written after #2515 — the three badge conversions were reading an empty field (#2594)
## Drift, unowned: the planner-activity signal was never being written

**Stacks on #2577.** Merge order: #2566 → #2577 → this.

### This is what made the other three PRs cosmetic

`addRecentPlannerActivityForFreshAgentLog` in `useTasks.ts` stamped
`recentAgentActivityAt` **only for cards literally in `triage`**. #2515
removed that column from the default lineage, so after that merge the
stamp never happened for a default-workflow card.

Every consumer downstream then had **no data to act on**, however
correctly it resolved its own column traits:

- the pulsing Planning badge (TaskCard, ListView)
- the agent-active row border
- the column header's executing count

So #2558 / #2566 / #2577 convert the *readers* of a field that nothing
was *writing*. They ask the right question of an empty value. This is
the fix that gives them something to read — and it was on nobody's drift
list. I found it chasing why a badge test would not go green.

### The decision, and why I did not thread metadata here

The hook processes SSE and has no resolved column metadata. The lane is
matched by id against **both** shapes — pre-merge `triage`, post-merge
`todo`.

Over-stamping a legacy hold-lane card is harmless: every consumer
additionally requires the column to be an **intake** lane before
rendering anything, so the extra timestamps are filtered downstream.
Threading board context into this hook to avoid a harmless over-stamp
would be a much larger change for no behavioural gain, so I widened
instead and wrote the reasoning at the site.

### Also converted

`Column.tsx`'s move-progress prompt. Unlike the same prompt in
TaskCard/ListView/TaskDetailModal, this component's `column` **is** the
drop target, so its own `columnFlags` are the target's traits — no
lookup needed. Worth noting because the same-looking regex meant three
different things across four files, which is exactly why these were
converted one at a time.

### Revert-proof

Restore `task.column !== "triage"` and the merged-column case fails:
`expected undefined to be '2026-07-28T12:00:01.000Z'` — nothing stamped,
badge has nothing to render. A companion case pins that the stamp still
**narrows**: an `in-progress` card is not planner activity.

### Verification

`pnpm test:gate` (482 + 10 + 71), `pnpm lint`, dashboard typecheck
green. `useTasks.test.ts` + `Board.test.tsx`: 210 passed.

### Audited and deliberately left

| site | verdict |
|---|---|
| `Column.tsx:550` `workflowMode \|\| column === "triage"` | Dead in
practice — `workflowMode` is true whenever lanes resolve, so the
disjunct only matters with no metadata at all. Not worth a change. |
| `taskSorting.ts:73` `column === "todo"` | Still correct for the
default (the merged column keeps that id); wrong only for a renamed
workflow's hold lane. Needs the sort to take flags — a wider signature
change than this PR's scope, and cosmetic (ordering) rather than a lost
affordance. |
| `worktreeGrouping.ts:77` | Same shape as above; grouping only, no lost
control. |

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 11:11:12 -07:00
..
2026-06-27 23:37:24 -07:00