From 295e8af43acf6bbd03d7b44eabbba547cda5063c Mon Sep 17 00:00:00 2001 From: atlas Date: Sat, 10 Oct 2026 00:42:10 +0200 Subject: [PATCH] docs: the agent config meta-flake input is the local applied mirror, not forge git+http MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit config-changes.md § Meta flake, hive-c0re nix comments and the meta.rs/exec.rs doc comments still described the declared agent- input as a forge-hosted git+http repo; meta.rs renders git+file://. --- docs/agent-lifecycle/config-changes.md | 31 +++++++++++----------- hive-c0re/src/job_queue/exec.rs | 2 +- hive-c0re/src/meta.rs | 21 +++++++-------- nix/host-modules/hive-c0re/default.nix | 10 +++---- nix/host-modules/hive-c0re/environment.nix | 5 ++-- 5 files changed, 33 insertions(+), 36 deletions(-) diff --git a/docs/agent-lifecycle/config-changes.md b/docs/agent-lifecycle/config-changes.md index 3ef05de4..39d56f3a 100644 --- a/docs/agent-lifecycle/config-changes.md +++ b/docs/agent-lifecycle/config-changes.md @@ -114,27 +114,26 @@ transient. The hive-c0re-owned repo at `/var/lib/hyperhive/meta/` declares one flake input per agent (`agent-.url = -"git+http:///agent-configs/.git"`) and one +"git+file://"`, the agent's local `applied` mirror) and one `nixosConfigurations.` output per agent. Each output wraps `inputs.agent-.nixosModules.default` with the identity + `HIVE_PORT` / `HIVE_LABEL` / `HIVE_DASHBOARD_PORT` injection module. Containers run against `--flake /var/lib/hyperhive/meta#`. -The declared input url is the agent's **forge config repo** (the -same `agent-configs/` config PRs merge into), so the meta flake -references a reviewable, reproducible source rather than a local -checkout. hive-c0re authenticates that `git+http` fetch via a git -credential helper that reads the live forge-core token — no token in -the url or the lock. The rebuild paths, however, do **not** re-lock -from the forge: they `--override-input agent- -git+file:///var/lib/hyperhive/applied/`, locking the exact config -`applied//main` was fast-forwarded to. That keeps a rebuild -reproducible and independent of forge reachability — rebuilds fire on -crash-restart and meta bumps, not just config merges — while the -declared url stays the forge. `sync_agents` re-renders + re-locks the -persistent input; a plain `nix flake lock` leaves an existing applied -override in place (it only re-locks when the declared url itself -changes), so the forge-declared / applied-deployed split is stable. +The declared input url is the agent's **local `applied` mirror** +(`/var/lib/hyperhive/applied/`) of its forge config repo +(`agent-configs/`, the one config PRs merge into). The meta flake +therefore resolves entirely from on-disk state: building, and booting, +never depend on the forge being reachable. hive-c0re fills the mirror +by fast-forwarding `applied//main` to the merged config commit, +reading the forge with the hive's read token +(`forge::reader_token()`); the forge repo is the review and audit +surface, not a flake input. The rebuild paths re-lock the input with +`--override-input agent- git+file:///var/lib/hyperhive/applied/`, +locking the exact config `applied//main` was fast-forwarded to. +Rebuilds fire on crash-restart and meta bumps, not just config +merges, so the lock stays on that head. `sync_agents` re-renders and +re-locks the persistent input. Lock updates are single-phase and commit when the lock changed: `meta::lock_update_for_rebuild(name)` relocks one agent's input for a diff --git a/hive-c0re/src/job_queue/exec.rs b/hive-c0re/src/job_queue/exec.rs index e8fcf260..f924aa28 100644 --- a/hive-c0re/src/job_queue/exec.rs +++ b/hive-c0re/src/job_queue/exec.rs @@ -884,7 +884,7 @@ fn parse_agent_input_names(inputs: &[String]) -> Vec { /// validating parser every other agent-name wire field in this codebase /// goes through, so a name that reaches /// [`fast_forward_applied_main`](crate::forge::fast_forward_applied_main) or -/// a `git+http://.../agent-configs/.git` URL built off it has already +/// an `agent-configs/` forge URL built off it has already /// passed the same bar as one that arrived over a socket. Not just a /// helper for [`parse_agent_input_names`]: `run_meta_lock`'s `fanout` /// parameter carries pre-computed agent names too, and while today's only diff --git a/hive-c0re/src/meta.rs b/hive-c0re/src/meta.rs index 5902cf42..1ce14990 100644 --- a/hive-c0re/src/meta.rs +++ b/hive-c0re/src/meta.rs @@ -235,9 +235,8 @@ pub async fn lock_update_for_rebuild(name: &str) -> Result<()> { let _guard = META_LOCK.lock().await; let dir = crate::paths::meta_root(); let input = format!("agent-{name}"); - // Re-lock from the local applied mirror, not the persistent forge URL: - // build exactly `applied//main` and stay reproducible when the forge - // is unreachable. + // Re-lock against `applied//main` explicitly, so the lock is the + // exact applied head whatever the declared input url says. let applied = applied_override_url(&crate::paths::applied_dir(name)); nix( &dir, @@ -264,12 +263,12 @@ pub async fn lock_update_for_rebuild(name: &str) -> Result<()> { } /// `--override-input` URL re-locking an agent's config input against its -/// LOCAL applied mirror (`git+file://`, current `main` head) -/// instead of the persistent forge URL declared in the meta flake. The -/// deploy + rebuild paths re-lock from here: the applied tree was already -/// fast-forwarded to the reviewed head, so this builds exactly that config -/// and stays reproducible when the forge is unreachable. No `?rev` — `main` -/// head is the reviewed head at deploy time. Pure so it's unit-testable. +/// LOCAL applied mirror (`git+file://`, current `main` head), +/// the same url the meta flake declares. The deploy + rebuild paths re-lock +/// from here: the applied tree was already fast-forwarded to the reviewed +/// head, so this builds exactly that config with no forge access. No +/// `?rev` — `main` head is the reviewed head at deploy time. Pure so it's +/// unit-testable. fn applied_override_url(applied_dir: &Path) -> String { format!("git+file://{}", applied_dir.display()) } @@ -1456,8 +1455,8 @@ mod tests { #[test] fn applied_override_url_targets_local_mirror_main_head() { // Deploy + rebuild re-lock against the local applied mirror's `main` - // head (no `?rev`), never the persistent forge URL — so a rebuild - // survives forge unreachability and builds the fast-forwarded config. + // head (no `?rev`) — so a rebuild survives forge unreachability and + // builds the fast-forwarded config. let p = Path::new("/var/lib/hyperhive/agents/iris/applied"); let url = applied_override_url(p); assert_eq!(url, "git+file:///var/lib/hyperhive/agents/iris/applied"); diff --git a/nix/host-modules/hive-c0re/default.nix b/nix/host-modules/hive-c0re/default.nix index 67d0128a..106e9636 100644 --- a/nix/host-modules/hive-c0re/default.nix +++ b/nix/host-modules/hive-c0re/default.nix @@ -56,9 +56,9 @@ let username = core [http] # Abort a stalled fetch instead of blocking startup indefinitely. If a - # git+http transfer (e.g. `nix flake lock` of the forge-hosted config - # inputs) drops below 1 KiB/s for 30s -- forge unreachable / not ready - # on cold boot -- git fails fast rather than hanging the whole daemon. + # git http transfer from the forge (e.g. filling an applied mirror) + # drops below 1 KiB/s for 30s -- forge unreachable / not ready on cold + # boot -- git fails fast rather than hanging the whole daemon. # Pairs with GIT_TERMINAL_PROMPT=0 (no credential-prompt hang) and the # migration shellout timeout in migrate.rs. lowSpeedLimit = 1024 @@ -265,8 +265,8 @@ in after = [ "hive-c0re.socket" ]; path = [ pkgs.git - # `git-credential-hive-forge` on PATH so git finds it when nix fetches - # the forge-hosted agent-config inputs (helper = hive-forge). + # `git-credential-hive-forge` on PATH so git finds it for git+http + # fetches from the forge (helper = hive-forge). forgeCredHelper "/run/current-system/sw" ]; diff --git a/nix/host-modules/hive-c0re/environment.nix b/nix/host-modules/hive-c0re/environment.nix index cc875197..766a2012 100644 --- a/nix/host-modules/hive-c0re/environment.nix +++ b/nix/host-modules/hive-c0re/environment.nix @@ -28,9 +28,8 @@ in # Never let git block on an interactive credential prompt. hive-core is a # TTY-less system user, so a prompt (e.g. the forge credential helper # returns nothing because the forge isn't reachable yet on cold boot) - # would hang forever — this is what froze the whole daemon during startup - # migration's `nix flake lock` of the forge-hosted config inputs. With - # this set, git fails fast instead of prompting. Paired with the git http + # would hang forever and freeze the daemon during startup. With this set, + # git fails fast instead of prompting. Paired with the git http # low-speed abort in `safeDirGitconfig` (bounds a stalled transfer) and # the 120s migration shellout timeout in migrate.rs. GIT_TERMINAL_PROMPT = "0";