Wheelhouse docs

Keep the router aligned on a timer#

You will end up with the agent re-diffing the desired-state file on a timer and either staging the difference or committing it. This is how a router stays where you put it when several people can change it.

It is off unless you ask for it. No flag, no loop.

Before you start#

  • A desired-state file you have planned against and are happy with.
  • A decision about which mode you want. Read both before choosing.
  • Shell access, to add the flags with a systemd drop-in.

The two modes#

ModeWhat the loop does when it finds drift
stage (default)Puts the operations in the Commit Bar and stops. A person still commits.
commitCommits with a confirm window, then confirms once the router still answers

Step 1 — Turn it on#

A systemd drop-in, not the packaged unit, which an image upgrade replaces.

/etc/systemd/system/wheelhouse-agent.service.d/reconcile.conf
[Service]
ExecStart=
ExecStart=/usr/bin/wheelhouse-agent … \
  --reconcile-file /config/wheelhouse/agent.yaml \
  --reconcile-mode stage \
  --reconcile-interval 60s

Repeat every flag the packaged unit passes; the empty ExecStart= clears the original.

bash
sudo systemctl daemon-reload
sudo systemctl restart wheelhouse-agent

Step 2 — Know what the flags do#

FlagDefaultMeaning
--reconcile-file <path>emptyThe file to enforce. Empty means the loop is off, which is the default.
--reconcile-modestagestage or commit
--reconcile-interval60sHow often it re-diffs. 10 s floor.
--reconcile-delay15sHow long it waits after start, so boot can settle
--reconcile-confirm2The commit-confirm window, in minutes, that commit mode uses
--reconcile-fulloffAlso delete what the file does not declare

Step 3 — Understand what it does not do twice#

The loop never stages the same operation twice. If it has already filled the Commit Bar and nobody has committed, the next pass says so in the log instead of duplicating the work.

Writes are audited as actor: reconcile-loop, role: system, so a change the loop made is distinguishable from one a person made in the audit log.

Check it worked#

The loop reports itself:

bash
R=https://127.0.0.1:8443
T=wh_...
curl -sk -H "Authorization: Bearer $T" "$R/api/drift"
json
{"managed":true,"file":"/config/wheelhouse/agent.yaml","mode":"stage","drifted":true,
 "ops":2,"checked_at":"2026-08-30T22:27:07Z"}

managed: false means no file is set and the loop is off. That is the default and it is what an agent without the flag reports.

Then make it work. Change something on the router by hand that the file declares, wait an interval, and check:

  • in stage mode: the Commit Bar has the operations that undo your change;
  • in commit mode: your change is gone, and the audit log has an entry from reconcile-loop.

And watch the journal:

bash
journalctl -u wheelhouse-agent -f | grep -i reconcile

Warnings from the file are logged once per change, not once per pass.

The interaction with people#

The staging area is shared. A loop in stage mode and a person editing in the UI put operations in the same working set, and one Commit Bar commits both. That is usually what you want — the person sees the drift the loop found, next to their own change — and it is worth telling the team about, because a Commit Bar with operations nobody remembers staging is otherwise alarming.

Undoing it#

Remove the drop-in and restart:

bash
sudo rm /etc/systemd/system/wheelhouse-agent.service.d/reconcile.conf
sudo systemctl daemon-reload
sudo systemctl restart wheelhouse-agent

GET /api/drift should go back to {"mode":"off"}. The wheelhouse_desired_* metrics stop being exported, which is how a dashboard notices.

See also#


Checked against agent/desired.go · agent/main.go · agent/metrics.go · docs/deploy.md

Updated 2026-09-02 reconcile desired-state automation