dwarves — guide
The forge is young; this describes how it is meant to be driven. Everything is
xtask.
Running a pipeline
cargo xtask <pipeline>
Pipelines (each pure Rust, each testable):
| pipeline | what it does |
build |
build the targeted members through nornir |
test |
run the members' test matrices (nornir testmatrix) |
bench |
run the heavy benches and record results to the warehouse |
release |
drive nornir's deps-first release cascade |
publish |
forge the resulting artifacts into holger |
How it binds
- nornir is the master builder dwarves calls — dwarves never re-implements build/test/ release logic, it orchestrates nornir.
- holger is where forged artifacts land and where dependencies are pulled from, so a dwarves pipeline works the same online or airgapped.
The dwarves CLI — thin or fat
The dwarves binary drives the forge two ways, mirroring nornir's client modes:
- Fat (no
--server): everything runs in-process against a repo'sbrokkr.toml—dwarves plan <path>,dwarves run <path>(DemoRunner + local warehouse history),dwarves history,dwarves doctor. - Thin (
--server <url>or$DWARVES_SERVER): the same verbs route over gRPC to a runningdwarves-server—dwarves runbecomes register+Trigger,doctorqueries the server's Health,historyreads the server's warehouse.
Running the forge as a daemon (dwarves serve)
dwarves serve # boot the gRPC forge + durable cron in THIS process
dwarves-server # the standalone daemon (identical bootstrap)
dwarves-server --install --start # install + start it as a skidbladnir systemd unit
serve binds $DWARVES_SERVER_ADDR (default 127.0.0.1:7900), historizes into $DWARVES_WAREHOUSE (default ~/.dwarves/warehouse), and spins the durable server-side cron loop: every minute it seeds its dedup from <warehouse>/cron.redb, ticks each registered pipeline's cron through the shared jera Scheduler, and persists the last-fired store back — so a cron pipeline fires exactly once per matching minute, even across a restart. Push-triggered pipelines fire the same way via the Dwarf.Webhook RPC.
- Auth is
authorization: Bearer <token>from$DWARVES_SERVER_TOKEN(or~/.dwarves/token); empty ⇒ open (single-workspace dev). The interceptor is the sharednornir-serviceone (constant-time compare) — dwarves does not hand-roll it. - Real builds:
--real(or$DWARVES_REAL_RUNNER=1) selects the cargo-buildingRealRunner(vianornir-build-thing, multi-target/variant, zero shell); the default is the hermeticDemoRunner. - Multi-machine:
dwarves agent --group <g> --caps <c,…>registers a worker; steps place onto a matching agent through the jera Scheduler (LocalAgent now, GrpcAgent next).
Principles
- No shell in any pipeline — if you reach for
std::process::Commandto callbash, stop and write the Rust. - Every pipeline emits a functional-status row so the forge is self-testing.