PR Resolver Skill
Purpose
You are the master orchestrator for finishing Pull Requests. Use bounded retries to keep finalize resilient, and delegate actual fixes to specialized skills (fix-merge-conflicts, fix-comments, fix-ci) when blockers are actionable.
The task is not complete until the target PR is merged or is proven already merged. A local fix, local commit, passing local test run, unresolved review reply, or unpushed branch is not a successful PR resolution.
Inputs (skill args)
- inputs.repo (optional)
- inputs.pr (optional)
- inputs.branch (optional)
- inputs.mergeMethod (merge|squash|rebase)
- inputs.maxIterations (default 5, full remediation cap per cycle)
- inputs.finalizeMaxRetries (default 60)
- inputs.finalizeBackoffSeconds (default 30)
- inputs.finalizeMaxSleepSeconds (default 120)
- inputs.finalizeMaxElapsedSeconds (default 7200)
- Retryable/no-progress blockers use at least 5 finalize attempts before
returning
attempts_exhausted, unless a hard timeout, hard failure, or non-retryable blocker is reached first. ci_runningfinalize waits use at least 60 seconds before the next check, even whenfinalizeBackoffSecondsis lower.- If the only visible PR comment/review is from
gemini-code-assist, the resolver treats that as a Codex-review grace window and polls for up to 10 minutes before merging. Any additional visible comment/review ends the grace wait immediately.
Skill authority and host boundary
This resolved Skill bundle is the sole semantic implementation of
pr-resolver, in MoonMind and outside it. The instructions in this file and the
portable helpers beside it own GitHub snapshot collection, comment retrieval,
comment actionability, CI interpretation, blocker priority, retry decisions,
specialized-skill selection, merge gating, and terminal-result construction.
MoonMind must execute this Skill through the ordinary agent Skill path. Native integration may resolve and materialize the immutable Skill bundle, provide the workspace and credentials, launch and supervise the runtime, enforce timeout or cancellation policy, capture logs, and persist or validate terminal artifacts. It must not replace any behavior listed above with MoonMind-only workflow, activity, adapter, or GitHub-client logic. In particular, MoonMind must not collect or classify PR comments on behalf of this Skill.
If a host cannot execute the resolved Skill bundle and its required Skills, it
must fail before mutation. It must never substitute a built-in implementation
based on the pr-resolver name, source, publish mode, or an implementation
metadata flag.
Workflow
Resolve the active
pr-resolverdirectory and use only the helpers from that immutable active Skill set. Resolvefix-comments,fix-ci, andfix-merge-conflictsfrom the same active set; do not use repo-global or host-native substitutes. MoonMind exports the active root asMOONMIND_ACTIVE_SKILLS_DIR. Outside MoonMind, setPR_RESOLVER_SKILL_DIRto the directory containing thisSKILL.md. Establish the portable paths before running a helper:PR_RESOLVER_SKILL_DIR="${PR_RESOLVER_SKILL_DIR:-${MOONMIND_ACTIVE_SKILLS_DIR:+$MOONMIND_ACTIVE_SKILLS_DIR/pr-resolver}}" ACTIVE_SKILLS_DIR="${MOONMIND_ACTIVE_SKILLS_DIR:-$(dirname "$PR_RESOLVER_SKILL_DIR")}" test -n "$PR_RESOLVER_SKILL_DIR" && test -f "$PR_RESOLVER_SKILL_DIR/SKILL.md"Run the finalize gate checker. It refreshes PR metadata, CI, and the complete comment inventory before deciding whether merge is allowed:
python3 "$PR_RESOLVER_SKILL_DIR/bin/pr_resolve_finalize.py" \ --pr <pr_number_or_branch> \ --merge-method <merge|squash|rebase> \ --strict-exit-codesRead
var/pr_resolver/result.jsonand perform exactly the indicated action:mergedor independently verifiedalready_merged: publish terminal evidence and stop. A successfulgh pr mergerequest is not terminal evidence until a freshgh pr viewreportsstate=MERGED; merge-queue or still-open states remain transient.merge_conflicts: the PR either conflicts with or is behind its base branch; followfix-merge-conflictscompletely to merge the latestorigin/main, then push the synchronized branch.ci_failures: followfix-cicompletely.actionable_comments: followfix-commentscompletely, including fresh comment retrieval, its disposition ledger, push verification, and resolving handled current review threads on GitHub.ci_running,codex_review_grace_wait, or another documented transient: wait with the bounded backoff configured by the Skill inputs, then return to step 2.- any unavailable, ambiguous, permission-sensitive, or non-retryable state:
publish
manual_revieworfailedevidence and stop without merging.
After every remediation, verify the exact local
HEADis visible on the PR branch, then return to step 2. Never reuse a pre-remediation snapshot.Enforce
maxIterations,finalizeMaxRetries, andfinalizeMaxElapsedSeconds. Retryable/no-progress states receive at least five finalize checks unless the elapsed-time limit or a hard failure is reached.Before reporting success, generate
artifacts/publish_result.jsonfrom the final resolver result with the shared publish-evidence helper.
Terminal Success Contract
Allowed successful terminal states:
var/pr_resolver/result.jsonhasstatus=merged,merge_outcome=merged, andmergeAutomationDisposition=merged.- The PR is independently confirmed as already merged after a snapshot/finalize race, with
mergeAutomationDisposition=already_merged.
Merge Automation Result Contract
Every terminal var/pr_resolver/result.json MUST include mergeAutomationDisposition:
merged: the resolver merged the PR.already_merged: the PR was independently confirmed as already merged.reenter_gate: the current resolver child completed a typed handoff to its validatedMoonMind.MergeAutomationparent. IncludegatedContinuationwith the reason and an absolute UTCnotBeforedeadline when the next cycle must wait. For Codex review grace, the direct finalizer copies the snapshot's originalcodexReviewGrace.expiresAt; it never restarts that deadline. Standalone resolvers cannot use this disposition successfully. Provider, authentication, rate-limit, infrastructure, timeout, cancellation, stale evidence, and malformed evidence failures are never cleared by continuation metadata; only the syntheticPR_RESOLVER_REENTER_GATEclassification may be cleared by an authorized handoff.manual_review: the resolver stopped on a blocker, exhausted attempts, or needs human follow-up.failed: the resolver hit a hard execution failure.
Everything else is blocked, failed, or still in-progress. In particular, never finish with task complete or a success summary when:
- the PR remains open,
- the branch is ahead of origin,
- a push failed,
- GitHub auth is unavailable,
gh pr mergefailed,- review comments remain actionable,
- CI is running, degraded, or failing,
- mergeability is unknown, dirty, or blocked.
Long waits have exactly two supported ownership patterns: keep the resolver command in the foreground with periodic progress, or write the authoritative typed continuation and return control to a validated merge-automation parent. Never start detached polling, emit the final agent response, and claim the poll will continue after the managed CLI exits. Background task identifiers in output have no lifecycle authority.
After any local commit-producing remediation, verify the exact current HEAD is visible on the remote PR branch before continuing. If git push, gh, or any GitHub connector path cannot publish the commit, stop as blocked with reason publish_unavailable; do not proceed to finalize and do not report success.
Never print raw environment variables while diagnosing GitHub auth or publish failures. Use targeted checks such as test -n "$GITHUB_TOKEN" or trusted-tool health calls; do not run printenv, env, set, or equivalent commands that can expose secrets.
When a delegated remediation step cannot publish, overwrite var/pr_resolver/result.json before stopping so parent workflows do not report stale gate state. Use status=blocked, merge_outcome=blocked, mergeAutomationDisposition=manual_review, reason=publish_unavailable, final_reason=publish_unavailable, and next_step=manual_review.
Bounded remediation actions
merge_conflicts, including a conflict-free PR reported asBEHIND, selectsfix-merge-conflictsonce.ci_failuresselectsfix-cionce.actionable_commentsselectsfix-commentsonce.- Transient waits and unknown/manual blockers never launch an agent remediation turn.
After a specialized Skill finishes, pr-resolver independently re-runs its
portable gate against the remote PR head. A remediation Skill must not claim
outer-loop success based on local commits, process output, or its own artifact
alone.
Lightweight Commands
- Finalize-only gate checker:
python3 "$PR_RESOLVER_SKILL_DIR/bin/pr_resolve_finalize.py" --pr <pr_number_or_branch> --merge-method <merge|squash|rebase>
- Full gate classifier (no merge, deterministic state classification):
python3 "$PR_RESOLVER_SKILL_DIR/bin/pr_resolve_full.py" --pr <pr_number_or_branch> --merge-method <merge|squash|rebase> --max-iterations <maxIterations>
Constraints
- Keep
pr_resolve_finalize.pyas a gate checker; do not add remediation mutations there. - Do NOT invent custom conflict/CI/comment workflows; always execute the specialized skill instructions.
- Do not ask MoonMind or another host to collect, summarize, or classify GitHub comments for this Skill.
- Respect retry caps; if retries are exhausted, return
attempts_exhaustedand stop. - This skill owns publishing under
task.publish.mode = "auto"and may commit, push, or merge only as required to resolve the target PR. Before reporting success, ensureartifacts/publish_result.jsonexists. The orchestration command normally generates it by running:python3 "$ACTIVE_SKILLS_DIR/_shared/publish_evidence.py" from-pr-resolver-result \ --result var/pr_resolver/result.json - A failed push, missing GitHub auth, or missing remote branch update is an unresolved PR blocker, even if all code changes are committed locally.
pr_resolve_orchestrate.pyis a portable utility for non-agent automation and tests. An agent executing this markdown owns specialized-skill dispatch and must follow the workflow above rather than assuming that utility can perform agent remediation.