Skip to content

forgectl pr — clean-room review + merge-driving (sub-epic) #3

Description

@cameronsjo

Part of #1.

forgectl pr — select open PRs and drive them to merge

Context

Getting a batch of open PRs "across the finish line" today means hand-running gh, watching CI and CodeRabbit, and dodging a pile of documented gh/git traps. The logic already exists as the cadence-forge:review-loop skill + poll-prs.sh; this issue ports that proven flow into a forgectl command so it's a one-shot, repeatable tool rather than a skill-driven session.

Scope

  • forgectl pr lists open PRs (gh pr list --json), offers a multi-select (huh multiselect / bubbletea list) of which to drive.
  • For the selected set, run a poll → triage → (optionally fix) → merge loop to completion, with a status table (TUI or repeating table render).
  • Merge when green + approved; surface findings otherwise. Respect a round cap and stale timeout (mirror review-loop's defaults: 10 rounds / 10 min).
  • CodeRabbit-aware: treat "no actionable comments" + incremental silent-review acks as approval-equivalent (see using-coderabbit).

Must bake in the documented gotchas (from CLAUDE.md)

  • Reading a file at a ref: gh api --method GET … -f ref=<branch> (-f alone flips the verb to POST).
  • Pre-merge check must include isDraft — draft PRs silently block merge even when mergeable/mergeStateStatus look clean (or run gh pr ready first).
  • After gh pr merge, verify with gh pr view <n> --json mergedAt,mergeCommit — a local post-merge step can fail while the server-side merge succeeded.
  • Branch-existence checks use the singular git/ref/heads/<branch> (plural refs returns [] with 200, masking deletion).
  • Stacked PRs: merging one re-bases main and turns siblings CONFLICTING — re-check each after every merge; retarget dependents before deleting any base branch (deleting a base branch closes its dependent PR).
  • --delete-branch fails locally when main (or the PR branch) is checked out in another worktree — verify merge, then git push origin --delete manually.

Acceptance criteria

  • Select N PRs, command merges all that are mergeable and reports precisely why each non-merged one was skipped.
  • Never merges a draft; never deletes a branch an open PR depends on; always verifies the merge landed server-side.
  • Hard stops on round cap / stale timeout instead of looping forever.

Reuse / pointers

  • cadence-forge/skills/review-loop/ (state machine, scripts/poll-prs.sh — consolidated gh api poll emitting NDJSON, fail-soft).
  • cadence-forge/skills/using-coderabbit/SKILL.md (green-check-≠-done, approval signals).
  • Gotchas: ~/.claude/CLAUDE.md GitHub CLI section.
  • All gh/git calls through internal/exec Runner for testability.

Open question

  • Should forgectl pr fix findings (spawn an agent) or stay merge-only and leave fixing to a Claude session? Recommend merge-only v1 (orchestrate, don't author).

Re-scope (2026-06-22) — pr is now a sub-epic

Tracked under the umbrella EPIC cameronsjo/claude-configurations#206; full flagship spec in cameronsjo/claude-configurations#202 ("pr — PR Review (the flagship)"). The pr surface is larger than one issue and decomposes into:

Sub-issues

Folded into the above (checklist, not separate issues yet)

  • pr teardown [path] (alias close) — scalpel teardown of one review; exact-match allow-entry (no glob)
  • pr cleanup — date-wide worktree discard
  • pr keys — tmux review-workflow keyboard cheatsheet
  • pr list / attach / open — session management (lands with feat(forgectl): pr <ref> — clean-room worktree review #29)

Dependencies

The reviewer (#29) consumes quarantine #20 (clean-room isolation), net #19 (network posture), and launch #2 (gateway auth). Build #29 first; #30/#31/#32 build on it.

Relationship to the original merge-loop scope (above)

The original forgectl pr scope — multi-select open PRs and drive them to merge (a review-loop port) — remains valid and folds into this sub-epic as the dashboard + merge path alongside #31's discovery surfaces. The v1 recommendation (merge-only; orchestrate, don't author) still holds. The #202 flagship adds the clean-room review-session facet (#29#32) on top of that merge-driving facet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    block:waitingWaits on other work, a release, or a date trigger. Clears itself.enhancementNew feature or requestexec:blockedWaits on a decision, a gate, or a close. Triage claim; verified at dispatch.forgectlforgectl component

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions