On the control node agents are to run as an account that cannot become root
(hq ADR 0266). The runtime keeps running as the operator, so the token, the
identity and the home-scope items go to the agent's home through a helper
started as that account; the licence and the account file follow the move,
what was placed in the operator's home goes once the agent holds the licence,
and the guard refuses every tool of a session running as anyone else,
recording to the journal. An API key is taken only from the agent's home and
only when it is one, here and in the licence manager, so the tool cannot carry
off the runtime's credential. Unchanged where no agent account is named.
mesh/merge-gate pass: builds claude-code → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh, merge-check-typescript.sh): main's version judged it; the change's judges the pull r…
On the nodes where the agent runs as the operator, the home scope wrote the
operator's own ~/.claude, whose rules and skills load in every session, and
any node's tool could be addressed from another (hq issue 340). Take it
only for the serving node, where its home is an agent account's own; never
place a bus item in the operator's home. Ignore the built binary.
A consumer made on 2026-10-06 was handed three hours of raised-and-cleared
conditions at once and the holder said each as new: 20 desktop notifications
in a second. What is said is now decided by the controller's open set and by
an event's own time, never by its arrival; bursts are one message, the
desktop gets warnings at most every 15 min, the cap is said once, and the
first minute after start says only the urgent conditions still open.
Replays of that morning's 96 events are tests. Also drops two committed
binaries. (novox/hq issue 271)
The mesh noticed 48 core failures in six days and told nobody (ADR 0227).
messenger holds the operator-channel seat: it consumes the controller's
condition events and sends them to Telegram and the desktop notifier,
deduplicated by key, reminded once, edited on clear, capped at 20 an hour
with the rest folded, and refusing anything carrying an address, a path or
a secret. mesh-watcher, on a machine other than the control node, sends to
Telegram directly when the self-check heartbeat or the bus goes silent.
Slack comes from the AUR and Toolbox from JetBrains' self-updating tarball,
so neither is declared: the host installs official packages only, and a
pinned archive would fight Toolbox's own updates. Slack's start and the
operator's i3 window rules become one node-display-session contribution,
because Slack's own launch-on-login is a symlink in ~/.config/autostart.
Toolbox keeps its own autostart entry as its one start. The shared
desktop.go header now names all four bundles.
umami is now a whole module, not a manifest: its own API client, its
tools, and its provisioner all live in the module and build on
@novox/mesh-sdk.
- client.ts — umami's API client, moved out of the shared sdk into the
module (ADR 0044); umami's tools and provisioner both import it.
- tools/ — umami_create_site / umami_delete_site on the sdk tool harness
(registerModuleTools); the tool logic and client are the module's.
- provisioner/ — the adapter making umami a provider of the mesh
'analytics' interface: a consumer contributes {domain}, receives
{siteId, snippet, dashboard}. ~20 lines, because the watch/seal/grant
loop is the sdk harness's.
Type-checks against the real mesh-sdk (tsc --noEmit clean); the manifest
parses against internal/catalogue. Remaining to actually run: build and
publish the module + its mesh-provision-umami-analytics image (the
placeholder digest), which is the pipeline's job.
Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF