This commit is contained in:
omp-port
2026-08-11 09:19:06 -04:00
parent 3d142ed217
commit 5b7796043e
7 changed files with 433 additions and 248 deletions

View File

@@ -20,6 +20,8 @@ import {
setAgentRunner,
resetAgentRunner,
fakeAgentRunner,
AGENT_TIMEOUT_ENV,
type AgentRunResult,
} from "../src/agent-runner.js";
import { handleCheckCommand, type PygieniumCtx } from "../src/commands.js";
import { loadRunState, runStatePath } from "../src/run-state.js";
@@ -128,4 +130,29 @@ describe("check-runner integration", () => {
expect(state?.checks.gated.status).toBe("skipped");
expect(state?.checks.gated.error).toBe("no source files matched");
});
it("fails the check loudly when the agent never settles", async () => {
// Models the silent hang: the sub-agent session never resolves after
// its last tool call (stalled provider stream / hung retry), leaving
// the run stuck mid-phase with no state save and no completion. The
// watchdog must abort the phase with a visible error instead.
setAgentRunner(() => new Promise<AgentRunResult>(() => {}));
const prev = process.env[AGENT_TIMEOUT_ENV];
process.env[AGENT_TIMEOUT_ENV] = "50";
try {
await handleCheckCommand(smokeCheck(), "", stubCtx(cwd));
} finally {
if (prev === undefined) delete process.env[AGENT_TIMEOUT_ENV];
else process.env[AGENT_TIMEOUT_ENV] = prev;
}
const state = await loadRunState(cwd);
expect(state?.checks.smoke.status).toBe("failed");
expect(state?.checks.smoke.error).toContain("did not settle within");
expect(state?.checks.smoke.error).toContain("/pygienium-resume");
expect(
state?.checks.smoke.phases.find((p) => p.id === "analysis")?.status,
).toBe("failed");
expect(state?.status).toBe("failed");
});
});