refactor: move hive-c0re options to hyperhive namespace (#612)

- Move options.services.hive-c0re → options.hyperhive.c0re
- Add options.hyperhive.enable to auto-enable c0re + subsystems
- Add deprecation alias for services.hive-c0re.enable (backward compat)
- Update doc references in README, flake.nix, docs, harness-base.nix
- Simplifies config: 'hyperhive.enable = true' now enables everything

Existing operator configs using services.hive-c0re.enable will
continue to work but emit a deprecation warning. Aligns the option
namespace with the existing hyperhive.* family (matrix, forge, domain).

fixes #612
This commit is contained in:
atlas 2026-05-29 23:23:58 +02:00 committed by Mara
commit 32148179e6
5 changed files with 111 additions and 82 deletions

View file

@ -13,7 +13,7 @@
...
}:
let
cfg = config.services.hive-c0re;
cfg = config.hyperhive.c0re;
in
{
# The forge is part of the standard install — hive-c0re mirrors
@ -26,6 +26,10 @@ in
./hive-matrix.nix
];
# Top-level hyperhive enable flag. When true, automatically enables
# hive-c0re and hyperhive subsystems.
options.hyperhive.enable = lib.mkEnableOption "hyperhive the agent swarm coordinator";
# Top-level option shared by any hyperhive subsystem that needs a
# stable hostname (matrix server_name today, forge ROOT_URL likely
# next). Type is nullable + default null so existing operator
@ -46,8 +50,23 @@ in
'';
};
options.services.hive-c0re = {
enable = lib.mkEnableOption "hive-c0re hyperhive coordinator daemon";
# Deprecated alias for backward compatibility. Remove in v0.2.
options.services.hive-c0re.enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
**DEPRECATED** (as of #612). Use `hyperhive.enable = true` or
`hyperhive.c0re.enable = true` instead. This option is maintained
for backward compatibility and will be removed in a future release.
'';
};
options.hyperhive.c0re = {
enable = lib.mkOption {
type = lib.types.bool;
default = config.hyperhive.enable;
description = "Enable hive-c0re coordinator daemon (auto-enabled by hyperhive.enable).";
};
package = lib.mkOption {
type = lib.types.package;
default = hyperhivePackage pkgs.stdenv.hostPlatform.system;
@ -166,77 +185,87 @@ in
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [
cfg.package
pkgs.git
];
# Pull the per-container toplevels into the host system closure
# (#97). `system.extraDependencies` adds paths to the system build
# without referencing them at runtime — nixos-rebuild fetches /
# builds them, they end up in /nix/store, and the first
# nixos-container update + start for an agent has nothing left to
# do. Gated because the closure is sizeable and pinned to x86_64.
system.extraDependencies = lib.optionals cfg.preBuildAgentTemplates [
agentBaseToplevel
managerToplevel
];
# Dashboard + per-container web UIs share the host's network namespace and
# need their ports reachable. Dashboard: `cfg.dashboardPort` (default 7000).
# Manager: 8000. Sub-agents: 8100..8999 (deterministic hash; see
# `lifecycle::agent_web_port`).
networking.firewall.allowedTCPPorts = [
cfg.dashboardPort
8000
];
networking.firewall.allowedTCPPortRanges = [
{
from = 8100;
to = 8999;
}
];
systemd.services.hive-c0re = {
description = "hyperhive coordinator daemon";
wantedBy = [ "multi-user.target" ];
path = [
pkgs.git
"/run/current-system/sw"
config = lib.mkMerge [
# Backward-compatibility redirect for deprecated services.hive-c0re.enable
(lib.mkIf config.services.hive-c0re.enable {
hyperhive.c0re.enable = true;
warnings = [
"services.hive-c0re.enable is deprecated (as of #612). Use 'hyperhive.enable = true' or 'hyperhive.c0re.enable = true' instead."
];
environment = {
HYPERHIVE_GIT = "${pkgs.git}/bin/git";
# Path to the dashboard static dist. The hive-c0re axum router
# serves this via `tower_http::ServeDir` for any path it doesn't
# match against an API/action route.
HIVE_STATIC_DIR = "${cfg.frontend}/dashboard";
# Path to the static runtime asset tree (branding + claude
# prompts). `hive_sh4re::assets::*` reads paths underneath.
# `forge.rs` reads the avatar PNGs from here on startup.
HIVE_ASSETS_DIR = "${cfg.assets}/share/hyperhive";
}
// lib.optionalAttrs config.hyperhive.forge.enable {
# Agents poll this URL for Forgejo notifications. Derived from
# hyperhive.forge.{domain,httpPort} so it tracks forge config changes.
HIVE_FORGE_URL = "http://${config.hyperhive.forge.domain}:${toString config.hyperhive.forge.httpPort}";
}
// lib.optionalAttrs config.hyperhive.matrix.gui.enable {
# Optional matrix-GUI static dist mounted at /matrix/ by the
# dashboard router (#607 v0). Pre-#15 / pre-nginx-front: this is
# the simplest same-origin shape — fluffychat-web ships as a
# static dist, no runtime daemon needed.
HIVE_MATRIX_GUI_DIR = "${config.hyperhive.matrix.gui.package}";
})
# Main config block
(lib.mkIf cfg.enable {
environment.systemPackages = [
cfg.package
pkgs.git
];
# Pull the per-container toplevels into the host system closure
# (#97). `system.extraDependencies` adds paths to the system build
# without referencing them at runtime — nixos-rebuild fetches /
# builds them, they end up in /nix/store, and the first
# nixos-container update + start for an agent has nothing left to
# do. Gated because the closure is sizeable and pinned to x86_64.
system.extraDependencies = lib.optionals cfg.preBuildAgentTemplates [
agentBaseToplevel
managerToplevel
];
# Dashboard + per-container web UIs share the host's network namespace and
# need their ports reachable. Dashboard: `cfg.dashboardPort` (default 7000).
# Manager: 8000. Sub-agents: 8100..8999 (deterministic hash; see
# `lifecycle::agent_web_port`).
networking.firewall.allowedTCPPorts = [
cfg.dashboardPort
8000
];
networking.firewall.allowedTCPPortRanges = [
{
from = 8100;
to = 8999;
}
];
systemd.services.hive-c0re = {
description = "hyperhive coordinator daemon";
wantedBy = [ "multi-user.target" ];
path = [
pkgs.git
"/run/current-system/sw"
];
environment = {
HYPERHIVE_GIT = "${pkgs.git}/bin/git";
# Path to the dashboard static dist. The hive-c0re axum router
# serves this via `tower_http::ServeDir` for any path it doesn't
# match against an API/action route.
HIVE_STATIC_DIR = "${cfg.frontend}/dashboard";
# Path to the static runtime asset tree (branding + claude
# prompts). `hive_sh4re::assets::*` reads paths underneath.
# `forge.rs` reads the avatar PNGs from here on startup.
HIVE_ASSETS_DIR = "${cfg.assets}/share/hyperhive";
}
// lib.optionalAttrs config.hyperhive.forge.enable {
# Agents poll this URL for Forgejo notifications. Derived from
# hyperhive.forge.{domain,httpPort} so it tracks forge config changes.
HIVE_FORGE_URL = "http://${config.hyperhive.forge.domain}:${toString config.hyperhive.forge.httpPort}";
}
// lib.optionalAttrs config.hyperhive.matrix.gui.enable {
# Optional matrix-GUI static dist mounted at /matrix/ by the
# dashboard router (#607 v0). Pre-#15 / pre-nginx-front: this is
# the simplest same-origin shape — fluffychat-web ships as a
# static dist, no runtime daemon needed.
HIVE_MATRIX_GUI_DIR = "${config.hyperhive.matrix.gui.package}";
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --hyperhive-flake ${cfg.hyperhiveFlake} --dashboard-port ${toString cfg.dashboardPort} --operator-pronouns ${lib.escapeShellArg cfg.operatorPronouns} --context-window-tokens ${lib.escapeShellArg (builtins.toJSON cfg.contextWindowTokens)}";
Restart = "on-failure";
RestartSec = 2;
RuntimeDirectory = "hyperhive";
RuntimeDirectoryMode = "0750";
RuntimeDirectoryPreserve = "yes";
StateDirectory = "hyperhive";
};
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --hyperhive-flake ${cfg.hyperhiveFlake} --dashboard-port ${toString cfg.dashboardPort} --operator-pronouns ${lib.escapeShellArg cfg.operatorPronouns} --context-window-tokens ${lib.escapeShellArg (builtins.toJSON cfg.contextWindowTokens)}";
Restart = "on-failure";
RestartSec = 2;
RuntimeDirectory = "hyperhive";
RuntimeDirectoryMode = "0750";
RuntimeDirectoryPreserve = "yes";
StateDirectory = "hyperhive";
};
};
};
})
];
}