From 1cefaf2c1655bae26390a7b36083813d7955ff7c Mon Sep 17 00:00:00 2001 From: damocles Date: Fri, 10 Jul 2026 19:31:20 +0200 Subject: [PATCH] refactor(#2285): add consolidated path fns/consts to paths.rs (foundation) --- hive-c0re/src/paths.rs | 178 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 170 insertions(+), 8 deletions(-) diff --git a/hive-c0re/src/paths.rs b/hive-c0re/src/paths.rs index 70be660a..739ae9e3 100644 --- a/hive-c0re/src/paths.rs +++ b/hive-c0re/src/paths.rs @@ -1,15 +1,22 @@ -//! Central host-side state paths under `/var/lib/hyperhive`. +//! Central host-side state paths under `/var/lib/hyperhive` (and the +//! `/run/hyperhive` + `/run/hive-agent` runtime roots). //! //! Historically these were flat string literals scattered across many //! modules (`broker.sqlite`, `matrix-admin-token`, `agent-sockets.json`, -//! …) directly under the state root. This module groups the **strictly -//! host-side** ones (read/written by hive-c0re alone, no nix-module or -//! container coupling) into subdirs: `db/`, `forge/`, `matrix/`, `run/`. +//! …). This module is the **single Rust-side source** for every host +//! path — the strictly host-side ones grouped into subdirs (`db/`, +//! `forge/`, `matrix/`, `run/`), plus the **nix-coupled** roots +//! (`agents/`, `applied/`, `meta/`, `shared/`, `gateway/`, `knowledge/`, +//! the register/core tokens, the `/run` runtime dirs). //! -//! Nix-coupled paths (`forge-core-token`, `matrix-register-token`, -//! `gateway/`, `meta/`, `agents/`) are intentionally **not** moved here -//! — they cross into nix modules / bind mounts and are tracked -//! separately so the Rust path and the nix default can move in lockstep. +//! Nix-coupled paths are NOT excluded (the old stance) — they're moved +//! here too, each carrying a `// nix: …` comment naming the module / +//! bind-mount whose literal must stay in lockstep. Centralising the Rust +//! side (one place to grep, one place to change) and documenting the nix +//! counterpart is strictly better than scattering the literals to avoid +//! drift — the drift risk is the same either way, and the reboot outage +//! is the argument for a single source. The nix modules keep their own +//! literals (that's their source of truth; out of scope here). //! //! [`relocate_legacy_state`] moves any file still at the old flat //! location into its new subdir on startup, before the broker db is @@ -18,8 +25,24 @@ use std::path::{Path, PathBuf}; /// Root of all hive-c0re persistent state. +// nix: bind-mount source `services.hyperhive.c0re.statePath` (hive-c0re.nix) — must match. pub const STATE_ROOT: &str = "/var/lib/hyperhive"; +/// `/run/hyperhive` — hive-c0re's runtime root (host admin socket, the +/// per-agent runtime dirs). Regenerated each boot; not persistent state. +// nix: `RuntimeDirectory=hyperhive` on the hive-c0re service (hive-c0re.nix) — must match. +pub const RUNTIME_ROOT: &str = "/run/hyperhive"; + +/// Default host admin socket (`/run/hyperhive/host.sock`). Exposed as a +/// `&str` for the `--socket` / `--host-socket` clap `default_value` in +/// `main.rs` (hive-c0re) and `bin/hivectl.rs`. +pub const HOST_SOCKET: &str = "/run/hyperhive/host.sock"; + +/// `/run/hive-agent` — per-agent runtime socket dir root (web + bound +/// markers), one subdir per agent. +// nix: agent container bind-mount / `RuntimeDirectory` (harness-base.nix) — must match. +pub const AGENT_SOCKET_DIR: &str = "/run/hive-agent"; + /// Default broker db path (`db/broker.sqlite`). Exposed as a `&str` for /// the `--broker-db` clap `default_value`; `build_logs.sqlite` is placed /// alongside it (the build-logs store keys off the broker db's parent). @@ -117,6 +140,145 @@ pub fn agent_sockets_file() -> PathBuf { run_dir().join("agent-sockets.json") } +// --------------------------------------------------------------------------- +// Nix-coupled roots + runtime dirs. Each carries a `// nix:` note naming the +// module / bind-mount whose literal must stay in lockstep with the value here. +// The nix modules keep their own literals (their source of truth); this is the +// single Rust-side source. +// --------------------------------------------------------------------------- + +/// `agents/` — per-agent persistent state root (one subdir per agent, +/// bind-mounted into each container as `/agents/`). +// nix: agent container bind-mount source (harness-base.nix / agent-base.nix) — must match. +#[must_use] +pub fn agents_root() -> PathBuf { + state_root().join("agents") +} + +/// `agents/` — one agent's persistent state root. +#[must_use] +pub fn agent_state_dir(name: &str) -> PathBuf { + agents_root().join(name) +} + +/// `applied/` — per-agent *applied* (deployed) config repos + rev markers, +/// distinct from the proposed configs under `agents//config`. +// nix: read by hive-c0re only, but paired with `agents/` in the deploy flow. +#[must_use] +pub fn applied_root() -> PathBuf { + state_root().join("applied") +} + +/// `applied/` — one agent's applied config working tree. +#[must_use] +pub fn applied_dir(name: &str) -> PathBuf { + applied_root().join(name) +} + +/// `applied/..hyperhive-rev` — marker recording the flake rev an +/// agent was last successfully rebuilt against (auto-update staleness check). +#[must_use] +pub fn applied_rev_marker(name: &str) -> PathBuf { + applied_root().join(format!(".{name}.hyperhive-rev")) +} + +/// `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. +#[must_use] +pub fn meta_root() -> PathBuf { + state_root().join("meta") +} + +/// `meta/flake.lock` — the meta flake lock (read for input rev display). +#[must_use] +pub fn meta_flake_lock() -> PathBuf { + meta_root().join("flake.lock") +} + +/// `meta/.git/index.lock` — git index lock; checked before meta git ops +/// so a stale lock from a crashed process can be cleared. +#[must_use] +pub fn meta_git_index_lock() -> PathBuf { + meta_root().join(".git/index.lock") +} + +/// `shared/` — the cross-agent `/shared` scratch space. +// nix: bind-mounted into every agent container as `/shared` (harness-base.nix) — must match. +#[must_use] +pub fn shared_root() -> PathBuf { + state_root().join("shared") +} + +/// `knowledge/` — local checkout of the `internal/knowledge` repo. +// nix: bind-mounted read-only into agent containers as `/knowledge` (harness-base.nix) — must match. +#[must_use] +pub fn knowledge_dir() -> PathBuf { + state_root().join("knowledge") +} + +/// `gateway/` — generated nginx include fragments for the gateway vhost. +// nix: bind-mounted into the gateway container (hive-gateway.nix) — must match. +#[must_use] +pub fn gateway_dir() -> PathBuf { + state_root().join("gateway") +} + +/// `gateway/agents.conf` — per-agent nginx `location` blocks (UDS upstreams). +#[must_use] +pub fn gateway_agents_conf() -> PathBuf { + gateway_dir().join("agents.conf") +} + +/// `forge-core-token` — the hive-c0re forge account API token. +// nix: bind-mounted into the forge container / read at provisioning (hive-forge.nix) — must match. +#[must_use] +pub fn forge_core_token() -> PathBuf { + state_root().join("forge-core-token") +} + +/// `matrix-register-token` — shared matrix registration token. +// nix: bind-mounted into the tuwunel/matrix container (hive-matrix.nix) — must match. +#[must_use] +pub fn matrix_register_token() -> PathBuf { + state_root().join("matrix-register-token") +} + +/// `.meta-migration-done` — one-shot marker: legacy meta layout migrated. +#[must_use] +pub fn meta_migration_marker() -> PathBuf { + state_root().join(".meta-migration-done") +} + +/// `.hroot-rename-done` — one-shot marker: legacy hive-root rename applied. +#[must_use] +pub fn hroot_rename_marker() -> PathBuf { + state_root().join(".hroot-rename-done") +} + +/// `/run/hyperhive` — the runtime root (host admin socket + per-agent dirs). +#[must_use] +pub fn runtime_root() -> PathBuf { + PathBuf::from(RUNTIME_ROOT) +} + +/// `/run/hyperhive/agents` — per-agent runtime dir root (regenerated each boot). +#[must_use] +pub fn agent_runtime_root() -> PathBuf { + runtime_root().join("agents") +} + +/// `/run/hyperhive/agents/` — one agent's runtime dir. +#[must_use] +pub fn agent_runtime_dir(name: &str) -> PathBuf { + agent_runtime_root().join(name) +} + +/// `/run/hive-agent` — per-agent socket dir root (web + bound markers). +#[must_use] +pub fn agent_socket_dir() -> PathBuf { + PathBuf::from(AGENT_SOCKET_DIR) +} + /// Move any host-side state file still at its legacy flat location /// (directly under [`STATE_ROOT`]) into its new subdir. Idempotent and /// rename-based: a move only happens when the old path exists and the