feat(FN-2087): finalize canonical memory path migration

- Remove legacy .fusion/memory.md fallback references and normalize prompts/docs to .fusion/memory/MEMORY.md
- Stop legacy mirror writes and fallback reads in core memory backend and project memory flows
- Update engine worktree boundary checks and tests for canonical memory file handling
- Align dashboard memory/settings surfaces and route tests with canonical memory behavior
- Add model-favorites persistence test coverage for mission interview and new agent dialogs
This commit is contained in:
Fusion
2026-04-18 22:47:17 -07:00
committed by gsxdsm
parent 3cb7c226ec
commit 049f356f88
32 changed files with 503 additions and 307 deletions

View File

@@ -2417,7 +2417,7 @@ describe("buildExecutionPrompt", () => {
} as any);
expect(result).toContain("Execute this task.");
expect(result).toContain("## Project Memory");
expect(result).toContain(".fusion/memory/");
expect(result).toContain(".fusion/memory/MEMORY.md");
});
it("excludes memory instructions when memoryEnabled: false", () => {
@@ -2434,7 +2434,7 @@ describe("buildExecutionPrompt", () => {
const result = buildExecutionPrompt(task, "/project", {} as any);
expect(result).toContain("Execute this task.");
expect(result).toContain("## Project Memory");
expect(result).toContain(".fusion/memory/");
expect(result).toContain(".fusion/memory/MEMORY.md");
});
it("includes selective memory write instruction for durable learnings at end of execution", () => {
@@ -2456,22 +2456,22 @@ describe("buildExecutionPrompt", () => {
const result = buildExecutionPrompt(task, "/project", {
memoryEnabled: true,
} as any);
expect(result).toContain(".fusion/memory/");
expect(result).toContain("`.fusion/memory/MEMORY.md`");
});
});
describe("memoryBackendType setting", () => {
it("includes .fusion/memory/ guidance for file backend", () => {
it("includes .fusion/memory/MEMORY.md for file backend", () => {
const task = createMockTaskDetail();
const result = buildExecutionPrompt(task, "/project", {
memoryEnabled: true,
memoryBackendType: "file",
} as any);
expect(result).toContain("## Project Memory");
// Check that the Project Memory section contains .fusion/memory/ guidance
// Check that the Project Memory section contains .fusion/memory/MEMORY.md
const memorySectionMatch = result.match(/## Project Memory\n([\s\S]*?)(?=\n## [^#]|$)/);
expect(memorySectionMatch).toBeTruthy();
expect(memorySectionMatch![1]).toContain(".fusion/memory/");
expect(memorySectionMatch![1]).toContain(".fusion/memory/MEMORY.md");
});
it("includes read-only wording for readonly backend without write directives in memory section", () => {
@@ -2488,10 +2488,10 @@ describe("buildExecutionPrompt", () => {
// Should NOT contain write/update directives in the memory section
expect(memorySection).not.toMatch(/write.*memory|update.*memory/i);
// Should NOT contain the specific file path in the memory section
expect(memorySection).not.toContain(".fusion/memory.md");
expect(memorySection).not.toContain(".fusion/memory/MEMORY.md");
});
it("does not include .fusion/memory.md in Project Memory section for qmd backend", () => {
it("does not include .fusion/memory/MEMORY.md in Project Memory section for qmd backend", () => {
const task = createMockTaskDetail();
const result = buildExecutionPrompt(task, "/project", {
memoryEnabled: true,
@@ -2502,8 +2502,8 @@ describe("buildExecutionPrompt", () => {
const memorySectionMatch = result.match(/## Project Memory\n([\s\S]*?)(?=\n## [^#]|$)/);
expect(memorySectionMatch).toBeTruthy();
const memorySection = memorySectionMatch![1];
// QMD should NOT unconditionally reference .fusion/memory.md in the memory section
expect(memorySection).not.toContain(".fusion/memory.md");
// QMD should NOT unconditionally reference .fusion/memory/MEMORY.md in the memory section
expect(memorySection).not.toContain(".fusion/memory/MEMORY.md");
expect(memorySection).toContain("memory_search");
expect(memorySection).toContain("memory_get");
});
@@ -2519,8 +2519,8 @@ describe("buildExecutionPrompt", () => {
const memorySectionMatch = result.match(/## Project Memory\n([\s\S]*?)(?=\n## [^#]|$)/);
expect(memorySectionMatch).toBeTruthy();
const memorySection = memorySectionMatch![1];
// QMD should NOT contain .fusion/memory.md
expect(memorySection).not.toContain(".fusion/memory.md");
// QMD should NOT contain .fusion/memory/MEMORY.md
expect(memorySection).not.toContain(".fusion/memory/MEMORY.md");
expect(memorySection).toContain("memory_search");
// Contains "end of execution" write guidance
expect(memorySection).toMatch(/end of execution/i);
@@ -10620,7 +10620,7 @@ describe("buildExecutionPrompt", () => {
const prompt = buildExecutionPrompt(task, "/project");
expect(prompt).toContain(".fusion/memory/");
expect(prompt).toContain(".fusion/memory/MEMORY.md");
expect(prompt).toContain("memory");
expect(prompt).toContain("durable");
});