Skip to content

Architecture

This page covers the internal architecture of Wezel. It’s aimed at contributors, integrators, and anyone self-hosting who wants to understand what’s running.

NameRole
BurrowThe backend API server. Built with Axum + Postgres. Ingests build events from Pheromone and Forager, serves historical data to Anthill. Runs on port 3001.
AnthillThe web dashboard frontend. Visualizes observations, trends, and regression events.
PheromoneThe local build agent. Ships as pheromone-<tool> binaries (e.g. pheromone-cargo) that hook into build tools to capture invocations and report them to Burrow.
ForagerThe benchmark runner CLI (forager). Runs defined benchmarks against a checked-out commit and reports measurements to Burrow. Ships forager plugins as forager-<name> binaries.
crates/
wezel_types/ # Shared API and config types (serde, camelCase JSON)
burrow/ # API server (axum, sqlx, postgres)
forager_cli/ # `forager` binary entry point
forager_exec/ # Built-in exec plugin
forager_llvm_lines/ # Built-in llvm-lines plugin
pheromone_cargo/ # Cargo build hook
wezel_cli/ # `wezel` CLI (config, project management)

All HTTP routes are defined in crates/burrow/src/main.rs. Key endpoints:

MethodPathDescription
POST/api/projectCreate a project
POST/api/project/:id/observationIngest a build observation from Pheromone
POST/api/forager/claimClaim a forager run token
POST/api/forager/runSubmit benchmark measurements

Postgres, migrated via sqlx::raw_sql in crates/burrow/src/db.rs. Key tables: projects, observations, measurements, forager_tokens.

Plugins are binaries named forager-<name>. The runner communicates with them via environment variables:

VariableDirectionDescription
FORAGER_INPUTSrunner → pluginJSON-encoded step inputs
FORAGER_OUTplugin → runnerPath to write JSON result
FORAGER_STEPrunner → pluginCurrent step name

Run forager-<name> --schema to inspect a plugin’s input/output schema.