import { describe, expect, it } from "vitest"; import { classifyRunLiveness } from "../services/run-liveness.ts"; const baseInput = { runStatus: "succeeded", issue: { status: "in_progress", title: "Implement feature", description: "Add the requested behavior.", }, resultJson: null, stdoutExcerpt: null, stderrExcerpt: null, error: null, errorCode: null, continuationAttempt: 0, evidence: null, }; describe("run liveness classifier", () => { it("classifies text-only future work as plan_only", () => { const classification = classifyRunLiveness({ ...baseInput, resultJson: { summary: "I will inspect the repo next and then implement the fix.", }, }); expect(classification.livenessState).toBe("plan_only"); expect(classification.nextAction).toContain("inspect the repo"); }); it("classifies empty successful output as empty_response", () => { const classification = classifyRunLiveness(baseInput); expect(classification.livenessState).toBe("empty_response"); }); it("treats issue comments, documents, products, and actions as progress", () => { const latestEvidenceAt = new Date("2026-04-18T12:00:00Z"); const classification = classifyRunLiveness({ ...baseInput, resultJson: { summary: "Updated implementation.", }, evidence: { issueCommentsCreated: 1, documentRevisionsCreated: 1, workProductsCreated: 1, toolOrActionEventsCreated: 1, latestEvidenceAt, }, }); expect(classification.livenessState).toBe("advanced"); expect(classification.lastUsefulActionAt).toBe(latestEvidenceAt); }); it("does not treat workspace operations alone as concrete progress", () => { const classification = classifyRunLiveness({ ...baseInput, resultJson: { summary: "I will inspect the repo next.", }, evidence: { workspaceOperationsCreated: 1, latestEvidenceAt: new Date("2026-04-18T12:00:00Z"), }, }); expect(classification.livenessState).toBe("plan_only"); expect(classification.lastUsefulActionAt).toBeNull(); }); it("exempts planning/document tasks from plan-only retry classification", () => { const classification = classifyRunLiveness({ ...baseInput, issue: { status: "in_progress", title: "Draft implementation plan", description: "Create a plan for the work.", }, resultJson: { summary: "Plan:\n- Inspect files\n- Implement after approval", }, }); expect(classification.livenessState).toBe("advanced"); }); it("exempts runs that update the plan document from plan-only classification", () => { const classification = classifyRunLiveness({ ...baseInput, resultJson: { summary: "Next steps:\n- inspect files\n- implement the service", }, evidence: { documentRevisionsCreated: 1, planDocumentRevisionsCreated: 1, latestEvidenceAt: new Date("2026-04-18T12:00:00Z"), }, }); expect(classification.livenessState).toBe("advanced"); }); it("classifies done issues as completed", () => { const classification = classifyRunLiveness({ ...baseInput, issue: { ...baseInput.issue, status: "done", }, resultJson: { summary: "Finished the implementation.", }, }); expect(classification.livenessState).toBe("completed"); }); it("classifies declared blockers as blocked", () => { const classification = classifyRunLiveness({ ...baseInput, resultJson: { summary: "I cannot proceed because I need access credentials.", }, }); expect(classification.livenessState).toBe("blocked"); }); });