When fgj pr merge exits 0 but the PR is still open, the loop now auto-resolves instead of immediately setting State/Question:
Merge conflicts (mergeable == false): spawns a rebase agent to rebase the branch onto main and push, writes pending-ci state so the next loop iteration waits for CI and retries the merge.
No conflicts (mergeable == true or null): retries _merge_pr up to 2 more times with a 5 s pause; closes the issue if any retry succeeds.
Fallback: if all retries are exhausted, falls back to the existing behaviour (State/Question + "Please merge manually" comment).
Both the main pending-issue path (section 2b) and the catch-up path use the shared _handle_pr_still_open_after_merge() helper.
Tests added
test_merge_fails_open_with_conflicts_spawns_rebase_agent — mergeable=false → agent spawned, state written as pending-ci
test_merge_fails_open_no_conflicts_retries_and_succeeds — mergeable=true, second attempt succeeds → issue closed
test_merge_fails_open_no_conflicts_all_retries_exhausted → falls through to State/Question
## Summary
When `fgj pr merge` exits 0 but the PR is still open, the loop now auto-resolves instead of immediately setting State/Question:
- **Merge conflicts** (`mergeable == false`): spawns a rebase agent to rebase the branch onto main and push, writes `pending-ci` state so the next loop iteration waits for CI and retries the merge.
- **No conflicts** (`mergeable == true` or `null`): retries `_merge_pr` up to 2 more times with a 5 s pause; closes the issue if any retry succeeds.
- **Fallback**: if all retries are exhausted, falls back to the existing behaviour (State/Question + "Please merge manually" comment).
Both the main pending-issue path (section 2b) and the catch-up path use the shared `_handle_pr_still_open_after_merge()` helper.
## Tests added
- `test_merge_fails_open_with_conflicts_spawns_rebase_agent` — `mergeable=false` → agent spawned, state written as `pending-ci`
- `test_merge_fails_open_no_conflicts_retries_and_succeeds` — `mergeable=true`, second attempt succeeds → issue closed
- `test_merge_fails_open_no_conflicts_all_retries_exhausted` → falls through to State/Question
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
When
fgj pr mergeexits 0 but the PR is still open, the loop now auto-resolves instead of immediately setting State/Question:mergeable == false): spawns a rebase agent to rebase the branch onto main and push, writespending-cistate so the next loop iteration waits for CI and retries the merge.mergeable == trueornull): retries_merge_prup to 2 more times with a 5 s pause; closes the issue if any retry succeeds.Both the main pending-issue path (section 2b) and the catch-up path use the shared
_handle_pr_still_open_after_merge()helper.Tests added
test_merge_fails_open_with_conflicts_spawns_rebase_agent—mergeable=false→ agent spawned, state written aspending-citest_merge_fails_open_no_conflicts_retries_and_succeeds—mergeable=true, second attempt succeeds → issue closedtest_merge_fails_open_no_conflicts_all_retries_exhausted→ falls through to State/Question