Files
fusion/packages/engine
gsxdsm ea0af4826f test(engine): third instance of the optional-role-parameter class, intra-file (#2799)
## What

One new live-PostgreSQL E2E suite, 4 tests. **No production file is
touched** — evidence, per the E2E worker's remit. Third measured
instance of the pattern from #2795 and #2798.


`packages/engine/src/__tests__/workflow-planning-continuation-terminal-gap-live-e2e.pg.test.ts`

## The finding — and why it is the sharpest form yet

The converted and unconverted call sites are **in the same file**, and
one is nested inside the other's call tree.

`in-process-runtime.ts` resolves terminal columns through an optional
parameter defaulting to `LEGACY_TERMINAL_PAIR` (`done` + `archived`):

| site | passes the resolved set? |
|---|---|
| `drainDuePlanningContinuations:386` | ✅ `{ terminalColumns }` |
| `selectActionablePlanningContinuations:413` | ❌ nothing |
| `resolvePlanningContinuationCandidate:199` → inner predicate | ❌ not
threaded |

**What breaks.** `selectActionablePlanningContinuations` documents its
own purpose as excluding *"soft-deleted / archived / done tasks so
archive-fallback rows returned by getTask cannot re-enter plan-review
after the card left the board."* On a renamed board its terminal test is
against ids that board does not have, so a card sitting in its
**complete** column is classified `actionable` and re-enters plan-review
— precisely the thing the function exists to prevent, silently, on every
custom board.

**The third site matters too**, because it shows the conversion is not
whole even along the *converted* path:
`resolvePlanningContinuationCandidate` applies the caller's resolved set
to its own terminal test, then delegates to
`isPlanningContinuationTaskDispatchable(task)` without passing it, so
that inner predicate re-tests against the legacy pair. A partially
threaded conversion is indistinguishable from a complete one at every
call site that looks converted.

### The class so far

| seam | call sites passing the resolved answer |
|---|---|
| `shouldHoldActiveFileScopeLease` | 2 of 4 — #2795 |
| `evaluateParkedAgentTaskLink` | 2 of 6 — #2798 |
| `resolvePlanningContinuationCandidate` | **1 of 2**, plus one
unthreaded inner call — this PR |

Verified clean and reported as such: `restart-recovery-coordinator.ts`,
the `isRecoverableMissingWorktreeReviewFailure` family,
`spec-staleness.ts`'s `plannerColumns`, `task-revert.ts`'s
`revertableColumns`, `agent-assignment.ts`'s `activeColumns`. Audited
since this PR was opened and also clean: `surfacing-sweeps.ts`'s
`roleColumn` (resolved internally through the async resolver — not a
caller-supplied parameter at all) and `auto-claim-snapshot.ts`'s role
trio (both `isRunnableAutoClaimCandidate` call sites pass
`rolesByTask`). **The class audit is therefore complete**: four seams
have unconverted callers (#2795, #2798, this PR, #2802); every other
seam is correct.

None of it is visible to the lifecycle-column census: there is no column
literal at any unconverted call site — the literal lives one function
away, where it is correct for an unconverted caller and correctly
annotated.

## Scope, stated honestly

The three behavioural cases are driven end to end with real persisted
rows from a live store and the real exported functions. The **call-site
split is asserted against source text** — driving the drain needs the
runtime's full dependency set, which I did not build — and the audit
case says so rather than dressing it up. It is an alarm in both
directions.

## Mutation-verified

Flipping `LEGACY_TERMINAL_PAIR` from `done` to the renamed complete id:

| case | result |
|---|---|
| CONTROL (default board) | **fails** |
| CHARACTERIZATION (renamed board) | **fails** |
| BOUND (resolved set passed) | passes — correct, the argument overrides
the default |
| AUDIT | passes — correct, it is a source assertion |

## Not done, and why

**No fix.** Threading the resolved set into
`selectActionablePlanningContinuations` changes its signature and every
caller; threading it into the inner predicate changes behaviour along
the already-converted path. Both are decisions for the file's owner. The
differential says exactly what the fix should make true.

## Verification

- new suite — **4/4 passed**, mutation matrix above
- full live-PG E2E surface — **137/137 passed** (133 on main + 4)
- `pnpm lint` — clean

Lane: `.pg.test.ts`, skipped via `pgDescribe` when no PostgreSQL is
reachable, so the merge gate is unaffected. Throwaway per-file database;
never port 4040.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 11:15:56 -07:00
..
2026-07-26 18:11:47 -07:00