From 1a3634e04696bfaee40b8c4e4c317c2202e6357f Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 1 Nov 2026 02:33:02 +0100 Subject: [PATCH] Document idunn order and add the idunn-orders unit Co-Authored-By: Claude Sonnet 5.5 --- README.md | 29 ++++++++++++++++++++++ deploy/idunn-orders.service | 48 +++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 deploy/idunn-orders.service diff --git a/README.md b/README.md index a5c48bc..6af4527 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,35 @@ idunn status --command the bindings, so `idunn up profile:full-gamecult` brings up everything bound into that profile. +### Steward orders + +A second root unit from the same binary, `idunn-orders` (`idunn orders serve`), +takes typed orders from one steward Mind over `/run/idunn-orders/steward.sock`. +It has its own store, `orders.cc`, and its own binding, `steward.toml`; the +survival daemon takes no order. There is still no command string: + +```bash +idunn order package-install [=version]... --reason TEXT # apt-get update, then install +idunn order unit --reason TEXT +idunn order deploy --reason TEXT # the same commit as `idunn up` +idunn order show # status and output tails +idunn order list +``` + +A unit order may act on any unit except Idunn's own (`idunn-*`) and the minds' +own (`mind-self@*`, `mind-persona@*`). That set is compiled into the binary and +read from no configuration. A name, an alias that resolves to one of them, or a +`stop` or `restart` whose dependents systemd would stop with it is refused, +recorded and posted. Slices, scopes and globs are not units an order can name. + +An order runs once, after the steward's uid is checked and the instance's +brake check (`mind-control --instance check`) exits 0; an order +that had started when the service died is recorded as lost and never run +again. No order releases a brake. Acceptance and result are posted to +`#operator` as a retried projection of `orders.cc`: a chat outage delays the +posts and not the orders. A refusal names the field and a code, never the value +it refused. + ## Authority **Owner.** Deployment admission, and the continuity of installed bodies. diff --git a/deploy/idunn-orders.service b/deploy/idunn-orders.service new file mode 100644 index 0000000..cd3c46b --- /dev/null +++ b/deploy/idunn-orders.service @@ -0,0 +1,48 @@ +[Unit] +Description=Idunn steward orders: typed package, unit and deploy orders from the steward +# Deliberately no After= or Requires= on any managed target, Synapse or +# idunn-yggdrasil: orders are how an operator repairs those, so none of them +# may be a condition of this unit starting. Posts are a retried projection and +# wait for Synapse on their own. + +[Service] +Type=simple + +# Root, from the same binary as idunn-yggdrasil, with its own store and socket. +# idunn-yggdrasil keeps its no-imperative-input invariant and its write set: +# no order code runs in `idunn serve`. +# +# The unit name matches idunn-*, which is in the always-refused set, so no +# order can stop or restart this service. +User=root +# The socket is created root:idunn-steward 0660 (UMask below). The steward user +# is the only peer the service answers: it checks SO_PEERCRED on every +# connection, so the group is a second door held shut, not the lock. +Group=idunn-steward +ExecStart=/usr/local/bin/idunn orders serve \ + --store /var/lib/gamecult/idunn-orders \ + --state-store /var/lib/gamecult/idunn/control.cc \ + --steward-binding /etc/gamecult/idunn/steward.toml \ + --socket /run/idunn-orders/steward.sock +Restart=always +RestartSec=5 +TimeoutStopSec=20 +UMask=0117 + +RuntimeDirectory=idunn-orders +RuntimeDirectoryMode=0750 + +# The Synapse access token of @idunn, copied from a root-only file, and read +# through $CREDENTIALS_DIRECTORY; the service names it in steward.toml. +LoadCredential=idunn-matrix-token:/etc/gamecult/idunn/matrix-token + +PrivateTmp=yes +ProtectHome=yes +ProtectSystem=strict +# Its own order store, and the control store a deploy order commits a command +# to. Transient units started with systemd-run run in the manager's namespace, +# so packages and units are not limited by this list. +ReadWritePaths=/var/lib/gamecult/idunn-orders /var/lib/gamecult/idunn + +[Install] +WantedBy=multi-user.target