Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/nix/reserved-names.nix
atlas cafa120d77 swarm-builder: scope the forge token to the forge, one build at a time, opt-in
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.
2026-10-14 03:30:46 +02:00

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.