matrix: drop the per-agent matrix.enable; accounts are the enable signal

`services.hyperhive.agent.matrix.enable` was a second source of truth for
a fact the account set already carried: after ①-③ the hive-internal
`main` account is an ordinary `matrixAccounts` entry, so "does this agent
have matrix" and "does this agent have an account" were the same question
asked twice, with the boolean able to disagree.

The option is gone and a non-empty `matrixAccounts` now gates the daemon
unit, its token path-watcher and the injected `extraMcpServers.matrix`
entry.

That is only a real condition because `matrixAccounts.main` is itself
gated: it is declared when `matrix.url != null`, never unconditionally. A
`main` with no homeserver is an account the daemon can never log in as,
so declaring one always would have made the signal trivially true and
turned matrix on for every agent in every hive. With the URL gate, the
empty set is reachable exactly for an agent the hive gave no homeserver
and whose operator declared no account of its own — the state the old
`enable = false` expressed.

Assertions: "extras require enable" is deleted, having become the
definition of the thing it checked (an external-only account with its own
homeserver is now rendered rather than rejected). `main.tokenFile` stays
pinned, re-guarded on `? main` instead of on the flag, since `main` is
absent whenever the URL is null and an unguarded index would throw there.

Both spellings of the option get `mkRemovedOptionModule`, following
../host-modules/deploy.nix's registrationTokenFile pair rather than a
silent delete: the definition whose meaning changes is `false`, and left
undeclared it would be ignored and hand the agent the tools its operator
turned off. Failing the eval with the replacement spelling is the only
outcome that cannot.

module-eval gains the three arms — URL, nothing, external-only — with the
middle one carrying why it exists: it is the only thing in the suite that
would notice `main` becoming unconditional again.

Refs #4475
This commit is contained in:
atlas 2026-09-18 09:42:23 +02:00
commit 99b141f5f2
7 changed files with 254 additions and 92 deletions

View file

@ -546,9 +546,15 @@ the body + marker check at that point.
process per agent. Serves its MCP tools directly over
streamable-http (`services.hyperhive.agent.mcp.matrixHttpPort`, no stdio bridge —
same shape as `hive-bash-daemon`), emits hyperhive wake signals
on incoming room events via `/run/hive/mcp.sock`. Conditional on
`services.hyperhive.agent.matrix.enable` (which both the daemon AND the
autoinjected `extraMcpServers.matrix` entry read).
on incoming room events via `/run/hive/mcp.sock`. Conditional on the
agent having at least one `services.hyperhive.agent.matrixAccounts`
entry — there is no separate enable switch, and the same condition gates
the daemon, its path watcher AND the autoinjected
`extraMcpServers.matrix` entry. The module declares the hive-internal
`main` entry whenever `services.hyperhive.agent.matrix.url` is non-null,
so on a real hive (where hive-c0re renders that URL per agent) every
agent has one; a `null` URL with no operator-declared account is the
"this agent has no matrix" state.
**First-boot ordering**: hive-c0re provisions the matrix token AFTER
agent containers come up. Without the path-trigger sibling