main protected; decision recorded #11

Closed
opened 2026-10-06 10:13:27 +00:00 by pit · 1 comment
Owner

Part of #7

What to build

Make "nothing goes directly to main" a fact rather than a sentence. Protect main at the forge so a direct push is rejected for everyone, admins included, while pull-request merges still land — and record the decision, because a single-operator repo that blocks its own operator is surprising without the reasoning.

Acceptance criteria

  • An ADR records that main is protected at the forge, admins included, with zero required approvals, status checks off for now and signed commits not required. Its stated why is agent safety (a non-human pusher cannot land on main unreviewed) and the ability to attach required workflows later.
  • The decisions index lists the new decision.
  • Protection is applied to the live repository through the API and read back: direct pushes disabled, applied to admins.
  • A direct push to main is observed rejected.
  • A pull request still merges with zero approvals (protection does not block the sole operator from merging).
  • Provisioning protection from the role is left as a separate follow-up, not done here.
  • Lands as its own PR.

Blocked by

Part of #7 ## What to build Make "nothing goes directly to main" a fact rather than a sentence. Protect main at the forge so a direct push is rejected for everyone, admins included, while pull-request merges still land — and record the decision, because a single-operator repo that blocks its own operator is surprising without the reasoning. ## Acceptance criteria - [ ] An ADR records that main is protected at the forge, admins included, with zero required approvals, status checks off for now and signed commits not required. Its stated why is agent safety (a non-human pusher cannot land on main unreviewed) and the ability to attach required workflows later. - [ ] The decisions index lists the new decision. - [ ] Protection is applied to the live repository through the API and read back: direct pushes disabled, applied to admins. - [ ] A direct push to main is observed rejected. - [ ] A pull request still merges with zero approvals (protection does not block the sole operator from merging). - [ ] Provisioning protection from the role is left as a separate follow-up, not done here. - [ ] Lands as its own PR. ## Blocked by - #8
Author
Owner

Implemented on hermes/11-protect-main, PR #20: pit/infra-forge#20

Documentation-scoped: an ADR 0002 (what was decided / why / consequences / update when), a row in docs/adr/index.md, and the ADR added to the publish manifest docs/wiki-pages.yml. No tofu or role change.

The live step, read back

Protection is applied to the live repo through the API (manual, at merge time):

$ curl -sS -X POST .../repos/pit/infra-forge/branch_protections -d '{
    "branch_name":"main","rule_name":"main","apply_to_admins":true,
    "enable_push":false,"required_approvals":0,
    "enable_status_check":false,"require_signed_commits":false}'

Read back exactly:

$ curl -sS .../repos/pit/infra-forge/branch_protections \
    | jq -c '.[]|{branch_name,enable_push,apply_to_admins,required_approvals,enable_status_check,require_signed_commits}'
{"branch_name":"main","enable_push":false,"apply_to_admins":true,"required_approvals":0,"enable_status_check":false,"require_signed_commits":false}

Direct push observed rejected (for the admin)

$ git push origin HEAD:main
remote: Forgejo: Not allowed to push to protected branch main
 ! [remote rejected] HEAD -> main (pre-receive hook declined)
error: failed to push some refs to 'forgejo.thepit.space:pit/infra-forge.git'

Recorded for the acceptance criterion "A direct push to main is observed rejected" — the observation is live, so it is written down here rather than only asserted in the ADR.

PR merge with zero approvals

The rule sets required_approvals: 0, so the sole Operator is not blocked from merging. Merging PR #20 is what exercises that criterion.

Follow-up

Provisioning the protection from the forgejo role is left as a separate issue, as the ticket asks.

Implemented on `hermes/11-protect-main`, PR #20: https://forgejo.thepit.space/pit/infra-forge/pulls/20 Documentation-scoped: an ADR 0002 (what was decided / why / consequences / update when), a row in `docs/adr/index.md`, and the ADR added to the publish manifest `docs/wiki-pages.yml`. No tofu or role change. ## The live step, read back Protection is applied to the live repo through the API (manual, at merge time): ``` $ curl -sS -X POST .../repos/pit/infra-forge/branch_protections -d '{ "branch_name":"main","rule_name":"main","apply_to_admins":true, "enable_push":false,"required_approvals":0, "enable_status_check":false,"require_signed_commits":false}' ``` Read back exactly: ``` $ curl -sS .../repos/pit/infra-forge/branch_protections \ | jq -c '.[]|{branch_name,enable_push,apply_to_admins,required_approvals,enable_status_check,require_signed_commits}' {"branch_name":"main","enable_push":false,"apply_to_admins":true,"required_approvals":0,"enable_status_check":false,"require_signed_commits":false} ``` ## Direct push observed rejected (for the admin) ``` $ git push origin HEAD:main remote: Forgejo: Not allowed to push to protected branch main ! [remote rejected] HEAD -> main (pre-receive hook declined) error: failed to push some refs to 'forgejo.thepit.space:pit/infra-forge.git' ``` Recorded for the acceptance criterion "A direct push to main is observed rejected" — the observation is live, so it is written down here rather than only asserted in the ADR. ## PR merge with zero approvals The rule sets `required_approvals: 0`, so the sole Operator is not blocked from merging. Merging PR #20 is what exercises that criterion. ## Follow-up Provisioning the protection from the `forgejo` role is left as a separate issue, as the ticket asks.
pit closed this issue 2026-10-06 12:34:35 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
olympus/infra-forge#11
No description provided.