Agent skill

PR Review Loop

by basicmachines-co in basicmachines-co/basic-memory

Enforce the Basic Machines GitHub PR review loop before merging.

AGPL-3.0Auto-check passedDevelopment

Install PR Review Loop

skills CLI
$ npx skills add basicmachines-co/basic-memory --skill pr-review-loop -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install basicmachines-co/basic-memory pr-review-loop --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/basicmachines-co/basic-memory.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/pr-review-loop .claude/skills/pr-review-loop && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
pr-review-loop
GitHub stars
4.1k
Token cost
~3.2k tokens
SKILL.md length
1,133 words
Files
1
Skills in repo
49
Repo updated
First seen
Licence
AGPL-3.0

At a glance

Enforce the Basic Machines GitHub PR review loop before merging.

  • Works in 2 steps: Resolve the PR and current head SHA. → Read Codex state on the latest head.…
  • Codex is preparing to merge
  • SKILL.md covers Hard Rule, Signals, Loop Workflow and Failure Mode This Prevents
  • Calls gh and jq

What it does

PR Review Loop is an agent skill from basicmachines-co/basic-memory. Enforce the Basic Machines GitHub PR review loop before merging. Use whenever Codex is preparing to merge, squash-merge, auto-merge, declare a PR ready, monitor Codex comments, address review feedback, or wait for Codex approval on a GitHub PR, especially when the user says "approved", "merge", "ship", "PR is ready", "monitor Codex comments", or "address Codex feedback".

Its SKILL.md is about 3.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Pull requests. It works with GitHub. The repository describes itself as: AI conversations that actually remember. Never re-explain your project to your AI again. Join our Discord: https://discord.gg/tyvKNccgqN. The licence is AGPL-3.0.

When your agent uses it

  • Codex is preparing to merge
  • Declare a PR ready
  • Monitor Codex comments
  • Address review feedback

Example prompts

  • “approved”
  • “PR is ready”
  • “monitor Codex comments”
  • “/pr-review-loop”

Workflow steps

2 steps, taken from the first numbered list in SKILL.md.

  1. Resolve the PR and current head SHA.
  2. Read Codex state on the latest head. Check every GitHub surface where Codex

What it can do on your machine

Read from SKILL.md and the folder at commit cb7407f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • gh
    • jq

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use gh, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

PR Review Loop loads about 3.2k tokens when it runs. Until then it costs about 97 tokens; SKILL.md has 1,133 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~97
When it runs · the whole SKILL.md, loaded when a task matches
~3.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from basicmachines-co/basic-memory at commit cb7407f, republished under its AGPL-3.0 licence (© basicmachines-co). 1,133 words, ~3,218 tokens.

Download SKILL.mdSave it as .claude/skills/pr-review-loop/SKILL.md (or your agent's skills folder).
name
pr-review-loop
description
Enforce the Basic Machines GitHub PR review loop before merging. Use whenever Codex is preparing to merge, squash-merge, auto-merge, declare a PR ready, monitor Codex comments, address review feedback, or wait for Codex approval on a GitHub PR, especially when the user says "approved", "merge", "ship", "PR is ready", "monitor Codex comments", or "address Codex feedback".

PR Review Loop

Hard Rule

Do not merge a PR merely because CI is green, the branch is mergeable, review threads are outdated, or no current Codex thread is visible.

Merge only when one of these is true:

  • Codex has finished reviewing the latest head and left an explicit thumbs-up approval signal.
  • The user explicitly overrides this gate with language like "merge without waiting for Codex approval" or "override Codex gate".

Codex often leaves that thumbs-up as a reaction on the PR description/body itself (the GitHub Issue/PR object), not on its "Codex Review" issue comment. Do not only inspect issue comments.

If Codex's newest fresh reaction on the PR body or a relevant comment is eyes, it is reviewing. Wait and keep checking.

If Codex leaves a comment, review body, or inline thread containing substantive feedback, the PR is not approved. Use judgement: fix the code when the comment is right; reply with evidence when it is wrong or intentionally not worth changing. A no-issue summary or boilerplate-only review body is not a blocker, but it also does not replace the required thumbs-up.

Signals

  • Eyes reaction on the PR body or a comment: pending when it is newer than the latest fresh thumbs-up on that same surface.
  • Thumbs-up reaction by chatgpt-codex-connector[bot] on the PR body/description: Codex approves/no suggestions. This is the common approval signal.
  • Thumbs-up reaction by chatgpt-codex-connector[bot] on a Codex issue comment: also an approval signal, but this is not the only place to look.
  • Codex issue comment saying "Didn't find any major issues": approval-like context, but confirm the PR body/comment thumbs-up or get an explicit user override.
  • Latest current-head Codex review per actor with CHANGES_REQUESTED or a substantive review body: blocking feedback even when it has no inline thread.
  • Codex comment, review body, or review thread containing substantive feedback: blocking until addressed, replied to with a clear rationale, or explicitly overridden by the user.
  • Outdated Codex comments: useful history, but not approval.
  • Empty reviewDecision, mergeable: MERGEABLE, mergeStateStatus: CLEAN, and green checks: necessary context, but not Codex approval.

Loop Workflow

  1. Resolve the PR and current head SHA.
bash
gh pr view <number> --json number,url,headRefOid,headRefName,mergeable,mergeStateStatus,statusCheckRollup
  1. Read Codex state on the latest head. Check every GitHub surface where Codex can leave state:
  • PR body/description reactions: the approval thumbs-up may be here.
  • PR issue comments: Codex posts "Codex Review" summaries here, including the reviewed commit.
  • PR reviews and inline review comments: Codex posts actionable findings here.
  • Review threads: unresolved, non-outdated Codex threads remain blocking across pushes. Do not infer thread state from the placement commit recorded on individual comments.

Any code push after a prior Codex approval invalidates that approval. A material PR-body edit should restart the loop for the description, but it does not invalidate the code-head review unless it changes the scope being reviewed.

Check the PR body reactions first, and verify both the reacting actor and the reaction's freshness for the current head and current PR description. The status rollup is scoped to the current head SHA, while GraphQL lastEditedAt captures later edits to the PR object. Use the later timestamp as the approval lower bound:

bash
head_state_json="$(
  gh pr view <number> --json headRefOid,statusCheckRollup
)" || exit 1
head_sha="$(printf '%s' "$head_state_json" | jq -r '.headRefOid')"
head_started_at="$(
  printf '%s' "$head_state_json" \
    | jq -r '[.statusCheckRollup[] | .startedAt // empty] | min // empty'
)"

edit_state_json="$(
  gh api graphql \
    -F owner=<owner> \
    -F name=<repo> \
    -F number=<number> \
    -f query='query($owner:String!,$name:String!,$number:Int!){
      repository(owner:$owner,name:$name){
        pullRequest(number:$number){headRefOid lastEditedAt}
      }
    }'
)" || exit 1
edit_head_sha="$(
  printf '%s' "$edit_state_json" \
    | jq -r '.data.repository.pullRequest.headRefOid'
)"
body_edited_at="$(
  printf '%s' "$edit_state_json" \
    | jq -r '.data.repository.pullRequest.lastEditedAt // empty'
)"

if [ "$edit_head_sha" != "$head_sha" ]; then
  echo "Head changed while checking review state; reaction is not approval."
  exit 1
fi

body_reactions_available=true
if [ -z "$head_started_at" ]; then
  body_reactions_available=false
  approval_not_before="$body_edited_at"
  echo "No timestamped current-head checks; skipping PR-body reactions."
else
  approval_not_before="$(
    jq -nr \
      --arg head_started_at "$head_started_at" \
      --arg body_edited_at "$body_edited_at" \
      '[$head_started_at, $body_edited_at]
      | map(select(length > 0))
      | max // empty'
  )"
fi

if [ "$body_reactions_available" = true ]; then
  reactions_json="$(
    gh api "repos/<owner>/<repo>/issues/<number>/reactions" --paginate --slurp \
      -H "Accept: application/vnd.github+json"
  )"

  echo "Fresh Codex reaction state:"
  printf '%s' "$reactions_json" \
    | jq --arg approval_not_before "$approval_not_before" '
      def latest_reaction($content):
        [.[][]
        | select(.user.login == "chatgpt-codex-connector[bot]"
          and .content == $content
          and .created_at >= $approval_not_before)
        | {content, created_at, user: .user.login}]
        | sort_by(.created_at)
        | last // null;

      {approval: latest_reaction("+1"), pending: latest_reaction("eyes")}
      | .state = (
          if .approval != null
            and (.pending == null
              or .approval.created_at > .pending.created_at)
          then "approved"
          elif .pending != null then "pending"
          else "none"
          end
        )'
fi

gh pr view --json reactionGroups is useful for counts, but it does not show which user reacted. Use the REST reactions endpoint above to prove Codex left the thumbs-up after both current-head activity began and the PR object was last edited. A reaction state of approved satisfies the reaction portion of the gate. pending means the newest fresh signal is eyes, so keep waiting; a newer thumbs-up supersedes an older eyes reaction. If the current head has no timestamped status/check activity, skip PR-body reactions and continue to the review and issue-comment checks below instead of exiting the workflow.

Then check Codex issue comments and confirm the latest "Reviewed commit" matches the current head prefix:

bash
gh api "repos/<owner>/<repo>/issues/<number>/comments" --paginate \
  --slurp \
  | jq '[.[][] | select(.user.login | test("chatgpt-codex-connector"))
    | {id, created_at, html_url, body: .body[0:240]}]'

When PR-body reactions were skipped, only use an issue comment that names the exact current head and, when body_edited_at is non-empty, was created after that edit. Its thumbs-up must also pass the actor and approval_not_before check below.

Top-level pull-request reviews are a separate API surface from issue comments and review threads. Fetch every page and inspect Codex reviews submitted for the exact current head:

Show full SKILL.md (443 more words)Show less
bash
head_sha="$(gh pr view <number> --json headRefOid --jq '.headRefOid')"

gh api "repos/<owner>/<repo>/pulls/<number>/reviews" --paginate --slurp \
  | jq --arg head_sha "$head_sha" \
    '[.[][]
    | select((.user.login | test("chatgpt-codex-connector"))
      and .commit_id == $head_sha)
    | {id, user: .user.login, state, submitted_at, html_url, body}]
    | sort_by(.user, .submitted_at, .id)
    | group_by(.user)
    | map(last)'

Evaluate only the latest current-head review returned for each Codex actor; a newer review supersedes that actor's earlier top-level state on the same head. A latest CHANGES_REQUESTED review is blocking. Read every latest non-empty review body and address any substantive finding even when the review has no inline thread. A boilerplate-only COMMENTED review that merely accompanies inline findings is not an additional blocker after those findings are resolved; it is also not an approval signal. Review-thread resolution remains a separate gate below and is never superseded by top-level review history alone.

For a relevant Codex issue comment, verify any approval reaction by actor. The aggregate reaction counts on the comment do not identify who reacted:

bash
gh api "repos/<owner>/<repo>/issues/comments/<comment-id>/reactions" \
  --paginate --slurp \
  -H "Accept: application/vnd.github+json" \
  | jq --arg approval_not_before "$approval_not_before" '
    def latest_reaction($content):
      [.[][]
      | select(.user.login == "chatgpt-codex-connector[bot]"
        and .content == $content
        and .created_at >= $approval_not_before)
      | {content, created_at, user: .user.login}]
      | sort_by(.created_at)
      | last // null;

    {approval: latest_reaction("+1"), pending: latest_reaction("eyes")}
    | .state = (
        if .approval != null
          and (.pending == null
            or .approval.created_at > .pending.created_at)
        then "approved"
        elif .pending != null then "pending"
        else "none"
        end
      )'

Finally, query GraphQL review threads. GitHub records comment placement SHAs in the REST payload, but only the thread exposes whether feedback remains unresolved and non-outdated after a follow-up push:

bash
gh api graphql --paginate --slurp \
  -F owner=<owner> \
  -F name=<repo> \
  -F number=<number> \
  -f query='query(
    $owner:String!
    $name:String!
    $number:Int!
    $endCursor:String
  ){
    repository(owner:$owner,name:$name){
      pullRequest(number:$number){
        reviewThreads(first:100,after:$endCursor){
          nodes{
            id isResolved isOutdated path line
            comments(first:100){
              nodes{author{login} body url createdAt commit{oid}}
            }
          }
          pageInfo{hasNextPage endCursor}
        }
      }
    }
  }' \
  | jq '[.[].data.repository.pullRequest.reviewThreads.nodes[]
    | select((.isResolved | not) and (.isOutdated | not))
    | select(any(.comments.nodes[];
        .author.login | test("chatgpt-codex-connector")))
    | {id, path, line, comments: .comments.nodes}]'

An empty result across every page means there are no unresolved, non-outdated Codex threads. Keep outdated threads as review history, but do not treat their comment SHAs as the current resolution state.

  1. If the latest fresh reaction state is pending, keep monitoring. Do not infer approval from silence.

  2. If Codex leaves feedback, start addressing it immediately. Do not wait for all tests to complete before reading and acting on comments; that wastes review-loop time. Tests can keep running in parallel while you inspect the feedback.

  3. For each Codex comment, use engineering judgement.

  • If the comment identifies a real issue, patch it, run focused validation, push, and restart the loop on the new head.
  • If the comment is wrong, stale, intentionally out of scope, or not worth changing, reply on GitHub with a concise rationale and evidence. You are not forced to make a code change.
  • If the tradeoff is unclear, explain the tradeoff to the user and ask before choosing.
  1. After every push, restart from step 1. A new head requires a new Codex response.

  2. The loop is complete only when all of these are true on the same latest head:

  • Required tests/checks are passing.
  • Codex has no unaddressed current-head comments, top-level review findings, or unresolved non-outdated review threads.
  • Codex has left the thumbs-up approval signal, or the user explicitly overrode the gate.
  1. Report the gate before merging:
text
Codex gate: approved | waiting | blocking | overridden
Head: <sha>
Tests: passing | pending | failing
Evidence: <thumbs-up reaction, blocking comment URL, reply URL, or explicit user override>
  1. Only run gh pr merge when the gate is approved or overridden and tests are passing on that same head.

Failure Mode This Prevents

PR basicmachines-co/basic-memory-cloud#1366 was merged after CI went green and existing Codex threads were outdated, but before Codex had left its thumbs-up. Codex then posted a P2 review comment on the merged head. This skill exists to prevent that exact mistake.

© basicmachines-co, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/pr-review-loop of basicmachines-co/basic-memory.

Open the folder on GitHubat commit cb7407f

Compare with similar skills

PR Review Loop next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

PR Review Loop compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
PR Review Loop this skillbasicmachines-co/basic-memory4.1k—~3.2kAutomated safety check: PassAGPL-3.0
PR Babysitteropeninterpreter/openinterpreter69k3 repos~4.2kAutomated safety check: PassApache-2.0
Check PRonyx-dot-app/onyx32k2 repos~2.3kAutomated safety check: PassMIT
Contributor-First PR MergeHKUDS/OpenHarness16k1 repos~847Automated safety check: PassMIT
Create Pull Requestcline/cline70k1 repos~1.6kAutomated safety check: PassApache-2.0
Pull Request Title and Body Writeropeninterpreter/openinterpreter69k2 repos~1.1kAutomated safety check: PassApache-2.0

Similar skills

  • PR Babysitter

    openinterpreter/openinterpreter

    Watches an open GitHub pull request until it merges, handling review comments, diagnosing CI failures and retrying flaky checks along the way.

    69k GitHub starsUsed in 3 repos~4.2k tokens
    DevelopmentAuto-check passed
  • Check PR

    onyx-dot-app/onyx

    Checks a GitHub, GitLab, or Perforce (p4) pull request (or merge request, or shelved changelist) for unresolved review comments, failing status checks, and incomplete PR descriptions.

    32k GitHub starsUsed in 2 repos~2.3k tokens
    DevelopmentAuto-check passed
  • Merges external GitHub pull requests while keeping the original author credited, and fixes conflicts after the merge instead of rewriting the contribution.

    16k GitHub starsUsed in 1 repo~847 tokens
    DevelopmentAuto-check passed
  • Opens a GitHub pull request from your current branch with the gh CLI, after reviewing the commits and diff and gathering the details the PR needs.

    70k GitHub starsUsed in 1 repo~1.6k tokens
    DevelopmentAuto-check passed
  • Pull Request Title and Body Writer

    openinterpreter/openinterpreter

    Rewrites the title and body of one or more pull requests with gh, leading with why the change was made, then what changed, and describing only the net result.

    69k GitHub starsUsed in 2 repos~1.1k tokens
    DevelopmentAuto-check passed
  • Official

    Runs a loop on a GitHub pull request: fetch review state, triage comments into actions, implement them and resolve threads, repeating until nothing actionable is left.

    48k GitHub stars~2.2k tokensUpdated today
    DevelopmentAuto-check passed

More from basicmachines-co/basic-memory

All 49 skills in this repo
  • cmux Settings Editor

    basicmachines-co/basic-memory

    Views, sets, unsets and validates cmux settings in ~/.config/cmux/cmux.json with a helper script that checks keys against the schema.

    4.1k GitHub starsUsed in 1 repo~1.3k tokens
    Auto-check passed
  • cmux Window and Pane Control

    basicmachines-co/basic-memory

    End-user control of cmux topology and routing (windows, workspaces, panes/surfaces, focus, moves, reorder, identify, trigger flash). Use when automation needs…

    4.1k GitHub starsUsed in 2 repos~842 tokens
    Auto-check passed
  • Cmux Markdown Viewer Panel

    basicmachines-co/basic-memory

    Opens markdown files in a formatted cmux panel beside the terminal that re-renders on every change, handy for plans and task lists.

    4.1k GitHub starsUsed in 2 repos~527 tokens
    Auto-check passed
  • cmux Workspace Scoping

    basicmachines-co/basic-memory

    Keeps agent actions scoped to the cmux workspace and terminal that invoked it, and lays out pane and surface commands that avoid disrupting the user's own focus.

    4.1k GitHub starsUsed in 2 repos~1.7k tokens
    Auto-check passed
  • Basic Memory Repo Images

    basicmachines-co/basic-memory

    Produces PR, changelog and two-week retro images for the Basic Memory repository from evidence in PR bodies, saved to fixed paths under docs/assets/infographics.

    4.1k GitHub stars~2.7k tokensUpdated today
    Auto-check passed
  • Logfire Instrumentation

    basicmachines-co/basic-memory

    Adds Pydantic Logfire tracing, logging and metrics to Python, JavaScript or TypeScript and Rust projects, with the correct setup order and library extras.

    4.1k GitHub stars~2.3k tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about PR Review Loop

What does PR Review Loop do?

Enforce the Basic Machines GitHub PR review loop before merging. PR Review Loop is an agent skill from basicmachines-co/basic-memory. Enforce the Basic Machines GitHub PR review loop before merging.

When should I use PR Review Loop?

PR Review Loop fits situations like: Codex is preparing to merge; declare a PR ready; monitor Codex comments; address review feedback.

How do I install PR Review Loop in Claude Code?

Run `npx skills add basicmachines-co/basic-memory --skill pr-review-loop -a claude-code`. Or copy the skill folder (.agents/skills/pr-review-loop in basicmachines-co/basic-memory) into .claude/skills/pr-review-loop in your project. Claude Code loads it when a task matches its description.

How do I install PR Review Loop in Codex?

Run `npx skills add basicmachines-co/basic-memory --skill pr-review-loop -a codex`. Or copy the skill folder (.agents/skills/pr-review-loop in basicmachines-co/basic-memory) into .agents/skills/pr-review-loop in your project. Codex loads it when a task matches its description.

Can I use PR Review Loop in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add basicmachines-co/basic-memory --skill pr-review-loop -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/pr-review-loop, .gemini/skills/pr-review-loop, .github/skills/pr-review-loop and .opencode/skills/pr-review-loop in your project.

What does PR Review Loop need to run?

Going by SKILL.md and its folder, PR Review Loop needs the command-line tools its instructions call (gh and jq).

Does PR Review Loop access the network?

SKILL.md contains no URLs. Its commands use gh, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is PR Review Loop safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does PR Review Loop use?

PR Review Loop is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does PR Review Loop use?

About 3.2k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to PR Review Loop?

Skills that share tags, products or a category with PR Review Loop: PR Babysitter (openinterpreter/openinterpreter, 69k stars), Check PR (onyx-dot-app/onyx, 32k stars), Contributor-First PR Merge (HKUDS/OpenHarness, 16k stars) and Create Pull Request (cline/cline, 70k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains PR Review Loop?

basicmachines-co (a GitHub organization) maintains it in basicmachines-co/basic-memory, which has 4,115 GitHub stars. The repository holds 49 skills in this directory. The repository was last updated on October 7, 2026.

Source: basicmachines-co/basic-memory on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.