feat(discord): systemd user service with a supervised run; brakes exit 3 and are never retried (#1509)

QUEUE row 17, MVP iteration 2. scripts/discord-service.sh renders and
installs mosaic-discord@<binding> from packages/discord/systemd/. The
unit's main process is `run --supervised`, which applies the new recover
policy first: a lock whose owner is gone is cleared and only the STOP
written for that is removed; an operator STOP or a held binding refuses
with exit 3, which RestartPreventExitStatus never retries. `recover` is
also a CLI verb. First cut used ExecStartPre and looped live, since systemd
honours the never-retry status only from the main process; replaced and
re-verified before any message traffic. Suite 40/40, 95 node tests.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
2026-09-13 14:39:11 -05:00
co-authored by Claude Fable 5.1
parent dc5902aafd
commit 436ba6ed6b
15 changed files with 630 additions and 30 deletions
+13 -4
View File
@@ -151,9 +151,11 @@ usage. Details and the record's fields: `packages/seat/README.md`.
```bash
scripts/discord.sh check <binding>
scripts/discord.sh run <binding>
scripts/discord.sh run <binding> [--supervised]
scripts/discord.sh stop <binding>
scripts/discord.sh unlock <binding>
scripts/discord.sh recover <binding>
scripts/discord-service.sh render | install [--dir DIR] [--no-reload] | uninstall [--dir DIR] [--no-reload] | status <binding>
```
One seat's conversation reachable from listed channels of one Discord
@@ -167,12 +169,19 @@ reconciled. `stop` writes `STOP` and signals the running process. `unlock`
writes `STOP` and removes a `run.lock` left by a dead process; it refuses
while the owner is alive with an unverifiable identity or its record cannot be
parsed. `run` refuses a stale lock rather than reclaiming it, and releases a
claim that meets `STOP`. Records
claim that meets `STOP`. `recover` is the supervised pre-start, and
`run --supervised` does it first in the same process: it refuses (exit 3)
while `STOP` is present or the binding is held, clears a lock whose owner
is gone and removes only the `STOP` it wrote for that.
`scripts/discord-service.sh install` renders and writes the systemd user
unit `[email protected]` (one instance per binding, restart on
failure, exit 3 never retried, SIGTERM on `systemctl --user stop`). Records
under `<dataRoot>/discord/<binding>/`: `inbox.jsonl`, `outbox.jsonl`,
`drops.jsonl`, `admissions.jsonl`, `notices.jsonl`, write-once `turns/<id>.json`. Suite:
`scripts/test-discord.sh`.
Exit codes: 0 ok, 1 operation failed, 2 invalid data or configuration, 4
usage. Details: `packages/discord/README.md`.
Exit codes: 0 ok, 1 operation failed, 2 invalid data or configuration, 3
refused by a brake (a supervisor must not retry), 4 usage. Details:
`packages/discord/README.md`.
## Tools (host-side)