Summary
merge-ready.sh hardcodes gh pr merge --merge and discards gh's stderr. In any consumer repo whose branch ruleset restricts allowed merge methods, every bot merge is rejected by GitHub and the script logs only a bare {"action":"merge-failed"} — indistinguishable from a transient failure, forever, on every tick.
Incident (reDeploy, 2026-07-24 → 2026-07-30)
Proposed fixes
- Don't hardcode the merge method. Read it from the adapter (
gates.json → e.g. merge.method) and/or fall back to what the repo actually permits (gh api repos/{repo}/rulesets → pull_request.parameters.allowed_merge_methods, and the repo's allow_*_merge flags). A squash-only repo should get --squash automatically.
- Surface the error. Capture
gh pr merge stderr and include it in the merge-failed JSON line ("error": "..."), so one journal read identifies the cause instead of requiring an out-of-band repro.
- Distinguish remote-merge failure from local cleanup failure. With
--delete-branch, gh exits non-zero if the head branch is checked out in a .claude/worktrees/ worktree even though the remote merge succeeded. The script then reports merge-failed on a merged PR and skips clean_worktree, leaving exactly the debris that census can mistake for in-flight work. Check the PR's merged state (or split the merge and the branch deletion) before deciding what to report.
Notes
Summary
merge-ready.shhardcodesgh pr merge --mergeand discards gh's stderr. In any consumer repo whose branch ruleset restricts allowed merge methods, every bot merge is rejected by GitHub and the script logs only a bare{"action":"merge-failed"}— indistinguishable from a transient failure, forever, on every tick.Incident (reDeploy, 2026-07-24 → 2026-07-30)
--mergewas rejected: 435 consecutive silentmerge-failedticks. PR feat(core): first-class upgradeable contracts (UUPS/Transparent proxies) — #155 reDeploy#169 sat green + owner-approved for 5 days and was re-approved 3× to no effect; PRs loop-census.sh: advance_ready eligibility ignores needs-human label, only matches feat/issue-N-* branches #170/fix(needs-human): REST label ops + confirmed-episode guard — stop per-tick comment spam (issue #169) #171 then queued the same way.>/dev/null 2>&1).merge. The script defect remains latent for every other consumer.Proposed fixes
gates.json→ e.g.merge.method) and/or fall back to what the repo actually permits (gh api repos/{repo}/rulesets→pull_request.parameters.allowed_merge_methods, and the repo'sallow_*_mergeflags). A squash-only repo should get--squashautomatically.gh pr mergestderr and include it in themerge-failedJSON line ("error": "..."), so one journal read identifies the cause instead of requiring an out-of-band repro.--delete-branch, gh exits non-zero if the head branch is checked out in a.claude/worktrees/worktree even though the remote merge succeeded. The script then reportsmerge-failedon a merged PR and skipsclean_worktree, leaving exactly the debris that census can mistake for in-flight work. Check the PR's merged state (or split the merge and the branch deletion) before deciding what to report.Notes
pull_requestrule — the defect is in the shipped script, so every consumer repo with a merge-method restriction inherits it.