Doc-only. B2 specifies the Gitea service account and its scoped token, but never says the project repo's default branch must be protected — which this week's exercise showed is the load-bearing part of the PR gate.
The finding, stated plainly: in Gitea, write access includes merging pull requests. The agent needs write to push branches, so it can also merge. Repository ownership does not change this — an account that merely collaborates can still merge, and one that owns the repo can merge and delete it. I confirmed this empirically against the sandbox: before protection was configured, the agent's own token merged its own PR (HTTP 200).
That means the review gate was holding only because our code does not call the merge endpoint — an advisory guarantee, which is exactly what A4 exists to rule out. With protection on, the same probe returns 405 ("Does not have enough approvals"), and a direct push to the default branch is refused outright.
The amendment records:
what must be configured (block direct pushes by the agent account; restrict merging to the operator via merge whitelist or required approvals the agent cannot satisfy),
that feature-branch pushes are unaffected, so the agent's workflow is unchanged,
and that the property should be asserted rather than assumed, so relaxing the protection later fails a test instead of quietly removing the gate. #18 carries that live assertion.
Sandbox is already configured this way. The same applies to real project repos when they exist.
Doc-only. B2 specifies the Gitea service account and its scoped token, but never says the project repo's **default branch must be protected** — which this week's exercise showed is the load-bearing part of the PR gate.
**The finding, stated plainly:** in Gitea, *write access includes merging pull requests*. The agent needs write to push branches, so it can also merge. Repository ownership does not change this — an account that merely collaborates can still merge, and one that owns the repo can merge and delete it. I confirmed this empirically against the sandbox: **before protection was configured, the agent's own token merged its own PR (HTTP 200).**
That means the review gate was holding only because our code does not call the merge endpoint — an advisory guarantee, which is exactly what A4 exists to rule out. With protection on, the same probe returns 405 ("Does not have enough approvals"), and a direct push to the default branch is refused outright.
The amendment records:
- what must be configured (block direct pushes by the agent account; restrict merging to the operator via merge whitelist or required approvals the agent cannot satisfy),
- that feature-branch pushes are unaffected, so the agent's workflow is unchanged,
- and that the property should be **asserted rather than assumed**, so relaxing the protection later fails a test instead of quietly removing the gate. #18 carries that live assertion.
Sandbox is already configured this way. The same applies to real project repos when they exist.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
B2 specified the service account and its scoped token but never said
the project repo's default branch must be protected — which turns out
to be the load-bearing part of the PR gate.
In Gitea, write access includes merging pull requests, and repository
ownership does not restrict merging either. So an agent with the
access it needs to push branches can also merge its own PR, and the
review gate holds only because the agent's code does not call the
merge endpoint. That is the advisory guarantee A4 exists to rule out.
Verified rather than assumed: before protection was configured, the
agent's own token merged its own PR (HTTP 200). With protection it is
refused (405), as is a direct push to the default branch. The
amendment says to assert both, so relaxing the protection later fails
a test instead of silently removing the gate.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Doc-only. B2 specifies the Gitea service account and its scoped token, but never says the project repo's default branch must be protected — which this week's exercise showed is the load-bearing part of the PR gate.
The finding, stated plainly: in Gitea, write access includes merging pull requests. The agent needs write to push branches, so it can also merge. Repository ownership does not change this — an account that merely collaborates can still merge, and one that owns the repo can merge and delete it. I confirmed this empirically against the sandbox: before protection was configured, the agent's own token merged its own PR (HTTP 200).
That means the review gate was holding only because our code does not call the merge endpoint — an advisory guarantee, which is exactly what A4 exists to rule out. With protection on, the same probe returns 405 ("Does not have enough approvals"), and a direct push to the default branch is refused outright.
The amendment records:
Sandbox is already configured this way. The same applies to real project repos when they exist.
🤖 Generated with Claude Code