Files
fusion/packages/engine/src/__tests__/prompt-cache-integration.test.ts
gsxdsm fb2c6e5098 FN-6235: source reviewer prompts from workflow IR
Deduplicate reviewer policy text by making workflow IR review seams the engine's built-in prompt source.

- Move the canonical built-in reviewer prompt into core agent prompts and export seam prompt resolution helpers.
- Resolve reviewer prompts from explicit role overrides first, then workflow IR review seams, with the built-in prompt as a fallback.
- Update prompt cache and reviewer tests to cover single-source reviewer prompt behavior.
- Add a patch changeset for the published Fusion package.

Files changed:
 .../FN-6235-reviewer-prompt-single-source.md       |   5 +
 packages/core/src/__tests__/agent-prompts.test.ts  |   8 +-
 packages/core/src/agent-prompts.ts                 | 109 +++++++++--
 packages/core/src/index.ts                         |   2 +
 packages/core/src/workflow-ir-resolver.ts          |  31 ++-
 .../src/__tests__/prompt-cache-integration.test.ts |  10 +-
 .../reviewer-prompt-single-source.test.ts          | 160 +++++++++++++++
 packages/engine/src/__tests__/reviewer.test.ts     |  97 ++++-----
 packages/engine/src/prompt-layers.ts               |   2 +-
 packages/engine/src/reviewer.ts                    | 217 ++-------------------
 10 files changed, 370 insertions(+), 271 deletions(-)

Fusion-Task-Id: FN-6235

Fusion-Task-Lineage: 725932d1-2469-4507-a0f9-0946c83a1572
2026-06-11 21:00:23 -07:00

52 lines
2.0 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { resolveAgentPrompt } from "@fusion/core";
import { buildPromptLayers, collapsePromptLayers, type SystemPromptLayers } from "../prompt-layers.js";
const DEFAULT_REVIEWER_PROMPT = resolveAgentPrompt("reviewer");
describe("cross-session prompt cache integration", () => {
const MEMORY_INSTRUCTIONS = "\n## Memory\n\nUse fn_memory_search to look up relevant context.";
function simulateReviewerSession(sessionIndex: number): SystemPromptLayers {
return buildPromptLayers({
basePrompt: DEFAULT_REVIEWER_PROMPT,
agentInstructions: `Session ${sessionIndex}: custom instructions that vary per agent.`,
memorySection: MEMORY_INSTRUCTIONS,
pluginContributions: sessionIndex % 2 === 0
? "## Plugin: lint\n\nCheck lint rules."
: "",
});
}
it("produces byte-identical stable prefixes across 10 reviewer sessions", () => {
const sessions = Array.from({ length: 10 }, (_, i) => simulateReviewerSession(i));
const stablePrefix = sessions[0].stable;
for (let i = 1; i < sessions.length; i++) {
expect(sessions[i].stable).toBe(stablePrefix);
}
});
it("dynamic layers vary across sessions as expected", () => {
const sessions = Array.from({ length: 5 }, (_, i) => simulateReviewerSession(i));
const uniqueDynamics = new Set(sessions.map((s) => s.dynamic));
expect(uniqueDynamics.size).toBeGreaterThan(1);
});
it("collapsed layers produce valid non-empty strings", () => {
const sessions = Array.from({ length: 5 }, (_, i) => simulateReviewerSession(i));
for (const session of sessions) {
const collapsed = collapsePromptLayers(session);
expect(collapsed.length).toBeGreaterThan(0);
expect(collapsed).toContain("independent code and plan reviewer");
}
});
it("stable prefix starts with the canonical default reviewer prompt", () => {
const layers = simulateReviewerSession(0);
expect(layers.stable.startsWith(DEFAULT_REVIEWER_PROMPT)).toBe(true);
});
});