docs(agents): why main requires cargo and not docker #131

Merged
jlxq0 merged 1 commit from branch-protection into main 2026-08-27 02:05:22 +00:00
Owner

Records the branch-protection rule armed on main today and, more usefully, why one context is required and another is deliberately not.

What was there before

enable_push=true  enable_status_check=false  contexts=null  required_approvals=0  apply_to_admins=true

A rule that exists and gates nothing. It read as protected in any listing and git push origin main went straight through.

What is there now

enable_push=false  apply_to_admins=true  enable_status_check=true
status_check_contexts=["CI / cargo*"]  required_approvals=0

required_approvals=0 keeps this free: work still merges without a second person, and CI merely stops being bypassable.

Why CI / cargo* and not CI / docker

Measured on this repository's own statuses, on commits where something failed rather than on green ones:

commit why docker skipped docker status docker task
c17aa805 needs: cargo failed pending skipped
a0a389d3 needs: cargo failed success skipped
3409c72 if: != pull_request success skipped

The same context reports two different wrong answers. Requiring it would build a gate satisfied by a commit whose cargo failed and where nothing was built, and one that on other commits never resolves at all. docker also cannot run on a pull request by its own if:, so its green there is always a skip.

The glob covers both event suffixes: a branch push posts CI / cargo (push), a pull-request head posts CI / cargo (pull_request).

Acceptance, before arming main

A rule read back from the server says it was stored, not that it bites. On a throwaway branch with a throwaway rule:

push 1, no rule armed                 rc=0, branch created
rule armed  enable_push=false, apply_to_admins=true
push 2                                rc=1
  remote: Forgejo: Not allowed to push to protected branch probe-protection
  ! [remote rejected] (pre-receive hook declined)

Both probes deleted afterwards, and git ls-remote --heads confirmed the branch list holds nothing that should not be there and exactly one rule remains.

This pull request is the second half of that acceptance: the first change to merge under the new flags, chosen because nothing depends on its outcome.

What arming did to the four open pull requests

PR mergeable head CI / cargo effect
#123 true success unaffected
#108 false success already unmergeable, unchanged
#94 true failure now blocked, and it was already red
#88 true success unaffected

Nothing was stranded that was not already broken, and #94 is the reason the second AGENTS.md entry exists: the API reported mergeable=true for a head whose cargo had failed, so reading that field would have said nothing was stranded when something was.

Records the branch-protection rule armed on `main` today and, more usefully, why one context is required and another is deliberately not. ## What was there before enable_push=true enable_status_check=false contexts=null required_approvals=0 apply_to_admins=true A rule that exists and gates nothing. It read as protected in any listing and `git push origin main` went straight through. ## What is there now enable_push=false apply_to_admins=true enable_status_check=true status_check_contexts=["CI / cargo*"] required_approvals=0 `required_approvals=0` keeps this free: work still merges without a second person, and CI merely stops being bypassable. ## Why `CI / cargo*` and not `CI / docker` Measured on this repository's own statuses, on commits where something failed rather than on green ones: | commit | why docker skipped | docker status | docker task | |---|---|---|---| | `c17aa805` | `needs: cargo` failed | **pending** | skipped | | `a0a389d3` | `needs: cargo` failed | **success** | skipped | | `3409c72` | `if: != pull_request` | **success** | skipped | **The same context reports two different wrong answers.** Requiring it would build a gate satisfied by a commit whose `cargo` failed and where nothing was built, and one that on other commits never resolves at all. `docker` also cannot run on a pull request by its own `if:`, so its green there is always a skip. The glob covers both event suffixes: a branch push posts `CI / cargo (push)`, a pull-request head posts `CI / cargo (pull_request)`. ## Acceptance, before arming `main` A rule read back from the server says it was stored, not that it bites. On a throwaway branch with a throwaway rule: push 1, no rule armed rc=0, branch created rule armed enable_push=false, apply_to_admins=true push 2 rc=1 remote: Forgejo: Not allowed to push to protected branch probe-protection ! [remote rejected] (pre-receive hook declined) Both probes deleted afterwards, and `git ls-remote --heads` confirmed the branch list holds nothing that should not be there and exactly one rule remains. **This pull request is the second half of that acceptance**: the first change to merge under the new flags, chosen because nothing depends on its outcome. ## What arming did to the four open pull requests | PR | `mergeable` | head `CI / cargo` | effect | |---|---|---|---| | #123 | true | success | unaffected | | #108 | false | success | already unmergeable, unchanged | | #94 | true | **failure** | now blocked, and it was already red | | #88 | true | success | unaffected | **Nothing was stranded that was not already broken**, and #94 is the reason the second `AGENTS.md` entry exists: the API reported `mergeable=true` for a head whose `cargo` had failed, so reading that field would have said nothing was stranded when something was.
docs(agents): why main requires cargo and not docker
All checks were successful
CI / cargo (pull_request) Successful in 2m30s
CI / docker (pull_request) Has been skipped
33e01d8af7
Branch protection on main is now enable_push=false, apply_to_admins=true,
enable_status_check=true, contexts=["CI / cargo*"], required_approvals=0. The
rule existed before with enable_push=true and enable_status_check=false, so it
read as protected in any listing and gated nothing: a plain push to main went
through.

The glob covers both event suffixes, since a branch push posts CI / cargo
(push) and a pull-request head posts CI / cargo (pull_request).

docker is excluded, and the entry records the measurement rather than the
conclusion. A skipped job still posts a status, and in this repository it posts
two different wrong answers depending on why it skipped: pending when it was
skipped because cargo failed, and success both when skipped for the same reason
on another commit and when skipped by its own if: condition on a pull request.
So requiring it would build a gate satisfied by a commit whose cargo failed and
where nothing was built, and one that on other commits never resolves. The rule
itself shows what is required and says nothing about why docker is absent,
which is how it comes back.

The second entry is the thing that nearly hid the answer: mergeable=true from
the pull-request API does not account for the status gate. PR 94 read
mergeable=true with a red cargo on its head at the moment main was armed, so
reading that field would have said nothing was stranded when something was.

Verified by removal before arming, on a throwaway branch with a throwaway rule:
first push with no rule succeeded, rule armed, second push refused with
"Not allowed to push to protected branch" and "pre-receive hook declined", exit
1. Both probes deleted afterwards and the remote branch list confirmed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEgtox6vnEkYPv9PrCCoYG
jlxq0 merged commit 4bd4f4a861 into main 2026-08-27 02:05:22 +00:00
jlxq0 deleted branch branch-protection 2026-08-27 02:05:22 +00:00
Sign in to join this conversation.
No description provided.