Watch
0
0
Fork
You've already forked hyperhive
0

describe core/meta as the legacy permission repo; drop stale meta-flake prose

Comments, docs and the hive-c0re README no longer say the hive renders, locks or pushes a meta flake. core/meta is the legacy permission-seed repo that meta::remove_permission_files still commits to; builds come from internal/meta (meta_rev.rs). Docs note that a start of a stale stopped agent can fail until the swarm's update pins the config.
This commit is contained in:
atlas 2026-10-25 15:08:50 +01:00
commit bd54372fcc
9 changed files with 35 additions and 25 deletions

View file

@ -444,7 +444,10 @@ nothing; a rebuild would have no flake to build from either. A hive deploy
alone doesn't rebuild agents.
A stopped agent gets its rebuild at its next start: the start path upgrades
the start of a stale, stopped agent to a rebuild followed by the start.
the start of a stale, stopped agent to a rebuild followed by the start. In
the window after a config merge, before the swarm's update has pinned the new
config, that rebuild fails with the error that names the agent, and the
agent stays stopped until the update lands and you ask for the start again.
The dashboard surfaces pending config changes per agent: a clickable
"needs update ↻" badge appears whenever the agent's applied repo has a

View file

@ -122,10 +122,11 @@ Two things live in the `agent-configs` Forgejo organization:
[config-changes.md § Config changes](../agent-lifecycle/config-changes.md#config-changes)).
hive-c0re pushes nothing to this org; it only reads from it.
Repos stay private, so an agent can't read another
agent's config. (Agents remain read-only collaborators on `core/meta`.)
agent's config. (Agents remain read-only collaborators on the legacy
`core/meta`, the hive's old permission-seed repo.)
The agent's **persistent meta flake input** is this repo's `main` head,
pinned by sha (`agent-<n>.url = git+<forge>/agent-configs/<n>.git?rev=<sha>`;
see
pinned by sha in `internal/meta` (`agent-<n>.url =
git+<forge>/agent-configs/<n>.git?rev=<sha>`; see
[config-changes.md § Meta flake](../agent-lifecycle/config-changes.md#meta-flake)).
hive-c0re's own git reads of this repo, which resolve the sha, authenticate with the hive's read
token through `forge::reader_token()` (see

View file

@ -41,8 +41,11 @@ to track it:
per-agent sockets.
- **`forge/`** — optional Forgejo wiring (`docs/integrations/forge.md`).
- **`coordinator.rs`** — top-level wiring for `serve`.
- **`meta.rs`**, **`migrate.rs`** — the meta flake + schema/state
migrations.
- **`meta_rev.rs`** — which `internal/meta` commit an agent builds from, and
the markers a successful build writes. **`agent_set.rs`** — the files that
follow the agent set (topology, gateway map). **`meta.rs`** — the commit
that removes the legacy permission seed files. **`migrate.rs`** —
schema/state migrations.
- **`matrix.rs`**, **`gateway_nginx.rs`**, **`priv_client.rs`** —
matrix provisioning, gateway vhosts, and the `hive-priv` client
respectively.

View file

@ -1,5 +1,6 @@
//! Optional Forgejo wiring — the `core/meta` repo and meta read-access
//! grants. Those writes, as `core`, run only beside a local `hive-forge`
//! Optional Forgejo wiring — the legacy `core/meta` repo (the hive's old
//! permission-seed repo, which `meta::remove_permission_files` still commits
//! to) and its read-access grants. Those writes, as `core`, run only beside a local `hive-forge`
//! container; reads of the forge go through [`reader_token`] on every hive.
//! The swarm-wide orgs, teams and repos, and each agent's read grant on
//! `internal/docs`, are swarm-controller's. Full design:
@ -215,8 +216,8 @@ where
.map_err(|_| anyhow::anyhow!("{op}: no answer from the forge within {API_TIMEOUT:?}"))
}
/// Per-agent forge sync: grant read access to `core/meta`, and wire the
/// `meta` remote in its proposed repo. All operations are idempotent;
/// Per-agent forge sync: grant read access to the legacy `core/meta`, and wire
/// the `meta` remote in its proposed repo. All operations are idempotent;
/// failures are logged as warnings but don't abort the caller.
///
/// `core_token` is `core_token()` — passed in so callers that already
@ -234,8 +235,9 @@ pub async fn sync_agent(name: &str, core_token: Option<&str>) -> bool {
// swarm-controller's; this hive creates none of them and pushes nothing
// to the repo.
let mut ok = true;
// Grant read-only access to core/meta and wire the `meta` remote
// into the proposed repo so agents can fetch their deployment context.
// Grant read-only access to the legacy core/meta and wire the `meta`
// remote into the proposed repo. Agents build from `internal/meta`, not
// from this repo.
if let Some(token) = core_token
&& let Err(e) = meta_read_access(name, token).await
{
@ -249,7 +251,7 @@ pub async fn sync_agent(name: &str, core_token: Option<&str>) -> bool {
ok
}
/// The `core_token.is_some()` half of [`ensure_all`]: the meta repo, the
/// The `core_token.is_some()` half of [`ensure_all`]: the legacy meta repo, the
/// core avatar, and removing this hive's own config-PR hook —
/// every step that needs an authenticated forge client. The swarm-wide
/// objects (orgs, the `operators` team, mirrors, `internal/docs`,
@ -258,9 +260,9 @@ pub async fn sync_agent(name: &str, core_token: Option<&str>) -> bool {
/// `ensure_all` under clippy's function-length limit; not meant to be called
/// from anywhere else.
async fn ensure_all_orgs_and_repos(token: &str) {
// Meta repo lives at core/meta — pushed from git_commit in
// meta.rs on every deploy/lock-update. Make sure it exists
// before the first push hits a 404.
// The legacy meta repo lives at core/meta. The only push to it is
// `meta::remove_permission_files`' commit; make sure the repo exists
// before that push hits a 404.
if let Err(e) = ensure_repo("meta", token).await {
tracing::warn!(error = ?e, "forge: ensure_repo core/meta failed");
crate::warnings::set_boot_warning(
@ -380,7 +382,7 @@ async fn wait_until_ready() -> bool {
}
/// Sweep the forge at startup: seed the `core` admin user (hive-c0re's own
/// identity for pushing the meta repo + driving the API) and its token, the
/// identity for pushing the legacy meta repo + driving the API) and its token, the
/// `core/meta` repo and the local knowledge clone, then run [`sync_agent`]
/// over every existing container (manager + sub-agents). Agent accounts,
/// tokens and `agent-configs/<name>` repos are the swarm-controller's, as is

View file

@ -6,7 +6,7 @@
//!
//! `Status` is read-only (fetches forge `main` into a scratch ref, reports
//! the divergence). `Apply(Forge)` resets the local applied checkout to
//! forge `main`; the meta flake pins forge `main` itself, not this tree. It
//! forge `main`; `internal/meta` pins forge `main` itself, not this tree. It
//! does NOT auto-deploy. `Apply(Local)` is not supported: forge `main` is
//! branch-protected, so it only advances through a config-PR merge.

View file

@ -89,11 +89,12 @@ pub async fn ensure_repo(name: &str, token: &str) -> Result<()> {
}
/// Dashboard-warning guard for the meta non-fast-forward condition.
/// Held while `core/meta` remote is ahead of our local mirror; cleared
/// Held while the `core/meta` remote is ahead of our local mirror; cleared
/// automatically when the next push succeeds.
static META_NON_FF_GUARD: Mutex<Option<crate::warnings::WarningGuard>> = Mutex::new(None);
/// Push `dir` (the meta repo) to `core/meta` on the local forge.
/// Push `dir` (the legacy hive meta repo) to `core/meta` on the local forge.
/// Its one caller is `meta::remove_permission_files`' commit.
/// Best-effort: returns Err which callers log + ignore. No-op when
/// the core token isn't present yet (forge container not provisioned).
pub async fn push_meta(dir: &Path) -> Result<()> {
@ -150,7 +151,7 @@ pub async fn push_meta(dir: &Path) -> Result<()> {
}
/// Grant agent `name` read-only collaborator access to `core/meta` on
/// the forge so the agent can clone/fetch the meta flake. Idempotent:
/// the forge so the agent can clone/fetch that legacy repo. Idempotent:
/// re-adding an existing collaborator succeeds (Forgejo answers 204
/// either way).
pub async fn meta_read_access(name: &str, core_token: &str) -> Result<()> {
@ -168,7 +169,7 @@ pub async fn meta_read_access(name: &str, core_token: &str) -> Result<()> {
/// Add the forge `core/meta.git` URL as the `meta` remote in the
/// agent's proposed config repo so the agent (and the manager) can
/// fetch the meta flake from the forge. Idempotent: no-op when the
/// fetch that legacy repo from the forge. Idempotent: no-op when the
/// remote already points at the right URL, or when the proposed repo
/// does not exist yet. No-op when the forge is not running.
pub async fn ensure_meta_remote(name: &str) -> Result<()> {

View file

@ -65,7 +65,7 @@ fn matrix_base() -> Result<&'static str> {
///
/// # Errors
/// When `HYPERHIVE_HIVE_NAME` is unset or empty. That is the same variable
/// [`stored_sender_token`] logs in with and `hive-c0re`'s meta flake asserts
/// [`stored_sender_token`] logs in with and the swarm meta flake asserts
/// for every hive, so its absence is a broken deployment rather than a
/// supported one — and there is no safe default to fall back to: the only one
/// available is the shared account this replaced.

View file

@ -11,7 +11,7 @@
//! queued node: operator/intent actions update the row synchronously
//! at request time, then submit the DAG whose terminal `Reconcile`
//! reads the fresh value — rapid toggles are last-writer-wins and the
//! reconciles converge. Power toggles never commit to the meta repo.
//! reconciles converge.
use std::path::Path;
use std::sync::Mutex;

View file

@ -110,7 +110,7 @@
defaultText = lib.literalMD "`\"path:\${pkgs.path}\"`";
description = ''
Store-path URL of the nixpkgs the swarm builder's check flake
builds on. The generated meta flake does not use it: its `nixpkgs`
builds on. The swarm meta flake does not use it: its `nixpkgs`
follows `hyperhive/nixpkgs`.
Defaults to `"path:''${pkgs.path}"`, the nixpkgs the host NixOS