Files
fusion/packages/engine
gsxdsm f5926d3b54 docs(engine): flag triage's evacuation guard — it looks two-thirds converted and is fully literal (#3108)
Completes the sync-listener audit across the three files holding the
remaining blocked guards — `executor.ts` (#3104), `scheduler.ts`
(#3100), and this one. Triage is the most misleading of the three.

## The shape lies

The guard reads as **two resolved arms and one literal**:

> `task.column === disposeLanes.hold || task.column ===
disposeLanes.intake || task.column === "in-progress"`

So the obvious next move is to convert the third arm with the same
helper. That is wrong twice:

**1. The two "resolved" arms are not resolved.** `resolvePlannerLanes`
goes through `resolveTaskWorkflowIrSync`, which cannot answer for a
**custom** workflow — the sync selection reader returns `undefined`
unconditionally, *and* the custom-workflow IR read goes through
`store.db`, whose implementation is an unconditional throw (#3103). So
`disposeLanes.hold` / `.intake` are `todo` / `triage` on every board.
**All three arms are literal in effect.** Converting the third the same
way adds a third inert comparison and retires a census entry that is
currently telling the truth.

**2. The guard's answer is consumed synchronously** — the criterion I
had to correct in #3104. Below it, `pauseAborted.add`,
`session.dispose()` and `activeSessions.delete` mutate in-memory state
in this tick, and other paths read those maps. Contrast
`self-healing.ts`'s fan-out, where three of four guards only gated work
the listener already `void`s and so *were* convertible via the async
resolver (#3094).

## What it costs, and the obvious reading is backwards

An evacuation **into** a renamed destination still falls through and
disposes correctly — no bug there.

The failure is the other direction: on a board whose **hold or intake**
lane is renamed, arms 1 and 2 stop matching, so a card **sitting still
in its own planning lane** is treated as evacuated and its live triage
session is aborted mid-run.

I state it that way because "renamed board → guard misses → nothing
happens" is the pattern everywhere else in this program, and here it
inverts.

## Census

**Unchanged at 1**, deliberately. Blocked, and now documented as *fully
literal* rather than part-converted — which is the fact a future pass
needs in order not to make it worse.

## Measured

- Comment-only.
- `src/__tests__/triage*` — **25 files / 374 tests pass**.
- `tsc --noEmit -p packages/engine` clean; `check-fnxc-future-dates`
clean.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 04:40:21 -07:00
..
2026-07-26 18:11:47 -07:00