import { randomUUID } from "node:crypto"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { describe, expect, test } from "vitest"; import { DatabaseConnection } from "../../src/main/database/connection"; import { OrganizationService } from "../../src/main/services/organization-service"; import { markStalledGoals, resumeGoal, spawnGoalReviews } from "../../src/main/services/goal-review-service"; import { RISK_LEVEL, TASK_PRIORITY, TASK_STATUS } from "../../src/shared/domain"; interface Harness { connection: DatabaseConnection; organization: OrganizationService; orgId: string; ceoId: string; goalId: string; kickoffId: string; } function createHarness(): Harness { const connection = new DatabaseConnection(join(tmpdir(), `ac-goal-review-${randomUUID()}.db`)); const organization = new OrganizationService(connection.db); let orgId = ""; let ceoId = ""; let goalId = ""; connection.transaction(() => { orgId = organization.createOrganization({ organizationName: "LoopCorp", employeeName: "Yang", mission: "m", goal: "g" }); const providerId = (connection.db.prepare("select id from providers where org_id = ? and provider_key = 'openai'").get(orgId) as { id: string }).id; ceoId = organization.createAgent({ orgId, name: "CEO", role: "CEO", department: "Executive", modelProviderId: providerId, modelId: "gpt-5.4", budgetCents: 25000, managerAgentId: null, roleLevel: "c_suite", }); goalId = organization.createGoal({ orgId, title: "Ship the platform", description: "Deliver it for real.", ownerAgentId: ceoId }); }); const kickoffId = (connection.db.prepare("select id from tasks where goal_id = ?").get(goalId) as { id: string }).id; return { connection, organization, orgId, ceoId, goalId, kickoffId }; } function setTaskStatus(h: Harness, taskId: string, status: string, updatedAt?: string): void { h.connection.db.prepare("update tasks set status = ?, updated_at = ? where id = ?") .run(status, updatedAt ?? new Date().toISOString(), taskId); } function addDoneTask(h: Harness, title: string, origin: string | null, updatedAt: string): string { let taskId = ""; h.connection.transaction(() => { taskId = h.organization.createTask({ orgId: h.orgId, title, description: "d", status: TASK_STATUS.DONE, assigneeAgentId: h.ceoId, risk: RISK_LEVEL.LOW, projectId: null, goalId: h.goalId, workspaceId: null, priority: TASK_PRIORITY.NORMAL, requiresFilesystem: false, ...(origin ? { origin: origin as "chat_wake" | "goal_review" } : {}), }); }); h.connection.db.prepare("update tasks set updated_at = ? where id = ?").run(updatedAt, taskId); return taskId; } function hoursFromNow(hours: number): string { return new Date(Date.now() + hours * 3_600_000).toISOString(); } function stalledReason(h: Harness): string | null { return (h.connection.db.prepare("select stalled_reason from goals where id = ?").get(h.goalId) as { stalled_reason: string | null }).stalled_reason; } function reviews(h: Harness): Array<{ id: string; status: string }> { return h.connection.db.prepare("select id, status from tasks where goal_id = ? and origin = 'goal_review' order by created_at") .all(h.goalId) as Array<{ id: string; status: string }>; } describe("goal review service", () => { test("spawns one review when the board drains, and never duplicates while it is open", () => { const h = createHarness(); // Open kickoff blocks the checkpoint. expect(h.connection.transaction(() => spawnGoalReviews(h.connection.db, h.organization))).toEqual([]); setTaskStatus(h, h.kickoffId, TASK_STATUS.DONE); const first = h.connection.transaction(() => spawnGoalReviews(h.connection.db, h.organization)); expect(first).toHaveLength(1); const review = h.connection.db.prepare("select title, origin, status, assignee_agent_id from tasks where id = ?") .get(first[0]) as { title: string; origin: string; status: string; assignee_agent_id: string }; expect(review).toMatchObject({ origin: "goal_review", status: "backlog", assignee_agent_id: h.ceoId }); expect(review.title).toContain("Goal review:"); // The open review itself blocks a duplicate. expect(h.connection.transaction(() => spawnGoalReviews(h.connection.db, h.organization))).toEqual([]); h.connection.close(); }); test("a review that ends without new work does not respawn; real progress does", () => { const h = createHarness(); setTaskStatus(h, h.kickoffId, TASK_STATUS.DONE); const [reviewId] = h.connection.transaction(() => spawnGoalReviews(h.connection.db, h.organization)); // CEO closes the review without creating tasks or completing the goal: no loop, but a visible stall. setTaskStatus(h, reviewId, TASK_STATUS.DONE, hoursFromNow(1)); expect(h.connection.transaction(() => spawnGoalReviews(h.connection.db, h.organization))).toEqual([]); expect(markStalledGoals(h.connection.db)).toBe(1); expect(markStalledGoals(h.connection.db)).toBe(0); expect(stalledReason(h)).toBe("Stalled: the last goal review neither closed the goal nor planned new work. Resume it to run a fresh review."); // Chatter never counts as progress. addDoneTask(h, "Reply to CEO", "chat_wake", hoursFromNow(2)); expect(h.connection.transaction(() => spawnGoalReviews(h.connection.db, h.organization))).toEqual([]); // A real completed task after the last review re-arms the checkpoint. addDoneTask(h, "Implement tenant module", null, hoursFromNow(3)); expect(h.connection.transaction(() => spawnGoalReviews(h.connection.db, h.organization))).toHaveLength(1); expect(reviews(h)).toHaveLength(2); expect(stalledReason(h)).toBeNull(); h.connection.close(); }); test("a review that spends its run budget stalls the goal; resuming closes it and starts a fresh review", () => { const h = createHarness(); setTaskStatus(h, h.kickoffId, TASK_STATUS.DONE); const [reviewId] = h.connection.transaction(() => spawnGoalReviews(h.connection.db, h.organization)); h.connection.db.prepare("update tasks set stalled_reason = 'Stalled: 3 sessions' where id = ?").run(reviewId); expect(markStalledGoals(h.connection.db)).toBe(1); expect(stalledReason(h)).toBe("Stalled: the goal review spent its run budget without a decision. Resume it to run a fresh review."); expect(h.connection.db.prepare("select count(*) as n from audit_events where entity_id = ? and action = 'stalled'").get(h.goalId)).toEqual({ n: 1 }); const fresh = h.connection.transaction(() => resumeGoal(h.connection.db, h.organization, h.orgId, h.goalId)); expect(reviews(h)).toEqual([{ id: reviewId, status: "done" }, { id: fresh, status: "backlog" }]); expect(stalledReason(h)).toBeNull(); expect(() => resumeGoal(h.connection.db, h.organization, h.orgId, h.goalId)).toThrow('Goal "Ship the platform" is not stalled.'); h.connection.close(); }); test("achieved goals never spawn reviews", () => { const h = createHarness(); setTaskStatus(h, h.kickoffId, TASK_STATUS.DONE); h.connection.db.prepare("update goals set status = 'achieved' where id = ?").run(h.goalId); expect(h.connection.transaction(() => spawnGoalReviews(h.connection.db, h.organization))).toEqual([]); h.connection.close(); }); });