Architecture
Two processes, one database, one git library. Everything else is discipline about which of them owns what.
asks · answers · approvals
budget · journal · attention
journal · facts · scores
sandboxed, capability-aware
merged green work out
fragments · scripts
The pieces
| Piece | What it owns |
|---|---|
forge daemon | The control plane: HTTP API and web UI, the scheduler and cron, the merge queue (one integrator per repository), budget policy and admission, the human-attention sweep, journaling. The only writer of SQLite. |
forge worker | Execution: claims work over the API, prepares isolated git worktrees, launches the agent executor with a frozen prompt and a result JSON schema, runs declared checks, reports heartbeats and a structured completion. Advertises repositories and capabilities (sandbox, browser). |
| SQLite | All runtime state: work, targets, attempts, journal, facts, verifications, budgets, workflows, the scratch-script cache. One file; the journal table is the audit log. |
~/.forge/directives | A plain git repository holding everything agents read — directives, personas, fragments, scripts — forked from a shared base library and merged forward like code. |
The load-bearing decisions
Frozen snapshots
When work is created, the fully-composed prompt — directive body, persona, fragments, operational envelope — is serialized byte-for-byte onto the work row, with a hash. Whatever the library does afterwards, you can always answer exactly what did this attempt run? Prompt experiments and A/B reverts hang off that hash.
The journal
Every state-changing store method appends a journal row —
work.created, target.merged,
supervise.assessment, scratch.promoted — with the entity
and a payload. The SSE stream, the plugins, and the operator's 3am debugging all
read the same log. Nothing important happens silently.
Provenance
Every spawned task records its immediate cause (plan_task,
verify, tool, promotion,
continuation), the work that caused it, and the root ask it serves.
The tree is walkable in one indexed query, which is what makes per-ask cost rollups
and the learning loop possible.
Pull-based scheduling
Workers claim; the daemon never pushes. Each claim recomputes the queue from committed state — dependencies, budget class, path leases, stack depth — so there is no scheduler state to drift. Blocked and deferred are derived at read time, never stored.
Budget as admission control
Three classes — interactive, normal,
backlog — gate admission against subscription-window usage, with hard
stops and quiet hours. An agent that wants more turns mid-flight asks an
adjudicator; extensions are granted, bounded, and journaled.
A run, end to end
- An ask arrives — UI, CLI, API, a schedule, or another agent through a tool.
- The daemon freezes the snapshot, creates the work and its per-repository targets, journals it.
- A worker claims a target, builds a worktree on a fresh branch, launches the agent with the frozen prompt and the mode's result schema.
- The completion is parsed, claims are verified (L0/L1), follow-ups spawn — a verify agent, a plan's task batch, a supervise continuation.
- Green, integrating work enters the merge queue: rebase onto the integration head, re-run checks, land or bounce.
- Facts land in the analytics table: phases, tokens, cost, verification outcome, scores, size, tree root.
Next: Work & verification — the state machine that makes "done" mean something.