From 0b332816d5b96fc388d62c38fd811f9c683b32f6 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 15 Jul 2026 19:57:34 -0700 Subject: [PATCH] FN-7986: raise plan review replan cap to 8 Allow more automatic Plan Review revisions before escalating tasks for human approval. - Raise the consecutive REVISE replan cap from 3 to 8. - Cover the seven- and eight-revision boundaries in triage tests. - Add a patch changeset describing the revised default. Files changed: .changeset/fn-7986-plan-review-cap.md | 7 +++++++ .../triage-plan-review-replan-cap.test.ts | 23 +++++++++++++--------- packages/engine/src/triage.ts | 8 ++++---- 3 files changed, 25 insertions(+), 13 deletions(-) Fusion-Task-Id: FN-7986 Fusion-Task-Lineage: 3b61f333-be9a-414a-bd27-aabdbb45caa0 Co-authored-by: Fusion (runfusion.ai) --- .changeset/fn-7986-plan-review-cap.md | 7 ++++++ .../triage-plan-review-replan-cap.test.ts | 23 +++++++++++-------- packages/engine/src/triage.ts | 8 +++---- 3 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 .changeset/fn-7986-plan-review-cap.md diff --git a/.changeset/fn-7986-plan-review-cap.md b/.changeset/fn-7986-plan-review-cap.md new file mode 100644 index 0000000000..e8759d5cf6 --- /dev/null +++ b/.changeset/fn-7986-plan-review-cap.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Plan Review now allows more automatic replan attempts (default 8) before asking a human. +category: internal +dev: Raised triage PLAN_REVIEW_GATE_REPLAN_CAP from 3 to 8 in packages/engine/src/triage.ts; escalation to awaiting-approval (awaitingApprovalReason "plan-review-replan-cap") now fires at 8 consecutive REVISE replans. diff --git a/packages/engine/src/__tests__/triage-plan-review-replan-cap.test.ts b/packages/engine/src/__tests__/triage-plan-review-replan-cap.test.ts index 5743ed6b1f..baa850c987 100644 --- a/packages/engine/src/__tests__/triage-plan-review-replan-cap.test.ts +++ b/packages/engine/src/__tests__/triage-plan-review-replan-cap.test.ts @@ -3,7 +3,7 @@ import type { Settings, Task, TaskStore } from "@fusion/core"; import { join } from "node:path"; import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; -import { PLAN_REVIEW_GATE_REPLAN_CAP, TriageProcessor } from "../triage.js"; +import { TriageProcessor } from "../triage.js"; /* * Bug A (part 2): the triage pre-execution Plan Review gate must bound consecutive @@ -142,11 +142,11 @@ describe("Plan Review replan cap", () => { it("escalates to awaiting-approval instead of replanning once the cap is reached", async () => { const rootDir = await createFixtureRoot(); roots.push(rootDir); - // Cap is PLAN_REVIEW_GATE_REPLAN_CAP (8): a task that has already consumed that many - // consecutive REVISE replans must escalate on the next REVISE rather than replanning again. + // Cap is 8: a task that has already consumed that many consecutive REVISE replans must + // escalate on the next REVISE rather than replanning again. const task = createRetryTask({ id: "FN-REPLAN-CAP-HIT", - planReviewReplanCount: PLAN_REVIEW_GATE_REPLAN_CAP, + planReviewReplanCount: 8, }); const prompt = `# Task: ${task.id} - Existing draft\n\n## Mission\n\nOnly rewrite after reviewer feedback.\n`; await writePrompt(rootDir, task.id, prompt); @@ -171,17 +171,22 @@ describe("Plan Review replan cap", () => { expect(store.logEntry).toHaveBeenCalledWith( task.id, "Plan Review replan cap reached — escalating to manual approval", - expect.stringContaining(`cap ${PLAN_REVIEW_GATE_REPLAN_CAP}`), + expect.stringContaining("cap 8"), ); }); - it("still replans when one attempt remains under the cap", async () => { + it("still replans from seven consecutive REVISE verdicts", async () => { const rootDir = await createFixtureRoot(); roots.push(rootDir); - const priorCount = PLAN_REVIEW_GATE_REPLAN_CAP - 1; + /* + FNXC:PlanReviewReplan 2026-07-15-11:30: + Keep this boundary literal rather than deriving it from the production constant. FN-7986 + requires proof that the default is truly 8: with the former cap of 3, seven prior REVISE + verdicts would escalate instead of returning the task to `needs-replan` at count 8. + */ const task = createRetryTask({ id: "FN-REPLAN-CAP-LAST", - planReviewReplanCount: priorCount, + planReviewReplanCount: 7, }); const prompt = `# Task: ${task.id} - Existing draft\n\n## Mission\n\nOnly rewrite after reviewer feedback.\n`; await writePrompt(rootDir, task.id, prompt); @@ -192,7 +197,7 @@ describe("Plan Review replan cap", () => { expect(store.updateTask).toHaveBeenCalledWith(task.id, expect.objectContaining({ status: "needs-replan", - planReviewReplanCount: PLAN_REVIEW_GATE_REPLAN_CAP, + planReviewReplanCount: 8, })); expect(store.updateTask).not.toHaveBeenCalledWith(task.id, expect.objectContaining({ status: "awaiting-approval", diff --git a/packages/engine/src/triage.ts b/packages/engine/src/triage.ts index dc53069f6a..22297022c2 100644 --- a/packages/engine/src/triage.ts +++ b/packages/engine/src/triage.ts @@ -61,10 +61,10 @@ The triage pre-execution Plan Review gate (runPlanReviewBeforeExecution) routes verdict back to `needs-replan`, which re-plans and re-reviews. Without a ceiling, a planner and reviewer that persistently disagree loop plan → Plan Review REVISE → replan forever (observed on TC-002), and in `planApprovalMode: require-all` there is no human escape because -the task never reaches `awaiting-approval`. Bound the consecutive REVISE replans with a small -cap (mirroring the executor graph's PLAN_REVIEW_REPLAN_HARD_CAP backstop): after this many -replans the gate escalates the task to `awaiting-approval` for a human decision instead of -replanning again. The counter (Task.planReviewReplanCount) resets when the gate passes. +the task never reaches `awaiting-approval`. Bound the consecutive REVISE replans with a +cap (default 8, mirroring the executor graph's PLAN_REVIEW_REPLAN_HARD_CAP backstop): after +this many replans the gate escalates the task to `awaiting-approval` for a human decision +instead of replanning again. The counter (Task.planReviewReplanCount) resets when the gate passes. FNXC:PlanReviewReplan 2026-07-15-11:09: Raise the automatic REVISE replan ceiling from 3 to 8 so planner/reviewer pairs get more