fix(FN-2364): harden diagnostics context and plugin reload imports

- Add explicit operation metadata to agent-generation and ai-session-store diagnostics for cleanup, recovery, and scheduled cleanup paths
- Extend dashboard guardrail coverage to explicitly enforce diagnostics protection for agent-generation.ts and ai-session-store.ts
- Stabilize plugin module reload imports by using temporary reload files with deterministic file URLs and cache updates
- Tighten CLI Vitest workspace cleanup to safely skip missing hidden dist directories during restore
This commit is contained in:
Fusion
2026-04-24 01:34:34 -07:00
committed by gsxdsm
parent 5e9cd88708
commit 4f9f36fe75
7 changed files with 58 additions and 42 deletions

View File

@@ -479,6 +479,8 @@ describe("agent-generation module", () => {
context: expect.objectContaining({
cleanedSessions: 1,
cleanedRateLimits: 2,
ttlMs: 30 * 60 * 1000,
rateLimitWindowMs: 60 * 60 * 1000,
operation: "cleanup-expired",
}),
});

View File

@@ -215,6 +215,8 @@ function cleanupExpiredSessions(): void {
diagnostics.info("Cleanup completed", {
cleanedSessions,
cleanedRateLimits,
ttlMs: SESSION_TTL_MS,
rateLimitWindowMs: RATE_LIMIT_WINDOW_MS,
operation: "cleanup-expired",
});
}

View File

@@ -153,6 +153,8 @@ describe("AiSessionStore", () => {
terminalDeleted: 2,
orphanedDeleted: 1,
totalDeleted: 3,
maxAgeMs: SESSION_CLEANUP_DEFAULT_MAX_AGE_MS,
operation: "cleanup-stale-sessions",
}),
}),
);
@@ -228,6 +230,7 @@ describe("AiSessionStore", () => {
message: "Scheduled cleanup failed",
context: expect.objectContaining({
ttlMs: 60_000,
operation: "scheduled-cleanup",
error: expect.objectContaining({ message: "boom" }),
}),
}),
@@ -282,7 +285,10 @@ describe("AiSessionStore", () => {
level: "info",
scope: "ai-session-store",
message: "Recovered stale sessions after restart",
context: expect.objectContaining({ recovered: 2 }),
context: expect.objectContaining({
recovered: 2,
operation: "recover-stale-sessions",
}),
}),
);
});

View File

@@ -406,7 +406,10 @@ export class AiSessionStore extends EventEmitter<AiSessionStoreEvents> {
recovered += Number(withoutQuestion.changes ?? 0);
if (recovered > 0) {
diagnostics.info("Recovered stale sessions after restart", { recovered });
diagnostics.info("Recovered stale sessions after restart", {
recovered,
operation: "recover-stale-sessions",
});
}
return recovered;
}
@@ -478,6 +481,8 @@ export class AiSessionStore extends EventEmitter<AiSessionStoreEvents> {
terminalDeleted,
orphanedDeleted,
totalDeleted,
maxAgeMs,
operation: "cleanup-stale-sessions",
});
return {
@@ -497,7 +502,10 @@ export class AiSessionStore extends EventEmitter<AiSessionStoreEvents> {
try {
this.cleanupStaleSessions(ttlMs);
} catch (error) {
diagnostics.errorFromException("Scheduled cleanup failed", error, { ttlMs });
diagnostics.errorFromException("Scheduled cleanup failed", error, {
ttlMs,
operation: "scheduled-cleanup",
});
}
};

View File

@@ -20,6 +20,9 @@ import { resolve } from "node:path";
/**
* List of AI-session modules that must use the shared diagnostics helper.
* These modules handle AI-session flows and must not use raw console.* diagnostics.
*
* Keep `agent-generation.ts` and `ai-session-store.ts` in this list — they are
* long-lived generation/cleanup surfaces with historical raw-console drift.
*/
const AI_SESSION_FLOW_MODULES = [
"planning.ts",
@@ -75,6 +78,11 @@ function findRawConsoleCalls(
}
describe("AI-Session Diagnostics Guardrail", () => {
it("explicitly guards agent-generation and ai-session-store modules", () => {
expect(AI_SESSION_FLOW_MODULES).toContain("agent-generation.ts");
expect(AI_SESSION_FLOW_MODULES).toContain("ai-session-store.ts");
});
/**
* Test that each AI-session flow module uses the shared diagnostics helper
* instead of raw console.* calls.