refactor: rename templates to agent.nix/ruth.nix, sweep stale name refs

This commit is contained in:
müde 2026-07-13 22:01:24 +02:00
commit 7c9d72b9ca
13 changed files with 28 additions and 28 deletions

View file

@ -96,11 +96,11 @@
in in
{ {
agent-base.imports = [ agent-base.imports = [
./nix/templates/agent-base.nix ./nix/templates/agent.nix
agentPackages agentPackages
]; ];
ruth.imports = [ ruth.imports = [
./nix/templates/manager.nix ./nix/templates/ruth.nix
agentPackages agentPackages
]; ];
# The full host stack (nix/modules/default.nix aggregator) plus # The full host stack (nix/modules/default.nix aggregator) plus

View file

@ -489,7 +489,7 @@ pub fn configured_effort() -> Option<&'static str> {
/// Context-window size in tokens for a given model name. /// Context-window size in tokens for a given model name.
/// ///
/// Canonical per-model sizes are declared in `harness-base.nix` as /// Canonical per-model sizes are declared in the harness nix modules as
/// `hyperhive.contextWindowTokens` and injected as /// `hyperhive.contextWindowTokens` and injected as
/// `HIVE_CONTEXT_WINDOW_TOKENS_<KEY_UPPER>` env vars — so this function /// `HIVE_CONTEXT_WINDOW_TOKENS_<KEY_UPPER>` env vars — so this function
/// normally just reads them. The Rust code carries no model knowledge; /// normally just reads them. The Rust code carries no model knowledge;

View file

@ -14,7 +14,7 @@ pub const SERVER_NAME: &str = "hyperhive";
/// Default loopback port the built-in hyperhive MCP surface is served on /// Default loopback port the built-in hyperhive MCP surface is served on
/// (streamable HTTP, via the persistent `hive-mcp-http` daemon). Overridable /// (streamable HTTP, via the persistent `hive-mcp-http` daemon). Overridable
/// via `hyperhive.mcp.httpPort`; **must match that option's default** in /// via `hyperhive.mcp.httpPort`; **must match that option's default** in
/// `nix/templates/harness-base.nix`. Safe as a single fixed value across all /// `nix/templates/harness/`. Safe as a single fixed value across all
/// agents because each container runs in its own private network namespace, /// agents because each container runs in its own private network namespace,
/// so `127.0.0.1:<port>` is per-container-private (no cross-agent collision). /// so `127.0.0.1:<port>` is per-container-private (no cross-agent collision).
pub const DEFAULT_MCP_HTTP_PORT: u16 = 8790; pub const DEFAULT_MCP_HTTP_PORT: u16 = 8790;
@ -246,13 +246,13 @@ pub fn builtin_tools_arg() -> String {
} }
/// Where the NixOS module writes the per-agent extra-MCP spec (see /// Where the NixOS module writes the per-agent extra-MCP spec (see
/// `nix/templates/harness-base.nix`). Each entry becomes an additional /// `nix/templates/harness/`). Each entry becomes an additional
/// `mcpServers.<key>` block in the rendered claude config + a /// `mcpServers.<key>` block in the rendered claude config + a
/// `mcp__<key>__<tool>` pattern in `--allowedTools`. /// `mcp__<key>__<tool>` pattern in `--allowedTools`.
const EXTRA_MCP_PATH: &str = "/etc/hyperhive/extra-mcp.json"; const EXTRA_MCP_PATH: &str = "/etc/hyperhive/extra-mcp.json";
/// Where the NixOS module writes the per-agent send allow-list (see /// Where the NixOS module writes the per-agent send allow-list (see
/// `nix/templates/harness-base.nix`). Empty list = unrestricted (the /// `nix/templates/harness/`). Empty list = unrestricted (the
/// default). Non-empty list constrains `mcp__hyperhive__send`'s `to` /// default). Non-empty list constrains `mcp__hyperhive__send`'s `to`
/// field; the manager is always implicitly permitted regardless of /// field; the manager is always implicitly permitted regardless of
/// the list contents. /// the list contents.

View file

@ -158,7 +158,7 @@ async fn set_nspawn_flags(
// Claude credentials land at `/home/<agent>/.claude` so the // Claude credentials land at `/home/<agent>/.claude` so the
// `claude` CLI (which reads `$HOME/.claude`) finds them. The // `claude` CLI (which reads `$HOME/.claude`) finds them. The
// harness service's environment sets `HOME` to the same path // harness service's environment sets `HOME` to the same path
// (`agent-base.nix` / `manager.nix`), so no `--setenv` plumbing // (`agent.nix` / `ruth.nix` templates), so no `--setenv` plumbing
// is needed here — the bind alone is enough. // is needed here — the bind alone is enough.
let claude_mount = container_claude_mount(agent_name); let claude_mount = container_claude_mount(agent_name);

View file

@ -169,7 +169,7 @@ pub fn agent_uid_gid(agent_name: &str) -> Option<(u32, u32)> {
/// uid/gid via [`agent_uid_gid`] and shells out to `std::os::unix::fs::chown`. /// uid/gid via [`agent_uid_gid`] and shells out to `std::os::unix::fs::chown`.
/// Silently no-ops when the container isn't built yet (`None` from /// Silently no-ops when the container isn't built yet (`None` from
/// [`agent_uid_gid`]) and logs at debug on chown syscall failure — the /// [`agent_uid_gid`]) and logs at debug on chown syscall failure — the
/// activation script in `harness-base.nix` is the steady-state safety /// activation script in the harness user module is the steady-state safety
/// net. Used by per-agent state writers in `forge` + `matrix` so the /// net. Used by per-agent state writers in `forge` + `matrix` so the
/// agent can read the file without waiting for the next container /// agent can read the file without waiting for the next container
/// rebuild. /// rebuild.

View file

@ -701,7 +701,7 @@ struct OtelConfig {
/// Read the hive-wide OTEL config from env, or `None` when OTEL is off. /// Read the hive-wide OTEL config from env, or `None` when OTEL is off.
/// Mirrors `hive_ca_source` — host state surfaced to the meta renderer /// Mirrors `hive_ca_source` — host state surfaced to the meta renderer
/// so it can bake build-time `hyperhive.otel.*` config into each agent /// so it can bake build-time `hyperhive.otel.*` config into each agent
/// (the per-agent options harness-base.nix consumes). Returns `None` /// (the per-agent options the harness modules consume). Returns `None`
/// when the endpoint signal is absent so the renderer emits no /// when the endpoint signal is absent so the renderer emits no
/// `hyperhive.otel.*` lines and agents keep the disabled default. /// `hyperhive.otel.*` lines and agents keep the disabled default.
fn otel_config() -> Option<OtelConfig> { fn otel_config() -> Option<OtelConfig> {
@ -914,7 +914,7 @@ where
// re-locks THIS input instead of re-hashing the whole `hyperhive` // re-locks THIS input instead of re-hashing the whole `hyperhive`
// source. Threaded to each agent below as `hyperhive.docs.source`. // source. Threaded to each agent below as `hyperhive.docs.source`.
// Empty = hive-c0re not built with the option wired up (legacy); // Empty = hive-c0re not built with the option wired up (legacy);
// agents then keep the harness-base default (`pkgs.hyperhive-docs`). // agents then keep the harness default (`hyperhive.packages.reference-docs`).
if !docs_flake.is_empty() { if !docs_flake.is_empty() {
// `flake = false`: the docs/ tree is a plain source (no flake.nix), // `flake = false`: the docs/ tree is a plain source (no flake.nix),
// so nix must treat it as raw source, not evaluate it as a flake. // so nix must treat it as raw source, not evaluate it as a flake.
@ -971,8 +971,8 @@ where
"#, "#,
); );
// Point the in-container docs dir (`$HIVE_DOCS_DIR`) at the narrow // Point the in-container docs dir (`$HIVE_DOCS_DIR`) at the narrow
// `hyperhive-docs` input instead of the harness-base default // `hyperhive-docs` input instead of the harness default
// (`pkgs.hyperhive-docs`, built from the now-docs-stripped source). // (`hyperhive.packages.reference-docs`, built from the now-docs-stripped source).
// `inputs."hyperhive-docs"` is reachable via the outputs `@inputs` // `inputs."hyperhive-docs"` is reachable via the outputs `@inputs`
// capture. Emitted only when the input exists (docs_flake non-empty). // capture. Emitted only when the input exists (docs_flake non-empty).
if !docs_flake.is_empty() { if !docs_flake.is_empty() {
@ -1000,7 +1000,7 @@ where
); );
} }
// Hive-wide OTEL stats export (`services.hyperhive.otel.*`): inject the // Hive-wide OTEL stats export (`services.hyperhive.otel.*`): inject the
// build-time `hyperhive.otel.*` config harness-base.nix consumes (its // build-time `hyperhive.otel.*` config the harness modules consume (its
// otelEnv + otelExecStart wrapper + LoadCredential). Host-driven, so // otelEnv + otelExecStart wrapper + LoadCredential). Host-driven, so
// the same config lands on every agent; emitted only when enabled. // the same config lands on every agent; emitted only when enabled.
// Mirrors the CA-cert injection above — host state -> build-time agent // Mirrors the CA-cert injection above — host state -> build-time agent
@ -1055,7 +1055,7 @@ where
# `iris`, `root`, ). UID auto-assigned by NixOS; the # `iris`, `root`, ). UID auto-assigned by NixOS; the
# per-agent override here is what makes # per-agent override here is what makes
# `hyperhive.user.name` match the agent's identity # `hyperhive.user.name` match the agent's identity
# instead of the harness-base default of `"agent"`. # instead of the harness default of `"agent"`.
hyperhive.user.name = name; hyperhive.user.name = name;
programs.git.config.user = { programs.git.config.user = {
name = name; name = name;
@ -1416,7 +1416,7 @@ mod tests {
"old-style follows must not appear when flake args are set:\n{out}" "old-style follows must not appear when flake args are set:\n{out}"
); );
// the narrow docs source is its own non-flake input, and each // the narrow docs source is its own non-flake input, and each
// agent's docs dir resolves from it rather than pkgs.hyperhive-docs. // agent's docs dir resolves from it rather than hyperhive.packages.reference-docs.
assert!( assert!(
out.contains("hyperhive-docs.url = \"path:/nix/store/bbbb-hyperhive-docs-source\""), out.contains("hyperhive-docs.url = \"path:/nix/store/bbbb-hyperhive-docs-source\""),
"expected hyperhive-docs input url:\n{out}" "expected hyperhive-docs input url:\n{out}"
@ -1434,7 +1434,7 @@ mod tests {
#[test] #[test]
fn render_flake_omits_docs_input_when_docs_flake_empty() { fn render_flake_omits_docs_input_when_docs_flake_empty() {
// Legacy / not-wired-up: empty docs_flake emits no docs input and // Legacy / not-wired-up: empty docs_flake emits no docs input and
// leaves each agent on the harness-base default (pkgs.hyperhive-docs). // leaves each agent on the harness default (hyperhive.packages.reference-docs).
let out = render_flake( let out = render_flake(
"github:example/hyperhive", "github:example/hyperhive",
"", "",
@ -1674,7 +1674,7 @@ mod tests {
// services.hyperhive.otel.* -> HYPERHIVE_OTEL_* on hive-c0re's unit // services.hyperhive.otel.* -> HYPERHIVE_OTEL_* on hive-c0re's unit
// -> injected as build-time hyperhive.otel.* into every agent. With // -> injected as build-time hyperhive.otel.* into every agent. With
// no endpoint signal, no hyperhive.otel lines are emitted (agents // no endpoint signal, no hyperhive.otel lines are emitted (agents
// keep the harness-base disabled default). // keep the the harness modules disabled default).
// //
// SAFETY: single-threaded mutation of process env vars no other // SAFETY: single-threaded mutation of process env vars no other
// test asserts on; restored before returning. // test asserts on; restored before returning.

View file

@ -42,7 +42,7 @@ pub const HOST_SOCKET: &str = "/run/hyperhive/host.sock";
/// `/run/hive-agent` — per-agent runtime socket dir root (web + bound /// `/run/hive-agent` — per-agent runtime socket dir root (web + bound
/// markers), one subdir per agent. /// markers), one subdir per agent.
// nix: agent container bind-mount / `RuntimeDirectory` (harness-base.nix) — must match. // nix: agent container bind-mount / `RuntimeDirectory` (the harness nix modules) — must match.
pub const AGENT_SOCKET_DIR: &str = "/run/hive-agent"; pub const AGENT_SOCKET_DIR: &str = "/run/hive-agent";
/// Default broker db path (`db/broker.sqlite`). Exposed as a `&str` for /// Default broker db path (`db/broker.sqlite`). Exposed as a `&str` for
@ -162,7 +162,7 @@ pub fn agent_sockets_file() -> PathBuf {
/// bind-mounted into each container as `/agents/<name>`). A `&str` (the /// bind-mounted into each container as `/agents/<name>`). A `&str` (the
/// dashboard state-file allow-list uses it for `strip_prefix` / /// dashboard state-file allow-list uses it for `strip_prefix` /
/// `starts_with` checks), so it stays a const; [`agents_root`] wraps it. /// `starts_with` checks), so it stays a const; [`agents_root`] wraps it.
// nix: agent container bind-mount source (harness-base.nix / agent-base.nix) — must match. // nix: agent container bind-mount source (harness modules / agent.nix template) — must match.
// sh4re: `hive_sh4re::priv_proto::AGENT_STATE_ROOT` is the same value and must stay in sync; // sh4re: `hive_sh4re::priv_proto::AGENT_STATE_ROOT` is the same value and must stay in sync;
// the privsep boundary prevents importing across the crate. // the privsep boundary prevents importing across the crate.
pub const AGENTS_ROOT: &str = "/var/lib/hyperhive/agents"; pub const AGENTS_ROOT: &str = "/var/lib/hyperhive/agents";
@ -200,7 +200,7 @@ pub fn applied_rev_marker(name: &str) -> PathBuf {
} }
/// `meta/` — the meta flake working tree (inputs, `flake.lock`, `.git`). /// `meta/` — the meta flake working tree (inputs, `flake.lock`, `.git`).
// nix: bind-mounted read-only into agent containers as `/meta` (harness-base.nix) — must match. // nix: bind-mounted read-only into agent containers as `/meta` (the harness nix modules) — must match.
#[must_use] #[must_use]
pub fn meta_root() -> PathBuf { pub fn meta_root() -> PathBuf {
state_root().join("meta") state_root().join("meta")
@ -222,7 +222,7 @@ pub fn meta_git_index_lock() -> PathBuf {
/// `shared/` — the cross-agent `/shared` scratch space. A `&str` (the /// `shared/` — the cross-agent `/shared` scratch space. A `&str` (the
/// dashboard state-file allow-list uses it for prefix checks), so it /// dashboard state-file allow-list uses it for prefix checks), so it
/// stays a const; [`shared_root`] wraps it. /// stays a const; [`shared_root`] wraps it.
// nix: bind-mounted into every agent container as `/shared` (harness-base.nix) — must match. // nix: bind-mounted into every agent container as `/shared` (the harness nix modules) — must match.
pub const SHARED_ROOT: &str = "/var/lib/hyperhive/shared"; pub const SHARED_ROOT: &str = "/var/lib/hyperhive/shared";
#[must_use] #[must_use]
@ -233,7 +233,7 @@ pub fn shared_root() -> PathBuf {
/// `knowledge/` — local checkout of the `internal/knowledge` repo. A /// `knowledge/` — local checkout of the `internal/knowledge` repo. A
/// `&str` (used as a git `-C` arg / clone target throughout the knowledge /// `&str` (used as a git `-C` arg / clone target throughout the knowledge
/// worker), so it stays a const rather than a `PathBuf` fn. /// worker), so it stays a const rather than a `PathBuf` fn.
// nix: bind-mounted read-only into agent containers as `/knowledge` (harness-base.nix) — must match. // nix: bind-mounted read-only into agent containers as `/knowledge` (the harness nix modules) — must match.
pub const KNOWLEDGE_DIR: &str = "/var/lib/hyperhive/knowledge"; pub const KNOWLEDGE_DIR: &str = "/var/lib/hyperhive/knowledge";
/// `gateway/` — generated nginx include fragments for the gateway vhost. /// `gateway/` — generated nginx include fragments for the gateway vhost.

View file

@ -51,14 +51,14 @@ let
}; };
# Agent module eval from the content-addressed nixSrc. Relative # Agent module eval from the content-addressed nixSrc. Relative
# imports inside agent-base.nix (the ./harness module dir) resolve # imports inside agent.nix (the ./harness module dir) resolve
# correctly against the nixSrc directory tree. `hyperhive.packages` # correctly against the nixSrc directory tree. `hyperhive.packages`
# stays unset — every option default that references it carries a # stays unset — every option default that references it carries a
# `defaultText`, so the doc walk never forces the packages. # `defaultText`, so the doc walk never forces the packages.
agentEval = nixosSystem { agentEval = nixosSystem {
system = pkgs.stdenv.hostPlatform.system; system = pkgs.stdenv.hostPlatform.system;
modules = [ modules = [
"${nixSrc}/templates/agent-base.nix" "${nixSrc}/templates/agent.nix"
]; ];
}; };
@ -155,7 +155,7 @@ let
`hyperhive.nixosModules.default` to operator host configurations `hyperhive.nixosModules.default` to operator host configurations
(`services.hyperhive.{enable,domain,c0re,forge,matrix,gateway}.*`). (`services.hyperhive.{enable,domain,c0re,forge,matrix,gateway}.*`).
- [per-agent options](agent.md) options declared in - [per-agent options](agent.md) options declared in
`nix/templates/harness-base.nix`, visible from every `agent.nix` `nix/templates/harness/`, visible from every `agent.nix`
(`hyperhive.model`, `hyperhive.allowedRecipients`, (`hyperhive.model`, `hyperhive.allowedRecipients`,
`hyperhive.extraMcpServers`, `hyperhive.frontend.*`, `hyperhive.extraMcpServers`, `hyperhive.frontend.*`,
`hyperhive.forge.*`, `hyperhive.matrix.*`, `hyperhive.gui.*`). `hyperhive.forge.*`, `hyperhive.matrix.*`, `hyperhive.gui.*`).

View file

@ -52,7 +52,7 @@ in
these models instead of a hardcoded set. these models instead of a hardcoded set.
Configure hive-wide by setting a shared default (e.g. in your Configure hive-wide by setting a shared default (e.g. in your
`agent-base.nix`) or per-agent to narrow the menu for example a `agent.nix` shared defaults) or per-agent to narrow the menu for example a
haiku-only agent can hide `opus` and `sonnet`. The *current* model is haiku-only agent can hide `opus` and `sonnet`. The *current* model is
still set by `hyperhive.model` and remains switchable at runtime via the still set by `hyperhive.model` and remains switchable at runtime via the
UI; this option only controls which choices the picker presents. UI; this option only controls which choices the picker presents.

View file

@ -1,5 +1,5 @@
# Shared scaffolding for every hyperhive harness container. # Shared scaffolding for every hyperhive harness container.
# `../agent-base.nix` and `../manager.nix` both import this; all # `../agent.nix` and `../ruth.nix` both import this; all
# agents use the same service unit regardless of which entry-point # agents use the same service unit regardless of which entry-point
# they came from. # they came from.
# #

View file

@ -15,7 +15,7 @@
`$HIVE_DOCS_DIR/`, and appends a single pointer sentence to the agent's `$HIVE_DOCS_DIR/`, and appends a single pointer sentence to the agent's
system prompt so it knows the docs exist (see system prompt so it knows the docs exist (see
`hive-ag3nt::prompt::render`). Default-on for the root/manager agent `hive-ag3nt::prompt::render`). Default-on for the root/manager agent
(see `../manager.nix`), off elsewhere; any agent can flip it from its (see `../ruth.nix`), off elsewhere; any agent can flip it from its
`agent.nix`. `agent.nix`.
''; '';