argus's review on #5177: the git credential helper answered every `get`, so a config PR's own flake inputs could have git send the builder's forge token to any host. The helper is now configured under `credential.<forge-url>.helper` and itself answers only an https request whose host is the forge's; a test runs it as git does and checks that other hosts, http and non-get operations get nothing. Builds are bounded: every `build_agent` node needs the one `builder` jobq resource, so one runs at a time and the rest wait pending, and a newer head cancels its PR's pending build (a running one finishes and writes on its own commit). The builder also holds a one-permit semaphore around each build. `builder` and `review-classifier`, the forge logins swarm-controller owns, join nix/reserved-names.nix, with a test tying the list to both constants. The builder is now opt-in like the CI runner: `allSwarmServices` no longer turns it on, since it runs unreviewed config PRs through the host's nix daemon. mara had not answered atlas's question on the PR.
104 lines
4.5 KiB
Nix
104 lines
4.5 KiB
Nix
# The one blacklist: names no agent and no hive may take.
|
|
#
|
|
# Nix owns this list and hands it to the Rust side as an environment variable
|
|
# (`HIVE_RESERVED_NAMES`), so keeping it current is a config change rather than
|
|
# a rebuild of a binary. Read by:
|
|
#
|
|
# - `host-modules/swarm-controller.nix` -> the env var, for the
|
|
# swarm-level `create_agent` path — the only name check that runs today
|
|
# - `host-modules/hive-c0re/environment.nix` -> the same var. hive-c0re
|
|
# creates no agent, so nothing reads it there now; still handed over so a
|
|
# future host-side path is wired by construction, not by remembering to.
|
|
# - `host-modules/swarm-otel.nix` -> its `<owner>` assertion, so
|
|
# a hive name and an agent name are checked against ONE list
|
|
# - `nix/checks.nix` -> exported into `cargo test`,
|
|
# which keeps the message layer's sentinels from drifting from this file
|
|
#
|
|
# A plain nix file rather than a module option because two of those readers are
|
|
# flake-level (`checks.nix`) and cannot see a NixOS option.
|
|
#
|
|
# ⚠️ Agent names and hive names are ONE namespace going forward (mara, 2026-08-27:
|
|
# "agent and hive names live in the swarm level going forward"). Adding a name
|
|
# here forbids it for both. That is the point: two lists is how they drift.
|
|
#
|
|
# ⚠️ Every entry must be a value some component actually PRODUCES as a message
|
|
# `from`/`to`, a component name the collector builds pipelines from, or a forge
|
|
# username the forge refuses or a swarm service owns — not a word that merely
|
|
# looked risky. A name nothing emits or refuses is a refusal with no failure.
|
|
#
|
|
# ⚠️ Matched by EQUALITY. Words forbidden *inside* a hive name live in
|
|
# `./reserved-hive-fragments.nix` — read its header before merging the two.
|
|
[
|
|
# ---- message-layer senders -------------------------------------------
|
|
# The human at the dashboard: the sender of operator-authored messages
|
|
# (`{from: "operator", ...}`) and the fallback attribution for an answered
|
|
# question.
|
|
"operator"
|
|
# Helper events (`container_crash`, `needs_update`) — the sender an
|
|
# agent is told to treat as hyperhive itself rather than as a peer.
|
|
# `hive_sh4re::manager::SYSTEM_SENDER`.
|
|
"system"
|
|
# A due self-scheduled reminder arrives as its own sender, so a wake I asked
|
|
# for last week is distinguishable from a peer message.
|
|
"reminder"
|
|
# Forge notification wakes, delivered by the notify daemon.
|
|
"forge"
|
|
# A scheduled prompt firing, pushed as a trusted sender.
|
|
"scheduled"
|
|
# Three synthetic wakes the harness itself produces: an in-container todo,
|
|
# the follow-up turn after a self-requested compaction, and the single flush
|
|
# turn before a graceful stop.
|
|
"todo"
|
|
"compact"
|
|
"graceful-stop"
|
|
|
|
# ---- swarm-tier component owners -------------------------------------
|
|
# The swarm collector names its components `<kind>/<owner>` and uses the hive
|
|
# name as the owner, so a hive called `swarm` would silently replace the
|
|
# swarm tier's own pipelines and lose its own — it would keep accepting
|
|
# pushes into a pipeline that routes nowhere. `swarm-otel.nix` asserts
|
|
# this name stays in the list, since its own `reservedOwners` reads it.
|
|
"swarm"
|
|
|
|
# ---- usernames the forge refuses -------------------------------------
|
|
# Every agent becomes a Forgejo user of the same name, and Forgejo answers
|
|
# these with a 422 one node into provisioning: `reservedUsernames` in
|
|
# Forgejo v16.0.5 `models/user/user.go:639-680`, and the bare `-` that
|
|
# `models/repo/repo.go:67` also refuses as a repo name. Forgejo's shape
|
|
# rules are not literals and live in `hive_types::forge_username_violation`.
|
|
# Its entries containing `.` or `_` are left out: `[a-z0-9-]` cannot spell them.
|
|
"-"
|
|
"admin"
|
|
"api"
|
|
"assets"
|
|
"attachments"
|
|
"avatar"
|
|
"avatars"
|
|
"captcha"
|
|
"explore"
|
|
"forgejo-actions"
|
|
"ghost"
|
|
"gitea-actions"
|
|
"issues"
|
|
"login"
|
|
"metrics"
|
|
"milestones"
|
|
"notifications"
|
|
"org"
|
|
"pulls"
|
|
"repo"
|
|
"repo-avatars"
|
|
"user"
|
|
"v2"
|
|
|
|
# ---- forge accounts swarm-controller owns ----------------------------
|
|
# Service accounts it creates under these logins (`forge::builder_account`,
|
|
# `forge::classifier_account`). An agent of the same name would be refused
|
|
# one node into provisioning, and would keep the service from its token.
|
|
"builder"
|
|
"review-classifier"
|
|
]
|
|
# Deliberately absent, and it is a load-bearing omission:
|
|
#
|
|
# `ruth` — a real agent, not a literal. A second agent wanting that name is a
|
|
# name that is TAKEN, which the roster answers, not this list.
|