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.
This commit is contained in:
1 parent
291816aa06
commit
26de3129b1
14 files changed
+365
-4
No files matched your search
@@ -0,0 +1,30 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { taskOriginSchema } from "../../src/main/database/migrations/055-task-origin";
|
||||
|
||||
describe("task origin migration", () => {
|
||||
test("adds the column and backfills historical wake vehicles from their runs", () => {
|
||||
const db = new DatabaseSync(join(tmpdir(), `agentcompany-origin-migration-${randomUUID()}.db`));
|
||||
db.exec(`
|
||||
create table schema_migrations(version integer primary key, name text not null, applied_at text not null);
|
||||
create table tasks(id text primary key, status text not null, updated_at text not null);
|
||||
create table task_runs(id text primary key, task_id text not null, trigger text not null, state text not null);
|
||||
insert into schema_migrations(version, name, applied_at) values (54, 'close_stale_wake_tasks', datetime('now'));
|
||||
insert into tasks(id, status, updated_at) values ('tsk_wake', 'done', datetime('now'));
|
||||
insert into tasks(id, status, updated_at) values ('tsk_real', 'done', datetime('now'));
|
||||
insert into task_runs(id, task_id, trigger, state) values ('run_1', 'tsk_wake', 'chat_mention', 'completed');
|
||||
insert into task_runs(id, task_id, trigger, state) values ('run_2', 'tsk_real', 'heartbeat', 'completed');
|
||||
`);
|
||||
|
||||
db.exec(taskOriginSchema);
|
||||
|
||||
const origins = Object.fromEntries(
|
||||
(db.prepare("select id, origin from tasks").all() as Array<{ id: string; origin: string | null }>).map((row) => [row.id, row.origin]),
|
||||
);
|
||||
expect(origins).toEqual({ tsk_wake: "chat_wake", tsk_real: null });
|
||||
expect(db.prepare("select version from schema_migrations order by version desc limit 1").get()).toEqual({ version: 55 });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user