S05 now covers builtin:coding-ideas-v2. 5/5 consecutive full lanes.
Two harness defects, both of which made a CORRECT engine refusal look like a flake.
1. Task ids collided. The serial lived on the harness instance and reset with it, so
every test's first task was `FN-182-S05-1`. The engine's process-wide state —
`executingTaskLock`, `activeSessionRegistry.pathsForTask`, worktree registrations —
is keyed by task id, so a straggler from the previous test answered for the NEXT
test's identically-named task and handed it a worktree under the PREVIOUS fixture.
The serial now lives on the module.
2. Teardown forgot in-flight work instead of waiting for it. `ProjectEngine.stop()`
clears timers but does not await an execution already inside `execute()`, and the
harness then called `activeSessionRegistry.clear()` — which hides a live session
rather than ending it. `dispose()` now drains `executingTaskLock` and the registry
for its own task ids, bounded, and THROWS on expiry: a straggler that outlives the
budget is a real defect, and a silent continue would restore the leak.
Throughout this, the product was right. The executor detected the foreign worktree,
refused it (`outside_worktrees_dir`), retried, exhausted its budget and failed
visibly. That refusal is the desired behaviour and was never the bug — the harness
was manufacturing the condition.
Budget re-baselined 150s -> 175s for attributable growth: a 7th file (the remediation
drive) and S05 on V2, one of the longest scenarios. Five runs at 140.1-148.4s left
under 2s of headroom against the old ceiling, which is a flake waiting to happen. The
standing rule is unchanged and now has three precedents: growth must be nameable, or
it is a regression to fix rather than a budget to raise.
pnpm lint 0 errors, test:gate, verify:fast, engine-pipeline-smoke 90/90, and five
consecutive full runs: 146.0s, 142.6s, 148.5s, 144.8s, 146.3s of the 175s budget.