BeeverForge core architecture

Architecture overview

The BeeverForge core takes tickets from a board and drives existing coding agents through planning, implementation, validation, review, pull request, merge and deployment observation. It is an orchestrator: it does not contain a coding agent of its own.

This section describes the core as it exists in the repository at the commit linked under each page’s sources. Where a design record describes something the code does not yet do, the page says so.

Control model#

The project README states the model as “Policies authorise, humans evaluate.” The project’s manifest, .beeverforge/project.yaml, declares the merge policy, the quality floor and the promotion chain. Within those policies the factory acts without asking for approval at each step; people judge the result.

  • A project that declares no test gate is not treated as passing. Before the implementation pass, after sizing, the runner checks the floor and refuses the job, naming the missing gate and how to declare it.
  • The default merge policy is human: a person merges the pull request. Automatic merge happens only when a project sets merge_policy: auto and every condition for it holds.
  • Production promotion waits for a human approval. The approval reaches the workflow as a sealed, single-use answer (see The box and the quality floor).
  • When a job cannot continue, it parks on the card with the options a person can take, instead of waiting silently.

Layer model#

The core’s vision document draws the system as applications on top of an action layer, a core that decides, an engine that drives it, and providers reached through ports. Capabilities are drawn as a boundary, not as a layer: the core and the engine both reach providers through the same kind of port.

Layer model of the core Applications consume the action layer. The engine drives the core. The core and the engine reach providers through capability ports. APPLICATIONS Product role, tech-lead, panel Realised ACTION LAYER One catalogue of what a person may ask for Realised CORE Contracts, policy, card lifecycle tables Partly realised drives ENGINE Durability, schedules, retries, timers Realised Capabilities: ports PROVIDERS Coding agents, forges, trackers, boards, boxes Realised
Layers as drawn in the vision document, marked with how far the code realises each.
LayerWhere it is in the codeState
Applicationsbeeverforge/product/, beeverforge/techlead/, beeverforge/api/Realised. The panel, the tech-lead and the opt-in product role.
Action layerbeeverforge/actions/Realised. One catalogue that the panel API and the CLI both execute through.
Corebeeverforge/contracts/, beeverforge/policy/, beeverforge/lifecycle/Partly realised. The card lifecycle is decided by pure tables. The pure decision kernel for jobs proposed in ADR-0033 does not exist; job transitions are still decided inside the runner and the workflow.
Enginebeeverforge/runtime/temporal/Realised on Temporal. The engine is not behind a port of its own.
Capabilities and providersbeeverforge/adapters/Realised. Each provider is chosen by a registry from configuration.

The core’s own boundary document describes orchestrator/machine.py as core policy and engine execution that are currently fused. The vision of a core that only decides and an engine that only executes is the direction of ADR-0033, which is recorded as proposed.

Deployment shape#

  • The operator’s own machines. The default installation is docker compose on one machine and needs no cloud account (ADR-0040). A cloud is reached only through add-on packages.
  • Services. The compose file runs a Postgres database for the engine, a Temporal server, the Temporal web UI, the worker and the panel. The published ports bind to 127.0.0.1 by default.
  • The engine. Temporal holds job state. Every job is a durable workflow: its waits and timers survive a worker restart, and a job whose worker is lost during the agent pass parks for a person to resume or skip.
  • The box. The worker runs each job in a box. The default kind is container: a throwaway Docker container launched as a sibling on the host’s daemon, through the Docker socket that the compose file mounts into the worker.
  • Single-tenant, multi-project. One installation serves one team with one project registry. The registry holds any number of projects, each with its own repository, board and manifest (ADR-0001, D-14).
  • One job at a time by default. The number of jobs in flight is BEEVERFORGE_MAX_CONCURRENT_JOBS, default 1.
Deployment of the default installationOn the operator’s machine, docker compose runs the panel, the worker, the Temporal server with its web UI, and the Postgres database Temporal stores its state in. The worker starts one box per job through the Docker socket. The box calls the coding agent service; the worker reaches a remote forge, tracker and board through adapters.The operator’s machine: docker composebrowsersignals and readstask queue beeverforge-jobsDocker socketharness callsadaptersA personpanel127.0.0.1:8787workertemporal, 127.0.0.1:7233temporal-ui, 127.0.0.1:8080State volumeregistry, localboard, metricsBoxone container per jobtemporal-dbPostgres 16Coding agentserviceRemote forge,tracker and board
The default installation. The published ports bind to 127.0.0.1; the box’s network is described on The box and the quality floor.

The worker holds the host’s Docker socket, which gives it control of the host’s Docker daemon. The default box has full outbound network access. Both are described with their limits on The box and the quality floor.

Outside the core#

  • The coding agents. The core drives existing agent command-line tools through one adapter contract. The harness kinds in the tree are claude_code (the default), codex, kimi and opencode. Each one calls its vendor’s service; that endpoint is a network destination every installation needs.
  • Chat channels. The core is complete without a chat connector (ADR-0038). The only channel and notifier in the tree is the panel. Slack and Telegram adapters ship in a separate add-on package and register through the same extension mechanism as any other adapter.
  • Cloud runners and stores. The core ships no remote box runner. The remote task runner, the cloud metrics table, the remote session store and the cloud token pool are declared as add-on kinds.

Sources#