Merge pull request #1726 from plarson/fix/triage-spec-review-fallback

fix(triage): pass fallback model settings to spec review
This commit is contained in:
gsxdsm
2026-06-23 09:52:58 -07:00
committed by GitHub
3 changed files with 72 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
---
"@runfusion/fusion": patch
---
Pass project fallback model settings into triage spec reviewer sessions so global default overrides are honored during review.

View File

@@ -1010,6 +1010,67 @@ describe("fast-mode triage", () => {
}
});
it("threads global fallback model settings into spec reviewer sessions", async () => {
const rootDir = await createTriageFixtureRoot("fusion-triage-review-fallback-");
try {
const taskId = "FN-REVIEW-FALLBACK";
await mkdir(join(rootDir, ".fusion", "tasks", taskId), { recursive: true });
await writeFile(
join(rootDir, ".fusion", "tasks", taskId, "PROMPT.md"),
"# Task\n\n## Mission\n\nDo the work.\n\n## Steps\n\n### Step 0: Implement\n\nShip it.",
);
mockReviewStep.mockResolvedValue({ verdict: "APPROVE", review: "ok", summary: "ok" });
const store = createMockStore({
getTask: vi.fn().mockResolvedValue({ ...mockTaskDetail, id: taskId, comments: [] }),
getSettings: vi.fn().mockResolvedValue({
maxConcurrent: 2,
maxWorktrees: 4,
pollIntervalMs: 10000,
groupOverlappingFiles: false,
autoMerge: true,
defaultProvider: "anthropic",
defaultModelId: "claude-opus-4-8",
defaultProviderOverride: "openai-codex",
defaultModelIdOverride: "gpt-5.5",
fallbackProvider: "openai-codex",
fallbackModelId: "gpt-5.5",
memoryEnabled: false,
agentPrompts: { roleAssignments: { reviewer: "custom-reviewer" } },
} as Settings),
});
const processor = new TriageProcessor(store, rootDir);
const tool = (processor as any).createReviewSpecTool(
taskId,
`.fusion/tasks/${taskId}/PROMPT.md`,
{ current: null },
{ current: null },
{ current: null },
{ current: "" },
{},
false,
);
await tool.execute({});
const reviewOptions = mockReviewStep.mock.calls[0]?.[7];
expect(reviewOptions).toMatchObject({
projectDefaultOverrideProvider: "openai-codex",
projectDefaultOverrideModelId: "gpt-5.5",
fallbackProvider: "openai-codex",
fallbackModelId: "gpt-5.5",
agentPrompts: { roleAssignments: { reviewer: "custom-reviewer" } },
});
expect(reviewOptions.settings).toMatchObject({
memoryEnabled: false,
agentPrompts: { roleAssignments: { reviewer: "custom-reviewer" } },
});
} finally {
mockReviewStep.mockReset();
await cleanupTriageFixtureRoot(rootDir);
}
});
it("passes post-session gate in fast mode after fn_review_spec auto-approval", async () => {
const rootDir = await createTriageFixtureRoot("fusion-triage-fast-gate-");
try {

View File

@@ -1890,6 +1890,10 @@ export class TriageProcessor {
// Project-level validator fallback
projectValidatorFallbackProvider: currentSettings.validatorFallbackProvider,
projectValidatorFallbackModelId: currentSettings.validatorFallbackModelId,
// FNXC:SpecReviewerFallback 2026-06-23-08:50:
// Spec review must inherit global/default fallback reviewer model settings when no validator-specific fallback is configured, plus the project settings/prompt payload that reviewer sessions use for memory and custom prompt behavior.
fallbackProvider: currentSettings.fallbackProvider,
fallbackModelId: currentSettings.fallbackModelId,
// Global validator lane
globalValidatorProvider: currentSettings.validatorGlobalProvider,
globalValidatorModelId: currentSettings.validatorGlobalModelId,
@@ -1901,8 +1905,10 @@ export class TriageProcessor {
taskId,
task: currentDetail,
userComments: currentUserComments.length > 0 ? currentUserComments : undefined,
agentPrompts: currentSettings.agentPrompts,
agentStore: this.options.agentStore,
rootDir,
settings: currentSettings,
// Track the spec reviewer's session under this task so it's
// disposed alongside the main triage session on global pause.
onSessionCreated: (s) => this.registerSubagentSession(taskId, s),