fix(automerge): surface merge-rejection reason + back off, don't retry forever (closes #322) #323
No reviewers
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
2 participants
Notifications
Total time spent: 44 seconds
Due date
igor
44 seconds
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor!323
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/automerge-backoff"
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?
Closes #322.
Root cause
do_automerge_tickretried a rejected merge every tick with a baremerge API failed. On igor.bot#290 the Forgejo API returns:The bot lacks merge permission on igor.bot (almost certainly the #319 branch-protection lockdown — the bot can't even read the protection rules). A 405 won't self-heal by re-POSTing, so the harness hammered it forever and the hourly logwatch pass filed #322.
automerge_do_mergeswallowed the error (>/dev/null 2>&1), which is why the warning was opaque.Fix (harness robustness — exactly what #322 asked for)
automerge_do_mergenow returnsHTTP <code>: <message>via a new_fj_mergehelper that keeps the error body_fj'scurl -fdiscards..automerge_blockand skipped for a cooldown (AUTOMERGE_BLOCK_COOLDOWN_SECS = 1h). The log shows why once, then goes quiet. It self-heals: a config fix is picked up after the cooldown, a new commit (different head) clears the block immediately, and a successful merge clears it.Not in scope (your call)
This fixes the harness. The actual igor.bot#290 merge still needs a decision: grant the bot merge rights on igor.bot (add it to the branch-protection merge whitelist) if you want auto-merge there, or keep it manual — in which case its
agent.json.smoke.url(what makes it auto-merge-eligible) should be dropped so the harness stops trying. Meanwhile you can merge #290 yourself to unblock the post.Tests
bin/check-sync.shgreen — added coverage for the reason surfacing, the merge payload, and the block-state machine (record / same-head-skip / different-head-retry / cooldown-elapsed / clear).🤖 Generated with Claude Code
🤖 Review —
COMMENT(automated)CI for
426cf1a5: successHarness fix:
automerge_do_mergenow surfaces the Forgejo merge-rejection reason anddo_automerge_tickrecords/backs-off rejected heads instead of re-POSTing every tick. The logic and unit coverage look sound; my reservation is one unverifiable variable in the integration path.Must verify (blocking-ish, can't confirm from diff):
do_automerge_ticknow references$sfin three new spots (automerge_block_active "$sf" ...,automerge_block_clear "$sf" ...,automerge_block_record "$sf" ...), but the diff does not showsfbeing assigned anywhere in that function. Ifsfisn't already a defined local/global earlier indo_automerge_tick, this passes an empty first arg to the block helpers (blocks silently never activate/record), or underset -uerrors out the tick entirely. The new unit tests exercise the block helpers with an explicit state file, so they would NOT catch a missing$sfin the tick. Please confirmsfis defined and points at the same state file the block state should live in.Looks correct:
_fj_mergecode/body split (${out##*$'\n'}/${out%$'\n'*}) and.message // emptyextraction are right; deliberately bypassing_fj'scurl -fto keep the error body is the correct call.automerge_do_merge:2??glob → sha+rc0, elseHTTP <code>: <msg>+rc1. curl timeout/failure (http_code=000) falls through to the reject branch and gets backed off — reasonable.Coverage gap: no test drives
do_automerge_tickitself through the reject→record→skip→clear flow, which is exactly why the$sfquestion above is invisible to CI. An integration-level assertion there would close the loop.Independent review by the harness on
claude-opus-4-8(effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.