hives read the forge through their own swarm-minted read account
swarm-controller now gives every hive in its directory a forge account, `hive-<hive>`, in a new `hives` team of `agent-configs` (read on `repo.code` + `repo.pulls`, every repo including later ones), and mints one `read:repository` token named `swarm-hive` into the store at `swarm/hives/<hive>/forge/token`. A five-minute pass queues a `MintHiveForgeToken` node for a hive whose token is missing or no longer matches the forge, whose account is missing, or whose team membership or team settings drifted. A hive whose store or forge read failed is never queued, so an outage cannot rotate every hive's token. The token decision reuses `agent_token`'s classifier and replace step, now parameterised by name and scopes. An agent may be called `hive-<x>`. The hive account is created with `hive-<hive>@hives.hyperhive.local` and the job refuses an account by that name with any other email before it locks it down, adds it to the team or mints for it; agent creation already refuses the hive's account by the same email check. The controller's bao policy gains the `swarm/hives/+/forge/token` leaf (create/read/update), pinned by the bao-grants module-eval assertion. The hive's own policy already reads `swarm/hives/<hive>/*`. hive-c0re reads that token through `forge::reader_token()`, falling back to the core token file when the store holds none, and uses it for: fetching a merged config rev (swarm deploy, `hivectl forge reconcile-config`), reseeding a purged `applied`, the meta-update cascade's fast-forward, seeding `proposed` on first deploy, and finding the PR that merged a refused rev. Those reads no longer require a local `hive-forge` container. The `/knowledge` clone moves from the forge host's boot sweep into the knowledge pull, so every hive clones it. Posting the deploy-failure comment on that PR stays on the core token. Refs #4851
This commit is contained in:
parent
c8472966e9
commit
21e3f626f4
17 changed files with 1222 additions and 138 deletions
|
|
@ -15,7 +15,7 @@ each agent on relevant activity.
|
|||
|
||||
## Token scopes
|
||||
|
||||
Two scope sets:
|
||||
Three scope sets:
|
||||
|
||||
**`AGENT_TOKEN_SCOPES`** (swarm-controller's `forge::agent_token`, pinned
|
||||
by a test). swarm-controller mints every agent token with it:
|
||||
|
|
@ -40,6 +40,53 @@ hive-c0re only mints the token when the file at
|
|||
a token minted with admin scopes keeps them until an operator deletes that
|
||||
file and restarts hive-c0re.
|
||||
|
||||
**`HIVE_TOKEN_SCOPES`** (swarm-controller's `forge::hive_token`, pinned by a
|
||||
test): `read:repository` alone, for each hive's read-only account (next
|
||||
section).
|
||||
|
||||
---
|
||||
|
||||
## How a hive reads the forge
|
||||
|
||||
Each hive in swarm-controller's hive directory has its own forge account,
|
||||
`hive-<hive>`. swarm-controller creates it, makes it a member of the `hives`
|
||||
team in `agent-configs`, and mints one token named `swarm-hive` into the
|
||||
swarm secret store at `swarm/hives/<hive>/forge/token`. The team has read
|
||||
permission on `repo.code` and `repo.pulls` of every repo in the org,
|
||||
including repos created later. A pass at start and every five minutes
|
||||
creates what's missing and re-mints a token that's missing or no longer
|
||||
matches the forge. A pass whose store or forge reads fail queues nothing, so
|
||||
an outage never rotates every hive's token.
|
||||
|
||||
The account name isn't reserved, so an agent may carry the name `hive-<x>` too.
|
||||
swarm-controller creates the hive's account with the email
|
||||
`hive-<hive>@hives.hyperhive.local` and refuses an account by that name with
|
||||
any other email: it never adds an agent's account to the team or mints a
|
||||
token for it. An agent's own creation refuses the hive's account the same
|
||||
way.
|
||||
|
||||
hive-c0re reads the token with `forge::reader_token()`, under the hive's own
|
||||
store certificate, every time it reads the forge. Where the store holds none,
|
||||
it falls back to the `core` token file, which only the host running the forge
|
||||
container has. These reads go through it, and none of them needs a local
|
||||
forge container:
|
||||
|
||||
- fetching a merged config commit for a swarm deploy, and
|
||||
`hivectl forge reconcile-config`
|
||||
- reseeding a purged `applied` repo, and the meta-update cascade's
|
||||
fast-forward of `applied/main`
|
||||
- seeding `proposed` from `agent-configs/<agent>` on first deploy
|
||||
- finding the PR that merged a config commit the hive refused to deploy
|
||||
- cloning and pulling `/knowledge`
|
||||
|
||||
Posting the refusal as a comment on that PR still needs the `core` token, so
|
||||
only the forge host posts it.
|
||||
|
||||
Roll a change to any of this out store host first (its granter writes the
|
||||
controller's grant on `swarm/hives/+/forge/token`), then the controller host,
|
||||
then the hives. A hive that starts before its token exists reads with the
|
||||
core file, or not at all, until the controller's next pass.
|
||||
|
||||
---
|
||||
|
||||
## Per-agent forge accounts
|
||||
|
|
|
|||
|
|
@ -87,10 +87,12 @@ message only, no forced wake, and it carries the standard "this was a
|
|||
broadcast" hint. hive-c0re logs a diff or per-agent send failure
|
||||
without blocking the pull itself.
|
||||
|
||||
`knowledge::ensure_local_clone` creates (or refreshes) the local
|
||||
clone once at startup. If the repo is brand new and
|
||||
empty, `ensure_local_clone` seeds it with the default README
|
||||
before returning.
|
||||
On a hive with no local clone yet, `knowledge::pull()` takes the clone
|
||||
instead of pulling, so every hive gets `/knowledge` from its first pull,
|
||||
whether or not it runs the forge. It authenticates with the hive's forge
|
||||
read token when it has one (see
|
||||
[forge.md](forge.md#how-a-hive-reads-the-forge)) and clones the public
|
||||
repo anonymously otherwise.
|
||||
|
||||
## State
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue