feat(FN-WF): cover S07 on V2 by releasing its operator park in recovery

Named remediation parks an unactionable review rejection as `awaiting-approval`
with `paused: true` — deliberately, because there is no actionable finding to
derive work from, so a human must decide. S07's recovery driver only re-drove the
graph, and a drive cannot move a paused card, so the declared recovery could never
reach a merge and the scenario read as a wedge.

The recovery now performs the operator's half of its own contract ("operator
retry, or the cause disappears") before driving: it releases an EXPLICIT
awaiting-approval park and then approves through the restored graph session. The
merge that follows is still fully asserted, so this widens no assertion.

builtin:coding-ideas-v2 covers 18 of 19 scenarios plus the multi-repository
workspace drive. Three consecutive full runs: 123.6s, 125.7s, 126.1s of 150s.

S05 stays on its original workflows. It passes 22/22 when its file runs alone but
fails intermittently under full-lane load, and settling in-flight merges at every
graph dispatch — before and after, with a 10x larger drain bound — did not remove
it. That points at cross-file interference rather than the merge race it first
resembled, and an unexplained flake is not something to ship.
This commit is contained in:
Fusion Agent
2026-08-25 04:22:49 +00:00
parent eba8c1052d
commit 19c3981a50
3 changed files with 22 additions and 3 deletions

View File

@@ -179,8 +179,27 @@ export const PIPELINE_SCENARIO_DRIVERS = {
}
throw new Error("S07 did not persist its real unactionable Code Review rejection.");
}),
s07Recovery: driver("provide an actionable approval through the restored graph session", async (context) => {
/*
FNXC:PipelineSmoke 2026-08-24-22:40:
The declared recovery for a park is "operator retry, or the cause disappears". Named remediation
parks an unactionable rejection as `awaiting-approval` with `paused: true` — deliberately, because
there is no actionable finding to derive work from, so a human must decide. A drive alone cannot
move a paused card, so the recovery must first perform the operator's half of that contract.
Releasing an EXPLICIT awaiting-approval park is the operator action under test; it is not a way to
make an unrelated failure pass, and the merge that follows is still fully asserted.
*/
s07Recovery: driver("release the operator park, then approve through the restored graph session", async (context) => {
const parked = context.result;
const task = taskFor(context);
const live = await context.harness.freshTask(task.id);
if (live.paused === true || live.status === "awaiting-approval") {
await context.harness.store.updateTask(task.id, {
paused: false,
pausedReason: undefined,
status: undefined,
awaitingApprovalReason: undefined,
} as never);
}
await driveMerged(context, { planReviewModes: ["approve"], codeReviewModes: ["approve"] });
context.result = parked;
}),

View File

@@ -881,7 +881,7 @@ export class PipelineSmokeHarness {
take before it is called wedged. A review-column workflow adds verification, documentation
and summary nodes to every rework cycle, so S05 ("REVISE twice, then approve") needs roughly
nine more dispatches than the same scenario on the base graph. Raising it does not weaken any
assertion <20> the declared terminal and the wedge detectors are unchanged.
assertion: the declared terminal and the wedge detectors are unchanged.
*/
maxIterations: 32,
signature: (state) => JSON.stringify({

View File

@@ -112,7 +112,7 @@ export const PIPELINE_SCENARIOS: readonly PipelineScenario[] = [
{
id: "S07",
title: "Unactionable review rejection parks then recovers",
workflows: ["builtin:coding-ideas"],
workflows: ["builtin:coding-ideas", "builtin:coding-ideas-v2"],
expectedTerminal: "parked",
arrange: PIPELINE_SCENARIO_DRIVERS.s07Arrange,
act: PIPELINE_SCENARIO_DRIVERS.s07Act,