diff --git a/docs/agent-lifecycle/persistence.md b/docs/agent-lifecycle/persistence.md index 08eb802f..c28f7b15 100644 --- a/docs/agent-lifecycle/persistence.md +++ b/docs/agent-lifecycle/persistence.md @@ -578,18 +578,20 @@ agent has one; a `null` URL with no operator-declared account is the "this agent has no matrix" state. **First-boot ordering**: a token can arrive after the container comes -up — a file the hive delivers, or a token the swarm mints into the store. +up — a declared token file, or a token the swarm mints into the store. Without the path-trigger sibling (`systemd.paths.hive-matrix-daemon`, `PathExistsGlob = /matrix-token*` — the trailing `*` also catches -a secondary multi-account token like `matrix-token-ccc`), the daemon +a declared secondary token file like `matrix-token-ccc`), the daemon would exit 0 quietly the first time it ran and the MCP would have no daemon until the next restart. The `.path` unit makes the appearance of the token re-fire the service so the daemon comes alive in the same boot cycle as provisioning. A token in the store changes no file, so a store-backed agent also gets a timer that restarts the daemon five minutes after it last -exited. The same token watcher also drives avatar setting: on a +exited. A running daemon re-lists its linked accounts in the store +every two minutes and, when the set changed, exits with status +75, which the unit's `RestartForceExitStatus` restarts. The same token watcher also drives avatar setting: on a restart the daemon re-runs each account's bring-up, which sets the avatar (see below). diff --git a/docs/tools/matrix.md b/docs/tools/matrix.md index 14f5236d..5cd8eeeb 100644 --- a/docs/tools/matrix.md +++ b/docs/tools/matrix.md @@ -104,8 +104,15 @@ evaluation with a message saying so. Declaring an external account with its own `homeserver` is enough on its own; a hive homeserver isn't required. +An account linked from the swarm UI needs no entry in this map. +`swarm-controller` stores it at `swarm/agents//matrix/`. +The daemon lists that directory under the agent's own certificate at +start and every two minutes, and restarts itself when the set of linked +accounts changes. A declared entry of the same name wins. + Every matrix tool above takes an optional `account` parameter (a name -from this map) to act as that identity instead of the primary one. +from this map, or a linked account's) to act as that identity instead +of the primary one. Declaring an extra account also changes what the agent *receives*: wake bodies and invite todos gain an `[acct:]` prefix — see diff --git a/docs/trust-boundary/security.md b/docs/trust-boundary/security.md index cf843b05..b14bdc62 100644 --- a/docs/trust-boundary/security.md +++ b/docs/trust-boundary/security.md @@ -295,11 +295,10 @@ known operations; there is no arbitrary command pass-through: | `RemoveServiceDropin` | remove `container@.service.d/` drop-in on destroy | | `DaemonReload` | `systemctl daemon-reload` | | `RunForgeAdmin` | `nixos-container run hive-forge -- runuser -u forgejo -- forgejo admin ` | -| `WriteAgentMatrixToken` | write `0600` credential file into agent state dir | | `ControlInfraContainer` | `systemctl container@.service` — the `InfraContainer` enum is the allowlist, and serde rejects unknown names at the wire boundary (`hive-c0re` has no variant, so no request can name it) | | `SyncAgentTmpfiles` | legacy: unlink `/etc/tmpfiles.d/hyperhive-agents.conf` and return `Ok`; kept one release for an older hive-c0re | | `SetAgentPaused` | create / remove the `//harness/paused` marker that parks an agent's turn loop | -| `WriteAgentGithubToken` | write `0600` `github-token` into agent state dir (same semantics as the forge/matrix token writes) | +| `WriteAgentGithubToken` | write `0600` `github-token` into agent state dir (same semantics as the extra-forge account writes) | | `WriteAgentExtraForgeAccount` / `DeleteAgentExtraForgeAccount` | write / remove `forge-