⚒ dwarves — for complete beginners
📍 THIS DOC LIVES IN
dwarves(moved fromnornir/.nornir/, 2026-07-22, move=delete). The code it documents is dwarves' own (crates/dwarves/src/…), so the doc follows the code. nornir keeps only the read-only viz surface that renders this engine's output. Source links below are dwarves-repo-relative.
Class:
idiot-guide· assumes nothing. What it is:dwarves-design.md. How to use it:dwarves-guide.md.
What problem does dwarves solve?
You want a build server (like TeamCity or GitHub Actions): something that watches your repos and, when code changes, automatically builds and tests them.
nordisk already had half of that. A crate called brokkr knew how to read a recipe file (brokkr.toml), work out the order to run the steps in, and run one. But brokkr was like a recipe and a chef with no kitchen timer and no waiter — nothing ever told it when to cook. All its clever parts (a queue of jobs, a pool of workers, a nightly schedule) were written and tested but never actually run.
dwarves is the finished kitchen. It has two dwarves:
- Brokkr — the smith who builds (the recipe + the chef). Already existed.
- Sindri — his brother, who directs the forge (the timer + the waiter). This is the new part. Sindri watches the clock and the repos, decides what to cook and when, hands each job to a free worker, and writes down what happened.
The three things Sindri does, every "tick"
Think of one tick as the waiter doing a lap of the kitchen:
- Clock check (cron). "Is it 3 a.m.? The nightly build is due — add it to the queue."
- Repo check (poll). "Did anyone push new code? That repo's pipeline goes in the queue."
- Serve the queue (drain). "Is there a free worker who can do this job? Yes → cook it now, and note the result. No → leave it in the queue and say why ('all workers busy')." One heavy build at a time (the exclusive gate), so the machine doesn't melt.
That's the whole idea. Everything else is detail.
Try it yourself in 60 seconds
Make a recipe file brokkr.toml:
[pipeline]
name = "hello-ci"
[[pipeline.trigger]]
kind = "poll"
events = ["push"]
[[pipeline.stage]]
name = "build"
[[pipeline.stage.step]]
name = "compile"
run = { variant = "server" }
Now:
dwarves # just type it — a friendly banner + "am I ready?" check
dwarves validate # "is my recipe well-formed?" → ✓ valid
dwarves plan # "what order will the steps run?"
dwarves run # "run it now (pretend build)" → passed
dwarves serve --once --poll . # "pretend this repo just changed" → Sindri cooks it
dwarves history # "what has run so far?"
dwarves run --real does an actual cargo build (no shell tricks — pure Rust). Without --real it uses a pretend "demo" build so you can see the whole flow without waiting for a real compile.
Where does this fit in nornir?
- The
dwarvesprogram is a standalone tool — you can use it on its own. - nornir also contains dwarves. When the nornir server is watching your repos and notices a change, it quietly asks Sindri to build the changed repo. So just by running the server, you already have a CI server.
- In the desktop app there's a ⚒ Brokkr tab: press Run and watch the little map light up green, station by station, as each step passes.
The ⚒ Build-Thing tab — "build me this, one of these ways"
There is also a ⚒ Build Thing tab. Think of it as a menu of everything in the whole family of repos that can be built, in every way it can be built. It reads each repo's own little list of build recipes and shows them to you. You pick one and press Build, and it really compiles it (on a background worker, so the app never freezes) and tells you the truth: where the file landed, how big it is, and — if it broke — the exact compiler error. If there are no repos to look at, it says so plainly instead of showing an empty page that looks "fine".
Some recipes make a whole little computer you can boot (a container or a virtual machine). For those you get a Boot button, a ↻ Reboot button, and — for the desktop ones — a built-in 🖥 screen viewer.
Watching korp from a Windows PC
One of those recipes is special. It packages korp (another app in the family) as a tiny window-into-a-remote-server: the app itself runs inside a little Linux desktop you can open from Windows with the built-in Remote Desktop program (mstsc), while the real heavy server stays on the oden machine. In the ⚒ tab you pick tunnr → the appliance → the "rdp-korp-thin" cell and press Build appliance. It honestly tells you two things: the package is staged (built and ready) and booting it needs a runtime — it never pretends to have started something it hasn't.
How do I open the dashboard?
There is a desktop app called dwarves-ui. It needs to know one thing: where the dwarves server is. You tell it with DWARVES_SERVER:
DWARVES_SERVER=http://oden:7900 dwarves-ui
That's the whole story. You do not set anything about "nornir" — the dwarves server has nornir built inside it, and the app just talks to the dwarves server. (There is a nornir door on port 7878, but that door is for OTHER programs, not this app. The app never knocks on it.) If some data view can't be shown yet, it says so honestly instead of going behind the server's back.
The words, decoded
- pipeline — your recipe (
brokkr.toml): the steps to build/test something. - trigger — when to run: on a push (poll), on a schedule (cron), or by hand.
- step / stage — one job / a group of jobs; steps can wait for other steps.
- DAG — the "who-waits-for-whom" map of the steps (no loops allowed).
- agent — a worker that can run a job (it advertises what it can do, like "cargo" or "macos").
- queue — jobs waiting for a free worker.
- historize — write down every run's result so you can look back at it.
What dwarves does NOT do yet (on purpose)
This first version drives the two common triggers (a push and a nightly schedule). It does not yet: receive GitHub webhooks, skip steps whose inputs didn't change, chain builds across projects, or run workers on other machines. Those are written up as "next steps" in dwarves-design.md so nobody forgets them.