{"id":16842,"plugin_id":"plugins_6a69ee33e3048191ab7da89ec70dbbe2","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T23:13:49.748Z","digest":"137e3184e866750f5956cee65c6d55ec48554598c0b9e18e73092e46451720ad","against":null,"payload":{"name":"gh-autoreview-resolve","description":"Run a bounded GitHub automated-review and resolution loop for a specified pull request. Use when an agent must mark a PR ready for review, confirm the automated reviewer started through an eyes reaction, wait for a thumbs-up or concrete review response, validate and address review threads, request a narrowly focused `@codex review` follow-up when warranted, prevent review scope creep through PR comments or a gh-create-issue follow-up, and optionally merge with the user's preferred strategy.","included_files":[{"relative_path":"agents/openai.yaml","size_in_bytes":259},{"relative_path":"references/agent-harnesses.md","size_in_bytes":1860},{"relative_path":"scripts/inspect_review_state.py","size_in_bytes":70198}],"skill_md_contents":"---\nname: gh-autoreview-resolve\ndescription: Run a bounded GitHub automated-review and resolution loop for a specified pull request. Use when an agent must mark a PR ready for review, confirm the automated reviewer started through an eyes reaction, wait for a thumbs-up or concrete review response, validate and address review threads, request a narrowly focused `@codex review` follow-up when warranted, prevent review scope creep through PR comments or a gh-create-issue follow-up, and optionally merge with the user's preferred strategy.\nlicense: MIT\n---\n\n# GitHub Auto Review Resolve\n\nMove one specified pull request from draft through a conservative automated-review loop. Keep the PR's original implementation goal authoritative; do not turn review follow-up into an open-ended audit.\n\n## Adapt to the agent host\n\nRead [references/agent-harnesses.md](references/agent-harnesses.md) before\nchoosing GitHub, waiting, or user-interaction tools. The `@codex review`\nmention in this workflow addresses GitHub's configured Codex reviewer; it does\nnot require the agent executing this skill to be Codex. Do not post the mention\nunless the repository actually uses that reviewer.\n\n## Establish the contract\n\n1. Read repository instructions, the linked issue, PR body, changed files, current head, checks, and existing review threads.\n2. Record the original goal, acceptance criteria, explicit non-goals, requested review focus, whether merge is authorized, and the user's preferred merge strategy.\n3. Verify `gh auth status`, the repository, PR number, local checkout, and unrelated working-tree changes before mutations.\n4. Run `scripts/inspect_review_state.py <PR> --repo OWNER/REPO` for one normalized, fully paginated baseline. Treat its GraphQL `reviewThreads` result as the source of truth for unresolved work. The inspector first reads `gh api rate_limit`, preserves 200 GraphQL points plus a five-point next-query buffer by default, and reports every query's `cost`, `remaining`, `used`, and `reset_at` values.\n5. Use only one active observer for an `OWNER/REPO#PR`. When waiting is required, give the loop to one `--watch` process and let other agents or tasks reuse its result instead of polling independently. The watcher enforces this on the same host with an advisory process lock in a user-private directory; it refuses symlinks or non-regular lock files and releases ownership automatically on process exit. Operators must preserve the same single-observer contract across hosts.\n\nDo not merge unless the user explicitly requested it. If merge was requested but the strategy is neither stated nor reliably discoverable, ask rather than guess.\n\n## Start review\n\n1. If the PR is a draft, run `gh pr ready <PR> --repo OWNER/REPO`. Do nothing if it is already ready.\n2. Record the UTC time and full head OID immediately before the ready transition. Inspect with `--after <ISO_TIME>` so old bot activity is not mistaken for the new review, and retain the OID so the ready-triggered review can be tied to unchanged code even though GitHub does not attach a `Review head:` marker to that implicit request.\n3. Confirm review start from an `eyes` reaction on the PR or the active `@codex review...` comment. If feedback or a pass response arrives before eyes is sampled, accept that as a completed start race.\n4. If no start signal appears after a reasonable bounded wait, confirm there is no active request, then post exactly one `@codex review` comment. Include the current full head OID on its own `Review head:` line so a later reaction can be tied to that exact code. Never post another request while eyes is present.\n5. When the user supplied a review target, request it narrowly and keep the head marker:\n\n   ```text\n   @codex review\n   Review head: `<full head OID>`\n\n   Focus on <specific contract, regression, or risk>.\n   ```\n\nAvoid leading the reviewer toward a predetermined implementation or inviting a repository-wide audit.\n\n## Wait and classify\n\nUse `inspect_review_state.py <PR> --repo OWNER/REPO --watch --after <ISO_TIME>` for a bounded wait. It takes one authoritative snapshot, then uses a lightweight transition fingerprint instead of repeatedly loading every thread and check. An unchanged fingerprint backs off from 60 to 120 to 240 seconds and then caps at 300 seconds, with jitter. A transition resets the backoff and triggers another fully paginated snapshot; even without a detected transition, the watcher forces an authoritative refresh every 10 minutes. Defaults cap a watcher at 20 minutes, 40 GraphQL requests, 20 pages per connection, and 90 seconds of actual GraphQL execution. Each `gh` request receives the remaining execution/deadline timeout. Adjust a ceiling only for a concrete PR-size or latency reason.\n\nDo not run a separate shell polling loop around the inspector. Keep the user informed during longer waits while the one watcher owns observation.\n\n- `eyes > 0`: review is still running; keep waiting.\n- `thumbs_up > 0`: no-issue pass tied to the current head, unless unresolved threads still exist.\n- `ignored_thumbs_up > 0`: a thumbs-up was observed without a matching explicit `Review head:` anchor. This is not automatically invalid. Accept it as the initial ready-triggered pass when the connector reaction occurred after the recorded ready time, the head recorded before ready still equals the current head, pagination is complete, and no unresolved thread exists. Otherwise do not treat it as a current-head pass. Absence of the marker alone does not require another `@codex review` comment; request an anchored review only when current-head applicability remains materially uncertain or a focused re-review is independently warranted.\n- `outcome: passed`: accept either thumbs-up or an explicit connector response such as “Didn't find any major issues,” provided the response applies to the current head.\n- `outcome: review_feedback`: inspect every unresolved thread.\n- `outcome: review_response`: inspect the response and thread state; do not assume pass or failure.\n- `outcome: not_started_or_pending`: allow short propagation time, then diagnose configuration or request state without posting duplicates.\n- `outcome: pagination_incomplete` or `pagination_incomplete: true`: stop. The inspector already followed cursors until an explicit ceiling or a missing/repeated cursor prevented progress. Read `pagination.unfinished`, raise a justified ceiling if safe, and resume only after checking the reported cursor and quota.\n- `outcome: rate_limited`: this is an operational pause, not review failure. The inspector reads included response headers, so honor `retry_after_seconds` for secondary limits or wait until the reported `reset_at`; do not immediately retry.\n- `outcome: preflight_unavailable`: the inspector could not establish the GraphQL budget and failed closed before issuing a GraphQL query. Restore `gh api rate_limit` access before retrying.\n- `outcome: budget_exhausted`: stop the observer and inspect its request, page, or execution-time ceiling before deciding whether one bounded rerun is justified.\n- `observer.outcome: watch_timeout`: the review is still non-terminal. Report the current state and decide whether another bounded observation window is warranted.\n- `observer.outcome: observer_active`: reuse the existing observer. Do not start another watcher for the same PR.\n\nCheck that the review applies to the current head. A stale or outdated anchor is evidence to reassess, not a reason to edit blindly. Never report `passed`, ready, or zero unresolved threads unless `pagination.complete` is `true`.\n\n## Resolve feedback\n\nFor each unresolved thread:\n\n1. Reproduce or disprove the claim against current code, tests, runtime behavior, and the PR's original contract.\n2. Classify it as:\n   - **valid and in scope**: caused by the PR or violates its acceptance criteria;\n   - **valid but out of scope**: pre-existing or an adjacent enhancement not needed for the PR goal;\n   - **invalid, duplicate, or stale**: contradicted by evidence, already handled, or based on an obsolete head.\n3. For valid in-scope findings, make the smallest coherent fix. Preserve unrelated work, follow repository instructions, add focused regressions, and run validation proportional to risk.\n4. Commit and push normally. Update the PR body when the new commit materially changes its described behavior or validation evidence.\n5. Reply on the exact thread with concise evidence: validity decision, root cause, fix or rejection rationale, tests, and commit when applicable.\n6. Resolve the thread only after the reply is posted. Re-fetch the current head, checks, reactions, and unresolved thread count.\n\nDo not silently resolve a substantive thread and do not equate reviewer priority labels with proven validity.\n\n## Bound the loop\n\nUse one initial review and, after in-scope fixes, normally one explicit focused verification re-review. When those fixes stay within the original development scope and that pass leaves no concrete regression concern, finish the loop.\n\nDo not treat that focused re-review as an absolute one-round cap. If a valid finding's fix changes a sensitive boundary or creates or leaves a concrete in-scope regression risk, request further focused re-review as needed. Before every additional round, require all of the following:\n\n- the preceding review produced a valid in-scope finding and a corresponding code change, or new evidence identifies a specific regression risk in that change;\n- the request names the exact current head and only the affected contract, regression, or risk;\n- the work remains within the PR's original goal and does not broaden the implementation scope;\n- no other review request is active.\n\nDo not request another round merely to obtain stronger reassurance or a different reaction. After each response, reassess the evidence and stop as soon as no concrete regression concern remains. Stop or split follow-up when any of these occurs:\n\n- new comments move beyond the PR's original goal;\n- the concern is pre-existing and non-blocking for this PR;\n- fixes begin spreading into unrelated modules or architectural redesign;\n- the next request cannot identify a new code change or a concrete regression hypothesis caused by the preceding fix;\n- the reviewer repeats an already answered behavior without new evidence;\n- the acceptance criteria and required regression coverage are already satisfied.\n\nWhen stopping:\n\n1. If no separate issue is warranted, comment on the PR with the scope decision and evidence, then stop the loop.\n2. If the finding is real and deserves implementation, invoke `gh-create-issue` using the current agent host's skill syntax. Research primary evidence, check for duplicates, create an implementation-ready English follow-up issue, comment its link and why it is separated, then stop this review line.\n3. If an in-scope release blocker remains unresolved, do not merge. Report the blocker.\n4. If only a non-blocking out-of-scope follow-up remains, the PR may proceed after the comment or issue link is recorded.\n\n## Finish and optionally merge\n\nBefore declaring the loop complete, verify the exact final head, required checks, no active eyes request, and zero unresolved review threads. A pass response is sufficient; do not manufacture extra review rounds merely to obtain a different reaction shape.\n\nAlso verify `pagination.complete: true` and `rate_limit.status: ok`. Partial data may contain useful feedback, but it is never terminal success.\n\nIf merge was requested:\n\n1. Reconfirm the PR is ready, mergeable, current checks are green, and no in-scope blocker remains.\n2. Use the user's preferred method: `--rebase`, `--squash`, or `--merge`.\n3. Merge in any user-specified dependency order. Do not delete branches or worktrees unless requested.\n4. Re-fetch and report the merged state, resulting commit, linked issue state, and any follow-up issue.\n\nIf merge was not requested, stop at the verified ready-to-merge state.\n\n## Inspection script\n\nRun from this skill directory:\n\n```bash\npython scripts/inspect_review_state.py 123 --repo owner/repository\npython scripts/inspect_review_state.py https://github.com/owner/repository/pull/123 --after 2026-07-23T00:00:00Z\npython scripts/inspect_review_state.py 123 --repo owner/repository --watch --after 2026-07-23T00:00:00Z\ngh api rate_limit --jq '.resources.graphql'\n```\n\nThe inspector fetches top-level comments without nested reactions, identifies the latest active anchored review request, and then fetches reactions only for that comment. It follows cursors for PR reactions, comments, reviews, threads, active-request reactions, check contexts, and nested thread comments. It collects every check context twice and requires the two snapshots to match so a change outside the lightweight last-20 suffix cannot produce false completion. Missing or non-advancing cursors fail closed with the exact unfinished connection.\n\nUse `--self-test` to validate the script's state classifier without GitHub access. Use `--reserve`, `--query-cost-buffer`, `--max-requests`, `--max-pages`, `--max-seconds`, or the watch timing flags only when the defaults do not fit a verified repository constraint.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}