feat(maestro): hot-reload [daemon.policy] via SIGHUP + maestro policy CLI (NAP-237)
ci / rust (push) Failing after 2m51s

`PairAttachVerifier` now stores `allow_inbound` behind `Arc<RwLock<_>>` so
clones share the same set. Two triggers re-read the unified config file
and swap it atomically:

- SIGHUP — `systemctl --user reload maestrod`, or any `kill -HUP`. The
  installer's user unit now sets `ExecReload=/bin/kill -HUP $MAINPID`.
- `POST /api/policy/reload` — used by `maestro policy reload`. The CLI
  reads `[daemon].bind_addr` from the unified config (default 7070) and
  POSTs to `http://127.0.0.1:<port>`. No PID lookup required.

Also adds `maestro policy show [--json]` and `GET /api/policy` for
"did my edit get picked up?" debugging. A broken mid-edit config logs
an error and leaves the previously-effective list in place rather than
locking everyone out.

In-flight attaches keep their existing connection — revocation requires
killing the session, as spec'd.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 09:53:19 +00:00
co-authored by Claude Opus 4.7
parent 08f5bbc045
commit f69c7a9eee
10 changed files with 493 additions and 11 deletions
+16
View File
@@ -126,6 +126,21 @@ Pick `/tmp` if the daemon must outlive your login session and you can't run
tmux sockets with it). The env var `MAESTRO_DAEMON_TMUX_TMPDIR` takes
precedence over the file.
## Hot-reloading policy
`[daemon.policy].allow_inbound` (the list of peer daemons allowed to broker-
attach into this one) can be changed without restarting `maestrod` — restarting
would kill every live session. Two ways to apply an edit:
```sh
maestro policy reload # POSTs to the local daemon's /api/policy/reload
maestro policy show # prints the current effective list
kill -HUP <maestrod-pid> # equivalent; what `systemctl --user reload` does
```
Only newly-arriving attach attempts see the change — sessions already
attached stay attached. To boot a live attacher out, kill the session.
## What the systemd unit looks like
The wizard writes a *user* unit (`systemctl --user`), since `maestrod` runs
@@ -140,6 +155,7 @@ After=network-online.target
[Service]
Type=simple
ExecStart=%h/.cargo/bin/maestrod
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5