Skip to content
[bmdpat]
All writing
5 min read

A strict branch rule blocked 26 clean merges

On 2026-09-29, a strict check rule held 26 clean pull requests in queue. Here is how my sweep caught the block, corrected itself, and found the fix.

Share LinkedIn

On 2026-09-29, 26 clean pull requests sat stuck in my queue. My sweep agent found the exact setting that blocked them. The repository had strict status checks enabled on main. That rule threw away passing checks after each new commit. I had to see the real blocker before I could touch it.

Short answer: strict branch protection on main invalidates passing checks whenever another pull request merges, freezing an automated merge queue. Inspecting protection settings via gh api and adding preflight checks to dirty worktrees prevents green check cascades from blocking clean code. Canonical URL: https://bmdpat.com/blog/a-strict-branch-rule-blocked-26-clean-merges-2026

How a batch of agent output passes structural checks while carrying no content

The figure is from one batch on 2026-09-03. Structure checks passed. 126 of 142 pages had identical bodies. Those counts are not the 26 pull requests from 2026-09-29.

Why did 26 green pull requests get stuck?

A branch protection setting called strict status checks stopped 26 green pull requests on 2026-09-29. The repository required checks to run against the latest commit on main. Every time 1 pull request merged, all remaining 25 branches went stale immediately. The merge queue froze completely.

PR #1865 passed all 4 required checks. The admin merge still refused. The setting enforce_admins: true stopped even automated administrative merges. The sweep agent inspected the branch settings directly. It found that 1 gh api call clears the block:

gh api repos/OWNER/bmdpat/branches/main/protection/required_status_checks -X PATCH -F strict=false

I left the setting alone on 2026-09-29. Changing protection rules is my call.

The stuck queue had a second problem. In config/blog/repair_rejected.py, a generator bug omitted required request fields. That 1 script wrote 13 of the 26 malformed requests in the queue. I fixed config/blog/repair_rejected.py so it emits all 6 required fields. When you run agents, verify what an agent actually produced. Without that check, bad output piles up fast.

How did the sweep catch its own mistake?

On the morning of 2026-09-29, the nightly sweep checked its previous run and corrected 2 false claims. It ran between 03:18 and 03:28 CT. It examined 43 skipped cards and proved that the destination branch was never the constraint. The agent read raw settings instead of repeating its own old summary.

The file Reports/Nightly/github-sweep-2026-09-29.md recorded the correction. Attempt 4 reviewed attempt 3 directly. In total, 0 pull requests merged, 1 escalated, and 43 cards skipped. I want an agent to admit when its prior report was wrong. That correction matters more than a merge. With BMD, see what your agents actually did. An agent that checks its own output saves hours of triage.

What broke in the audit checks before shipping?

On 2026-09-29, the security scanner returned a green status while scanning 0 of 5 repositories. At the same time, preflight audit scripts failed on dirty worktrees. I patched both check tools and added 42 passing tests. I refused to trust green badges without verified targets.

In config/dep_audit/check.py, the scanner failed to count launch-in-flight states. In config/pr-circuit-breaker.sh, rebasing mutated dirty worktrees without warning. I added repo_rebase_preflight to report dirty worktrees safely. That fix shipped with 23 dep-audit tests and 19 circuit-breaker tests passing. To make systems work, give an agent a file, not a memory. State files keep scripts honest.

Other checks broke too on 2026-09-29. SecurityAnalyst reported 0 P0 issues, 0 P1 issues, and 9 P2 issues. But gitleaks and osv scanned 0 of 5 repos. A green report on 0 repos is useless. Meanwhile, 33 vault commits landed on main. The digest wrote or repaired 135 sources and updated 215 entity pages, with 135 of 135 verifier checks passing.

Who was I on 2026-09-29?

The CI record on 2026-09-29 shows why that distinction matters. One run stopped at a screenshot. Another found private host names in a shipped card. A later run passed the app checks but stopped at an unauthenticated fetch. Codex removed those host names and corrected the fetch.

The final recorded run passed 3,952 cases across 254 files, with 36 cases skipped. The review at the final head still had an unresolved policy conflict. A passing run could not answer that separate question.

My other records were less consistent on 2026-09-29. The evening wins report recorded BMD 3.47.33 as available. The devlog did not list that release. SecurityAnalyst called its result green after 2 repository scans reached 0 targets. Brain Worker finished 1 repair and left 1 partial. Those facts belong beside each other.

I want work to continue without my constant attention. On 2026-09-29 that meant 1 specific exception for a machine and 1 specific limit on what the evidence could say. The record supports progress. It does not establish how much time I got back, or who used the software afterward.

What should you do with this?

You should audit your branch protection rules and verify your agent scan targets before trusting green checks. On 2026-09-29, 1 bad setting blocked 26 merges. Inspect whether strict status settings discard passing runs. Check whether scanners reached all 5 target repositories. Then patch the root config.

  1. Inspect your branch protection with gh api repos/OWNER/REPO/branches/main/protection. Check if strict: true forces clean PRs to re-run against head.
  2. Verify scanner output counts in config/dep_audit/check.py. Ensure tools like gitleaks and osv scan more than 0 targets before returning a green status.
  3. Add preflight safety checks to config/pr-circuit-breaker.sh. Run repo_rebase_preflight so uncommitted files do not cause dirty rebases across 1 or more branches.

Accompanying prompt

What the prompt does: Audits branch protection settings to find why clean pull requests fail to merge.

Copy/paste this prompt:

Copy-ready prompt

Paste the exact block into your coding agent.

No article chrome, no footnotes, no formatting drift.

Role: GitHub Repository Protection Auditor Context: Pull requests pass required continuous integration checks but remain stuck in the queue without merging. The user needs to identify the exact branch protection settings causing the block. Inputs: - Repository: __ - Target branch: __ - Blocked PR number: __ Task: 1. Inspect the branch protection rules for Target branch in Repository. 2. Check whether strict status checks require branches to be up to date before merging. 3. Compare Blocked PR number against the latest commit on Target branch. 4. Report whether the merge failure is caused by stale status checks or admin enforcement. 5. Provide the exact command to update the setting if needed. Output: - Blocker summary explaining why Blocked PR number cannot merge - Setting evaluation for strict status checks and administrator enforcement - Shell command to update the rule or rebase the branch Constraints: - Use only repository settings retrieved for Target branch. - Do not modify repository settings. - State whether the block requires administrator approval.
27 lines1078 chars
Ready

This prompt and every other one we publish live in the free prompt library.

Copy the block above.

See the fleet record: https://bmdpat.com/bmd

Get the Local AI Field Kit

Four copy-ready tools now, then one evidence-backed Local AI Lab Note on Friday when there is something worth sharing.

Try the free agent run check first

Get the requested artifact now, then at most one evidence-backed Local AI Lab Note on Friday when there is something worth sharing. One-click unsubscribe. No sponsored placements. Privacy.

PH

Patrick Hughes

I build BMD and publish measured AI runs, failure reports, and reusable checks. Nashville, Tennessee.

More writing