{ hyperhive, pkgs, lib, config, ... }: let cfg = config.my.constellation-swarm; adminUsers = [ "muede" ]; otelCredential = "/etc/hyperhive/otel-cred"; runtimeDirName = "claude-otel"; in { options.my.constellation-swarm = { enable = lib.mkEnableOption "hyperhive / constellation swarm"; hiveName = lib.mkOption { type = lib.types.str; }; userOtelHeaderDir = lib.mkOption { type = lib.types.str; default = "/run/${runtimeDirName}"; readOnly = true; description = '' Directory holding the per-admin copies of the hive's OTLP auth header, one 0400 file per user named after them. Read-only so the home-manager side (homeConfigurations/muede/claude.nix) can point at it via `osConfig` instead of repeating the path. ''; }; }; imports = [ hyperhive.nixosModules.default ]; config.services.hyperhive = lib.mkIf cfg.enable { enable = true; swarmName = "constellation"; ruthless = true; domain = "${cfg.hiveName}.darkest.space"; hiveName = cfg.hiveName; matrix.enable = true; forge.ci.enable = true; gateway = { localHostsEntry = true; openFirewall = true; }; swarm.peers = { "umbra.darkest.space" = { certFingerprint = "sha256:ae68d089e0155978fff7a9963bfb1e123ed645e7c9f93a4b4bb3e278c5f32a27"; }; "pr1ma.darkest.space" = { certFingerprint = "sha256:63e026f8682d6b5496f3eec99edb2ef62a8999c6d767228051e6e057f8cd90c6"; }; }; otel = { enable = true; endpoint = "https://exponentials.vibec0re.mov/otel"; headersCredential = otelCredential; }; c0re = { inherit adminUsers; agentMemoryMax = "6G"; claudeCodePackage = pkgs.unstable.claude-code; }; }; # `otelCredential` is root:root 0600, so the interactive `claude` an admin # runs as themselves cannot read it — only the hive's agent units can, via # LoadCredential. Hand each admin their own copy so the wrapper in # homeConfigurations/muede/claude.nix can pick it up. It lands in /run # (tmpfs) rather than the nix store because the store is world-readable, and # rather than /etc because the header should not outlive a reboot. config.systemd.services.claude-otel-user-header = lib.mkIf cfg.enable { description = "Expose the hive OTLP auth header to interactive admin users"; wantedBy = [ "multi-user.target" ]; unitConfig.ConditionPathExists = otelCredential; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; RuntimeDirectory = runtimeDirName; # Traversable by everyone; the per-user files inside are the 0400 part. RuntimeDirectoryMode = "0755"; ExecStart = pkgs.writeShellScript "claude-otel-user-header" '' set -eu umask 077 for user in ${lib.escapeShellArgs adminUsers}; do ${pkgs.coreutils}/bin/install -m0400 -o "$user" -g root \ ${lib.escapeShellArg otelCredential} "$RUNTIME_DIRECTORY/$user" done ''; }; }; }