Watch
0
0
Fork
You've already forked hyperhive
0

the meta flake takes docs from the pinned hyperhive input

This commit is contained in:
atlas 2026-10-18 20:06:08 +02:00
commit daf38e4c55
16 changed files with 29 additions and 197 deletions

View file

@ -358,7 +358,6 @@ fn render_hive_flake(hive: &HiveEnv, agents: &[AgentSpec]) -> Result<String> {
fn render_hive_flake_at(hive: &HiveEnv, hyperhive_url: &str, agents: &[AgentSpec]) -> String {
render_flake(
hyperhive_url,
&hive.hyperhive_docs_flake,
hive.claude_code_path.as_deref(),
hive.dashboard_port,
agents,
@ -367,14 +366,12 @@ fn render_hive_flake_at(hive: &HiveEnv, hyperhive_url: &str, agents: &[AgentSpec
fn render_flake(
hyperhive_url: &str,
docs_flake: &str,
claude_code_path: Option<&str>,
dashboard_port: u16,
agents: &[AgentSpec],
) -> String {
render_flake_with_lookup(
hyperhive_url,
docs_flake,
claude_code_path,
dashboard_port,
agents,
@ -756,7 +753,6 @@ fn agent_canonical_inputs(name: &str) -> Vec<&'static str> {
)]
fn render_flake_with_lookup<F>(
hyperhive_url: &str,
docs_flake: &str,
claude_code_path: Option<&str>,
dashboard_port: u16,
agents: &[AgentSpec],
@ -774,17 +770,6 @@ where
// `agent-<n>.inputs.nixpkgs.follows = "nixpkgs"` resolves to this node.
let _ = writeln!(out, " hyperhive.url = \"{hyperhive_url}\";");
out.push_str(" nixpkgs.follows = \"hyperhive/nixpkgs\";\n");
// Narrow `docs/` source as its own input so a doc edit only
// re-locks THIS input instead of re-hashing the whole `hyperhive`
// source. Threaded to each agent below as `services.hyperhive.agent.docs.source`.
// Empty = hive-c0re not built with the option wired up (legacy);
// agents then keep the harness default (`services.hyperhive.agent.packages.reference-docs`).
if !docs_flake.is_empty() {
// `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.
let _ = writeln!(out, " hyperhive-docs.url = \"{docs_flake}\";");
out.push_str(" hyperhive-docs.flake = false;\n");
}
// Each agent's config input is its LOCAL applied mirror
// (`git+file://<applied>`), so the meta flake resolves entirely from
// on-disk state and boot never depends on the forge being reachable.
@ -845,14 +830,6 @@ where
{
"#,
);
// Point the in-container docs dir (`$HIVE_DOCS_DIR`) at the narrow
// `hyperhive-docs` input instead of the harness default
// (`services.hyperhive.agent.packages.reference-docs`, built from the now-docs-stripped source).
// `inputs."hyperhive-docs"` is reachable via the outputs `@inputs`
// capture. Emitted only when the input exists (docs_flake non-empty).
if !docs_flake.is_empty() {
out.push_str(" services.hyperhive.agent.docs.source = inputs.\"hyperhive-docs\".outPath;\n");
}
// The `claude-code` agents run, as a bare store path rather than a
// flake input: containers share the host's `/nix/store`, so the
// binary is already there with its closure and has nothing to
@ -1305,7 +1282,6 @@ mod tests {
fn render_flake_pins_hyperhive_by_url_and_follows_its_nixpkgs() {
let out = render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],
@ -1324,38 +1300,11 @@ mod tests {
!out.contains("nixpkgs.url") && !out.contains("hyperhive.inputs.nixpkgs"),
"no separate nixpkgs input:\n{out}"
);
// the narrow docs source is its own non-flake input, and each
// agent's docs dir resolves from it rather than services.hyperhive.agent.packages.reference-docs.
// docs come from the pinned hyperhive input: no separate docs input,
// no docs.source override.
assert!(
out.contains("hyperhive-docs.url = \"path:/nix/store/bbbb-hyperhive-docs-source\""),
"expected hyperhive-docs input url:\n{out}"
);
assert!(
out.contains("hyperhive-docs.flake = false;"),
"docs source is not a flake, must be flake = false:\n{out}"
);
assert!(
out.contains(
"services.hyperhive.agent.docs.source = inputs.\"hyperhive-docs\".outPath;"
),
"expected per-agent docs source wired to the input:\n{out}"
);
}
#[test]
fn render_flake_omits_docs_input_when_docs_flake_empty() {
// Legacy / not-wired-up: empty docs_flake emits no docs input and
// leaves each agent on the harness default (services.hyperhive.agent.packages.reference-docs).
let out = render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"",
None,
8000,
&[sample_spec("alice", 9001)],
);
assert!(
!out.contains("hyperhive-docs"),
"no docs input/source when docs_flake is empty:\n{out}"
!out.contains("hyperhive-docs") && !out.contains("docs.source"),
"no docs input or override:\n{out}"
);
}
@ -1363,7 +1312,6 @@ mod tests {
fn render_flake_names_each_agent_container_after_the_agent() {
let out = render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"",
None,
8000,
&[sample_spec("alice", 9001)],
@ -1400,7 +1348,6 @@ mod tests {
// the closure the binary actually needs.
let out = render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
Some("/nix/store/cccc-claude-code-2.1.220"),
8000,
&[sample_spec("alice", 9001)],
@ -1425,7 +1372,6 @@ mod tests {
// unpinned case self-contained).
let out = render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],
@ -1448,7 +1394,6 @@ mod tests {
};
let out = render_flake_with_lookup(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[
@ -1478,7 +1423,6 @@ mod tests {
fn render_flake_builds_every_agent_from_agent_base() {
let out = render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001), sample_spec("ruth", 9002)],
@ -1504,7 +1448,6 @@ mod tests {
fn render_flake_skips_canonical_follows_when_lookup_returns_empty() {
let out = render_flake_with_lookup(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],
@ -1533,7 +1476,6 @@ mod tests {
};
let out = render_flake_with_lookup(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001), android],
@ -1585,7 +1527,6 @@ mod tests {
}
let out = render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],
@ -1627,7 +1568,6 @@ mod tests {
}
render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],
@ -1823,7 +1763,6 @@ mod tests {
}
let out = render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],
@ -1856,7 +1795,6 @@ mod tests {
// review surface, but they are not the flake's build input.
let out = render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],
@ -1897,7 +1835,6 @@ mod tests {
let render = || {
render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],
@ -1986,7 +1923,6 @@ mod tests {
let render = || {
render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],
@ -2057,7 +1993,6 @@ mod tests {
let render = || {
render_flake(
"git+https://forge.example/hyperhive/hyperhive.git?rev=0123abcd",
"path:/nix/store/bbbb-hyperhive-docs-source",
None,
8000,
&[sample_spec("alice", 9001)],