feat(FN-4640): complete Step 6 — dashboard sandbox audit surface
Fusion-Task-Id: FN-4640 Fusion-Task-Lineage: 4a91265f-1714-4854-b08d-7ddb06074253
This commit is contained in:
committed by
gsxdsm
parent
e4769ea889
commit
ad73d76586
@@ -44,7 +44,7 @@ describe("ContaminationAutoRecoveryHandler", () => {
|
||||
|
||||
it("mode off does not call handler", async () => {
|
||||
const issueRetry = vi.fn();
|
||||
const dispatcher = new AutoRecoveryDispatcher({ taskStore: {} as any, auditEmitter: { database: vi.fn(), git: vi.fn(), filesystem: vi.fn() }, handlers: { issueRetry } });
|
||||
const dispatcher = new AutoRecoveryDispatcher({ taskStore: {} as any, auditEmitter: { database: vi.fn(), git: vi.fn(), filesystem: vi.fn(), sandbox: vi.fn() }, handlers: { issueRetry } });
|
||||
const decision = await dispatcher.dispatch({ class: "branch-cross-contamination", taskId: "FN-1", pausedReason: "branch-cross-contamination" }, { task: baseTask, retryCount: 0, settings: { mode: "off", maxRetries: 3 } });
|
||||
expect(decision.action).toBe("pause");
|
||||
expect(issueRetry).not.toHaveBeenCalled();
|
||||
|
||||
@@ -8,7 +8,7 @@ function createDispatcher() {
|
||||
const database = vi.fn(async () => {});
|
||||
const dispatcher = new AutoRecoveryDispatcher({
|
||||
taskStore: {} as never,
|
||||
auditEmitter: { database, git: vi.fn(), filesystem: vi.fn() },
|
||||
auditEmitter: { database, git: vi.fn(), filesystem: vi.fn(), sandbox: vi.fn() },
|
||||
});
|
||||
return { dispatcher, database };
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ describe("reliability interaction: contamination auto-recovery precedence", () =
|
||||
const issueRetry = vi.fn();
|
||||
const dispatcher = new AutoRecoveryDispatcher({
|
||||
taskStore: {} as never,
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn() },
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn(), sandbox: vi.fn() },
|
||||
handlers: { issueRetry },
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ describe("reliability interaction: contamination auto-recovery precedence", () =
|
||||
const issueRetry = vi.fn(async () => {});
|
||||
const dispatcher = new AutoRecoveryDispatcher({
|
||||
taskStore: {} as never,
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn() },
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn(), sandbox: vi.fn() },
|
||||
handlers: { issueRetry },
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@ describe("reliability interaction: contamination auto-recovery precedence", () =
|
||||
it("mode off and destructive ambiguity preserve pause", () => {
|
||||
const dispatcher = new AutoRecoveryDispatcher({
|
||||
taskStore: {} as never,
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn() },
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn(), sandbox: vi.fn() },
|
||||
handlers: { issueRetry: vi.fn() },
|
||||
});
|
||||
|
||||
@@ -88,7 +88,7 @@ describe("reliability interaction: contamination auto-recovery precedence", () =
|
||||
it("retry budget exhaustion pauses on subsequent event", () => {
|
||||
const dispatcher = new AutoRecoveryDispatcher({
|
||||
taskStore: {} as never,
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn() },
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn(), sandbox: vi.fn() },
|
||||
handlers: { issueRetry: vi.fn() },
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ describe("reliability interaction: auto-recovery dispatcher precedence", () => {
|
||||
it("mode off preserves legacy pausedReason contract across wired classes", () => {
|
||||
const dispatcher = new AutoRecoveryDispatcher({
|
||||
taskStore: {} as never,
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn() },
|
||||
auditEmitter: { database: vi.fn(async () => {}), git: vi.fn(), filesystem: vi.fn(), sandbox: vi.fn() },
|
||||
});
|
||||
|
||||
const wired = [
|
||||
|
||||
@@ -1838,7 +1838,7 @@ export function createSendMessageTool(
|
||||
options?: { autoRecovery?: ProjectSettings["autoRecovery"]; runAudit?: RunAuditor; taskStore?: TaskStore; settings?: Settings },
|
||||
): ToolDefinition {
|
||||
const deliveryHandler = new MessageDeliveryAutoRecoveryHandler({
|
||||
runAudit: options?.runAudit ?? { database: async () => {}, git: async () => {}, filesystem: async () => {} },
|
||||
runAudit: options?.runAudit ?? { database: async () => {}, git: async () => {}, filesystem: async () => {}, sandbox: async () => {} },
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -2167,7 +2167,7 @@ export function createPostRoomMessageTool(
|
||||
options?: { autoRecovery?: ProjectSettings["autoRecovery"]; runAudit?: RunAuditor; taskStore?: TaskStore; settings?: Settings },
|
||||
): ToolDefinition {
|
||||
const deliveryHandler = new MessageDeliveryAutoRecoveryHandler({
|
||||
runAudit: options?.runAudit ?? { database: async () => {}, git: async () => {}, filesystem: async () => {} },
|
||||
runAudit: options?.runAudit ?? { database: async () => {}, git: async () => {}, filesystem: async () => {}, sandbox: async () => {} },
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -17,7 +17,7 @@ function makeBackend(runImpl?: (command: string, options: SandboxRunOptions) =>
|
||||
policy.onFallback?.({ fromBackendId: "sandbox-exec", toBackendId: "native", reason: "unavailable" });
|
||||
}),
|
||||
run: runImpl ?? vi.fn(async () => ({ stdout: "ok", stderr: "", exitCode: 0, signal: null, timedOut: false, bufferExceeded: false })),
|
||||
runStreaming: vi.fn(async () => ({ outcome: "success", stdout: "", stderr: "", bufferOverflow: false })),
|
||||
runStreaming: vi.fn(async () => ({ outcome: "success" as const, stdout: "", stderr: "", bufferOverflow: false })),
|
||||
dispose: vi.fn(async () => {}),
|
||||
};
|
||||
}
|
||||
@@ -39,8 +39,9 @@ describe("withSandboxAudit", () => {
|
||||
await backend.prepare({ allowNetwork: false });
|
||||
await backend.prepare({ allowNetwork: false });
|
||||
|
||||
const prepareEvents = auditor.sandbox.mock.calls.filter(([input]) => input.type === "sandbox:prepare");
|
||||
const fallbackEvents = auditor.sandbox.mock.calls.filter(([input]) => input.type === "sandbox:fallback");
|
||||
const sandboxCalls = auditor.sandbox.mock.calls as unknown as Array<[Parameters<RunAuditor["sandbox"]>[0]]>;
|
||||
const prepareEvents = sandboxCalls.filter(([input]) => input.type === "sandbox:prepare");
|
||||
const fallbackEvents = sandboxCalls.filter(([input]) => input.type === "sandbox:fallback");
|
||||
expect(prepareEvents).toHaveLength(1);
|
||||
expect(fallbackEvents).toHaveLength(2);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user