# `checks.module-eval-agent-matrix` — see ./lib.nix for the shared # rationale (why this suite exists, naming convention, "evaluates # not executes"). { pkgs, lib, self, nixosSystem, }: let inherit (import ./lib.nix { inherit pkgs lib self nixosSystem ; }) agent runGroup ; # Matrix's enable signal, which is the account set itself — there is no # `matrix.enable` option left to read. Three arms, because the property has # three distinct shapes and only one of them is the common case: # # - a homeserver URL, which is what the module turns into a `main` account; # - neither URL nor operator account, the state that replaced # `matrix.enable = false`. ⚠️ **This is the arm that matters.** `main` is # declared by the module itself, so "any account declared" would be # trivially true — and matrix would render for every agent in every hive — # the moment that declaration stops being gated on the URL. Nothing else in # this suite would notice; # - an operator account carrying its own homeserver and no hive one, which is # matrix on with no `main` at all. agentMatrix = agent { matrix.url = "https://chat.t.local"; }; agentNoMatrix = agent { }; agentMatrixExternalOnly = agent { matrixAccounts.ccc = { tokenFile = "/agents/a1/state/matrix-token-ccc"; sessionDir = "/agents/a1/state/matrix-sdk-state-ccc"; homeserver = "https://matrix.example.invalid"; }; }; cases = [ { # A homeserver URL is the whole input: from it the module derives the # hive-internal `main` account, and from a non-empty account set the three # things that used to hang off `matrix.enable`. name = "an agent with a homeserver gets a main account and the matrix units"; ok = let a = agentMatrix.services.hyperhive.agent.matrixAccounts; in lib.attrNames a == [ "main" ] && a.main.tokenFile == "/agents/a1/state/matrix-token" && a.main.homeserver == "https://chat.t.local" && agentMatrix.systemd.services ? hive-matrix-daemon && agentMatrix.systemd.paths ? hive-matrix-daemon && agentMatrix.services.hyperhive.agent.extraMcpServers ? matrix; } { # The absence arm, and the reason the enable signal is not vacuous. An # agent the hive gave no homeserver, whose operator declared nothing, must # come out with an EMPTY account set — not a `main` that can never log in # — and therefore with none of the three. Assert the emptiness itself and # not just the units: it is the account set that is load-bearing now, and # a `main` sneaking back in is the regression this case exists to name. name = "an agent with no homeserver and no declared account gets no matrix at all"; ok = agentNoMatrix.services.hyperhive.agent.matrixAccounts == { } && !(agentNoMatrix.systemd.services ? hive-matrix-daemon) && !(agentNoMatrix.systemd.paths ? hive-matrix-daemon) && !(agentNoMatrix.services.hyperhive.agent.extraMcpServers ? matrix); } { # Matrix without a hive homeserver: one operator account, its own # homeserver, no `main`. Under the deleted `matrix.enable` this config was # an assertion failure ("extras require enable") even though every account # in it was complete; the account set being the signal is what makes it # expressible, and the serialized env var is where that has to show up. name = "an external-only account enables matrix with no main entry"; ok = let accts = agentMatrixExternalOnly.services.hyperhive.agent.matrixAccounts; env = agentMatrixExternalOnly.systemd.services.hive-matrix-daemon.environment; in lib.attrNames accts == [ "ccc" ] && !(accts ? main) && builtins.fromJSON env.HIVE_MATRIX_ACCOUNTS == [ { name = "ccc"; token_file = "/agents/a1/state/matrix-token-ccc"; state_dir = "/agents/a1/state/matrix-sdk-state-ccc"; homeserver = "https://matrix.example.invalid"; } ] # No hive homeserver, so nothing may claim one. && !(env ? HIVE_MATRIX_URL); } ]; in runGroup "agent-matrix" cases