config PRs: document the operator merge, deploy only merges into main
docs: the config-repo `main` merge gate (merge = `core` + team `operators`, approvals = `operators`), the operator merge in the forge UI and what it deploys, the hand-added `operators` membership, and that with no eval-verify a failed rebuild leaves `applied/main` at the merged commit. The swarm README lists the converged gate and the merge deploy. `merged()` also requires `pull_request.base.ref == "main"`: the hive deploys its config repo's `main`, so a merge into another branch would only cost a forge fetch and a refusal comment (argus, #4894). Refs #4850
This commit is contained in:
parent
f1c695c212
commit
a5ea015bc6
4 changed files with 90 additions and 16 deletions
|
|
@ -62,9 +62,10 @@ request.
|
|||
config, not the tree to edit: authoring in place there produces no PR
|
||||
and no approval. (it's currently mounted read-write, which is a
|
||||
defect tracked separately, not an authoring path.)
|
||||
Branch protection (push/merge allowlist = `core`, approvals allowlist
|
||||
= operator team; see "Forge mirror" below) makes the agent a
|
||||
write collaborator that **can't merge its own config PR**.
|
||||
Branch protection (the agent isn't on the `main` push allowlist;
|
||||
merge allowlist = `core` user + `operators` team; approvals allowlist
|
||||
= `operators` team; see "Forge mirror" below) makes the agent a write
|
||||
collaborator that **can't merge its own config PR**.
|
||||
2. hive-c0re's `/webhook/config-pr` endpoint receives the Forgejo
|
||||
`pull_request` event (opened / synchronized / reopened) and queues a
|
||||
`MergeConfigPr` approval; a poll fallback catches any missed webhook.
|
||||
|
|
@ -109,6 +110,39 @@ request.
|
|||
canonical sha and the terminal tag (the approval row carries a
|
||||
`submitter` column recording the agent the change is for).
|
||||
|
||||
### Operator merge in the forge UI
|
||||
|
||||
An operator can also merge a config PR straight in the Forgejo UI. That
|
||||
deploys the merged commit on the hive that runs the agent:
|
||||
|
||||
1. swarm-controller gets the `agent-configs` org's `pull_request`
|
||||
delivery. A `closed` event with `merged: true` and base branch `main`
|
||||
names the commit in `merge_commit_sha`.
|
||||
2. The controller looks up which hive's wanted state places the agent
|
||||
and publishes a deploy request carrying that commit on that hive's
|
||||
deploy subject. With no such hive, or more than one, it deploys
|
||||
nothing and logs a warning naming them.
|
||||
3. If the hive's `applied/main` already is that commit — a dashboard
|
||||
approval merges and deploys its own PR — it does nothing. Otherwise
|
||||
it fetches the config repo's `main`, requires the commit to descend
|
||||
from `applied/main`, fast-forwards `applied/main` to it, and queues a
|
||||
rebuild. A failure before the rebuild (the fetch, or a commit that
|
||||
doesn't descend) deploys nothing and posts the error as a comment on
|
||||
the merged PR. An agent with no container on that hive yet ignores
|
||||
the commit; its first deploy builds what it seeds.
|
||||
|
||||
This path runs **no eval-verify**. A merged config that doesn't
|
||||
evaluate or build fails the rebuild, and `applied/main` stays at that
|
||||
commit, so the agent's rebuilds keep failing until a fix merges. A
|
||||
failed rebuild shows on the hive like any other and isn't commented on
|
||||
the PR.
|
||||
|
||||
Merging needs membership of the `operators` team in `agent-configs`.
|
||||
The team starts empty: add each operator by hand in the forge UI. A
|
||||
merge whose webhook delivery never reaches the controller deploys
|
||||
nothing. The hive's own poll cancels the dashboard card for that PR
|
||||
with the note `PR merged/closed outside the approval`.
|
||||
|
||||
### Withdrawing a pending approval
|
||||
|
||||
The submitting agent can call `cancel_loose_end(kind: "approval", id)` to
|
||||
|
|
@ -450,9 +484,12 @@ forge never blocks a deploy.
|
|||
Each agent is a **write collaborator on its own** `agent-configs/<name>`
|
||||
repo — so it can push a branch and open a config PR — but not a member
|
||||
of any other agent's, so it can't reach another agent's config through
|
||||
the forge. Branch protection keeps `main` push/merge `core`-only with
|
||||
operator-team approval, so an agent can't fast-forward its own config or
|
||||
self-merge its PR (see the End-to-end flow above). hive-c0re passes the tokenised push
|
||||
the forge. Branch protection keeps the agent off the `main` push
|
||||
allowlist and whitelists merging to the `core` user and the `operators`
|
||||
team, so an agent can't fast-forward its own config or self-merge its
|
||||
PR (see the End-to-end flow and
|
||||
[Operator merge in the forge UI](#operator-merge-in-the-forge-ui) above).
|
||||
hive-c0re passes the tokenised push
|
||||
URL inline to `git push`, never writing it into
|
||||
`applied/<n>/.git/config`; that repo is RO-bind-mounted into the root
|
||||
agent, and a stored token would leak core's admin credential to an
|
||||
|
|
|
|||
Loading…
Reference in a new issue