From d893097ffec5ad3859410de4c38ad380e3c6e503 Mon Sep 17 00:00:00 2001 From: atlas Date: Sun, 25 Oct 2026 19:42:54 +0100 Subject: [PATCH] remove the unread forge-core-token at startup --- docs/agent-lifecycle/config-changes.md | 6 +++--- hive-c0re/src/migrate.rs | 28 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/docs/agent-lifecycle/config-changes.md b/docs/agent-lifecycle/config-changes.md index 37814b49..17d31cf0 100644 --- a/docs/agent-lifecycle/config-changes.md +++ b/docs/agent-lifecycle/config-changes.md @@ -339,9 +339,9 @@ once already applied: (`agent_set::refresh`) from the current agent list. Set `HIVE_SKIP_META_MIGRATION=1` on the service to defer this phase. - **Legacy meta repo**: deletes the leftover `.git` in - `/var/lib/hyperhive/meta/` and the `meta` remote in each proposed repo. - The files beside the `.git` stay. The `core/meta` repo on the forge is - not touched. + `/var/lib/hyperhive/meta/`, the `meta` remote in each proposed repo and the + unread `/var/lib/hyperhive/forge-core-token`. The files beside the `.git` + stay. The forge-side `core/meta` repo and `core` account aren't touched. No state loss in either migration: claude creds, `/state/` notes, the events DB, and both proposed + applied history all survive. The root diff --git a/hive-c0re/src/migrate.rs b/hive-c0re/src/migrate.rs index 7c889216..04f04d9c 100644 --- a/hive-c0re/src/migrate.rs +++ b/hive-c0re/src/migrate.rs @@ -69,6 +69,11 @@ pub async fn run() -> Result<()> { migrate_harness_files(name); } + match remove_core_token(&crate::paths::state_root()) { + Ok(true) => tracing::info!("migration: removed the unread forge-core-token"), + Ok(false) => {} + Err(e) => tracing::warn!(error = ?e, "migration: removing the forge-core-token failed"), + } match remove_legacy_meta_git(&crate::paths::meta_root()) { Ok(true) => tracing::info!("migration: removed the legacy meta repo's .git"), Ok(false) => {} @@ -174,6 +179,17 @@ fn remove_legacy_meta_git(meta: &Path) -> Result { } } +/// Remove the forge admin token file an earlier hive left in `state`; nothing +/// reads it. `true` when it was there. +fn remove_core_token(state: &Path) -> Result { + let file = state.join("forge-core-token"); + match std::fs::remove_file(&file) { + Ok(()) => Ok(true), + Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false), + Err(e) => Err(e).with_context(|| format!("removing {}", file.display())), + } +} + /// Remove the `meta` remote from the proposed repo at `dir`. `true` when it /// was there; a missing remote, or a `dir` that is no repo, is `false`. async fn remove_meta_remote(dir: &Path) -> Result { @@ -342,6 +358,18 @@ mod tests { ); } + #[test] + fn core_token_goes_once_and_its_neighbours_stay() { + let dir = tempfile::tempdir().expect("tempdir"); + std::fs::write(dir.path().join("forge-core-token"), "x").expect("write token"); + std::fs::write(dir.path().join("forge-other"), "x").expect("write neighbour"); + + assert!(remove_core_token(dir.path()).expect("first")); + assert!(!dir.path().join("forge-core-token").exists()); + assert!(dir.path().join("forge-other").exists(), "neighbour stays"); + assert!(!remove_core_token(dir.path()).expect("second"), "no-op"); + } + #[tokio::test] async fn a_dir_that_is_no_repo_has_no_meta_remote() { let dir = tempfile::tempdir().expect("tempdir");