Merge pull request 'Record default-branch protection as a B2 requirement' (#19) from b2-branch-protection into main
CI / checks (push) Successful in 39s

This commit was merged in pull request #19.
This commit is contained in:
dev-agent committed 2026-09-07 22:55:22 +00:00
commit 1f292793c1
1 file changed
+19
+19
View File
@@ -550,6 +550,25 @@ PR_OPEN
- *Outbound:* `git` + Gitea API to push branches and open PRs, via a dedicated - *Outbound:* `git` + Gitea API to push branches and open PRs, via a dedicated
Gitea **service account** with a scoped token. Record any runnable test service's Gitea **service account** with a scoped token. Record any runnable test service's
URL/port in the PR description. URL/port in the PR description.
- **The project repo's default branch must be protected, and this is what makes
the PR gate real.** The service account needs write access to push branches —
and in Gitea, *write access includes merging pull requests*. Repository
ownership does not help: an account that merely collaborates can still merge,
and one that owns the repo can merge and delete it. So without branch
protection the agent can merge its own PR, and the review gate holds only
because the agent's code does not call the merge endpoint. That is precisely
the advisory guarantee A4 exists to rule out.
- Required on the default branch: **block direct pushes** by the agent
account, and **restrict merging** to the operator (a merge whitelist, or
required approvals that the agent's own account cannot satisfy).
- Feature-branch pushes are unaffected, so the agent's normal workflow is
unchanged.
- **Verify it rather than assume it.** The property is observable from
outside: the agent's own token must be refused when it attempts to merge
its own PR and when it pushes to the default branch. Assert both, so that
relaxing the protection later fails a test instead of silently removing
the gate. (Discovered the hard way — before protection was configured, the
agent's token merged its own PR successfully.)
- *Inbound:* react to PR comments, commits, pushes. **Poll** the Gitea API - *Inbound:* react to PR comments, commits, pushes. **Poll** the Gitea API
(15–30s) rather than take webhooks, to keep the VM outbound-only. Intake is (15–30s) rather than take webhooks, to keep the VM outbound-only. Intake is
structured JSON — never via a chat bridge. structured JSON — never via a chat bridge.