Fix-forward for the P1 that arrived on **#2787 after it merged** — so it
lands as its own PR rather than a thread reply on merged code.
## The finding
`selectPermanentAgentForTask`'s `activeColumns` was resolved from the
**candidate** task's workflow and then applied to every row `listTasks`
returned. On a project running several workflows — the normal case —
assignments living in another workflow's load-bearing lanes vanished
from the tally, and the already-loaded-agent-wins bug returned through a
different door.
**A column id means something only relative to its OWN workflow.**
`blocker-fanout.ts` documents exactly this and offers a per-task
`classify`; the option is now that same shape rather than a third
invention:
```ts
countsAsAssignmentLoad?: (task: Task) => boolean
```
The scheduler resolves each assigned row against its own IR, sharing one
cache for the selection, so a board spanning three workflows reads three
IRs — not one per assigned card.
## Why this is the third round on the same parameter, stated plainly
1. I added the parameter and **never wired the caller** — inert in
production.
2. I wired it as a **union of wip+review**, which dropped hold/intake
and made it a *regression* for backlog work.
3. I resolved it from **one workflow** and applied it to all — this fix.
Each round was a smaller version of the same error: treating a lane
answer as global when it is per-task, and per-role when it is
per-membership. Worth recording because the first two rounds both looked
correct and both passed their tests — the tests asserted the renamed
case I was thinking about, not the shape of the data.
## Verification
- new cross-workflow case; reverting the predicate to a single
workflow's lanes **fails it**
- `agent-assignment` suite **14 passed**
- `pnpm test:gate` — **161 / 13 / 487 / 71** · lint clean · census
`--strict` exits 0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>