Files
AgentCompany/tests/unit/agent-goal-tools.test.ts
T
ZacharyZhang-NY 26de3129b1 Goals end at achieved, not at an empty board: the goal-review loop
The board draining to 280/280 done left the company idle under a
still-active goal, with 24 markdown files and zero code as its life's work.
Two structural gaps caused it: goals had no lifecycle (status was written
once as 'active' and never read again — nothing re-engages anyone when the
last task closes), and nothing anywhere distinguished plans from product,
so every "engineering" objective closed on documents.

The loop, closed:
- tasks.origin (migration 055) records provenance: chat_wake for mention
  vehicles (backfilled from their runs), goal_review for checkpoints, null
  for real work. Chatter and checkpoints can therefore never count as
  progress.
- spawnGoalReviews (each worker tick): an active goal with zero open tasks
  and real progress since the last review gets ONE review task for the goal
  owner. The review demands evidence — list the workspace, read the code,
  run the tests; documents are how work starts, not proof it happened — and
  must end in exactly one of: complete_goal, or the next wave of tasks with
  requires_filesystem engineering. A review closed with neither spawns
  nothing: termination is structural, not a counter.
- complete_goal (CEO or goal owner) finally lets someone say a goal is
  achieved, audited.
- CEO and department-head voices now state the doctrine: a goal that
  promises software closes on code that builds and passes tests in the
  workspace, and implementation is delegated with requires_filesystem: true.

On the live profile this arms one review: the active platform goal has 0
open tasks and 21 real completed ones, so the CEO gets the checkpoint on
next launch and the company starts building instead of stopping.
2026-07-09 20:29:42 -04:00

57 lines
3.0 KiB
TypeScript

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 { ChatService } from "../../src/main/services/chat-service";
import { dispatchAgentTool, type AgentToolContext, type AgentToolDeps } from "../../src/main/services/agent-tools";
import type { ToolCall } from "../../src/main/services/provider-tool-turn";
function call(name: string): ToolCall {
return { id: `call_${randomUUID()}`, name, arguments: {} };
}
describe("complete_goal tool", () => {
test("the CEO can close their goal; a staff engineer cannot", () => {
const connection = new DatabaseConnection(join(tmpdir(), `ac-goal-tool-${randomUUID()}.db`));
const organization = new OrganizationService(connection.db);
let orgId = "";
let ceoId = "";
let staffId = "";
let goalId = "";
connection.transaction(() => {
orgId = organization.createOrganization({ organizationName: "GoalCorp", 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",
});
staffId = organization.createAgent({
orgId, name: "Dev", role: "Engineer", department: "Engineering",
modelProviderId: providerId, modelId: "gpt-5.4", budgetCents: 10000, managerAgentId: ceoId, roleLevel: "staff",
});
goalId = organization.createGoal({ orgId, title: "Ship it", description: "For real.", ownerAgentId: ceoId });
});
const deps: AgentToolDeps = { db: connection.db, organization, chat: new ChatService(connection.db) };
const ctxFor = (agentId: string): AgentToolContext => ({
orgId, agent: { id: agentId, modelProviderId: null, modelId: null },
taskProjectId: null, taskGoalId: goalId, workspace: null,
});
expect(dispatchAgentTool(deps, ctxFor(staffId), call("complete_goal"))).toContain("ERROR");
expect(connection.db.prepare("select status from goals where id = ?").get(goalId)).toEqual({ status: "active" });
expect(dispatchAgentTool(deps, ctxFor(ceoId), call("complete_goal"))).toContain("achieved");
expect(connection.db.prepare("select status from goals where id = ?").get(goalId)).toEqual({ status: "achieved" });
// Idempotent, and honest about it.
expect(dispatchAgentTool(deps, ctxFor(ceoId), call("complete_goal"))).toContain("already achieved");
// A task with no goal attached cannot complete anything.
const noGoalCtx = { ...ctxFor(ceoId), taskGoalId: null };
expect(dispatchAgentTool(deps, noGoalCtx, call("complete_goal"))).toContain("ERROR");
connection.close();
});
});