Why (novox/hq): the operator's direction of 2026-10-07 that a machine's journal for a time window be readable through the seat the module occupies. During the incident of the control node's mail being recreated, reading the controller's journal for a window had no tool, and a person reached for a shell.
What changes (modules/systemd):
node-service-manager.journal takes since / until (RFC 3339, relative like -30min, 2h ago, yesterday, or a local date), priority (0-7 or emerg…debug, mapped to a number) and match (a fixed string, at most 256 bytes, one line). The 2000-line cap and the default of 100 stay. lines is read as a number or as its text, because the seat's schema carries strings.
Nothing reaches a shell or is read as an option: journalctl runs from an argv slice (under sudo -n for the system journal). Every value is held to the forms journalctl reads and passed inside its own option word (--since=-30min, --until=@<epoch>, --priority=4, --unit=<u>, --lines=N). Anything else is refused before anything runs (tested with --merge, -D/, $(id), embedded newlines and similar).
The match is a fixed string, applied in Go, after redaction, so a caller cannot find a secret by matching on it. A match scans the window's last 50 000 lines. The answer says how many were scanned and adds a note when the scan was full.
Secret redaction, added (the journal verb had none). It is copied from docker's docker_logs (issues 268/282) and covers: the unit's own Environment= values named like a secret, passwords in URIs, the word after a password flag, and NAME=value named like a secret. Each one shows as [redacted: <what it was>], with redacted and leak in the answer. If the environment cannot be read, the answer says so and the redaction falls back to shape alone. Lines are cut at 4096 bytes.
systemd_failed becomes the seat's failed, with an optional scope (both managers when absent). The module-private tool and the manifest's tools entry are removed.
Delivery group: this needs novox/mesh-controller on the branch of the same name, which adds failed and the new journal arguments to the seat. The running controller refuses a claim serving failed ("which that seat's protocol does not promise"), so merge the controller first. Locally, check-here against the running controller fails on exactly that line. sh merge-check.sh with the branch's controller passes (module check ok, health count 70 as kept, systemd's tests pass under -race).
Tests:journal_test.go covers the argv shape, the accepted and refused forms, priority, the cap, the fixed-string match after redaction, redaction (also with an unreadable environment), cut lines, Environment parsing, and failed on the seat. The manifest test still holds the served tools equal to the claim.
**Why** (novox/hq): the operator's direction of 2026-10-07 that a machine's journal for a time window be readable through the seat the module occupies. During the incident of the control node's mail being recreated, reading the controller's journal for a window had no tool, and a person reached for a shell.
**What changes** (`modules/systemd`):
- `node-service-manager.journal` takes `since` / `until` (RFC 3339, relative like `-30min`, `2h ago`, `yesterday`, or a local date), `priority` (0-7 or emerg…debug, mapped to a number) and `match` (a fixed string, at most 256 bytes, one line). The 2000-line cap and the default of 100 stay. `lines` is read as a number or as its text, because the seat's schema carries strings.
- **Nothing reaches a shell or is read as an option:** journalctl runs from an argv slice (under `sudo -n` for the system journal). Every value is held to the forms journalctl reads and passed inside its own option word (`--since=-30min`, `--until=@<epoch>`, `--priority=4`, `--unit=<u>`, `--lines=N`). Anything else is refused before anything runs (tested with `--merge`, `-D/`, `$(id)`, embedded newlines and similar).
- **The match is a fixed string, applied in Go, after redaction,** so a caller cannot find a secret by matching on it. A match scans the window's last 50 000 lines. The answer says how many were scanned and adds a note when the scan was full.
- **Secret redaction, added** (the journal verb had none). It is copied from docker's `docker_logs` (issues 268/282) and covers: the unit's own `Environment=` values named like a secret, passwords in URIs, the word after a password flag, and `NAME=value` named like a secret. Each one shows as `[redacted: <what it was>]`, with `redacted` and `leak` in the answer. If the environment cannot be read, the answer says so and the redaction falls back to shape alone. Lines are cut at 4096 bytes.
- `systemd_failed` becomes the seat's `failed`, with an optional scope (both managers when absent). The module-private tool and the manifest's `tools` entry are removed.
**Delivery group:** this needs novox/mesh-controller on the branch of the same name, which adds `failed` and the new journal arguments to the seat. The running controller refuses a claim serving `failed` ("which that seat's protocol does not promise"), so merge the controller first. Locally, `check-here` against the running controller fails on exactly that line. `sh merge-check.sh` with the branch's controller passes (module check ok, health count 70 as kept, systemd's tests pass under `-race`).
**Tests:** `journal_test.go` covers the argv shape, the accepted and refused forms, priority, the cap, the fixed-string match after redaction, redaction (also with an unreadable environment), cut lines, Environment parsing, and `failed` on the seat. The manifest test still holds the served tools equal to the claim.
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-catalog@cb733d1b7cea (merged as 2fa39eac into main, walk plan-17914094762…
An incident is read for the minutes it happened in (the operator's direction
2026-10-07): journal takes since, until, priority and a fixed-string match.
Every value is one word of journalctl's argv, held to the forms journalctl
reads, so nothing reaches a shell or is read as an option under sudo. What
the unit printed of a secret is redacted, as docker_logs does, before the
match is applied, so a match cannot find one.
systemd_failed becomes the seat's failed, with an optional scope. Needs the
controller's seat with these verbs (mesh-controller, same branch): an older
controller refuses a claim serving a verb its seat does not promise.
2026-10-07 17:24 (new) → proposed (announced): novox/mesh-catalog#105's head announced
2026-10-07 17:25 proposed → checked (checked): the verdict names this commit
2026-10-07 17:25 checked → rejected (refused): the gate failed or could not run, or the repository's own check failed
2026-10-07 21:34 rejected → proposed (recheck): mesh-controller #114 (failed is an optional verb of node-service-manager) is live; the refusal was the old controller's
2026-10-07 21:37 proposed → checked (checked): the verdict names this commit
2026-10-07 21:37 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-07 21:40 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-07 21:40 published → held (hold): something holds it for a person: its group's composed check did not pass for the heads that merged, or it merged and no walk was opened for it
2026-10-09 07:31 held → covered (covered): covered: a later merge that contains it was delivered: novox/mesh-catalog@cb733d1b7c (merged as 2fa39eac into main, walk plan-1791409476261602005): systemd
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@66106d93accd` — **covered** since 2026-10-09T07:31:59Z
**Delivery plan** — builds systemd → ace, g14, novox, shanks; no bus step
- tier 0: systemd
- ace: receives systemd
- g14: receives systemd
- novox: receives systemd
- shanks: receives systemd
**Group** `feat/journal-window-on-the-seat`, in order: novox/mesh-controller@13b6fc6d97f3 → novox/mesh-catalog@66106d93accd
- novox/mesh-controller@13b6fc6d97f3 before novox/mesh-catalog@66106d93accd: built by
**Transitions**
- 2026-10-07 17:24 (new) → proposed (announced): novox/mesh-catalog#105's head announced
- 2026-10-07 17:25 proposed → checked (checked): the verdict names this commit
- 2026-10-07 17:25 checked → rejected (refused): the gate failed or could not run, or the repository's own check failed
- 2026-10-07 21:34 rejected → proposed (recheck): mesh-controller #114 (failed is an optional verb of node-service-manager) is live; the refusal was the old controller's
- 2026-10-07 21:37 proposed → checked (checked): the verdict names this commit
- 2026-10-07 21:37 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-07 21:40 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-07 21:40 published → held (hold): something holds it for a person: its group's composed check did not pass for the heads that merged, or it merged and no walk was opened for it
- 2026-10-09 07:31 held → covered (covered): covered: a later merge that contains it was delivered: novox/mesh-catalog@cb733d1b7cea (merged as 2fa39eac into main, walk plan-1791409476261602005): systemd
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
mesh/merge-gate: FAIL — a manifest the change touches fails the module check: systemd claims node-service-manager and says it serves failed, which that seat's protocol does not promise — a claim's serves names the seat's verbs and nothing else (modules: systemd)
mesh/repo-check: FAIL — its merge-check.sh failed: long-running resources without health: 70
Change plan — builds systemd → ace, g14, novox, shanks; no bus step
tier 0: systemd
ace: receives systemd
g14: receives systemd
novox: receives systemd
shanks: receives systemd
Run by the build seat on novox as build-1791393893961792301 (builds --log build-1791393893961792301).
--- the gate: systemd
mesh-controller: 1 problem(s) in 1 manifest(s)
systemd claims node-service-manager and says it serves failed, which that seat's protocol does not promise — a claim's serves names the seat's verbs and nothing else
systemd: ok
long-running resources without health: 0
--- the same manifests on main
systemd: ok, 1 tool(s)
long-running resources without health: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
--- its merge-check.sh (go toolchain)
mesh-controller: 1 problem(s) in 113 manifest(s)
systemd claims node-service-manager and says it serves failed, which that seat's protocol does not promise — a claim's serves names the seat's verbs and nothing else
adwaita: ok, 4 tool(s)
asus-zephyrus-g14: ok, 11 tool(s); WARNING: asusd, supergfxd, upower stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
audit-logger: ok, keeps trail (valuable), spool (valuable)
avahi: ok, 4 tool(s); WARNING: daemon stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
baserow: ok, keeps data (valuable), ready: server by its image's own check every 30s
blueman: ok, 3 tool(s)
bluetooth: ok, 9 tool(s); WARNING: daemon stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
build-agent: ok, keeps workspace (cache); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
ca-trust: ok; WARNING: trust stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
claude-code: ok, 35 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable)
claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings
clipmenu: ok, 3 tool(s)
confluence: ok
cups: ok, 7 tool(s); WARNING: socket, scheduler stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
dbus: ok, 5 tool(s); WARNING: system-bus stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
de-spiegel: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
distribution: ok, keeps registry (rebuildable); WARNING: store stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
dmenu: ok, 2 tool(s)
dnsmasq: ok; WARNING: service stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
docker: ok, 20 tool(s); WARNING: socket, runtime, prune stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
docker-compose: ok, 9 tool(s)
dunst: ok, 5 tool(s)
fail2ban: ok, 1 tool(s); WARNING: run stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
feh: ok, 2 tool(s)
flatpak: ok, 11 tool(s)
fonts: ok, 6 tool(s)
forticlient: ok, 3 tool(s); WARNING: scheduler stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
gitea: ok, keeps data (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
gitlab: ok
gnome-keyring: ok, 4 tool(s)
grafana: ok, keeps data (valuable), ready: server by http / on web every 30s
hello-web: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
home-assistant: ok, keeps config (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
hostname: ok
i3: ok, 10 tool(s)
i3status-rust: ok, 4 tool(s)
icecast: ok, keeps logs (cache); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
influxdb: ok, keeps data (valuable), config (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
invoicing: ok; WARNING: app, api stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
jira: ok
keycloak: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
lab: ok, keeps work (cache)
lemurs: ok, 2 tool(s); WARNING: service stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
letta: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
local-model-consumer: ok
localization: ok, 4 tool(s)
logrotate: ok, 7 tool(s); WARNING: timer stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
mailu: ok, keeps mail (valuable), dkim (valuable), data (valuable), dav (valuable), webmail (valuable), queue (valuable), filter (rebuildable), certs (rebuildable), automx (rebuildable), fetchmail (rebuildable), clamav (cache), redis (cache), ready: resolver by its image's own check every 30s; admin by its image's own check every 30s; imap by its image's own check every 30s; smtp by its image's own check every 30s; antispam by its image's own check every 30s; webmail by its image's own check every 30s; webdav by its image's own check every 30s; fetchmail by its image's own check every 30s; front by its image's own check every 30s; WARNING: redis, antivirus, automx stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
marrytts: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
matrix: ok, keeps db (valuable), ready: element by its image's own check every 30s; WARNING: homeserver stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
memory-pressure: ok, 6 tool(s); WARNING: oomd stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
mesh-catalog: ok
mesh-delivery: ok, 1 tool(s), invokes seat:mesh-controller.delivery-plan, seat:mesh-controller.delivery-order, seat:mesh-controller.delivery-check, seat:mesh-controller.deliver, seat:mesh-controller.delivery-stop, seat:mesh-controller.delivery-walks, gitea.gitea_note_append, gitea.gitea_delivery_view, gitea.gitea_commit_status, keeps state deliveries, groups
mesh-vault: ok, keeps state (valuable), ledger (valuable), root (valuable)
mesh-watcher: ok, 4 tool(s), invokes mesh-watcher.watcher_ping, seat:mesh-controller.seats
messenger: ok, 4 tool(s), invokes seat:node-notifier.send, seat:mesh-controller.conditions, keeps state open, sent
minio: ok, keeps data (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
model-usage: ok, keeps state (cache), spool (valuable)
mongodb: ok, keeps data (valuable), dumps (rebuildable), ready: server by tcp on database every 30s
mosquitto: ok, keeps data (rebuildable), ready: server by tcp on mqtt every 30s
mssql: ok, keeps data (valuable), dumps (rebuildable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
n8n: ok, keeps data (valuable), cache (cache); WARNING: server, cache-server, browser stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
nats: ok, 8 tool(s), keeps jetstream (valuable), snapshots (rebuildable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
netcheck: ok, 3 tool(s)
networkmanager: ok
nextcloud: ok, keeps html (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
nextcloud-client: ok, 4 tool(s)
nftables: ok, 1 tool(s); WARNING: load stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
nm-applet: ok, 3 tool(s)
node-env: ok
nodered: ok, keeps data (valuable), ready: server by its image's own check every 30s
ollama: ok, keeps models (rebuildable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
only-office: ok, keeps data (rebuildable), lib (rebuildable), db (rebuildable), fonts (rebuildable), logs (cache), rabbitmq (cache), redis (cache); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
openai-consumer: ok
openrazer: ok, 3 tool(s)
pacman: ok, 15 tool(s); WARNING: mirror-refresh, cache-cleaning stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
photos-eef: ok; WARNING: client stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
photos-filip: ok; WARNING: client stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
picom: ok, 4 tool(s)
polychromatic: ok, 3 tool(s)
postgres: ok, keeps store (valuable), dumps (rebuildable), ready: server by tcp on database every 30s
power: ok, 5 tool(s); WARNING: after-boot, before-shutdown stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
powerlevel10k: ok
records: ok, 5 tool(s), keeps checkout (rebuildable)
redis: ok, keeps data (cache), ready: server by tcp on cache every 30s
restic: ok, keeps repository (rebuildable), state (cache)
rofi: ok, 3 tool(s)
route-adapter: ok
route-proxy: ok, keeps acme (rebuildable), ca (cache); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
screen-lock: ok, 3 tool(s)
searxng: ok, keeps valkey (cache); WARNING: cache, server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
showcase: ok; WARNING: server, tools stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
slack: ok, 4 tool(s)
snapd: ok, 10 tool(s)
ssh-client: ok, 8 tool(s), keeps ssh (valuable)
sshd: ok; WARNING: run stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
step-ca: ok, keeps home (valuable), ready: server by its image's own check every 30s
sudo: ok, 3 tool(s)
supabase: ok, keeps db (valuable), dumps (rebuildable), storage (valuable), functions (valuable), db-config (rebuildable), ready: db by its image's own check every 30s; kong by its image's own check every 30s; meta by its image's own check every 30s; studio by its image's own check every 30s; WARNING: vector, analytics, auth, rest, realtime, imgproxy, storage-api, edge-functions, pooler stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
systemd: ok
systemd-networkd: ok
time-sync: ok, 3 tool(s); WARNING: daemon stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
triggerhappy: ok, 4 tool(s); WARNING: service stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
umami: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
unifi: ok, keeps data (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
website: ok, ready: server by http / on web every 30s
xclip: ok, 4 tool(s)
xdg: ok, 5 tool(s)
xorg: ok, 8 tool(s)
xterm: ok, 2 tool(s)
zsh: ok, 1 tool(s)
zsh-autosuggestions: ok
zsh-syntax-highlighting: ok
long-running resources without health: 70
**Merge check** at `66106d93`
- `mesh/merge-gate`: **FAIL** — a manifest the change touches fails the module check: systemd claims node-service-manager and says it serves failed, which that seat's protocol does not promise — a claim's serves names the seat's verbs and nothing else (modules: systemd)
- `mesh/repo-check`: **FAIL** — its merge-check.sh failed: long-running resources without health: 70
**Change plan** — builds systemd → ace, g14, novox, shanks; no bus step
- tier 0: systemd
- ace: receives systemd
- g14: receives systemd
- novox: receives systemd
- shanks: receives systemd
Run by the build seat on novox as `build-1791393893961792301` (`builds --log build-1791393893961792301`).
```
--- the gate: systemd
mesh-controller: 1 problem(s) in 1 manifest(s)
systemd claims node-service-manager and says it serves failed, which that seat's protocol does not promise — a claim's serves names the seat's verbs and nothing else
systemd: ok
long-running resources without health: 0
--- the same manifests on main
systemd: ok, 1 tool(s)
long-running resources without health: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
--- its merge-check.sh (go toolchain)
mesh-controller: 1 problem(s) in 113 manifest(s)
systemd claims node-service-manager and says it serves failed, which that seat's protocol does not promise — a claim's serves names the seat's verbs and nothing else
adwaita: ok, 4 tool(s)
asus-zephyrus-g14: ok, 11 tool(s); WARNING: asusd, supergfxd, upower stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
audit-logger: ok, keeps trail (valuable), spool (valuable)
avahi: ok, 4 tool(s); WARNING: daemon stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
baserow: ok, keeps data (valuable), ready: server by its image's own check every 30s
blueman: ok, 3 tool(s)
bluetooth: ok, 9 tool(s); WARNING: daemon stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
build-agent: ok, keeps workspace (cache); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
ca-trust: ok; WARNING: trust stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
claude-code: ok, 35 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable)
claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings
clipmenu: ok, 3 tool(s)
confluence: ok
cups: ok, 7 tool(s); WARNING: socket, scheduler stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
dbus: ok, 5 tool(s); WARNING: system-bus stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
de-spiegel: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
distribution: ok, keeps registry (rebuildable); WARNING: store stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
dmenu: ok, 2 tool(s)
dnsmasq: ok; WARNING: service stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
docker: ok, 20 tool(s); WARNING: socket, runtime, prune stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
docker-compose: ok, 9 tool(s)
dunst: ok, 5 tool(s)
fail2ban: ok, 1 tool(s); WARNING: run stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
feh: ok, 2 tool(s)
flatpak: ok, 11 tool(s)
fonts: ok, 6 tool(s)
forticlient: ok, 3 tool(s); WARNING: scheduler stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
gitea: ok, keeps data (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
gitlab: ok
gnome-keyring: ok, 4 tool(s)
grafana: ok, keeps data (valuable), ready: server by http / on web every 30s
hello-web: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
home-assistant: ok, keeps config (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
hostname: ok
i3: ok, 10 tool(s)
i3status-rust: ok, 4 tool(s)
icecast: ok, keeps logs (cache); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
influxdb: ok, keeps data (valuable), config (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
invoicing: ok; WARNING: app, api stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
jira: ok
keycloak: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
lab: ok, keeps work (cache)
lemurs: ok, 2 tool(s); WARNING: service stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
letta: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
local-model-consumer: ok
localization: ok, 4 tool(s)
logrotate: ok, 7 tool(s); WARNING: timer stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
mailu: ok, keeps mail (valuable), dkim (valuable), data (valuable), dav (valuable), webmail (valuable), queue (valuable), filter (rebuildable), certs (rebuildable), automx (rebuildable), fetchmail (rebuildable), clamav (cache), redis (cache), ready: resolver by its image's own check every 30s; admin by its image's own check every 30s; imap by its image's own check every 30s; smtp by its image's own check every 30s; antispam by its image's own check every 30s; webmail by its image's own check every 30s; webdav by its image's own check every 30s; fetchmail by its image's own check every 30s; front by its image's own check every 30s; WARNING: redis, antivirus, automx stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
marrytts: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
matrix: ok, keeps db (valuable), ready: element by its image's own check every 30s; WARNING: homeserver stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
memory-pressure: ok, 6 tool(s); WARNING: oomd stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
mesh-catalog: ok
mesh-delivery: ok, 1 tool(s), invokes seat:mesh-controller.delivery-plan, seat:mesh-controller.delivery-order, seat:mesh-controller.delivery-check, seat:mesh-controller.deliver, seat:mesh-controller.delivery-stop, seat:mesh-controller.delivery-walks, gitea.gitea_note_append, gitea.gitea_delivery_view, gitea.gitea_commit_status, keeps state deliveries, groups
mesh-vault: ok, keeps state (valuable), ledger (valuable), root (valuable)
mesh-watcher: ok, 4 tool(s), invokes mesh-watcher.watcher_ping, seat:mesh-controller.seats
messenger: ok, 4 tool(s), invokes seat:node-notifier.send, seat:mesh-controller.conditions, keeps state open, sent
minio: ok, keeps data (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
model-usage: ok, keeps state (cache), spool (valuable)
mongodb: ok, keeps data (valuable), dumps (rebuildable), ready: server by tcp on database every 30s
mosquitto: ok, keeps data (rebuildable), ready: server by tcp on mqtt every 30s
mssql: ok, keeps data (valuable), dumps (rebuildable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
n8n: ok, keeps data (valuable), cache (cache); WARNING: server, cache-server, browser stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
nats: ok, 8 tool(s), keeps jetstream (valuable), snapshots (rebuildable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
netcheck: ok, 3 tool(s)
networkmanager: ok
nextcloud: ok, keeps html (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
nextcloud-client: ok, 4 tool(s)
nftables: ok, 1 tool(s); WARNING: load stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
nm-applet: ok, 3 tool(s)
node-env: ok
nodered: ok, keeps data (valuable), ready: server by its image's own check every 30s
ollama: ok, keeps models (rebuildable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
only-office: ok, keeps data (rebuildable), lib (rebuildable), db (rebuildable), fonts (rebuildable), logs (cache), rabbitmq (cache), redis (cache); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
openai-consumer: ok
openrazer: ok, 3 tool(s)
pacman: ok, 15 tool(s); WARNING: mirror-refresh, cache-cleaning stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
photos-eef: ok; WARNING: client stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
photos-filip: ok; WARNING: client stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
picom: ok, 4 tool(s)
polychromatic: ok, 3 tool(s)
postgres: ok, keeps store (valuable), dumps (rebuildable), ready: server by tcp on database every 30s
power: ok, 5 tool(s); WARNING: after-boot, before-shutdown stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
powerlevel10k: ok
records: ok, 5 tool(s), keeps checkout (rebuildable)
redis: ok, keeps data (cache), ready: server by tcp on cache every 30s
restic: ok, keeps repository (rebuildable), state (cache)
rofi: ok, 3 tool(s)
route-adapter: ok
route-proxy: ok, keeps acme (rebuildable), ca (cache); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
screen-lock: ok, 3 tool(s)
searxng: ok, keeps valkey (cache); WARNING: cache, server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
showcase: ok; WARNING: server, tools stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
slack: ok, 4 tool(s)
snapd: ok, 10 tool(s)
ssh-client: ok, 8 tool(s), keeps ssh (valuable)
sshd: ok; WARNING: run stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
step-ca: ok, keeps home (valuable), ready: server by its image's own check every 30s
sudo: ok, 3 tool(s)
supabase: ok, keeps db (valuable), dumps (rebuildable), storage (valuable), functions (valuable), db-config (rebuildable), ready: db by its image's own check every 30s; kong by its image's own check every 30s; meta by its image's own check every 30s; studio by its image's own check every 30s; WARNING: vector, analytics, auth, rest, realtime, imgproxy, storage-api, edge-functions, pooler stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
systemd: ok
systemd-networkd: ok
time-sync: ok, 3 tool(s); WARNING: daemon stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
triggerhappy: ok, 4 tool(s); WARNING: service stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
umami: ok; WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
unifi: ok, keeps data (valuable); WARNING: server stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
website: ok, ready: server by http / on web every 30s
xclip: ok, 4 tool(s)
xdg: ok, 5 tool(s)
xorg: ok, 8 tool(s)
xterm: ok, 2 tool(s)
zsh: ok, 1 tool(s)
zsh-autosuggestions: ok
zsh-syntax-highlighting: ok
long-running resources without health: 70
```
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: systemd)
mesh/repo-check: PASS — its merge-check.sh passed
Delivery plan — builds systemd → ace, g14, novox, shanks; no bus step
tier 0: systemd
ace: receives systemd
g14: receives systemd
novox: receives systemd
shanks: receives systemd
Run by the build seat on novox as build-1791408867233299578 (builds --log build-1791408867233299578).
--- the gate: systemd
systemd: ok
long-running resources without health: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T21:23:22Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-07T21:23:22Z
modules the change moves:
- systemd (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 1 module(s) in 1 tier(s): systemd
--- its merge-check.sh (go toolchain)
long-running resources without health: 70, as kept
testing modules/systemd
ok systemd-tools/cmd/systemd-tools 1.019s
**Merge check** at `66106d93`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: systemd)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds systemd → ace, g14, novox, shanks; no bus step
- tier 0: systemd
- ace: receives systemd
- g14: receives systemd
- novox: receives systemd
- shanks: receives systemd
Run by the build seat on novox as `build-1791408867233299578` (`builds --log build-1791408867233299578`).
```
--- the gate: systemd
systemd: ok
long-running resources without health: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T21:23:22Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-07T21:23:22Z
modules the change moves:
- systemd (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 1 module(s) in 1 tier(s): systemd
--- its merge-check.sh (go toolchain)
long-running resources without health: 70, as kept
testing modules/systemd
ok systemd-tools/cmd/systemd-tools 1.019s
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why (novox/hq): the operator's direction of 2026-10-07 that a machine's journal for a time window be readable through the seat the module occupies. During the incident of the control node's mail being recreated, reading the controller's journal for a window had no tool, and a person reached for a shell.
What changes (
modules/systemd):node-service-manager.journaltakessince/until(RFC 3339, relative like-30min,2h ago,yesterday, or a local date),priority(0-7 or emerg…debug, mapped to a number) andmatch(a fixed string, at most 256 bytes, one line). The 2000-line cap and the default of 100 stay.linesis read as a number or as its text, because the seat's schema carries strings.sudo -nfor the system journal). Every value is held to the forms journalctl reads and passed inside its own option word (--since=-30min,--until=@<epoch>,--priority=4,--unit=<u>,--lines=N). Anything else is refused before anything runs (tested with--merge,-D/,$(id), embedded newlines and similar).docker_logs(issues 268/282) and covers: the unit's ownEnvironment=values named like a secret, passwords in URIs, the word after a password flag, andNAME=valuenamed like a secret. Each one shows as[redacted: <what it was>], withredactedandleakin the answer. If the environment cannot be read, the answer says so and the redaction falls back to shape alone. Lines are cut at 4096 bytes.systemd_failedbecomes the seat'sfailed, with an optional scope (both managers when absent). The module-private tool and the manifest'stoolsentry are removed.Delivery group: this needs novox/mesh-controller on the branch of the same name, which adds
failedand the new journal arguments to the seat. The running controller refuses a claim servingfailed("which that seat's protocol does not promise"), so merge the controller first. Locally,check-hereagainst the running controller fails on exactly that line.sh merge-check.shwith the branch's controller passes (module check ok, health count 70 as kept, systemd's tests pass under-race).Tests:
journal_test.gocovers the argv shape, the accepted and refused forms, priority, the cap, the fixed-string match after redaction, redaction (also with an unreadable environment), cut lines, Environment parsing, andfailedon the seat. The manifest test still holds the served tools equal to the claim.Delivery
novox/mesh-catalog@66106d93accd— covered since 2026-10-09T07:31:59ZDelivery plan — builds systemd → ace, g14, novox, shanks; no bus step
Group
feat/journal-window-on-the-seat, in order: novox/mesh-controller@13b6fc6d97 → novox/mesh-catalog@66106d93acTransitions
2fa39eacinto main, walk plan-1791409476261602005): systemdThe commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
66106d93mesh/merge-gate: FAIL — a manifest the change touches fails the module check: systemd claims node-service-manager and says it serves failed, which that seat's protocol does not promise — a claim's serves names the seat's verbs and nothing else (modules: systemd)mesh/repo-check: FAIL — its merge-check.sh failed: long-running resources without health: 70Change plan — builds systemd → ace, g14, novox, shanks; no bus step
Run by the build seat on novox as
build-1791393893961792301(builds --log build-1791393893961792301).Merge check at
66106d93mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: systemd)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds systemd → ace, g14, novox, shanks; no bus step
Run by the build seat on novox as
build-1791408867233299578(builds --log build-1791408867233299578).