Automated Pull Request Remediation Workflow Automated Pull Request Remediation Workflow review-fix-loop orchestrates two existing skills into a repeat-until-clean cycle against an open GitHub PR: code-review-to-github (Codex CLI reviews a commit or range) and code-review-workflow:respond (fixes what it finds, replies, and resolves). It keeps running rounds — review, fix, review again — until a round comes back clean, a round cap is hit, or Codex can’t produce a result after a few retries. It runs entirely in the current session. There’s no /loop scheduling involved — codex exec runs as a backgrounded shell command, and its completion is what drives the orchestrator to the next step.

How It’s Triggered

Invoke it with the Skill tool (skill: "review-fix-loop") or the /review-fix-loop slash command, with the PR number as the first argument:
Arguments are positional, left to right, all but the PR number optional: <pr_number> [max_rounds] [model]. Natural language works too — “run the review-fix loop on PR 93 with gpt-5.6-sol” parses the same way.

How It Works

The core design constraint: Codex cannot talk to GitHub at all. Its -s workspace-write sandbox blocks outbound network from spawned shell commands entirely — a plain curl or gh call from inside it fails instantly (“Could not resolve host”, 0ms), which is a hard sandbox policy, not flaky DNS or a bad credential. So the two skills split cleanly by what each side can actually do:
  • code-review-to-github runs sandboxed, local-only. It reads a pre-fetched JSON snapshot of the PR (context_file) — state, conversation comments, and unresolved threads — does its analysis against the local git diff, tests, and CodeGraph, and writes its finished review as a JSON payload (output_file). It never calls gh, curl, or the Codex GitHub connector.
  • review-fix-loop (this skill) does every actual GitHub read and write, from its own unsandboxed shell: fetching context before each round, and publishing whatever Codex wrote after each round.
  • code-review-workflow:respond does the fix side once a round finds something: fixes the code, pushes, replies to each thread, resolves it, and posts a final round-summary comment tagging the human reviewer.

Two identities, split by role

Publishing runs as a separate reviewer account, not the PR author, so the review reads as an independent pass rather than the author reviewing themselves. Everything else — replying, resolving, pushing fixes — runs as the default account (the PR author), because that’s who is actually responding to the feedback. Mixing these up is a real failure mode, not a hypothetical one — a reply or resolve posted under the reviewer account reads as the reviewer talking to itself instead of the author responding.

GitHub is the only source of truth for findings

codex exec’s log output may be read to diagnose why a round failed (a crash, a malformed payload) — never to extract a finding’s title, file, or fix and act on it. A finding only counts once it’s in output_file, and after publishing, once it’s an actual review or thread on the PR. This matters because Codex’s own review attempts can fail to publish for reasons that have nothing to do with whether it found something real — treating log text as a substitute for a published, re-verifiable finding breaks the audit trail the whole design exists to protect.

The Workflow

  1. Validate the PR is open. Stop if it isn’t.
  2. Set up round 0 — the merge-base with the PR’s base branch becomes the starting review boundary.
  3. Loop, once per round, until clean or capped:
    1. Fetch this round’s PR context (state, comments, unresolved threads) and write it to context_file.
    2. Run codex exec against code-review-to-github, passing the commit range plus the context/output file paths. Retry up to codex_retries times if it exits without a valid output_file.
    3. Publish output_file to GitHub exactly as Codex wrote it, as the reviewer account. Verify the review count actually increased.
    4. Query unresolved threads — anything new is this round’s findings.
    5. Zero findings → the loop is clean, stop here. Any findings → run code-review-workflow:respond through all of its own steps (fix, push, reply, resolve, and its final round-summary comment) — not a partial, hand-rolled version of the same steps.
    6. Advance the review boundary to this round’s commit, start the next round.
  4. Cap hit — if rounds run out with findings still open, stop and report incomplete rather than looping silently past the limit.
  5. Codex blocked — if a round exhausts its retries without ever producing a valid output_file, stop immediately. A missing result is never treated as “clean.”

What to Expect

Every run ends with a short summary:
  • Outcomeclean (reached zero findings), cap hit (findings still open past max_rounds), or blocked (a round never got a valid result from Codex).
  • Rounds executed.
  • Findings by axis × priority — e.g. Standards: P1×1, P2×3 · Spec: P2×1, P3×2.
  • Total elapsed wall-clock time.
  • If blocked: which round, how many codex exec attempts, and the error seen in the log (for diagnosis, not as a finding).
A clean run means the last published review had no comments and everything from earlier rounds is resolved — verifiable by reopening the PR, not by trusting a session’s memory of what happened. A blocked run means nothing was silently guessed at; whatever caused Codex not to finish needs a human look before retrying.
  • Code Review Process Guide — the two skills this orchestrates, in detail.
  • .claude/skills/review-fix-loop/SKILL.md — the skill definition itself.
  • .agents/skills/code-review-to-github/SKILL.md — the review half (local-only, sandboxed).
  • .claude/commands/code-review-workflow/respond.md — the fix half.