Watch
0
0
Fork
You've already forked hyperhive
0

hive-c0re: drop the spawn-time forge user-email, repo-creation and config-repo passes

sync_agent no longer runs ensure_user_email, ensure_repo_creation_disabled
or ensure_config_repo. swarm-controller does all three before any deploy:
CreateForgeUser sets the account email and max_repo_creation = 0 (and the
agent_token backfill re-runs CreateForgeUser), CreateRepo creates and
protects agent-configs/<agent>, AddRepoMember grants the agent write on it,
and InitAgentConfigRepo seeds it.

What goes with them: the email-aligned and repo-creation-disabled marker
paths and the legacy email-marker relocate, sparse_edit_user_option,
is_forbidden and its tests, and ensure_org_repo. A config repo deleted by
hand is no longer recreated on the next spawn; the operator recreates the
agent at swarm level. Comments in swarm-controller that described the
removed hive passes now state only the current behaviour.

Closes #4848
This commit is contained in:
atlas 2026-10-04 20:12:48 +02:00 • committed by mara
commit 1de8a01936
6 changed files with 44 additions and 351 deletions

View file

@ -397,8 +397,8 @@ impl Client {
/// Then locks the account out of creating repos
/// ([`Self::disable_repo_creation`]), whether it was just created or
/// already existed. Nothing else does that for a swarm-created agent, so
/// a failure fails the node. Does not align the account's email the way
/// `hive-c0re`'s `ensure_user_email` does — cosmetic, not a guard.
/// a failure fails the node. Leaves an existing account's email as it
/// finds it.
pub async fn ensure_agent_user(&self, agent: &str) -> Result<()> {
self.create_agent_user(agent).await?;
self.disable_repo_creation(agent).await
@ -421,13 +421,8 @@ impl Client {
/// account once and checks the one thing that *is* comparable: the
/// email. A match against either [`agent_email`] (what
/// `create_agent_user` itself sets) or [`legacy_agent_email`] (what
/// `hive-c0re::forge::users::ensure_user_exists` used before its own
/// `ensure_user_email` alignment pass runs) counts as this agent's
/// account — the legacy value has to be accepted too, not just the
/// aligned one, because `ensure_user_email` only runs on the forge-host
/// hive and only once it has a core token and has ticked at least once,
/// so a real, existing legacy agent can still carry the old email when
/// this node reads it mid-rollout. A mismatch against both means the
/// older hive-created agent accounts carry) counts as this agent's
/// account. A mismatch against both means the
/// name collided with an account this node didn't create, so it fails
/// the node rather than sending the PATCH (or silently skipping) to an
/// account nobody verified is agent-controlled.
@ -1139,30 +1134,23 @@ fn initial_flake_nix() -> &'static str {
/// [`Client::disable_repo_creation`] before it sends the account's PATCH. Same
/// format string as `hive-c0re::forge::users::agent_email` — not called
/// across the crate boundary (see this module's doc comment), but both
/// creators (and `hive-c0re`'s `ensure_user_email`, which aligns older
/// accounts to it) converge on this exact value, so it doubles as the
/// creators use this exact value, so it doubles as the
/// marker that distinguishes an agent's own account from an unrelated one
/// that happens to share its username.
fn agent_email(agent: &str) -> String {
format!("{agent}@hyperhive.local")
}
/// The pre-alignment email `hive-c0re::forge::users::ensure_user_exists`
/// gave an agent account before that crate's own `ensure_user_email`
/// existed — see that function's doc comment ("Existing agents were
/// created with `{name}@hive.local`; this corrects that"). Accepted by
/// [`Client::disable_repo_creation`]'s guard alongside [`agent_email`]
/// because `ensure_user_email`'s alignment PATCH only runs on the
/// forge-host hive, and only after it has a core token and has ticked at
/// least once, so a real legacy agent can still carry this value when this
/// node reads it.
/// The email older hive-created agent accounts carry, and keep: nothing
/// rewrites it to [`agent_email`]. Accepted by
/// [`Client::disable_repo_creation`]'s guard alongside [`agent_email`] so
/// such an account is still recognised as the agent's own.
fn legacy_agent_email(agent: &str) -> String {
format!("{agent}@hive.local")
}
/// The `admin_edit_user` body that sets `max_repo_creation = 0` on `agent`
/// and nothing else. Same shape as `hive-c0re::forge::users`'
/// `sparse_edit_user_option`: `login_name` + `source_id = 0` (local auth,
/// and nothing else. `login_name` + `source_id = 0` (local auth,
/// which is what [`Client::create_agent_user`] creates) ride along because
/// Forgejo resets `use_custom_avatar` on an admin edit that omits
/// `login_name`; every other field is left unset so nothing else is touched.
@ -1548,9 +1536,9 @@ mod tests {
}
/// A refused lockdown fails the node with Forgejo's own message, rather
/// than warning and reporting the account as provisioned — that is
/// `hive-c0re`'s `ensure_repo_creation_disabled` shape, which leaves an
/// agent able to create and self-merge with nothing marked failed.
/// than warning and reporting the account as provisioned, which would
/// leave an agent able to create and self-merge with nothing marked
/// failed.
#[tokio::test]
async fn a_refused_lockdown_fails_the_node() {
let (client, _seen) = stub_forge(
@ -1598,10 +1586,9 @@ mod tests {
);
}
/// A legacy account `hive-c0re::forge::users::ensure_user_exists` (or
/// its `ensure_user_email` alignment pass) created carries the same
/// `{agent}@hyperhive.local` marker, plus the `login_name`/`source_id`
/// fields its own `sparse_edit_user_option` sets — this node must still
/// A legacy hive-created account can carry the same
/// `{agent}@hyperhive.local` marker, plus `login_name`/`source_id` from
/// a hive admin edit — this node must still
/// lock such an account down, not just ones it created itself.
#[tokio::test]
async fn a_legacy_hive_created_agent_account_still_gets_locked_down() {
@ -1621,14 +1608,9 @@ mod tests {
assert_eq!(body["max_repo_creation"], 0);
}
/// argus's round-2 🟡: `hive-c0re`'s `ensure_user_email` alignment pass
/// (the thing that rewrites a legacy `{name}@hive.local` account to
/// `{name}@hyperhive.local`) only runs on the forge-host hive, and only
/// once it has a core token and has ticked — so a real, pre-existing
/// agent can still be sitting on the pre-alignment `@hive.local` email
/// when this node reads it. The guard must accept that value too, not
/// just the aligned one, or a real agent would fail with "not this
/// agent's" during the rollout window.
/// A real, pre-existing agent account can carry the legacy
/// `@hive.local` email, and nothing rewrites it. The guard must accept
/// that value too, or such an agent would fail with "not this agent's".
#[tokio::test]
async fn a_pre_alignment_legacy_email_still_gets_locked_down() {
let (client, seen) = stub_forge(