diff --git a/.changeset/fix-completion-summary-contract.md b/.changeset/fix-completion-summary-contract.md new file mode 100644 index 0000000000..d864aeea6f --- /dev/null +++ b/.changeset/fix-completion-summary-contract.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Prevent review-contract retry instructions from replacing workflow completion summaries. +category: fix +dev: Limits approved PROMPT.md contract injection to review-type workflow nodes. diff --git a/packages/engine/src/__tests__/ce-workflow-step-executor.test.ts b/packages/engine/src/__tests__/ce-workflow-step-executor.test.ts index 288ceea239..aa1f6d7de7 100644 --- a/packages/engine/src/__tests__/ce-workflow-step-executor.test.ts +++ b/packages/engine/src/__tests__/ce-workflow-step-executor.test.ts @@ -955,6 +955,28 @@ Ship FIVE kinds. Do NOT add roadmap-item in this task. expect(cap.last?.systemPrompt).toContain("Return REVISE with the single reason that the approved contract could not be loaded"); }); + it.each([ + ["completion summary", { name: "Completion summary", summaryTarget: "task" }], + ["ordinary advisory prompt", { name: "Publish artifacts" }], + ])("does not inject review-contract instructions into the %s surface", async (_label, stepOverrides) => { + const store = createMockStore(); + const { executor } = makeExecutor(store); + const cap = captureSession("Finished the requested work and verified the affected behavior."); + const readTaskArtifact = vi.spyOn(executor as any, "readTaskArtifact"); + + await (executor as any).executeWorkflowStep( + baseStepTask(), + makeStep(stepOverrides), + "/tmp/wt", + {}, + ); + + expect(readTaskArtifact).not.toHaveBeenCalled(); + expect(cap.last?.systemPrompt).not.toContain("Approved Task Contract:"); + expect(cap.last?.systemPrompt).not.toContain("Approved Task Contract Unavailable:"); + expect(cap.last?.systemPrompt).not.toContain("canonical scope"); + }); + it("sets FUSION_HEADLESS=1 only when unattended=true; always sets FUSION_WORKFLOW_STEP", async () => { const store = createMockStore(); const { executor } = makeExecutor(store); diff --git a/packages/engine/src/executor.ts b/packages/engine/src/executor.ts index a0d7f7d38a..7e4fb991ea 100644 --- a/packages/engine/src/executor.ts +++ b/packages/engine/src/executor.ts @@ -16309,7 +16309,7 @@ ${scopeGuard} * unrelated local commits can make a plan-only gate reject implementation * state and loop back to triage after the planner already approved the spec. */ - const approvedContractBlock = !isPlanReviewStep + const approvedContractBlock = isReviewTypeWorkflowStep && !isPlanReviewStep ? workflowReviewSpecText ? `