No repo requires a passing status check to merge, so 'do not merge red' is a habit rather than a gate #927
Labels
No labels
burndown-2026-06
burndown-2026-08
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/advocate
role/director
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/science
role/sysadmin
state
ambient
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/infrastructure#927
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Raised by Kai noticing that merge behavior looked inconsistent between repositories. It is not: the repositories are uniform, and what varies is whoever is driving.
What I measured
Eight repositories across four orgs, reading
main's branch protection rather than inferring from behavior:status_check_contextsisnulleverywhere. Merge settings are uniform too: squash default, fast-forward-only allowed, delete-branch-after-merge on.So no repository blocks a merge on red CI. Every one of them will merge a failing pull request today.
Why it matters, with a worked example
coilyco-flight-deck/wardsat red onmainfrom 2026-08-17 to 2026-08-25 and kept accepting merges the whole time. Nothing stopped anyone, andpromote.ymlre-runs the gate on every push tomain, so the red propagated toreleaseby simply never advancing it: eight days with no release cut while the tap stayed pinned at0.887.0.What actually held the line was a person.
ward#1681records its author writing "I am leaving it open and unmerged rather than merging a red PR" aboutward#1680. That is exactly the right call and it is completely unenforced. The next agent or the same agent on a worse day merges it.I did the same thing four times in one session and unevenly: waited for green on four pull requests, held one back for being red, and held another for a reason that was not CI at all. Consistent-looking behavior, entirely dependent on me remembering.
Two mechanisms, not one
Branch protection is the gate: set
enable_status_checkwith the rightstatus_check_contextsper repo, and the forge refuses the merge. This is the durable half, and it is what makes the rule a property of the repository.merge_when_checks_succeedis a flag on Forgejo's merge API that neither I nor, as far as I can tell, any tooling here passes. It schedules the merge for when checks go green instead of merging now. That is the built-in version of the polling loops agents hand-roll, and it removes a whole class of "waited, got distracted, merged stale".The two compose: protection refuses a red merge, the flag stops anyone needing to sit and watch.
Why this is filed here
Per the authoring-versus-rollout split, a fleet-wide convergence of forge settings is an ansible rollout rather than a per-repo edit, and this repository owns rollout. The per-repo context-name list is the real work:
status_check_contextshas to name the checks each repository actually produces, and getting it wrong locks a repository rather than guarding it.What I did not do
I did not turn it on anywhere. It is a fleet policy change that could wedge every repository at once if the context names are wrong, and Kai should decide the shape before anything converges. Filed rather than flipped.
Suggested sequence
mainstalls a pipeline)status_check_contextsper repository from its actual workflow job names rather than a hand-written listmerge_when_checks_succeedso waiting stops being a polling loop