Counted in evidence 20 while tasks 013–015 were still building, so Built is understated today. Spot-checked on 12 rows, of which 2 were corrected. 52 of the Not addressed rows are premises, not work.
Total: 346
- Built: 87 [evidence 20]
- Building: 52 [evidence 20]
- Adopted: 38 [evidence 20]
- Open: 19 [evidence 20]
- Not addressed: 150 [evidence 20]
v1: one worker, the planner does the rest
Built 2026-10-25. Service stopped by the owner on 2026-10-30.
First version, so everything is new. The worker runs coder and reviewer; merging, deploying and watching stay with an Opus session.
- Serial queue that halts on any block.
- Nothing watches a run and nothing measures it.
- Phase 01.2: 12 tasks, about 370 min, 73% in the coder.
Source: draft version summary
-
Owner gate
NEW
The owner decides on a go deck. A task moves to
readyonly once its gate is clear.Measured: Not measured. [not measured]
Source: agent-workforce, task contract
-
Intake
Not present. The planner writes task files directly.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
NEW
A Claude session on Opus plans, dispatches, verifies, merges and deploys.
Measured: Phase 01.2: 75 min of planning agents, of which only the 28-min pass was needed. An Opus agent polled for 4 h. Planning and plan-checking three phases cost about 2.4M tokens, about 850k of it on checkers. [v2 design log § Diagnosis; agent-workforce]
Source: v2 design log § Diagnosis; agent-workforce
-
Ruling step
No ruling step. A blocked task halted the queue until a person answered.
Measured: Gaps from rulings, a timeout, a dispatcher swap and halted queues: about 80 of 370 min (22%). [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Task file
NEW
A task file with a
status:field.ready, committed on the default branch, is the only dispatch signal.Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Claim
NEW
One worker claims
readytasks one at a time, each in its own worktree on branchoc/<slug>.Measured: Phase 01.2: 12 tasks in about 370 min. Two blocked tasks stopped the line. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Coder
NEW
opencode in its own git worktree, on the OpenCode Go lane through the relay.
Measured: Page tasks 29–48 min of coder time. Coder 269 of about 370 min (73%) in phase 01.2. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Checks
NEW
The coder had only the full build and test suite to run.
Measured: Phase 01.2 task 016: 10 full <code>build_data.py</code> runs (about 80 s each) and about 34 test runs. [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Reviewer
NEW
The repo's reviewer agent checks the branch, with up to 2 fix rounds.
Measured: 18 min of about 370 (5%) in phase 01.2. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Merge
NEW
The planner verifies the approved branch and merges it.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Deploy
NEW
The planner deploys, per phase.
Measured: Six merged features sat undeployed for 9 h. [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Model route
NEW
Coder and reviewer calls go through the studio relay. No agent holds the Go key.
Measured: Not recorded in draft. [not measured]
Source: kernel, factory edict
-
Job isolation
NEW
opencode's permission settings per agent. A
shell:versusbash:hole was found and closed on 2026-10-26.Measured: Not recorded in draft. [not measured]
Source: v2 design handoff
-
Forge
NEW
GitHub holds the code. linkexch is PR-only, other repos merge directly.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Driver
NEW
One worker service for all registered repos.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
State
NEW
A state file per task outside the repo, recording start, end and exit code.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce; v2 design log
-
Watchdog
Nothing watched a run. The worker recorded start, end and exit code.
Measured: Not recorded in draft. [not measured]
Source: v2 design log § Diagnosis
-
Wake-ups
NEW
Each outcome posts to Matrix. Sessions poll for the rest.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Measurement
No metrics, no retrospective. The diagnosis table was built by hand after the owner complained.
Measured: Not recorded in draft. [not measured]
Source: v2 design log § Diagnosis
-
Status view
NEW
factory statusshows every task in every repo.Measured: Not recorded in draft. [not measured]
Source: agent-workforce
v1: one worker, the planner does the rest
Built 2026-10-25. Service stopped by the owner on 2026-10-30.
First version, so everything is new. The worker runs coder and reviewer; merging, deploying and watching stay with an Opus session.
- Serial queue that halts on any block.
- Nothing watches a run and nothing measures it.
- Phase 01.2: 12 tasks, about 370 min, 73% in the coder.
Source: draft version summary
| Role | Reads | Writes | Tokens |
|---|---|---|---|
| Planner | Research, plans, checks, revisions | Task files | Yes: checkers re-read plans cold (about 850k tokens). One executor re-read 194 KB of plans to rewrite them as tasks. [uncited in draft] |
| Coder | Task file and repo | Branch | Not measured [not measured] |
| Reviewer | Task and branch | Verdict | Not measured [not measured] |
Token counts are from one symbol-map session on 2026-10-25.
-
Owner gate
NEW
The owner decides on a go deck. A task moves to
readyonly once its gate is clear.Measured: Not measured. [not measured]
Source: agent-workforce, task contract
-
Intake
Not present. The planner writes task files directly.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
NEW
A Claude session on Opus plans, dispatches, verifies, merges and deploys.
Measured: Phase 01.2: 75 min of planning agents, of which only the 28-min pass was needed. An Opus agent polled for 4 h. Planning and plan-checking three phases cost about 2.4M tokens, about 850k of it on checkers. [v2 design log § Diagnosis; agent-workforce]
Source: v2 design log § Diagnosis; agent-workforce
-
Ruling step
No ruling step. A blocked task halted the queue until a person answered.
Measured: Gaps from rulings, a timeout, a dispatcher swap and halted queues: about 80 of 370 min (22%). [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Task file
NEW
A task file with a
status:field.ready, committed on the default branch, is the only dispatch signal.Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Claim
NEW
One worker claims
readytasks one at a time, each in its own worktree on branchoc/<slug>.Measured: Phase 01.2: 12 tasks in about 370 min. Two blocked tasks stopped the line. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Coder
NEW
opencode in its own git worktree, on the OpenCode Go lane through the relay.
Measured: Page tasks 29–48 min of coder time. Coder 269 of about 370 min (73%) in phase 01.2. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Checks
NEW
The coder had only the full build and test suite to run.
Measured: Phase 01.2 task 016: 10 full <code>build_data.py</code> runs (about 80 s each) and about 34 test runs. [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Reviewer
NEW
The repo's reviewer agent checks the branch, with up to 2 fix rounds.
Measured: 18 min of about 370 (5%) in phase 01.2. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Merge
NEW
The planner verifies the approved branch and merges it.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Deploy
NEW
The planner deploys, per phase.
Measured: Six merged features sat undeployed for 9 h. [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Model route
NEW
Coder and reviewer calls go through the studio relay. No agent holds the Go key.
Measured: Not recorded in draft. [not measured]
Source: kernel, factory edict
-
Job isolation
NEW
opencode's permission settings per agent. A
shell:versusbash:hole was found and closed on 2026-10-26.Measured: Not recorded in draft. [not measured]
Source: v2 design handoff
-
Forge
NEW
GitHub holds the code. linkexch is PR-only, other repos merge directly.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Driver
NEW
One worker service for all registered repos.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
State
NEW
A state file per task outside the repo, recording start, end and exit code.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce; v2 design log
-
Watchdog
Nothing watched a run. The worker recorded start, end and exit code.
Measured: Not recorded in draft. [not measured]
Source: v2 design log § Diagnosis
-
Wake-ups
NEW
Each outcome posts to Matrix. Sessions poll for the rest.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Measurement
No metrics, no retrospective. The diagnosis table was built by hand after the owner complained.
Measured: Not recorded in draft. [not measured]
Source: v2 design log § Diagnosis
-
Status view
NEW
factory statusshows every task in every repo.Measured: Not recorded in draft. [not measured]
Source: agent-workforce
v1: one worker, the planner does the rest
Built 2026-10-25. Service stopped by the owner on 2026-10-30.
First version, so everything is new. The worker runs coder and reviewer; merging, deploying and watching stay with an Opus session.
- Serial queue that halts on any block.
- Nothing watches a run and nothing measures it.
- Phase 01.2: 12 tasks, about 370 min, 73% in the coder.
Source: draft version summary
A blocked task waits for a person
- The coder or reviewer stops.
- The queue halts, because the worker runs one task at a time.
- A planner notices, by polling or from a Matrix post.
- The planner edits and re-dispatches.
Nothing carries the answer back except a person.
-
Owner gate
NEW
The owner decides on a go deck. A task moves to
readyonly once its gate is clear.Measured: Not measured. [not measured]
Source: agent-workforce, task contract
-
Intake
Not present. The planner writes task files directly.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
NEW
A Claude session on Opus plans, dispatches, verifies, merges and deploys.
Measured: Phase 01.2: 75 min of planning agents, of which only the 28-min pass was needed. An Opus agent polled for 4 h. Planning and plan-checking three phases cost about 2.4M tokens, about 850k of it on checkers. [v2 design log § Diagnosis; agent-workforce]
Source: v2 design log § Diagnosis; agent-workforce
-
Ruling step
No ruling step. A blocked task halted the queue until a person answered.
Measured: Gaps from rulings, a timeout, a dispatcher swap and halted queues: about 80 of 370 min (22%). [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Task file
NEW
A task file with a
status:field.ready, committed on the default branch, is the only dispatch signal.Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Claim
NEW
One worker claims
readytasks one at a time, each in its own worktree on branchoc/<slug>.Measured: Phase 01.2: 12 tasks in about 370 min. Two blocked tasks stopped the line. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Coder
NEW
opencode in its own git worktree, on the OpenCode Go lane through the relay.
Measured: Page tasks 29–48 min of coder time. Coder 269 of about 370 min (73%) in phase 01.2. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Checks
NEW
The coder had only the full build and test suite to run.
Measured: Phase 01.2 task 016: 10 full <code>build_data.py</code> runs (about 80 s each) and about 34 test runs. [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Reviewer
NEW
The repo's reviewer agent checks the branch, with up to 2 fix rounds.
Measured: 18 min of about 370 (5%) in phase 01.2. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Merge
NEW
The planner verifies the approved branch and merges it.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Deploy
NEW
The planner deploys, per phase.
Measured: Six merged features sat undeployed for 9 h. [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Model route
NEW
Coder and reviewer calls go through the studio relay. No agent holds the Go key.
Measured: Not recorded in draft. [not measured]
Source: kernel, factory edict
-
Job isolation
NEW
opencode's permission settings per agent. A
shell:versusbash:hole was found and closed on 2026-10-26.Measured: Not recorded in draft. [not measured]
Source: v2 design handoff
-
Forge
NEW
GitHub holds the code. linkexch is PR-only, other repos merge directly.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Driver
NEW
One worker service for all registered repos.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
State
NEW
A state file per task outside the repo, recording start, end and exit code.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce; v2 design log
-
Watchdog
Nothing watched a run. The worker recorded start, end and exit code.
Measured: Not recorded in draft. [not measured]
Source: v2 design log § Diagnosis
-
Wake-ups
NEW
Each outcome posts to Matrix. Sessions poll for the rest.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Measurement
No metrics, no retrospective. The diagnosis table was built by hand after the owner complained.
Measured: Not recorded in draft. [not measured]
Source: v2 design log § Diagnosis
-
Status view
NEW
factory statusshows every task in every repo.Measured: Not recorded in draft. [not measured]
Source: agent-workforce
v1: one worker, the planner does the rest
Built 2026-10-25. Service stopped by the owner on 2026-10-30.
First version, so everything is new. The worker runs coder and reviewer; merging, deploying and watching stay with an Opus session.
- Serial queue that halts on any block.
- Nothing watches a run and nothing measures it.
- Phase 01.2: 12 tasks, about 370 min, 73% in the coder.
Source: draft version summary
| Metric | Figure |
|---|---|
| Scope measured | Phase 01.2: 12 tasks, symbol-map [uncited in draft] |
| Lead time | Not measured per task [not measured] |
| Coder time | Page tasks 29–48 min [uncited in draft] |
| Review time | 18 min over 12 tasks [uncited in draft] |
| Cost per accepted task | Not measured [not measured] |
| Planner usage | 2.4M tokens on 3 phases of planning [uncited in draft] |
| Human involvement | Not measured [not measured] |
| Stale waits | Not measured [not measured] |
| Restart safety | Not measured [not measured] |
| Long-lived sessions | Yes [uncited in draft] |
-
Owner gate
NEW
The owner decides on a go deck. A task moves to
readyonly once its gate is clear.Measured: Not measured. [not measured]
Source: agent-workforce, task contract
-
Intake
Not present. The planner writes task files directly.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
NEW
A Claude session on Opus plans, dispatches, verifies, merges and deploys.
Measured: Phase 01.2: 75 min of planning agents, of which only the 28-min pass was needed. An Opus agent polled for 4 h. Planning and plan-checking three phases cost about 2.4M tokens, about 850k of it on checkers. [v2 design log § Diagnosis; agent-workforce]
Source: v2 design log § Diagnosis; agent-workforce
-
Ruling step
No ruling step. A blocked task halted the queue until a person answered.
Measured: Gaps from rulings, a timeout, a dispatcher swap and halted queues: about 80 of 370 min (22%). [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Task file
NEW
A task file with a
status:field.ready, committed on the default branch, is the only dispatch signal.Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Claim
NEW
One worker claims
readytasks one at a time, each in its own worktree on branchoc/<slug>.Measured: Phase 01.2: 12 tasks in about 370 min. Two blocked tasks stopped the line. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Coder
NEW
opencode in its own git worktree, on the OpenCode Go lane through the relay.
Measured: Page tasks 29–48 min of coder time. Coder 269 of about 370 min (73%) in phase 01.2. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Checks
NEW
The coder had only the full build and test suite to run.
Measured: Phase 01.2 task 016: 10 full <code>build_data.py</code> runs (about 80 s each) and about 34 test runs. [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Reviewer
NEW
The repo's reviewer agent checks the branch, with up to 2 fix rounds.
Measured: 18 min of about 370 (5%) in phase 01.2. [agent-workforce; v2 design log]
Source: agent-workforce; v2 design log
-
Merge
NEW
The planner verifies the approved branch and merges it.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Deploy
NEW
The planner deploys, per phase.
Measured: Six merged features sat undeployed for 9 h. [v2 design log § Diagnosis]
Source: v2 design log § Diagnosis
-
Model route
NEW
Coder and reviewer calls go through the studio relay. No agent holds the Go key.
Measured: Not recorded in draft. [not measured]
Source: kernel, factory edict
-
Job isolation
NEW
opencode's permission settings per agent. A
shell:versusbash:hole was found and closed on 2026-10-26.Measured: Not recorded in draft. [not measured]
Source: v2 design handoff
-
Forge
NEW
GitHub holds the code. linkexch is PR-only, other repos merge directly.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Driver
NEW
One worker service for all registered repos.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
State
NEW
A state file per task outside the repo, recording start, end and exit code.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce; v2 design log
-
Watchdog
Nothing watched a run. The worker recorded start, end and exit code.
Measured: Not recorded in draft. [not measured]
Source: v2 design log § Diagnosis
-
Wake-ups
NEW
Each outcome posts to Matrix. Sessions poll for the rest.
Measured: Not recorded in draft. [not measured]
Source: agent-workforce
-
Measurement
No metrics, no retrospective. The diagnosis table was built by hand after the owner complained.
Measured: Not recorded in draft. [not measured]
Source: v2 design log § Diagnosis
-
Status view
NEW
factory statusshows every task in every repo.Measured: Not recorded in draft. [not measured]
Source: agent-workforce
v2: the worker takes over merge, deploy and watching
Built 2026-10-26. Stopped 2026-10-30. 149 tasks claimed, 125 merged.
Changes from v1, and why:
- Merge and deploy move to the worker, because features sat undeployed for 9 h.
- Blocks stop halting the queue, because two blocked tasks stopped a phase.
- Scoped checks and budgets, because page tasks took 29–48 min of coder time. Median fell to 4.3 min on a different task mix.
- What went wrong: almost all lead time became waiting, and the Opus layer used up the weekly limit on 10-28.
Source: draft version summary
-
Owner gate
CHANGED
Per-task go through
fw go. Repos withauto_mergedelegate the merge and publish gates to the worker.Changed: Merge and publish no longer wait for a person on delegated repos.
Why: v1 held six merged features undeployed for 9 h.
Measured: 91 go and 32 no-go events. The slowest holds were 13–14 h. Hold time is not recorded on its own; it sits inside wait time. [design § 1, evidence 01]
Source: design § 1, evidence 01
-
Intake
Not present.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
CHANGED
One planning pass by rule, cheap models after it. In practice long-lived Opus sessions and a coordinator layer drove the factory.
Changed: Dispatch and merging moved to the worker. Coordinators appeared.
Why: Planning economy (owner, 2026-10-25): tokens were going to re-verifying plans.
Measured: 1,831M tokens over 47 sessions: specs 1.1%, rulings 2.7%. Median turn context 205k, p90 473k. Coordinators 24%, repair 12%. 66% of it was project planners. The weekly limit ran out on 10-28 and halted the factory. [design § 0]
Source: design § 0
-
Ruling step
NEW
An on-demand planner bot, then human planners. A
--noteruling reached only the first coder message of the resumed run.Changed: Stops got a bot and an escalation ledger.
Why: Blocked tasks no longer halted the queue, so someone had to clear them.
Measured: Bot: 17 rulings, median 0.2 min. Humans: 57 rulings, median 1.2 min, p90 78 min, max 538 min, 26.5 h in total. [evidence 01, 02]
Source: evidence 01, 02
-
Task file
CHANGED
Template adds
depends:,budget_min:and scoped checks beside acceptance checks.Changed: Tasks carry a time budget and a fast check.
Why: Nobody reviewed a spec, and coders had only the full build to run.
Measured: About 23 of about 70 stops were real spec contradictions or design questions. [v2 design log; evidence 01]
Source: v2 design log; evidence 01
-
Claim
CHANGED
At most 2 per host and 1 per repo. A block no longer stops the queue. Tasks with overlapping
files:never run together.Changed: Parallel across repos; a block stays local.
Why: The serial queue halted on every block.
Measured: Queue wait p90 441 min. This was the biggest wait in v2. [design § 1, evidence 02]
Source: design § 1, evidence 02
-
Coder
CHANGED
opencode on Haiku 5.5 with a time budget and a repeat-command watchdog.
Changed: Different model lane, telemetry, budget stop, scoped checks.
Why: One 01.2 task ran 10 full builds and about 34 test runs.
Measured: Median 4.3 min, p90 16.7 (latest attempt only, so understated). About half of coder tokens went to runs that did not merge; blocked runs alone were 32%. [evidence 01; design § 0 B]
Source: evidence 01; design § 0 B
-
Checks
CHANGED
Scoped checks while working, the full matrix once at the gate.
factory-lintruns every check on main beforeready.Changed: Fast inner loop and a ready gate.
Why: Task 012 contradicted itself, and running its check once would have shown that in seconds.
Measured: About 25 of about 70 stops were a red environment or baseline. [v2 design log; design § 1]
Source: v2 design log; design § 1
-
Reviewer
CHANGED
A reviewer station with a 2-round cap. Rulings never reached it.
Changed: Scope check against
files:.Why: Merging moved to the worker, so review became the last judgment.
Measured: Median 0.9 min, p90 2.1. 67% approved in round 0. The cap fired 9 times. A settled must-fix was re-raised 3 or more times. [evidence 01, 02]
Source: evidence 01, 02
-
Merge
CHANGED
The worker merges after review and a post-merge test on the merged tree.
Changed: No session needed to merge.
Why: Planning economy rule 5.
Measured: Post-merge gate failed 7 times. [AGENTS § Human gates; evidence 01]
Source: AGENTS § Human gates; evidence 01
-
Deploy
CHANGED
On delegated repos the worker deploys and pings the owner with the live URL.
Changed: Per task, automatic.
Why: Features sat undeployed.
Measured: Deploy failed 2 times. [AGENTS § Human gates; evidence 01]
Source: AGENTS § Human gates; evidence 01
-
Model route
CHANGED
opencode reaches Haiku 5.5 through the relay.
Changed: Paid API instead of the Go window.
Measured: About $0.13–0.15 per merged task at published prices. [design §§ 0 B, 3]
Source: design §§ 0 B, 3
-
Job isolation
CHANGED
unshare -rmwith mounts that hide secret directories, plus text denies on shell commands. The template calls them "a tripwire, not a fence", and coderbashgets pastexternal_directory.Changed: A sandbox around the coder.
Why: Coder and reviewer needed no deploy or secret capabilities.
Measured: About 23 of about 70 stops were sandbox or permission denials. [evidence 02; design § 1]
Source: evidence 02; design § 1
-
Forge
CHANGED
The worker has a
deliver_prpath. Forgejo exists and is not used by the factory.Measured: linkexch/023 spent 6 h on PR checks. <code>deliver_pr</code> has no tests. [evidence 01, 02; design § 3]
Source: evidence 01, 02; design § 3
-
Driver
CHANGED
One
serveprocess spawning arun-taskchild per pick, in one 4,204-line file. Every repo change needs a restart, and a bad edit stops every repo.Changed: Telemetry, budget, delivery, resume, sandbox and per-repo fields added.
Why: v2 build list.
Measured: 240 worker tests. End to end runs only through fakes. [evidence 02]
Source: evidence 02
-
State
CHANGED
JSON per task plus an append-only
escalations.jsonl. Behaviour hangs on substrings of the reason text.Changed: Ledger added. Lead, touch and wait times recorded.
Measured: 152 escalations, 106 still open, 80 of those for tasks already merged. [evidence 01, 02]
Source: evidence 01, 02
-
Watchdog
NEW
A supervisor on a 60 s timer plus a budget watchdog.
Changed: Runs get watched; quota pauses and auto-resume appear.
Why: Supervision had been an Opus agent polling for 4 h.
Measured: It restarted deliberate stops. A restart used up the single auto-resume. A dead child went undetected until the next <code>serve</code> start. Worker died 2 times, budget watchdog fired 2 times. [evidence 01, 02]
Source: evidence 01, 02
-
Wake-ups
CHANGED
Matrix pings and
fw status. Sessions wake themselves to poll, with a mediansleepof 15 s inside an Opus turn.Changed: Escalations and owner pushes added.
Measured: Polling was 15.3% of planner tokens. Only 22% of tokens followed a real event. [design § 0 A, R2]
Source: design § 0 A, R2
-
Measurement
NEW
factory-metricsandfactory-report, from state files.Changed: Lead, touch and wait per task.
Why: No numbers existed for v1.
Measured: The ledger double-records 16% of tokens. Coder and reviewer minutes cover only the latest attempt. [design § 0 B; evidence 01]
Source: design § 0 B; evidence 01
-
Status view
fw status, read by sessions.Measured: Coordinators polled the same queues as planners. [design §§ 0 A, 3]
Source: design §§ 0 A, 3
v2: the worker takes over merge, deploy and watching
Built 2026-10-26. Stopped 2026-10-30. 149 tasks claimed, 125 merged.
Changes from v1, and why:
- Merge and deploy move to the worker, because features sat undeployed for 9 h.
- Blocks stop halting the queue, because two blocked tasks stopped a phase.
- Scoped checks and budgets, because page tasks took 29–48 min of coder time. Median fell to 4.3 min on a different task mix.
- What went wrong: almost all lead time became waiting, and the Opus layer used up the weekly limit on 10-28.
Source: draft version summary
| Role | Reads | Writes | Tokens |
|---|---|---|---|
| Planner, coordinator | Whole session on every turn, from a 70k floor | Task files, notes | Yes: 73% of tokens fell in turns over 200k. The floor times turns alone was 27%. [uncited in draft] |
| Coder | Task file; a resume note in the first message only | Branch, Report, escalation | Yes: requests over 100k were 10.7% of requests and about 40% of dollars. [uncited in draft] |
| Reviewer | Task, diff, checks table. Never rulings. | Verdict | Re-raised settled must-fixes 3 or more times. [uncited in draft] |
| Planner bot | Brief | Ruling note | Not measured [not measured] |
Median 1.1M tokens per outcome. Category shares in the planner audit come from keyword rules; context sizes and token counts are measured.
-
Owner gate
CHANGED
Per-task go through
fw go. Repos withauto_mergedelegate the merge and publish gates to the worker.Changed: Merge and publish no longer wait for a person on delegated repos.
Why: v1 held six merged features undeployed for 9 h.
Measured: 91 go and 32 no-go events. The slowest holds were 13–14 h. Hold time is not recorded on its own; it sits inside wait time. [design § 1, evidence 01]
Source: design § 1, evidence 01
-
Intake
Not present.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
CHANGED
One planning pass by rule, cheap models after it. In practice long-lived Opus sessions and a coordinator layer drove the factory.
Changed: Dispatch and merging moved to the worker. Coordinators appeared.
Why: Planning economy (owner, 2026-10-25): tokens were going to re-verifying plans.
Measured: 1,831M tokens over 47 sessions: specs 1.1%, rulings 2.7%. Median turn context 205k, p90 473k. Coordinators 24%, repair 12%. 66% of it was project planners. The weekly limit ran out on 10-28 and halted the factory. [design § 0]
Source: design § 0
-
Ruling step
NEW
An on-demand planner bot, then human planners. A
--noteruling reached only the first coder message of the resumed run.Changed: Stops got a bot and an escalation ledger.
Why: Blocked tasks no longer halted the queue, so someone had to clear them.
Measured: Bot: 17 rulings, median 0.2 min. Humans: 57 rulings, median 1.2 min, p90 78 min, max 538 min, 26.5 h in total. [evidence 01, 02]
Source: evidence 01, 02
-
Task file
CHANGED
Template adds
depends:,budget_min:and scoped checks beside acceptance checks.Changed: Tasks carry a time budget and a fast check.
Why: Nobody reviewed a spec, and coders had only the full build to run.
Measured: About 23 of about 70 stops were real spec contradictions or design questions. [v2 design log; evidence 01]
Source: v2 design log; evidence 01
-
Claim
CHANGED
At most 2 per host and 1 per repo. A block no longer stops the queue. Tasks with overlapping
files:never run together.Changed: Parallel across repos; a block stays local.
Why: The serial queue halted on every block.
Measured: Queue wait p90 441 min. This was the biggest wait in v2. [design § 1, evidence 02]
Source: design § 1, evidence 02
-
Coder
CHANGED
opencode on Haiku 5.5 with a time budget and a repeat-command watchdog.
Changed: Different model lane, telemetry, budget stop, scoped checks.
Why: One 01.2 task ran 10 full builds and about 34 test runs.
Measured: Median 4.3 min, p90 16.7 (latest attempt only, so understated). About half of coder tokens went to runs that did not merge; blocked runs alone were 32%. [evidence 01; design § 0 B]
Source: evidence 01; design § 0 B
-
Checks
CHANGED
Scoped checks while working, the full matrix once at the gate.
factory-lintruns every check on main beforeready.Changed: Fast inner loop and a ready gate.
Why: Task 012 contradicted itself, and running its check once would have shown that in seconds.
Measured: About 25 of about 70 stops were a red environment or baseline. [v2 design log; design § 1]
Source: v2 design log; design § 1
-
Reviewer
CHANGED
A reviewer station with a 2-round cap. Rulings never reached it.
Changed: Scope check against
files:.Why: Merging moved to the worker, so review became the last judgment.
Measured: Median 0.9 min, p90 2.1. 67% approved in round 0. The cap fired 9 times. A settled must-fix was re-raised 3 or more times. [evidence 01, 02]
Source: evidence 01, 02
-
Merge
CHANGED
The worker merges after review and a post-merge test on the merged tree.
Changed: No session needed to merge.
Why: Planning economy rule 5.
Measured: Post-merge gate failed 7 times. [AGENTS § Human gates; evidence 01]
Source: AGENTS § Human gates; evidence 01
-
Deploy
CHANGED
On delegated repos the worker deploys and pings the owner with the live URL.
Changed: Per task, automatic.
Why: Features sat undeployed.
Measured: Deploy failed 2 times. [AGENTS § Human gates; evidence 01]
Source: AGENTS § Human gates; evidence 01
-
Model route
CHANGED
opencode reaches Haiku 5.5 through the relay.
Changed: Paid API instead of the Go window.
Measured: About $0.13–0.15 per merged task at published prices. [design §§ 0 B, 3]
Source: design §§ 0 B, 3
-
Job isolation
CHANGED
unshare -rmwith mounts that hide secret directories, plus text denies on shell commands. The template calls them "a tripwire, not a fence", and coderbashgets pastexternal_directory.Changed: A sandbox around the coder.
Why: Coder and reviewer needed no deploy or secret capabilities.
Measured: About 23 of about 70 stops were sandbox or permission denials. [evidence 02; design § 1]
Source: evidence 02; design § 1
-
Forge
CHANGED
The worker has a
deliver_prpath. Forgejo exists and is not used by the factory.Measured: linkexch/023 spent 6 h on PR checks. <code>deliver_pr</code> has no tests. [evidence 01, 02; design § 3]
Source: evidence 01, 02; design § 3
-
Driver
CHANGED
One
serveprocess spawning arun-taskchild per pick, in one 4,204-line file. Every repo change needs a restart, and a bad edit stops every repo.Changed: Telemetry, budget, delivery, resume, sandbox and per-repo fields added.
Why: v2 build list.
Measured: 240 worker tests. End to end runs only through fakes. [evidence 02]
Source: evidence 02
-
State
CHANGED
JSON per task plus an append-only
escalations.jsonl. Behaviour hangs on substrings of the reason text.Changed: Ledger added. Lead, touch and wait times recorded.
Measured: 152 escalations, 106 still open, 80 of those for tasks already merged. [evidence 01, 02]
Source: evidence 01, 02
-
Watchdog
NEW
A supervisor on a 60 s timer plus a budget watchdog.
Changed: Runs get watched; quota pauses and auto-resume appear.
Why: Supervision had been an Opus agent polling for 4 h.
Measured: It restarted deliberate stops. A restart used up the single auto-resume. A dead child went undetected until the next <code>serve</code> start. Worker died 2 times, budget watchdog fired 2 times. [evidence 01, 02]
Source: evidence 01, 02
-
Wake-ups
CHANGED
Matrix pings and
fw status. Sessions wake themselves to poll, with a mediansleepof 15 s inside an Opus turn.Changed: Escalations and owner pushes added.
Measured: Polling was 15.3% of planner tokens. Only 22% of tokens followed a real event. [design § 0 A, R2]
Source: design § 0 A, R2
-
Measurement
NEW
factory-metricsandfactory-report, from state files.Changed: Lead, touch and wait per task.
Why: No numbers existed for v1.
Measured: The ledger double-records 16% of tokens. Coder and reviewer minutes cover only the latest attempt. [design § 0 B; evidence 01]
Source: design § 0 B; evidence 01
-
Status view
fw status, read by sessions.Measured: Coordinators polled the same queues as planners. [design §§ 0 A, 3]
Source: design §§ 0 A, 3
v2: the worker takes over merge, deploy and watching
Built 2026-10-26. Stopped 2026-10-30. 149 tasks claimed, 125 merged.
Changes from v1, and why:
- Merge and deploy move to the worker, because features sat undeployed for 9 h.
- Blocks stop halting the queue, because two blocked tasks stopped a phase.
- Scoped checks and budgets, because page tasks took 29–48 min of coder time. Median fell to 4.3 min on a different task mix.
- What went wrong: almost all lead time became waiting, and the Opus layer used up the weekly limit on 10-28.
Source: draft version summary
A stop opens an escalation; a note carries the answer
- The worker records a reason as text and appends to
escalations.jsonl. - The planner bot or a human reads it, often by polling.
fw resume --noterestarts the task.- The note reaches only the first coder message. Later rounds and the reviewer never see it.
- Only an explicit
resolvecloses the record, so 80 stayed open on merged tasks.
Median human ruling 1.2 min, p90 78 min, max 538 min.
-
Owner gate
CHANGED
Per-task go through
fw go. Repos withauto_mergedelegate the merge and publish gates to the worker.Changed: Merge and publish no longer wait for a person on delegated repos.
Why: v1 held six merged features undeployed for 9 h.
Measured: 91 go and 32 no-go events. The slowest holds were 13–14 h. Hold time is not recorded on its own; it sits inside wait time. [design § 1, evidence 01]
Source: design § 1, evidence 01
-
Intake
Not present.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
CHANGED
One planning pass by rule, cheap models after it. In practice long-lived Opus sessions and a coordinator layer drove the factory.
Changed: Dispatch and merging moved to the worker. Coordinators appeared.
Why: Planning economy (owner, 2026-10-25): tokens were going to re-verifying plans.
Measured: 1,831M tokens over 47 sessions: specs 1.1%, rulings 2.7%. Median turn context 205k, p90 473k. Coordinators 24%, repair 12%. 66% of it was project planners. The weekly limit ran out on 10-28 and halted the factory. [design § 0]
Source: design § 0
-
Ruling step
NEW
An on-demand planner bot, then human planners. A
--noteruling reached only the first coder message of the resumed run.Changed: Stops got a bot and an escalation ledger.
Why: Blocked tasks no longer halted the queue, so someone had to clear them.
Measured: Bot: 17 rulings, median 0.2 min. Humans: 57 rulings, median 1.2 min, p90 78 min, max 538 min, 26.5 h in total. [evidence 01, 02]
Source: evidence 01, 02
-
Task file
CHANGED
Template adds
depends:,budget_min:and scoped checks beside acceptance checks.Changed: Tasks carry a time budget and a fast check.
Why: Nobody reviewed a spec, and coders had only the full build to run.
Measured: About 23 of about 70 stops were real spec contradictions or design questions. [v2 design log; evidence 01]
Source: v2 design log; evidence 01
-
Claim
CHANGED
At most 2 per host and 1 per repo. A block no longer stops the queue. Tasks with overlapping
files:never run together.Changed: Parallel across repos; a block stays local.
Why: The serial queue halted on every block.
Measured: Queue wait p90 441 min. This was the biggest wait in v2. [design § 1, evidence 02]
Source: design § 1, evidence 02
-
Coder
CHANGED
opencode on Haiku 5.5 with a time budget and a repeat-command watchdog.
Changed: Different model lane, telemetry, budget stop, scoped checks.
Why: One 01.2 task ran 10 full builds and about 34 test runs.
Measured: Median 4.3 min, p90 16.7 (latest attempt only, so understated). About half of coder tokens went to runs that did not merge; blocked runs alone were 32%. [evidence 01; design § 0 B]
Source: evidence 01; design § 0 B
-
Checks
CHANGED
Scoped checks while working, the full matrix once at the gate.
factory-lintruns every check on main beforeready.Changed: Fast inner loop and a ready gate.
Why: Task 012 contradicted itself, and running its check once would have shown that in seconds.
Measured: About 25 of about 70 stops were a red environment or baseline. [v2 design log; design § 1]
Source: v2 design log; design § 1
-
Reviewer
CHANGED
A reviewer station with a 2-round cap. Rulings never reached it.
Changed: Scope check against
files:.Why: Merging moved to the worker, so review became the last judgment.
Measured: Median 0.9 min, p90 2.1. 67% approved in round 0. The cap fired 9 times. A settled must-fix was re-raised 3 or more times. [evidence 01, 02]
Source: evidence 01, 02
-
Merge
CHANGED
The worker merges after review and a post-merge test on the merged tree.
Changed: No session needed to merge.
Why: Planning economy rule 5.
Measured: Post-merge gate failed 7 times. [AGENTS § Human gates; evidence 01]
Source: AGENTS § Human gates; evidence 01
-
Deploy
CHANGED
On delegated repos the worker deploys and pings the owner with the live URL.
Changed: Per task, automatic.
Why: Features sat undeployed.
Measured: Deploy failed 2 times. [AGENTS § Human gates; evidence 01]
Source: AGENTS § Human gates; evidence 01
-
Model route
CHANGED
opencode reaches Haiku 5.5 through the relay.
Changed: Paid API instead of the Go window.
Measured: About $0.13–0.15 per merged task at published prices. [design §§ 0 B, 3]
Source: design §§ 0 B, 3
-
Job isolation
CHANGED
unshare -rmwith mounts that hide secret directories, plus text denies on shell commands. The template calls them "a tripwire, not a fence", and coderbashgets pastexternal_directory.Changed: A sandbox around the coder.
Why: Coder and reviewer needed no deploy or secret capabilities.
Measured: About 23 of about 70 stops were sandbox or permission denials. [evidence 02; design § 1]
Source: evidence 02; design § 1
-
Forge
CHANGED
The worker has a
deliver_prpath. Forgejo exists and is not used by the factory.Measured: linkexch/023 spent 6 h on PR checks. <code>deliver_pr</code> has no tests. [evidence 01, 02; design § 3]
Source: evidence 01, 02; design § 3
-
Driver
CHANGED
One
serveprocess spawning arun-taskchild per pick, in one 4,204-line file. Every repo change needs a restart, and a bad edit stops every repo.Changed: Telemetry, budget, delivery, resume, sandbox and per-repo fields added.
Why: v2 build list.
Measured: 240 worker tests. End to end runs only through fakes. [evidence 02]
Source: evidence 02
-
State
CHANGED
JSON per task plus an append-only
escalations.jsonl. Behaviour hangs on substrings of the reason text.Changed: Ledger added. Lead, touch and wait times recorded.
Measured: 152 escalations, 106 still open, 80 of those for tasks already merged. [evidence 01, 02]
Source: evidence 01, 02
-
Watchdog
NEW
A supervisor on a 60 s timer plus a budget watchdog.
Changed: Runs get watched; quota pauses and auto-resume appear.
Why: Supervision had been an Opus agent polling for 4 h.
Measured: It restarted deliberate stops. A restart used up the single auto-resume. A dead child went undetected until the next <code>serve</code> start. Worker died 2 times, budget watchdog fired 2 times. [evidence 01, 02]
Source: evidence 01, 02
-
Wake-ups
CHANGED
Matrix pings and
fw status. Sessions wake themselves to poll, with a mediansleepof 15 s inside an Opus turn.Changed: Escalations and owner pushes added.
Measured: Polling was 15.3% of planner tokens. Only 22% of tokens followed a real event. [design § 0 A, R2]
Source: design § 0 A, R2
-
Measurement
NEW
factory-metricsandfactory-report, from state files.Changed: Lead, touch and wait per task.
Why: No numbers existed for v1.
Measured: The ledger double-records 16% of tokens. Coder and reviewer minutes cover only the latest attempt. [design § 0 B; evidence 01]
Source: design § 0 B; evidence 01
-
Status view
fw status, read by sessions.Measured: Coordinators polled the same queues as planners. [design §§ 0 A, 3]
Source: design §§ 0 A, 3
v2: the worker takes over merge, deploy and watching
Built 2026-10-26. Stopped 2026-10-30. 149 tasks claimed, 125 merged.
Changes from v1, and why:
- Merge and deploy move to the worker, because features sat undeployed for 9 h.
- Blocks stop halting the queue, because two blocked tasks stopped a phase.
- Scoped checks and budgets, because page tasks took 29–48 min of coder time. Median fell to 4.3 min on a different task mix.
- What went wrong: almost all lead time became waiting, and the Opus layer used up the weekly limit on 10-28.
Source: draft version summary
| Metric | Figure |
|---|---|
| Scope measured | 149 claimed, 125 merged, 8 repos [uncited in draft] |
| Lead time | Median 40 min, p90 509 [uncited in draft] |
| Coder time | Median 4.3, p90 16.7, latest attempt only [uncited in draft] |
| Review time | Median 0.9, p90 2.1 [uncited in draft] |
| Cost per accepted task | About $0.13–0.15, published prices [uncited in draft] |
| Planner usage | 1,831M over 47 sessions, all projects [uncited in draft] |
| Human involvement | 57 human rulings, 91 go, 32 no-go [uncited in draft] |
| Stale waits | 80 open on merged tasks [uncited in draft] |
| Restart safety | A restart used up the auto-resume [uncited in draft] |
| Long-lived sessions | Yes, 5 sessions were 70% of tokens [uncited in draft] |
-
Owner gate
CHANGED
Per-task go through
fw go. Repos withauto_mergedelegate the merge and publish gates to the worker.Changed: Merge and publish no longer wait for a person on delegated repos.
Why: v1 held six merged features undeployed for 9 h.
Measured: 91 go and 32 no-go events. The slowest holds were 13–14 h. Hold time is not recorded on its own; it sits inside wait time. [design § 1, evidence 01]
Source: design § 1, evidence 01
-
Intake
Not present.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
CHANGED
One planning pass by rule, cheap models after it. In practice long-lived Opus sessions and a coordinator layer drove the factory.
Changed: Dispatch and merging moved to the worker. Coordinators appeared.
Why: Planning economy (owner, 2026-10-25): tokens were going to re-verifying plans.
Measured: 1,831M tokens over 47 sessions: specs 1.1%, rulings 2.7%. Median turn context 205k, p90 473k. Coordinators 24%, repair 12%. 66% of it was project planners. The weekly limit ran out on 10-28 and halted the factory. [design § 0]
Source: design § 0
-
Ruling step
NEW
An on-demand planner bot, then human planners. A
--noteruling reached only the first coder message of the resumed run.Changed: Stops got a bot and an escalation ledger.
Why: Blocked tasks no longer halted the queue, so someone had to clear them.
Measured: Bot: 17 rulings, median 0.2 min. Humans: 57 rulings, median 1.2 min, p90 78 min, max 538 min, 26.5 h in total. [evidence 01, 02]
Source: evidence 01, 02
-
Task file
CHANGED
Template adds
depends:,budget_min:and scoped checks beside acceptance checks.Changed: Tasks carry a time budget and a fast check.
Why: Nobody reviewed a spec, and coders had only the full build to run.
Measured: About 23 of about 70 stops were real spec contradictions or design questions. [v2 design log; evidence 01]
Source: v2 design log; evidence 01
-
Claim
CHANGED
At most 2 per host and 1 per repo. A block no longer stops the queue. Tasks with overlapping
files:never run together.Changed: Parallel across repos; a block stays local.
Why: The serial queue halted on every block.
Measured: Queue wait p90 441 min. This was the biggest wait in v2. [design § 1, evidence 02]
Source: design § 1, evidence 02
-
Coder
CHANGED
opencode on Haiku 5.5 with a time budget and a repeat-command watchdog.
Changed: Different model lane, telemetry, budget stop, scoped checks.
Why: One 01.2 task ran 10 full builds and about 34 test runs.
Measured: Median 4.3 min, p90 16.7 (latest attempt only, so understated). About half of coder tokens went to runs that did not merge; blocked runs alone were 32%. [evidence 01; design § 0 B]
Source: evidence 01; design § 0 B
-
Checks
CHANGED
Scoped checks while working, the full matrix once at the gate.
factory-lintruns every check on main beforeready.Changed: Fast inner loop and a ready gate.
Why: Task 012 contradicted itself, and running its check once would have shown that in seconds.
Measured: About 25 of about 70 stops were a red environment or baseline. [v2 design log; design § 1]
Source: v2 design log; design § 1
-
Reviewer
CHANGED
A reviewer station with a 2-round cap. Rulings never reached it.
Changed: Scope check against
files:.Why: Merging moved to the worker, so review became the last judgment.
Measured: Median 0.9 min, p90 2.1. 67% approved in round 0. The cap fired 9 times. A settled must-fix was re-raised 3 or more times. [evidence 01, 02]
Source: evidence 01, 02
-
Merge
CHANGED
The worker merges after review and a post-merge test on the merged tree.
Changed: No session needed to merge.
Why: Planning economy rule 5.
Measured: Post-merge gate failed 7 times. [AGENTS § Human gates; evidence 01]
Source: AGENTS § Human gates; evidence 01
-
Deploy
CHANGED
On delegated repos the worker deploys and pings the owner with the live URL.
Changed: Per task, automatic.
Why: Features sat undeployed.
Measured: Deploy failed 2 times. [AGENTS § Human gates; evidence 01]
Source: AGENTS § Human gates; evidence 01
-
Model route
CHANGED
opencode reaches Haiku 5.5 through the relay.
Changed: Paid API instead of the Go window.
Measured: About $0.13–0.15 per merged task at published prices. [design §§ 0 B, 3]
Source: design §§ 0 B, 3
-
Job isolation
CHANGED
unshare -rmwith mounts that hide secret directories, plus text denies on shell commands. The template calls them "a tripwire, not a fence", and coderbashgets pastexternal_directory.Changed: A sandbox around the coder.
Why: Coder and reviewer needed no deploy or secret capabilities.
Measured: About 23 of about 70 stops were sandbox or permission denials. [evidence 02; design § 1]
Source: evidence 02; design § 1
-
Forge
CHANGED
The worker has a
deliver_prpath. Forgejo exists and is not used by the factory.Measured: linkexch/023 spent 6 h on PR checks. <code>deliver_pr</code> has no tests. [evidence 01, 02; design § 3]
Source: evidence 01, 02; design § 3
-
Driver
CHANGED
One
serveprocess spawning arun-taskchild per pick, in one 4,204-line file. Every repo change needs a restart, and a bad edit stops every repo.Changed: Telemetry, budget, delivery, resume, sandbox and per-repo fields added.
Why: v2 build list.
Measured: 240 worker tests. End to end runs only through fakes. [evidence 02]
Source: evidence 02
-
State
CHANGED
JSON per task plus an append-only
escalations.jsonl. Behaviour hangs on substrings of the reason text.Changed: Ledger added. Lead, touch and wait times recorded.
Measured: 152 escalations, 106 still open, 80 of those for tasks already merged. [evidence 01, 02]
Source: evidence 01, 02
-
Watchdog
NEW
A supervisor on a 60 s timer plus a budget watchdog.
Changed: Runs get watched; quota pauses and auto-resume appear.
Why: Supervision had been an Opus agent polling for 4 h.
Measured: It restarted deliberate stops. A restart used up the single auto-resume. A dead child went undetected until the next <code>serve</code> start. Worker died 2 times, budget watchdog fired 2 times. [evidence 01, 02]
Source: evidence 01, 02
-
Wake-ups
CHANGED
Matrix pings and
fw status. Sessions wake themselves to poll, with a mediansleepof 15 s inside an Opus turn.Changed: Escalations and owner pushes added.
Measured: Polling was 15.3% of planner tokens. Only 22% of tokens followed a real event. [design § 0 A, R2]
Source: design § 0 A, R2
-
Measurement
NEW
factory-metricsandfactory-report, from state files.Changed: Lead, touch and wait per task.
Why: No numbers existed for v1.
Measured: The ledger double-records 16% of tokens. Coder and reviewer minutes cover only the latest attempt. [design § 0 B; evidence 01]
Source: design § 0 B; evidence 01
-
Status view
fw status, read by sessions.Measured: Coordinators polled the same queues as planners. [design §§ 0 A, 3]
Source: design §§ 0 A, 3
v3 now: a program runs one task; the rest is not built yet
Merged on factory-v3 main: tasks 001–019. Only the factory-v3 repo runs on it.
Changes from v2, and why:
- A deterministic program replaces the worker and supervisor for one task, because repair took 12% of planner tokens.
- A fresh container replaces text denies, because about 23 of about 70 stops were denials.
- Rulings reach every round, because they reached only the first coder message (O-325).
- Not there yet: queue, ruler, notifications, deploy, status view, PRs and workflow engine. A stop waits until someone looks.
Source: draft version summary
-
Owner gate
CHANGED
D18 sets one approval per phase, on a deck. Deck factory-v3-r4 closed 15 of 15 go. The loop has no gate of its own: it runs when someone starts it.
Changed: Per-task go is gone. The per-phase gate is a rule, with no code behind it yet.
Why: Owner-go holds of 13–14 h for under 20 min of work.
Measured: Not measured: owner hold time is not recorded. [not measured]
Source: design D18, loop README
-
Intake
Not present. One Opus planning pass writes task files.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
CHANGED
Opus writes task specs and rules when the loop stops. On task 016 the planner read the diff, then reran with
--auto-merge.Changed: Dispatching, reading results, writing round notes and merging moved into a program.
Why: D15: running out of subscription usage is what halted the factory.
Measured: <b>Not recorded.</b> The report shows "planner: not recorded" on every task, so the main goal has no v3 number yet. [not measured]
Source: loop README; instrument report
-
Ruling step
REMOVED
The loop stops, writes a brief of at most 4 KB and exits 3. A person answers with
--rulingand reruns. That ruling goes into every later coder and reviewer task, and the reviewer may not reopen it without new evidence.Changed: Bot and ledger removed. Rulings now reach every round.
Why: O-325: rulings never reached the reviewer or later rounds in v2.
Measured: 7 interventions recorded, all on tasks 012 and 013. None on 014–019. Eight tasks, so this is thin. [loop README; instrument report]
Source: loop README; instrument report
-
Task file
CHANGED
issue: Nnames the issue the task resolves. The ID becomesfactory-v3-017across events, state directory and worktree.risk,escalate_ifand caps are ruled by D18 but not in the task files yet (019 has status, issue, files).Changed: One ID now follows a task through its events.
Why: D12 and D18: an ID must be unique before any second repo.
Measured: Not recorded in draft. [not measured]
Source: loop README; task 019
-
Claim
CHANGED
A person or planner runs
loop.run_taskon one task. Each task has its own state directory and lock, and the loop runs no tasks in parallel.Changed: The claim queue is gone for now.
Why: Build order: the task path first, the workflow around it later (D15).
Measured: Not measured: there is no queue to measure. [not measured]
Source: loop README
-
Coder
CHANGED
Each round is a new job in a fresh container. The loop applies its diff with
git apply --indexand commits it. Runtime gap: the bake-off chose opencode (8 of 8, $0.33), but tasks 016 to 019 ranruntime: claudeaccording to theirresult.json.Changed: The coder has no commit rights or checkout. A job dies without harming the branch.
Why: About 23 of about 70 v2 stops were sandbox or permission denials.
Measured: Implement stage median 11.4 min across all rounds, eight tasks. Last four tasks: 3.3, 7.8, 3.1 and 7.9 min. Not comparable with v2's latest-attempt figure. [loop README; instrument report; result.json]
Source: loop README; instrument report; result.json
-
Checks
CHANGED
After the coder finishes, the job stops its leftover processes, removes gitignored files it made and reruns setup, then the checks. A failure goes back as a round with the commands, exit codes and output tails.
Changed: Checks no longer see the coder's leftovers.
Why: Task 012 found checks had run in the coder's tree.
Measured: Bake-off re-score: 35 of 35 passing runs still pass when rebuilt from base plus diff. [design D9; loop README]
Source: design D9; loop README
-
Reviewer
CHANGED
A separate job that may write only
.agents/reviews/NNN-roundK.md. Any must-fix sends the task back, even underVerdict: approve. Haiku 5.5 stays (D18).Changed: Rulings included in every round. Verdict read by a parser.
Why: O-325.
Measured: Review stage median 6.3 min across all rounds, eight tasks. Last four: 0.8, 1.6, 0.8 and 4.0 min. Reviews per task: 4, 4, 3, 2, 1, 1, 1, 2. [loop README; instrument report]
Source: loop README; instrument report
-
Merge
CHANGED
Rebase on main, run the host tests, then
git merge --ff-onlyand push. Without--auto-mergeit stops at READY_TO_MERGE. If main moved after the tests, it tests again.Changed: Delegation moved from a repo registry to a flag on the run.
Why: D17: local merge now, PRs next.
Measured: Eight accepted tasks. [loop README, D17]
Source: loop README, D17
-
Deploy
REMOVED
The loop ends at the push. The only repo on it is
factory-v3itself.Measured: Not recorded in draft. [not measured]
Source: loop README
-
Model route
CHANGED
Every model call in a job goes through a usage proxy, which records tokens and cost.
Changed: Spend is measured per call rather than rebuilt afterwards.
Why: D12 and D16: instrument first.
Measured: Bake-off relay audit: 0 bypass lines. Task 017 replay: compacting gave 0 requests over 100k against 20, for $0.17 against $0.25, but 735 s against 469 s. [design D9, D12, D19]
Source: design D9, D12, D19
-
Job isolation
CHANGED
A fresh container for every job, with the coder free inside it.
--sysboxgives a job its own Docker daemon.Changed: The container is the fence, not a list of commands.
Why: v2's text denies stopped real work and did not stop
bash.Measured: <code>supabase start</code> in a job: 3m17s cold, 12.1 GB of images per cold container. RAM caps studio at one or two such jobs. Peak memory 163–953 MiB on measured tasks. [design § 6 step 2; instrument report]
Source: design § 6 step 2; instrument report
-
Forge
CHANGED
Issues track the owner's inquiries. Ruleset
protect-mainblocks deletion and non-fast-forward, with no bypass. No PRs or check reporting yet. The forge inventory is still in progress under Issue #3.Why: D17.
Measured: Not recorded in draft. [not measured]
Source: design D17; Issue #3
-
Driver
CHANGED
A deterministic program: implement, check, review, route, test, merge. Models run only inside jobs. Rerunning the same command resumes it. It replaces the Sonnet hand loop.
Changed: Plain state machine with named stop reasons. Runs one task per command.
Why: R4: v2's fragility pulled Opus into repair, 12% of planner tokens.
Measured: Four real runs, tasks 016–019, no interventions. 016–018 took 1 coder round and 1 review; 019 took a repair round and 2 reviews. [loop README; change log]
Source: loop README; change log
-
State
CHANGED
One
state.jsonper task, written atomically after each transition, a lock, and a fixed list of stop reasons.Changed: No ledger, so nothing is left to go stale. Reasons are an enum, not text.
Why: v2's 80 stale escalations and substring matching.
Measured: Crash resume is covered by tests. Not measured under real load. [loop README]
Source: loop README
-
Watchdog
REMOVED
No supervisor. Every job records why it died (signal, Docker events). Rerunning the command reuses finished jobs. Nothing notices a loop that died until someone looks.
Changed: Supervisor and its restart faults removed.
Why: Its faults are the case against keeping it.
Measured: 2 kills recorded: SIGKILL on 013, SIGABRT on 015. 013 and 017 peaked at 111 and 428 pids. [instrument report; loop README]
Source: instrument report; loop README
-
Wake-ups
CHANGED
A stop is a brief on disk and an exit code. There is no notification and no event. Whoever started the run has to look.
Changed: Polling sessions removed from the task path. Nothing replaces the push yet.
Why: Slice order (D15).
Measured: Prototypes only: see the Events view. [loop README]
Source: loop README
-
Measurement
CHANGED
Every stage, model call and container sample goes to
events.jsonl;instrument.cli reportreads it. Prompts, outputs and env values are not in the event log. Since task 019 each job keeps a redacted transcript, andinstrument.cli readsreports what it read and re-read.Changed: Cost per accepted task is the headline.
Why: D12, D16.
Measured: $0.43 per accepted task over eight tasks (report headline $0.4431 includes two probes). A lower bound: 3 stages have no cost. Planner tokens not recorded. [instrument report]
Source: instrument report
-
Status view
REMOVED
No status view. State is in files and the report CLI.
Measured: Not recorded in draft. [not measured]
Source: loop README
v3 now: a program runs one task; the rest is not built yet
Merged on factory-v3 main: tasks 001–019. Only the factory-v3 repo runs on it.
Changes from v2, and why:
- A deterministic program replaces the worker and supervisor for one task, because repair took 12% of planner tokens.
- A fresh container replaces text denies, because about 23 of about 70 stops were denials.
- Rulings reach every round, because they reached only the first coder message (O-325).
- Not there yet: queue, ruler, notifications, deploy, status view, PRs and workflow engine. A stop waits until someone looks.
Source: draft version summary
| Role | Reads | Writes | Tokens |
|---|---|---|---|
| Planner | Brief at a stop, at most 4 KB. Its own session is not measured. | Task spec, rulings | Not recorded [not measured] |
| Coder job | Generated task: failed checks or findings, plus all of <code>rulings.md</code>. Then the repo. | Diff only | Within a job, yes: 017 started at 18.8k, crossed 100k at call 35 and peaked at 144k. The size is history, not the prompt. Since the 100k compaction window (018), 019's coder jobs peaked at 68.3k and 43.6k with no call over the limit. [uncited in draft] |
| Reviewer job | Generated task with the diff. Largest prompt measured: 67,502 (019). | Review file only | Each review is a fresh job. [uncited in draft] |
| Loop program | <code>state.json</code>, <code>result.json</code>. No model. | Brief, round task | None: it spends no tokens. [uncited in draft] |
Across the eight tasks, 68.04M of 71.41M prompt tokens (95%) were cache reads, meaning history sent again on each call. Task 017 crossed 100k. 018 predates the per-job count, so it reads not measured. 019 is the one task with the count and none over. What each job read: <code>instrument.cli reads</code> exists since 019, and 019's own jobs read not measured, because they ran before that code merged. So re-reads have no number yet.
-
Owner gate
CHANGED
D18 sets one approval per phase, on a deck. Deck factory-v3-r4 closed 15 of 15 go. The loop has no gate of its own: it runs when someone starts it.
Changed: Per-task go is gone. The per-phase gate is a rule, with no code behind it yet.
Why: Owner-go holds of 13–14 h for under 20 min of work.
Measured: Not measured: owner hold time is not recorded. [not measured]
Source: design D18, loop README
-
Intake
Not present. One Opus planning pass writes task files.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
CHANGED
Opus writes task specs and rules when the loop stops. On task 016 the planner read the diff, then reran with
--auto-merge.Changed: Dispatching, reading results, writing round notes and merging moved into a program.
Why: D15: running out of subscription usage is what halted the factory.
Measured: <b>Not recorded.</b> The report shows "planner: not recorded" on every task, so the main goal has no v3 number yet. [not measured]
Source: loop README; instrument report
-
Ruling step
REMOVED
The loop stops, writes a brief of at most 4 KB and exits 3. A person answers with
--rulingand reruns. That ruling goes into every later coder and reviewer task, and the reviewer may not reopen it without new evidence.Changed: Bot and ledger removed. Rulings now reach every round.
Why: O-325: rulings never reached the reviewer or later rounds in v2.
Measured: 7 interventions recorded, all on tasks 012 and 013. None on 014–019. Eight tasks, so this is thin. [loop README; instrument report]
Source: loop README; instrument report
-
Task file
CHANGED
issue: Nnames the issue the task resolves. The ID becomesfactory-v3-017across events, state directory and worktree.risk,escalate_ifand caps are ruled by D18 but not in the task files yet (019 has status, issue, files).Changed: One ID now follows a task through its events.
Why: D12 and D18: an ID must be unique before any second repo.
Measured: Not recorded in draft. [not measured]
Source: loop README; task 019
-
Claim
CHANGED
A person or planner runs
loop.run_taskon one task. Each task has its own state directory and lock, and the loop runs no tasks in parallel.Changed: The claim queue is gone for now.
Why: Build order: the task path first, the workflow around it later (D15).
Measured: Not measured: there is no queue to measure. [not measured]
Source: loop README
-
Coder
CHANGED
Each round is a new job in a fresh container. The loop applies its diff with
git apply --indexand commits it. Runtime gap: the bake-off chose opencode (8 of 8, $0.33), but tasks 016 to 019 ranruntime: claudeaccording to theirresult.json.Changed: The coder has no commit rights or checkout. A job dies without harming the branch.
Why: About 23 of about 70 v2 stops were sandbox or permission denials.
Measured: Implement stage median 11.4 min across all rounds, eight tasks. Last four tasks: 3.3, 7.8, 3.1 and 7.9 min. Not comparable with v2's latest-attempt figure. [loop README; instrument report; result.json]
Source: loop README; instrument report; result.json
-
Checks
CHANGED
After the coder finishes, the job stops its leftover processes, removes gitignored files it made and reruns setup, then the checks. A failure goes back as a round with the commands, exit codes and output tails.
Changed: Checks no longer see the coder's leftovers.
Why: Task 012 found checks had run in the coder's tree.
Measured: Bake-off re-score: 35 of 35 passing runs still pass when rebuilt from base plus diff. [design D9; loop README]
Source: design D9; loop README
-
Reviewer
CHANGED
A separate job that may write only
.agents/reviews/NNN-roundK.md. Any must-fix sends the task back, even underVerdict: approve. Haiku 5.5 stays (D18).Changed: Rulings included in every round. Verdict read by a parser.
Why: O-325.
Measured: Review stage median 6.3 min across all rounds, eight tasks. Last four: 0.8, 1.6, 0.8 and 4.0 min. Reviews per task: 4, 4, 3, 2, 1, 1, 1, 2. [loop README; instrument report]
Source: loop README; instrument report
-
Merge
CHANGED
Rebase on main, run the host tests, then
git merge --ff-onlyand push. Without--auto-mergeit stops at READY_TO_MERGE. If main moved after the tests, it tests again.Changed: Delegation moved from a repo registry to a flag on the run.
Why: D17: local merge now, PRs next.
Measured: Eight accepted tasks. [loop README, D17]
Source: loop README, D17
-
Deploy
REMOVED
The loop ends at the push. The only repo on it is
factory-v3itself.Measured: Not recorded in draft. [not measured]
Source: loop README
-
Model route
CHANGED
Every model call in a job goes through a usage proxy, which records tokens and cost.
Changed: Spend is measured per call rather than rebuilt afterwards.
Why: D12 and D16: instrument first.
Measured: Bake-off relay audit: 0 bypass lines. Task 017 replay: compacting gave 0 requests over 100k against 20, for $0.17 against $0.25, but 735 s against 469 s. [design D9, D12, D19]
Source: design D9, D12, D19
-
Job isolation
CHANGED
A fresh container for every job, with the coder free inside it.
--sysboxgives a job its own Docker daemon.Changed: The container is the fence, not a list of commands.
Why: v2's text denies stopped real work and did not stop
bash.Measured: <code>supabase start</code> in a job: 3m17s cold, 12.1 GB of images per cold container. RAM caps studio at one or two such jobs. Peak memory 163–953 MiB on measured tasks. [design § 6 step 2; instrument report]
Source: design § 6 step 2; instrument report
-
Forge
CHANGED
Issues track the owner's inquiries. Ruleset
protect-mainblocks deletion and non-fast-forward, with no bypass. No PRs or check reporting yet. The forge inventory is still in progress under Issue #3.Why: D17.
Measured: Not recorded in draft. [not measured]
Source: design D17; Issue #3
-
Driver
CHANGED
A deterministic program: implement, check, review, route, test, merge. Models run only inside jobs. Rerunning the same command resumes it. It replaces the Sonnet hand loop.
Changed: Plain state machine with named stop reasons. Runs one task per command.
Why: R4: v2's fragility pulled Opus into repair, 12% of planner tokens.
Measured: Four real runs, tasks 016–019, no interventions. 016–018 took 1 coder round and 1 review; 019 took a repair round and 2 reviews. [loop README; change log]
Source: loop README; change log
-
State
CHANGED
One
state.jsonper task, written atomically after each transition, a lock, and a fixed list of stop reasons.Changed: No ledger, so nothing is left to go stale. Reasons are an enum, not text.
Why: v2's 80 stale escalations and substring matching.
Measured: Crash resume is covered by tests. Not measured under real load. [loop README]
Source: loop README
-
Watchdog
REMOVED
No supervisor. Every job records why it died (signal, Docker events). Rerunning the command reuses finished jobs. Nothing notices a loop that died until someone looks.
Changed: Supervisor and its restart faults removed.
Why: Its faults are the case against keeping it.
Measured: 2 kills recorded: SIGKILL on 013, SIGABRT on 015. 013 and 017 peaked at 111 and 428 pids. [instrument report; loop README]
Source: instrument report; loop README
-
Wake-ups
CHANGED
A stop is a brief on disk and an exit code. There is no notification and no event. Whoever started the run has to look.
Changed: Polling sessions removed from the task path. Nothing replaces the push yet.
Why: Slice order (D15).
Measured: Prototypes only: see the Events view. [loop README]
Source: loop README
-
Measurement
CHANGED
Every stage, model call and container sample goes to
events.jsonl;instrument.cli reportreads it. Prompts, outputs and env values are not in the event log. Since task 019 each job keeps a redacted transcript, andinstrument.cli readsreports what it read and re-read.Changed: Cost per accepted task is the headline.
Why: D12, D16.
Measured: $0.43 per accepted task over eight tasks (report headline $0.4431 includes two probes). A lower bound: 3 stages have no cost. Planner tokens not recorded. [instrument report]
Source: instrument report
-
Status view
REMOVED
No status view. State is in files and the report CLI.
Measured: Not recorded in draft. [not measured]
Source: loop README
v3 now: a program runs one task; the rest is not built yet
Merged on factory-v3 main: tasks 001–019. Only the factory-v3 repo runs on it.
Changes from v2, and why:
- A deterministic program replaces the worker and supervisor for one task, because repair took 12% of planner tokens.
- A fresh container replaces text denies, because about 23 of about 70 stops were denials.
- Rulings reach every round, because they reached only the first coder message (O-325).
- Not there yet: queue, ruler, notifications, deploy, status view, PRs and workflow engine. A stop waits until someone looks.
Source: draft version summary
No events in the loop yet: a brief and a rerun
- The loop hits one of its named stop reasons and writes
brief.md, then exits 3. - Nobody is told. Whoever started it has to look.
- A person reruns the same command with
--ruling '…'. - The ruling is appended to
rulings.mdand goes into every later coder and reviewer task.
-
Owner gate
CHANGED
D18 sets one approval per phase, on a deck. Deck factory-v3-r4 closed 15 of 15 go. The loop has no gate of its own: it runs when someone starts it.
Changed: Per-task go is gone. The per-phase gate is a rule, with no code behind it yet.
Why: Owner-go holds of 13–14 h for under 20 min of work.
Measured: Not measured: owner hold time is not recorded. [not measured]
Source: design D18, loop README
-
Intake
Not present. One Opus planning pass writes task files.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
CHANGED
Opus writes task specs and rules when the loop stops. On task 016 the planner read the diff, then reran with
--auto-merge.Changed: Dispatching, reading results, writing round notes and merging moved into a program.
Why: D15: running out of subscription usage is what halted the factory.
Measured: <b>Not recorded.</b> The report shows "planner: not recorded" on every task, so the main goal has no v3 number yet. [not measured]
Source: loop README; instrument report
-
Ruling step
REMOVED
The loop stops, writes a brief of at most 4 KB and exits 3. A person answers with
--rulingand reruns. That ruling goes into every later coder and reviewer task, and the reviewer may not reopen it without new evidence.Changed: Bot and ledger removed. Rulings now reach every round.
Why: O-325: rulings never reached the reviewer or later rounds in v2.
Measured: 7 interventions recorded, all on tasks 012 and 013. None on 014–019. Eight tasks, so this is thin. [loop README; instrument report]
Source: loop README; instrument report
-
Task file
CHANGED
issue: Nnames the issue the task resolves. The ID becomesfactory-v3-017across events, state directory and worktree.risk,escalate_ifand caps are ruled by D18 but not in the task files yet (019 has status, issue, files).Changed: One ID now follows a task through its events.
Why: D12 and D18: an ID must be unique before any second repo.
Measured: Not recorded in draft. [not measured]
Source: loop README; task 019
-
Claim
CHANGED
A person or planner runs
loop.run_taskon one task. Each task has its own state directory and lock, and the loop runs no tasks in parallel.Changed: The claim queue is gone for now.
Why: Build order: the task path first, the workflow around it later (D15).
Measured: Not measured: there is no queue to measure. [not measured]
Source: loop README
-
Coder
CHANGED
Each round is a new job in a fresh container. The loop applies its diff with
git apply --indexand commits it. Runtime gap: the bake-off chose opencode (8 of 8, $0.33), but tasks 016 to 019 ranruntime: claudeaccording to theirresult.json.Changed: The coder has no commit rights or checkout. A job dies without harming the branch.
Why: About 23 of about 70 v2 stops were sandbox or permission denials.
Measured: Implement stage median 11.4 min across all rounds, eight tasks. Last four tasks: 3.3, 7.8, 3.1 and 7.9 min. Not comparable with v2's latest-attempt figure. [loop README; instrument report; result.json]
Source: loop README; instrument report; result.json
-
Checks
CHANGED
After the coder finishes, the job stops its leftover processes, removes gitignored files it made and reruns setup, then the checks. A failure goes back as a round with the commands, exit codes and output tails.
Changed: Checks no longer see the coder's leftovers.
Why: Task 012 found checks had run in the coder's tree.
Measured: Bake-off re-score: 35 of 35 passing runs still pass when rebuilt from base plus diff. [design D9; loop README]
Source: design D9; loop README
-
Reviewer
CHANGED
A separate job that may write only
.agents/reviews/NNN-roundK.md. Any must-fix sends the task back, even underVerdict: approve. Haiku 5.5 stays (D18).Changed: Rulings included in every round. Verdict read by a parser.
Why: O-325.
Measured: Review stage median 6.3 min across all rounds, eight tasks. Last four: 0.8, 1.6, 0.8 and 4.0 min. Reviews per task: 4, 4, 3, 2, 1, 1, 1, 2. [loop README; instrument report]
Source: loop README; instrument report
-
Merge
CHANGED
Rebase on main, run the host tests, then
git merge --ff-onlyand push. Without--auto-mergeit stops at READY_TO_MERGE. If main moved after the tests, it tests again.Changed: Delegation moved from a repo registry to a flag on the run.
Why: D17: local merge now, PRs next.
Measured: Eight accepted tasks. [loop README, D17]
Source: loop README, D17
-
Deploy
REMOVED
The loop ends at the push. The only repo on it is
factory-v3itself.Measured: Not recorded in draft. [not measured]
Source: loop README
-
Model route
CHANGED
Every model call in a job goes through a usage proxy, which records tokens and cost.
Changed: Spend is measured per call rather than rebuilt afterwards.
Why: D12 and D16: instrument first.
Measured: Bake-off relay audit: 0 bypass lines. Task 017 replay: compacting gave 0 requests over 100k against 20, for $0.17 against $0.25, but 735 s against 469 s. [design D9, D12, D19]
Source: design D9, D12, D19
-
Job isolation
CHANGED
A fresh container for every job, with the coder free inside it.
--sysboxgives a job its own Docker daemon.Changed: The container is the fence, not a list of commands.
Why: v2's text denies stopped real work and did not stop
bash.Measured: <code>supabase start</code> in a job: 3m17s cold, 12.1 GB of images per cold container. RAM caps studio at one or two such jobs. Peak memory 163–953 MiB on measured tasks. [design § 6 step 2; instrument report]
Source: design § 6 step 2; instrument report
-
Forge
CHANGED
Issues track the owner's inquiries. Ruleset
protect-mainblocks deletion and non-fast-forward, with no bypass. No PRs or check reporting yet. The forge inventory is still in progress under Issue #3.Why: D17.
Measured: Not recorded in draft. [not measured]
Source: design D17; Issue #3
-
Driver
CHANGED
A deterministic program: implement, check, review, route, test, merge. Models run only inside jobs. Rerunning the same command resumes it. It replaces the Sonnet hand loop.
Changed: Plain state machine with named stop reasons. Runs one task per command.
Why: R4: v2's fragility pulled Opus into repair, 12% of planner tokens.
Measured: Four real runs, tasks 016–019, no interventions. 016–018 took 1 coder round and 1 review; 019 took a repair round and 2 reviews. [loop README; change log]
Source: loop README; change log
-
State
CHANGED
One
state.jsonper task, written atomically after each transition, a lock, and a fixed list of stop reasons.Changed: No ledger, so nothing is left to go stale. Reasons are an enum, not text.
Why: v2's 80 stale escalations and substring matching.
Measured: Crash resume is covered by tests. Not measured under real load. [loop README]
Source: loop README
-
Watchdog
REMOVED
No supervisor. Every job records why it died (signal, Docker events). Rerunning the command reuses finished jobs. Nothing notices a loop that died until someone looks.
Changed: Supervisor and its restart faults removed.
Why: Its faults are the case against keeping it.
Measured: 2 kills recorded: SIGKILL on 013, SIGABRT on 015. 013 and 017 peaked at 111 and 428 pids. [instrument report; loop README]
Source: instrument report; loop README
-
Wake-ups
CHANGED
A stop is a brief on disk and an exit code. There is no notification and no event. Whoever started the run has to look.
Changed: Polling sessions removed from the task path. Nothing replaces the push yet.
Why: Slice order (D15).
Measured: Prototypes only: see the Events view. [loop README]
Source: loop README
-
Measurement
CHANGED
Every stage, model call and container sample goes to
events.jsonl;instrument.cli reportreads it. Prompts, outputs and env values are not in the event log. Since task 019 each job keeps a redacted transcript, andinstrument.cli readsreports what it read and re-read.Changed: Cost per accepted task is the headline.
Why: D12, D16.
Measured: $0.43 per accepted task over eight tasks (report headline $0.4431 includes two probes). A lower bound: 3 stages have no cost. Planner tokens not recorded. [instrument report]
Source: instrument report
-
Status view
REMOVED
No status view. State is in files and the report CLI.
Measured: Not recorded in draft. [not measured]
Source: loop README
v3 now: a program runs one task; the rest is not built yet
Merged on factory-v3 main: tasks 001–019. Only the factory-v3 repo runs on it.
Changes from v2, and why:
- A deterministic program replaces the worker and supervisor for one task, because repair took 12% of planner tokens.
- A fresh container replaces text denies, because about 23 of about 70 stops were denials.
- Rulings reach every round, because they reached only the first coder message (O-325).
- Not there yet: queue, ruler, notifications, deploy, status view, PRs and workflow engine. A stop waits until someone looks.
Source: draft version summary
| Metric | Figure |
|---|---|
| Scope measured | 8 accepted, factory-v3 only [uncited in draft] |
| Lead time | Median 33.3 min. By task: 114, 127, 46, 64, 17, 16, 12, 21. [uncited in draft] |
| Coder time | Median 11.4 min, all rounds. Last four: 3.3, 7.8, 3.1, 7.9. [uncited in draft] |
| Review time | Median 6.3 min, all rounds. Last four: 0.8, 1.6, 0.8, 4.0. [uncited in draft] |
| Cost per accepted task | $0.43 (lower bound). Last four: $0.06, $0.27, $0.05, $0.16. [uncited in draft] |
| Planner usage | Not recorded [not measured] |
| Human involvement | 7 interventions, all on 012 and 013 [uncited in draft] |
| Stale waits | No ledger. Untested on a phase. [uncited in draft] |
| Restart safety | Crash resume in tests; not on a live phase [uncited in draft] |
| Long-lived sessions | Not measured; the planner session still exists [not measured] |
-
Owner gate
CHANGED
D18 sets one approval per phase, on a deck. Deck factory-v3-r4 closed 15 of 15 go. The loop has no gate of its own: it runs when someone starts it.
Changed: Per-task go is gone. The per-phase gate is a rule, with no code behind it yet.
Why: Owner-go holds of 13–14 h for under 20 min of work.
Measured: Not measured: owner hold time is not recorded. [not measured]
Source: design D18, loop README
-
Intake
Not present. One Opus planning pass writes task files.
Measured: Not recorded in draft. [not measured]
Source: evidence 20
-
Planner
CHANGED
Opus writes task specs and rules when the loop stops. On task 016 the planner read the diff, then reran with
--auto-merge.Changed: Dispatching, reading results, writing round notes and merging moved into a program.
Why: D15: running out of subscription usage is what halted the factory.
Measured: <b>Not recorded.</b> The report shows "planner: not recorded" on every task, so the main goal has no v3 number yet. [not measured]
Source: loop README; instrument report
-
Ruling step
REMOVED
The loop stops, writes a brief of at most 4 KB and exits 3. A person answers with
--rulingand reruns. That ruling goes into every later coder and reviewer task, and the reviewer may not reopen it without new evidence.Changed: Bot and ledger removed. Rulings now reach every round.
Why: O-325: rulings never reached the reviewer or later rounds in v2.
Measured: 7 interventions recorded, all on tasks 012 and 013. None on 014–019. Eight tasks, so this is thin. [loop README; instrument report]
Source: loop README; instrument report
-
Task file
CHANGED
issue: Nnames the issue the task resolves. The ID becomesfactory-v3-017across events, state directory and worktree.risk,escalate_ifand caps are ruled by D18 but not in the task files yet (019 has status, issue, files).Changed: One ID now follows a task through its events.
Why: D12 and D18: an ID must be unique before any second repo.
Measured: Not recorded in draft. [not measured]
Source: loop README; task 019
-
Claim
CHANGED
A person or planner runs
loop.run_taskon one task. Each task has its own state directory and lock, and the loop runs no tasks in parallel.Changed: The claim queue is gone for now.
Why: Build order: the task path first, the workflow around it later (D15).
Measured: Not measured: there is no queue to measure. [not measured]
Source: loop README
-
Coder
CHANGED
Each round is a new job in a fresh container. The loop applies its diff with
git apply --indexand commits it. Runtime gap: the bake-off chose opencode (8 of 8, $0.33), but tasks 016 to 019 ranruntime: claudeaccording to theirresult.json.Changed: The coder has no commit rights or checkout. A job dies without harming the branch.
Why: About 23 of about 70 v2 stops were sandbox or permission denials.
Measured: Implement stage median 11.4 min across all rounds, eight tasks. Last four tasks: 3.3, 7.8, 3.1 and 7.9 min. Not comparable with v2's latest-attempt figure. [loop README; instrument report; result.json]
Source: loop README; instrument report; result.json
-
Checks
CHANGED
After the coder finishes, the job stops its leftover processes, removes gitignored files it made and reruns setup, then the checks. A failure goes back as a round with the commands, exit codes and output tails.
Changed: Checks no longer see the coder's leftovers.
Why: Task 012 found checks had run in the coder's tree.
Measured: Bake-off re-score: 35 of 35 passing runs still pass when rebuilt from base plus diff. [design D9; loop README]
Source: design D9; loop README
-
Reviewer
CHANGED
A separate job that may write only
.agents/reviews/NNN-roundK.md. Any must-fix sends the task back, even underVerdict: approve. Haiku 5.5 stays (D18).Changed: Rulings included in every round. Verdict read by a parser.
Why: O-325.
Measured: Review stage median 6.3 min across all rounds, eight tasks. Last four: 0.8, 1.6, 0.8 and 4.0 min. Reviews per task: 4, 4, 3, 2, 1, 1, 1, 2. [loop README; instrument report]
Source: loop README; instrument report
-
Merge
CHANGED
Rebase on main, run the host tests, then
git merge --ff-onlyand push. Without--auto-mergeit stops at READY_TO_MERGE. If main moved after the tests, it tests again.Changed: Delegation moved from a repo registry to a flag on the run.
Why: D17: local merge now, PRs next.
Measured: Eight accepted tasks. [loop README, D17]
Source: loop README, D17
-
Deploy
REMOVED
The loop ends at the push. The only repo on it is
factory-v3itself.Measured: Not recorded in draft. [not measured]
Source: loop README
-
Model route
CHANGED
Every model call in a job goes through a usage proxy, which records tokens and cost.
Changed: Spend is measured per call rather than rebuilt afterwards.
Why: D12 and D16: instrument first.
Measured: Bake-off relay audit: 0 bypass lines. Task 017 replay: compacting gave 0 requests over 100k against 20, for $0.17 against $0.25, but 735 s against 469 s. [design D9, D12, D19]
Source: design D9, D12, D19
-
Job isolation
CHANGED
A fresh container for every job, with the coder free inside it.
--sysboxgives a job its own Docker daemon.Changed: The container is the fence, not a list of commands.
Why: v2's text denies stopped real work and did not stop
bash.Measured: <code>supabase start</code> in a job: 3m17s cold, 12.1 GB of images per cold container. RAM caps studio at one or two such jobs. Peak memory 163–953 MiB on measured tasks. [design § 6 step 2; instrument report]
Source: design § 6 step 2; instrument report
-
Forge
CHANGED
Issues track the owner's inquiries. Ruleset
protect-mainblocks deletion and non-fast-forward, with no bypass. No PRs or check reporting yet. The forge inventory is still in progress under Issue #3.Why: D17.
Measured: Not recorded in draft. [not measured]
Source: design D17; Issue #3
-
Driver
CHANGED
A deterministic program: implement, check, review, route, test, merge. Models run only inside jobs. Rerunning the same command resumes it. It replaces the Sonnet hand loop.
Changed: Plain state machine with named stop reasons. Runs one task per command.
Why: R4: v2's fragility pulled Opus into repair, 12% of planner tokens.
Measured: Four real runs, tasks 016–019, no interventions. 016–018 took 1 coder round and 1 review; 019 took a repair round and 2 reviews. [loop README; change log]
Source: loop README; change log
-
State
CHANGED
One
state.jsonper task, written atomically after each transition, a lock, and a fixed list of stop reasons.Changed: No ledger, so nothing is left to go stale. Reasons are an enum, not text.
Why: v2's 80 stale escalations and substring matching.
Measured: Crash resume is covered by tests. Not measured under real load. [loop README]
Source: loop README
-
Watchdog
REMOVED
No supervisor. Every job records why it died (signal, Docker events). Rerunning the command reuses finished jobs. Nothing notices a loop that died until someone looks.
Changed: Supervisor and its restart faults removed.
Why: Its faults are the case against keeping it.
Measured: 2 kills recorded: SIGKILL on 013, SIGABRT on 015. 013 and 017 peaked at 111 and 428 pids. [instrument report; loop README]
Source: instrument report; loop README
-
Wake-ups
CHANGED
A stop is a brief on disk and an exit code. There is no notification and no event. Whoever started the run has to look.
Changed: Polling sessions removed from the task path. Nothing replaces the push yet.
Why: Slice order (D15).
Measured: Prototypes only: see the Events view. [loop README]
Source: loop README
-
Measurement
CHANGED
Every stage, model call and container sample goes to
events.jsonl;instrument.cli reportreads it. Prompts, outputs and env values are not in the event log. Since task 019 each job keeps a redacted transcript, andinstrument.cli readsreports what it read and re-read.Changed: Cost per accepted task is the headline.
Why: D12, D16.
Measured: $0.43 per accepted task over eight tasks (report headline $0.4431 includes two probes). A lower bound: 3 stages have no cost. Planner tokens not recorded. [instrument report]
Source: instrument report
-
Status view
REMOVED
No status view. State is in files and the report CLI.
Measured: Not recorded in draft. [not measured]
Source: loop README
Full roadmap: v3 build order, then v4
Purple dashed is the adopted build order (design § 6). Purple dotted is v4, a proposed line from evidence 20, which the owner sets.
What comes next, in build order:
- Task workflow on a durable engine, then adapter and prompt composition.
- PR delivery with required checks from studio (5a).
- Cloudflare control plane: API proxy, webhook receiver, status view, notifications.
- gallery as second runner; tessella first, then symbol-map.
- v4, proposed: intake, more escalation triggers, factory-level and provider routing, CI-shaped checks, multi-repo lanes, per-tool timing, percentile dashboards.
Source: draft version summary
-
Owner gate
PLANNED
The owner approves a phase once. Per-task holds happen only on request.
Measured: Target: at most 10% of tasks reach a human planner or the owner. Holds are reported separately. [design §§ 3, 5]
Source: design §§ 3, 5
-
Intake
V4, PROPOSED
A small model turns the owner's description into a structured task, classifies repo, type, risk and complexity, and writes acceptance criteria and a test plan. The full discussion is stored for audit.
Measured: Not built, not measured. [not measured]
Source: evidence 20 § Proposed v4 boundary, item 1
-
Planner
PLANNED
One pass per phase, then the session exits. Rulings are one-shot runs started by an event. No session polls or coordinates.
Measured: Targets: planner tokens per merged task at most 40% of v2's, and zero long-lived factory sessions during a phase. [design §§ 2, 5]
Source: design §§ 2, 5
-
Ruling step
PLANNED
Cheapest capable resolver first: the machine fixes a red environment, then a Sonnet one-shot, an Opus one-shot, the owner. Each step hands up a brief. v4 adds triggers for cross-repo architecture, conflicting reviews and high-risk changes.
Measured: The ladder is prototyped on both engines with stub steps. It is not wired to the loop. [design § 2; evidence 20 item 2]
Source: design § 2; evidence 20 item 2
-
Task file
PLANNED
Failing tests first, plus
risk,escalate_ifand a spend and attempt cap. Each repo declares setup, tests, gate, deploy and generated paths infactory.toml.Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 3, D18
-
Claim
PLANNED
Start at 2 jobs on studio and 2 per repo when files do not overlap, raised only when memory samples show room. gallery is the second runner. Multi-repo lanes are proposed for v4.
Measured: Targets: lead time median at most 20 min, p90 at most 90 min. [design D18, §§ 5, 6]
Source: design D18, §§ 5, 6
-
Coder
PLANNED
The coder decides reversible choices and logs them. BLOCKED only when the spec contradicts itself, the task needs a file it does not own, or an external fact is missing.
Measured: Unproven: whether Haiku coders carry on under logged assumptions. [design §§ 2, 8, D18]
Source: design §§ 2, 8, D18
-
Checks
PLANNED
A ready step runs the checks on main before a phase, and a red main holds the repo with one alert. CI status, security scan and telling flaky from real are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design § 4; evidence 20 item 5
-
Reviewer
PLANNED
Tests decide whether it works. The reviewer judges scope and quality and may not reopen a logged decision without new evidence. Alternatives get tested on replay diffs without the OpenAI route.
Measured: Not recorded in draft. [not measured]
Source: design § 2, D18
-
Merge
PLANNED
Delivery through PRs, with required checks reported from studio. Merge queue only if parallel merges collide.
Measured: Not recorded in draft. [not measured]
Source: design § 6 step 5a, D17
-
Deploy
PLANNED
After merge, deploy on Cloudflare and ping the live URL.
Measured: Not recorded in draft. [not measured]
Source: design § 3
-
Model route
PLANNED
A Worker holds the key. Coders get a URL and a per-runner token. Provider routing and fallback are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design D1; evidence 20 item 4
-
Job isolation
PLANNED
Allow-all inside, no secrets, no host mounts, an egress allowlist and resource limits. A denial becomes a counted event, never a coder stop. Firecracker or Kata is the upgrade path.
Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 3
-
Forge
PLANNED
PRs, review records, required checks reported from studio and webhooks into the control plane. Forgejo is a true backup route. No GitHub-hosted runners (D13) and no extra paid GitHub service.
Measured: Not recorded in draft. [not measured]
Source: design D3, D13, D17, § 3
-
Driver
PLANNED
One durable workflow per task, with the loop's steps as activities. D8 is open between Temporal and Cloudflare Workflows until the two long waits answer (O-339, O-342).
Measured: Target: a redeploy mid-phase loses no attempt and no waiting ruling. [design D7, D8, D20, § 5]
Source: design D7, D8, D20, § 5
-
State
PLANNED
The workflow engine is the single truth and D1 a read-only copy, fed by a studio bridge that pulls from a Cloudflare Queue. If Cloudflare Workflows wins D8, the bridge and Temporal go and D1 becomes the truth.
Measured: Target: open escalations equal tasks actually waiting, by query. [design D18, § 5]
Source: design D18, § 5
-
Watchdog
PLANNED
The engine owns retries, timeouts and heartbeats. A redeploy does not count as an attempt. A canary task runs after every runner or worker change.
Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 4
-
Wake-ups
PLANNED
Forge webhook to a Worker, to a Cloudflare Queue, pulled by a studio bridge into the waiting run as a named event. Studio needs no inbound route.
Measured: Unproven: a wait of days on either engine (O-339, O-342). [design § 3]
Source: design § 3
-
Measurement
PLANNED
One task ID through workflow, agent call, checks, PR and deploy, with cost per accepted PR as the headline. Percentile views and per-tool timing are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design D12; evidence 20 items 7, 8
-
Status view
PLANNED
A status view on Cloudflare, read from D1, so that status needs no session. Status must read the step row as well, because Cloudflare says Running at first even with a wait open.
Measured: Not recorded in draft. [not measured]
Source: design D1, D8
Full roadmap: v3 build order, then v4
Purple dashed is the adopted build order (design § 6). Purple dotted is v4, a proposed line from evidence 20, which the owner sets.
What comes next, in build order:
- Task workflow on a durable engine, then adapter and prompt composition.
- PR delivery with required checks from studio (5a).
- Cloudflare control plane: API proxy, webhook receiver, status view, notifications.
- gallery as second runner; tessella first, then symbol-map.
- v4, proposed: intake, more escalation triggers, factory-level and provider routing, CI-shaped checks, multi-repo lanes, per-tool timing, percentile dashboards.
Source: draft version summary
| Role | Reads | Writes | Tokens |
|---|---|---|---|
| All roles | Not drawn here | Not drawn here | Open [uncited in draft] |
How a task's context gets sectioned so no later session re-reads it is an open design question, held by the redesign thread: <a href="https://github.com/srvo-labs/factory-v3/issues/11">Issue #11</a>. This map shows today's state only. Task 018 added a backstop and a count of requests over 100k; task 019 keeps transcripts so re-reads can be counted.
-
Owner gate
PLANNED
The owner approves a phase once. Per-task holds happen only on request.
Measured: Target: at most 10% of tasks reach a human planner or the owner. Holds are reported separately. [design §§ 3, 5]
Source: design §§ 3, 5
-
Intake
V4, PROPOSED
A small model turns the owner's description into a structured task, classifies repo, type, risk and complexity, and writes acceptance criteria and a test plan. The full discussion is stored for audit.
Measured: Not built, not measured. [not measured]
Source: evidence 20 § Proposed v4 boundary, item 1
-
Planner
PLANNED
One pass per phase, then the session exits. Rulings are one-shot runs started by an event. No session polls or coordinates.
Measured: Targets: planner tokens per merged task at most 40% of v2's, and zero long-lived factory sessions during a phase. [design §§ 2, 5]
Source: design §§ 2, 5
-
Ruling step
PLANNED
Cheapest capable resolver first: the machine fixes a red environment, then a Sonnet one-shot, an Opus one-shot, the owner. Each step hands up a brief. v4 adds triggers for cross-repo architecture, conflicting reviews and high-risk changes.
Measured: The ladder is prototyped on both engines with stub steps. It is not wired to the loop. [design § 2; evidence 20 item 2]
Source: design § 2; evidence 20 item 2
-
Task file
PLANNED
Failing tests first, plus
risk,escalate_ifand a spend and attempt cap. Each repo declares setup, tests, gate, deploy and generated paths infactory.toml.Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 3, D18
-
Claim
PLANNED
Start at 2 jobs on studio and 2 per repo when files do not overlap, raised only when memory samples show room. gallery is the second runner. Multi-repo lanes are proposed for v4.
Measured: Targets: lead time median at most 20 min, p90 at most 90 min. [design D18, §§ 5, 6]
Source: design D18, §§ 5, 6
-
Coder
PLANNED
The coder decides reversible choices and logs them. BLOCKED only when the spec contradicts itself, the task needs a file it does not own, or an external fact is missing.
Measured: Unproven: whether Haiku coders carry on under logged assumptions. [design §§ 2, 8, D18]
Source: design §§ 2, 8, D18
-
Checks
PLANNED
A ready step runs the checks on main before a phase, and a red main holds the repo with one alert. CI status, security scan and telling flaky from real are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design § 4; evidence 20 item 5
-
Reviewer
PLANNED
Tests decide whether it works. The reviewer judges scope and quality and may not reopen a logged decision without new evidence. Alternatives get tested on replay diffs without the OpenAI route.
Measured: Not recorded in draft. [not measured]
Source: design § 2, D18
-
Merge
PLANNED
Delivery through PRs, with required checks reported from studio. Merge queue only if parallel merges collide.
Measured: Not recorded in draft. [not measured]
Source: design § 6 step 5a, D17
-
Deploy
PLANNED
After merge, deploy on Cloudflare and ping the live URL.
Measured: Not recorded in draft. [not measured]
Source: design § 3
-
Model route
PLANNED
A Worker holds the key. Coders get a URL and a per-runner token. Provider routing and fallback are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design D1; evidence 20 item 4
-
Job isolation
PLANNED
Allow-all inside, no secrets, no host mounts, an egress allowlist and resource limits. A denial becomes a counted event, never a coder stop. Firecracker or Kata is the upgrade path.
Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 3
-
Forge
PLANNED
PRs, review records, required checks reported from studio and webhooks into the control plane. Forgejo is a true backup route. No GitHub-hosted runners (D13) and no extra paid GitHub service.
Measured: Not recorded in draft. [not measured]
Source: design D3, D13, D17, § 3
-
Driver
PLANNED
One durable workflow per task, with the loop's steps as activities. D8 is open between Temporal and Cloudflare Workflows until the two long waits answer (O-339, O-342).
Measured: Target: a redeploy mid-phase loses no attempt and no waiting ruling. [design D7, D8, D20, § 5]
Source: design D7, D8, D20, § 5
-
State
PLANNED
The workflow engine is the single truth and D1 a read-only copy, fed by a studio bridge that pulls from a Cloudflare Queue. If Cloudflare Workflows wins D8, the bridge and Temporal go and D1 becomes the truth.
Measured: Target: open escalations equal tasks actually waiting, by query. [design D18, § 5]
Source: design D18, § 5
-
Watchdog
PLANNED
The engine owns retries, timeouts and heartbeats. A redeploy does not count as an attempt. A canary task runs after every runner or worker change.
Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 4
-
Wake-ups
PLANNED
Forge webhook to a Worker, to a Cloudflare Queue, pulled by a studio bridge into the waiting run as a named event. Studio needs no inbound route.
Measured: Unproven: a wait of days on either engine (O-339, O-342). [design § 3]
Source: design § 3
-
Measurement
PLANNED
One task ID through workflow, agent call, checks, PR and deploy, with cost per accepted PR as the headline. Percentile views and per-tool timing are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design D12; evidence 20 items 7, 8
-
Status view
PLANNED
A status view on Cloudflare, read from D1, so that status needs no session. Status must read the step row as well, because Cloudflare says Running at first even with a wait open.
Measured: Not recorded in draft. [not measured]
Source: design D1, D8
Full roadmap: v3 build order, then v4
Purple dashed is the adopted build order (design § 6). Purple dotted is v4, a proposed line from evidence 20, which the owner sets.
What comes next, in build order:
- Task workflow on a durable engine, then adapter and prompt composition.
- PR delivery with required checks from studio (5a).
- Cloudflare control plane: API proxy, webhook receiver, status view, notifications.
- gallery as second runner; tessella first, then symbol-map.
- v4, proposed: intake, more escalation triggers, factory-level and provider routing, CI-shaped checks, multi-repo lanes, per-tool timing, percentile dashboards.
Source: draft version summary
A named event wakes the run that waits for it
- Forge or owner action reaches a webhook Worker.
- The Worker puts it on a Cloudflare Queue. A studio bridge pulls it, so studio needs no inbound route.
- The event wakes the waiting run, by name. The wait lives inside the run, so it closes when the run moves on.
- Ladder state travels as input and output. A step's name never changes (D20).
If Cloudflare Workflows wins D8, the bridge and Temporal go. A wait of days is still unanswered on both engines.
-
Owner gate
PLANNED
The owner approves a phase once. Per-task holds happen only on request.
Measured: Target: at most 10% of tasks reach a human planner or the owner. Holds are reported separately. [design §§ 3, 5]
Source: design §§ 3, 5
-
Intake
V4, PROPOSED
A small model turns the owner's description into a structured task, classifies repo, type, risk and complexity, and writes acceptance criteria and a test plan. The full discussion is stored for audit.
Measured: Not built, not measured. [not measured]
Source: evidence 20 § Proposed v4 boundary, item 1
-
Planner
PLANNED
One pass per phase, then the session exits. Rulings are one-shot runs started by an event. No session polls or coordinates.
Measured: Targets: planner tokens per merged task at most 40% of v2's, and zero long-lived factory sessions during a phase. [design §§ 2, 5]
Source: design §§ 2, 5
-
Ruling step
PLANNED
Cheapest capable resolver first: the machine fixes a red environment, then a Sonnet one-shot, an Opus one-shot, the owner. Each step hands up a brief. v4 adds triggers for cross-repo architecture, conflicting reviews and high-risk changes.
Measured: The ladder is prototyped on both engines with stub steps. It is not wired to the loop. [design § 2; evidence 20 item 2]
Source: design § 2; evidence 20 item 2
-
Task file
PLANNED
Failing tests first, plus
risk,escalate_ifand a spend and attempt cap. Each repo declares setup, tests, gate, deploy and generated paths infactory.toml.Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 3, D18
-
Claim
PLANNED
Start at 2 jobs on studio and 2 per repo when files do not overlap, raised only when memory samples show room. gallery is the second runner. Multi-repo lanes are proposed for v4.
Measured: Targets: lead time median at most 20 min, p90 at most 90 min. [design D18, §§ 5, 6]
Source: design D18, §§ 5, 6
-
Coder
PLANNED
The coder decides reversible choices and logs them. BLOCKED only when the spec contradicts itself, the task needs a file it does not own, or an external fact is missing.
Measured: Unproven: whether Haiku coders carry on under logged assumptions. [design §§ 2, 8, D18]
Source: design §§ 2, 8, D18
-
Checks
PLANNED
A ready step runs the checks on main before a phase, and a red main holds the repo with one alert. CI status, security scan and telling flaky from real are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design § 4; evidence 20 item 5
-
Reviewer
PLANNED
Tests decide whether it works. The reviewer judges scope and quality and may not reopen a logged decision without new evidence. Alternatives get tested on replay diffs without the OpenAI route.
Measured: Not recorded in draft. [not measured]
Source: design § 2, D18
-
Merge
PLANNED
Delivery through PRs, with required checks reported from studio. Merge queue only if parallel merges collide.
Measured: Not recorded in draft. [not measured]
Source: design § 6 step 5a, D17
-
Deploy
PLANNED
After merge, deploy on Cloudflare and ping the live URL.
Measured: Not recorded in draft. [not measured]
Source: design § 3
-
Model route
PLANNED
A Worker holds the key. Coders get a URL and a per-runner token. Provider routing and fallback are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design D1; evidence 20 item 4
-
Job isolation
PLANNED
Allow-all inside, no secrets, no host mounts, an egress allowlist and resource limits. A denial becomes a counted event, never a coder stop. Firecracker or Kata is the upgrade path.
Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 3
-
Forge
PLANNED
PRs, review records, required checks reported from studio and webhooks into the control plane. Forgejo is a true backup route. No GitHub-hosted runners (D13) and no extra paid GitHub service.
Measured: Not recorded in draft. [not measured]
Source: design D3, D13, D17, § 3
-
Driver
PLANNED
One durable workflow per task, with the loop's steps as activities. D8 is open between Temporal and Cloudflare Workflows until the two long waits answer (O-339, O-342).
Measured: Target: a redeploy mid-phase loses no attempt and no waiting ruling. [design D7, D8, D20, § 5]
Source: design D7, D8, D20, § 5
-
State
PLANNED
The workflow engine is the single truth and D1 a read-only copy, fed by a studio bridge that pulls from a Cloudflare Queue. If Cloudflare Workflows wins D8, the bridge and Temporal go and D1 becomes the truth.
Measured: Target: open escalations equal tasks actually waiting, by query. [design D18, § 5]
Source: design D18, § 5
-
Watchdog
PLANNED
The engine owns retries, timeouts and heartbeats. A redeploy does not count as an attempt. A canary task runs after every runner or worker change.
Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 4
-
Wake-ups
PLANNED
Forge webhook to a Worker, to a Cloudflare Queue, pulled by a studio bridge into the waiting run as a named event. Studio needs no inbound route.
Measured: Unproven: a wait of days on either engine (O-339, O-342). [design § 3]
Source: design § 3
-
Measurement
PLANNED
One task ID through workflow, agent call, checks, PR and deploy, with cost per accepted PR as the headline. Percentile views and per-tool timing are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design D12; evidence 20 items 7, 8
-
Status view
PLANNED
A status view on Cloudflare, read from D1, so that status needs no session. Status must read the step row as well, because Cloudflare says Running at first even with a wait open.
Measured: Not recorded in draft. [not measured]
Source: design D1, D8
Full roadmap: v3 build order, then v4
Purple dashed is the adopted build order (design § 6). Purple dotted is v4, a proposed line from evidence 20, which the owner sets.
What comes next, in build order:
- Task workflow on a durable engine, then adapter and prompt composition.
- PR delivery with required checks from studio (5a).
- Cloudflare control plane: API proxy, webhook receiver, status view, notifications.
- gallery as second runner; tessella first, then symbol-map.
- v4, proposed: intake, more escalation triggers, factory-level and provider routing, CI-shaped checks, multi-repo lanes, per-tool timing, percentile dashboards.
Source: draft version summary
| Metric | Figure |
|---|---|
| Scope measured | One real phase of at least 10 tasks in a migrated repo [uncited in draft] |
| Lead time | Median ≤ 20, p90 ≤ 90 [uncited in draft] |
| Coder time | No target [uncited in draft] |
| Review time | No target [uncited in draft] |
| Cost per accepted task | ≤ about $0.14 [uncited in draft] |
| Planner usage | ≤ 40% of v2 per merged task [uncited in draft] |
| Human involvement | ≤ 10% of tasks [uncited in draft] |
| Stale waits | Open = actually waiting [uncited in draft] |
| Restart safety | No loss mid-phase [uncited in draft] |
| Long-lived sessions | Zero during a phase [uncited in draft] |
-
Owner gate
PLANNED
The owner approves a phase once. Per-task holds happen only on request.
Measured: Target: at most 10% of tasks reach a human planner or the owner. Holds are reported separately. [design §§ 3, 5]
Source: design §§ 3, 5
-
Intake
V4, PROPOSED
A small model turns the owner's description into a structured task, classifies repo, type, risk and complexity, and writes acceptance criteria and a test plan. The full discussion is stored for audit.
Measured: Not built, not measured. [not measured]
Source: evidence 20 § Proposed v4 boundary, item 1
-
Planner
PLANNED
One pass per phase, then the session exits. Rulings are one-shot runs started by an event. No session polls or coordinates.
Measured: Targets: planner tokens per merged task at most 40% of v2's, and zero long-lived factory sessions during a phase. [design §§ 2, 5]
Source: design §§ 2, 5
-
Ruling step
PLANNED
Cheapest capable resolver first: the machine fixes a red environment, then a Sonnet one-shot, an Opus one-shot, the owner. Each step hands up a brief. v4 adds triggers for cross-repo architecture, conflicting reviews and high-risk changes.
Measured: The ladder is prototyped on both engines with stub steps. It is not wired to the loop. [design § 2; evidence 20 item 2]
Source: design § 2; evidence 20 item 2
-
Task file
PLANNED
Failing tests first, plus
risk,escalate_ifand a spend and attempt cap. Each repo declares setup, tests, gate, deploy and generated paths infactory.toml.Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 3, D18
-
Claim
PLANNED
Start at 2 jobs on studio and 2 per repo when files do not overlap, raised only when memory samples show room. gallery is the second runner. Multi-repo lanes are proposed for v4.
Measured: Targets: lead time median at most 20 min, p90 at most 90 min. [design D18, §§ 5, 6]
Source: design D18, §§ 5, 6
-
Coder
PLANNED
The coder decides reversible choices and logs them. BLOCKED only when the spec contradicts itself, the task needs a file it does not own, or an external fact is missing.
Measured: Unproven: whether Haiku coders carry on under logged assumptions. [design §§ 2, 8, D18]
Source: design §§ 2, 8, D18
-
Checks
PLANNED
A ready step runs the checks on main before a phase, and a red main holds the repo with one alert. CI status, security scan and telling flaky from real are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design § 4; evidence 20 item 5
-
Reviewer
PLANNED
Tests decide whether it works. The reviewer judges scope and quality and may not reopen a logged decision without new evidence. Alternatives get tested on replay diffs without the OpenAI route.
Measured: Not recorded in draft. [not measured]
Source: design § 2, D18
-
Merge
PLANNED
Delivery through PRs, with required checks reported from studio. Merge queue only if parallel merges collide.
Measured: Not recorded in draft. [not measured]
Source: design § 6 step 5a, D17
-
Deploy
PLANNED
After merge, deploy on Cloudflare and ping the live URL.
Measured: Not recorded in draft. [not measured]
Source: design § 3
-
Model route
PLANNED
A Worker holds the key. Coders get a URL and a per-runner token. Provider routing and fallback are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design D1; evidence 20 item 4
-
Job isolation
PLANNED
Allow-all inside, no secrets, no host mounts, an egress allowlist and resource limits. A denial becomes a counted event, never a coder stop. Firecracker or Kata is the upgrade path.
Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 3
-
Forge
PLANNED
PRs, review records, required checks reported from studio and webhooks into the control plane. Forgejo is a true backup route. No GitHub-hosted runners (D13) and no extra paid GitHub service.
Measured: Not recorded in draft. [not measured]
Source: design D3, D13, D17, § 3
-
Driver
PLANNED
One durable workflow per task, with the loop's steps as activities. D8 is open between Temporal and Cloudflare Workflows until the two long waits answer (O-339, O-342).
Measured: Target: a redeploy mid-phase loses no attempt and no waiting ruling. [design D7, D8, D20, § 5]
Source: design D7, D8, D20, § 5
-
State
PLANNED
The workflow engine is the single truth and D1 a read-only copy, fed by a studio bridge that pulls from a Cloudflare Queue. If Cloudflare Workflows wins D8, the bridge and Temporal go and D1 becomes the truth.
Measured: Target: open escalations equal tasks actually waiting, by query. [design D18, § 5]
Source: design D18, § 5
-
Watchdog
PLANNED
The engine owns retries, timeouts and heartbeats. A redeploy does not count as an attempt. A canary task runs after every runner or worker change.
Measured: Not recorded in draft. [not measured]
Source: design §§ 2, 4
-
Wake-ups
PLANNED
Forge webhook to a Worker, to a Cloudflare Queue, pulled by a studio bridge into the waiting run as a named event. Studio needs no inbound route.
Measured: Unproven: a wait of days on either engine (O-339, O-342). [design § 3]
Source: design § 3
-
Measurement
PLANNED
One task ID through workflow, agent call, checks, PR and deploy, with cost per accepted PR as the headline. Percentile views and per-tool timing are proposed for v4.
Measured: Not recorded in draft. [not measured]
Source: design D12; evidence 20 items 7, 8
-
Status view
PLANNED
A status view on Cloudflare, read from D1, so that status needs no session. Status must read the step row as well, because Cloudflare says Running at first even with a wait open.
Measured: Not recorded in draft. [not measured]
Source: design D1, D8