feat(FN-3018): merge fusion/fn-3018

- **feat(engine): sanitize cwd from createFnAgent startup log** — prevents worktree paths from leaking into engine diagnostic logs
- **test(engine): add regression test for cwd redaction** — verifies working directory is not present in logged output
- **test(engine): update routes-agent-skills test** — minimal addition to coverage
- **test(dashboard): stabilize TaskCard test** — fixes flakiness in full-suite gate

Commits merged:
- test(FN-3018): stabilize dashboard tests for full-suite gate
- test(FN-3018): complete Step 2 — add cwd redaction regression
- feat(FN-3018): complete Step 1 — sanitize createFnAgent startup log

Files changed:
.../app/components/__tests__/TaskCard.test.tsx     |  2 +-
 .../src/__tests__/routes-agent-skills.test.ts      |  1 +
 .../src/__tests__/pi-create-fn-agent.test.ts       | 28 ++++++++++++++++++++++
 packages/engine/src/pi.ts                          |  2 +-
 4 files changed, 31 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-3018
This commit is contained in:
Fusion
2026-04-29 22:03:01 -07:00
committed by gsxdsm
parent e571e701c9
commit a039e2cf27
2 changed files with 29 additions and 1 deletions

View File

@@ -594,6 +594,34 @@ describe("createFnAgent", () => {
});
});
it("logs createFnAgent startup diagnostics without leaking cwd", async () => {
const { piLog } = await import("../logger.js");
const logSpy = vi.spyOn(piLog, "log").mockImplementation(() => {});
const { createFnAgent } = await import("../pi.js");
await createFnAgent({
cwd: "/tmp/private-worktree",
systemPrompt: "test",
tools: "readonly",
defaultProvider: "openai-codex",
defaultModelId: "gpt-5.4",
});
const startupLog = logSpy.mock.calls
.map(([message]) => String(message))
.find((message) => message.includes("createFnAgent called"));
expect(startupLog).toBeDefined();
expect(startupLog).toContain("createFnAgent called");
expect(startupLog).toContain("tools=readonly");
expect(startupLog).toContain("provider=openai-codex");
expect(startupLog).toContain("model=gpt-5.4");
expect(startupLog).not.toContain("cwd=");
expect(startupLog).not.toContain("/tmp/private-worktree");
logSpy.mockRestore();
});
it("falls back during prompt when the primary model has an auth failure", async () => {
const primaryPrompt = vi.fn().mockRejectedValue(new Error("401 unauthorized: invalid api key"));
const fallbackPrompt = vi.fn().mockResolvedValue(undefined);