Coding & Development✨gemini🤖claude💬gpt🌐universal

Agent Loop Skill — Claude Code Native Mode

Local Claude/Codex PR review loop using existing CLI subscriptions instead of model API keys

Quick Start

Install this Skill

npx skills add wwind123/coding-review-agent-loop
# Agent Loop Skill — Claude Code Native Mode

This skill lets you run the `coding-review-agent-loop` orchestration directly inside
an interactive Claude Code session, without calling `claude -p` for Claude turns.

Claude (you, the host) performs coder/plan turns using your active session context.
External agents (Codex, Gemini) are invoked via their local CLIs as subprocesses.
GitHub operations go through `gh`.

**Skill vs the `agent-loop` CLI (when to use which):** use the skill when you want to
participate/oversee, want Claude turns on your **session model** (e.g. Opus, no
`--claude-model` needed), want conversational setup, or want the host to investigate an
unexpected failure interactively. The skill still requires the `claude` executable to
start Claude Code; it avoids launching a new `claude -p` process for each host turn, so
an on-disk binary update does not affect the already-running session. Use the CLI for
lower-overhead orchestration in typical runs: its round control and state transitions are
mechanical Python code, while skill mode also spends host-session context and output tokens
interpreting and executing the orchestration workflow. Actual quota use varies. The CLI also
supports hands-off automation and externally scheduled resume after quota reset — optionally a
`--test-command` gate and, with
`--auto-merge`, CI-wait + merge, or explicit `--managed-ci` exact-head qualification
with a printed head-guarded manual merge command (all are configuration-dependent;
without `--test-command`, `--auto-merge`, or `--managed-ci`, the CLI runs no gate
and does not poll or merge). The skill never auto-merges (merge stays a human
decision), cannot continue or schedule its own restart after the host session exhausts
quota, and may still encounter Claude Code tool-approval prompts. Keeping the skill also
reduces reliance on
`claude -p` for Claude turns if it is ever billed/restricted differently (announced once,
then reversed) — whether interactive-session usage is treated differently depends on
Anthropic's current terms and product behavior (see the "Billing and terms note" below),
so this is about reducing the dependency, not a guaranteed billing outcome. See
[`Claude Code Skill Mode`](README.md#claude-code-skill-mode) in `README.md` for a summary.

## Prerequisites

- `gh` authenticated and configured.
- `codex` CLI installed (for Codex reviewer turns).
- `gemini` CLI installed (for Gemini reviewer turns).
- The `coding-review-agent-loop` package importable from `src/` (run from repo root).

## Process-tree containment

External agents and `--test-command` gates are mechanically contained when the
host supports systemd 253+, a user manager, delegated unified cgroup v2, and
the requested controllers. They share a per-user `agent-loop.slice`, with a
conservative aggregate that reserves OS headroom and child profiles for
`coder`, `reviewer`, `repair`, and `test-gate`. The foreground launcher is
`systemd-run --user --scope --quiet`; it intentionally has no `--wait`,
`--service`, or `--pipe`. A scope-internal shim records target start or target
exec failure, so the report—not a launcher exit number—decides whether a
numeric status belongs to the target.

Run `agent-loop containment-preflight` to inspect resolved limits and
capability-aware telemetry. `auto` visibly falls back to process-group
TERM/KILL, which is deterministic but has no memory ceiling; `required` fails
closed. OOM, hard memory/swap, and task-limit events are `resource-exhausted`;
`MemoryHigh` and PSI are pressure diagnostics. Missing optional counters are
`not collected on this host`, not evidence loss. The managed test wrapper
rejects a same-lane duplicate before spawn and does not learn its runtime.
Unwrapped commands cannot be deduplicated from free-form logs without a
structured hook. In-session Claude and arbitrary descendants remain part of
the host session; use the managed wrapper for test gates and external agents
for the mechanical containment boundary.

Skill-mode test gates select this policy with
`AGENT_LOOP_CONTAINMENT_MODE=auto|required|off`; the default is `auto`.

## How to invoke this skill

Open a Claude Code session **in the `coding-review-agent-loop` repo root** (or
any directory where `helpers/` is on the Python path).  Then tell Claude what
you want in natural language, for example:

```
Run the agent-loop skill for issue #123 in myorg/myrepo with gemini as reviewer.
```

```
Plan and implement issue #42 in myorg/myrepo, reviewers: codex and gemini.
```

```
Run agent-loop on PR #99 in myorg/myrepo.
```

```
Resume the agent-loop skill for issue #123 in myorg/myrepo.
```

Claude will read this file, pick a mode, and follow the procedure below.  You do
not need to type any slash command; natural-language requests are enough.

---

## Choosing a mode

This is one skill with three modes; pick the procedure from what you're given:

- A **PR number** to review → **PR mode** (run the PR-loop).
- An **issue number**, or you want a plan first → **issue mode** (plan-loop, then
  *optionally* implement + PR-loop). Confirm whether to stop at an approved plan
  or continue into implementation.
- A **free-form task** with no issue yet → **task mode** (create a scratch issue,
  then proceed as issue mode).

All modes share the sub-procedures below, the same primitives, the same session/
resume model, and the same posture: **merge is always a human decision.** For any
mode, you need `OWNER/REPO` and the reviewer set (`codex`, `gemini`, and/or
`antigravity` — the `agy` CLI, the migration path for Gemini CLI consumer access
that Google retires on 2026-06-18). `antigravity` works wherever an external
coder/reviewer does (`--coder antigravity` / `--reviewers antigravity ...`); `agy` is
accepted as an alias (e.g. `--coder agy` / `--reviewers agy`), normalized to `antigravity`.
With no override, it uses the ordered fallback chain `Gemini 3.7 Flash (High)` →
`Gemini 3.6 Flash (High)` → `Gemini 3.1 Pro (High)`. Use `--model MODEL` for the legacy single-model
override or `--antigravity-models MODEL [MODEL ...]` for a custom ordered chain;
the two model options are mutually exclusive. Customize fallback detection with
`--antigravity-quota-signatures SIGNATURE [SIGNATURE ...]`. Each `agy --print`
call passes `--print-timeout` from `--antigravity-print-timeout-seconds`
(default `600`, i.e. ten minutes, matching the `agent-loop` CLI), overriding
`agy`'s own five-minute print-mode default so long turns are not cut short.
For a required local test that may run up to 1,800 seconds, configure this
whole-invocation deadline above that cap with additional budget for analysis,
edits, reporting, and other turn work; the default cannot accommodate it.
Provider capacity failures retry the active model before fallback; the
`--max-retries` allowance is shared across the chain, capping calls at
`models + retries`. Custom quota signatures control eligibility, while settings,
model, timeout, and schema failures remain deterministic.
These options are available on every skill command that can invoke an
external agent.

---

## Sub-procedures

These are the building blocks; the modes sequence them.

### Plan-loop (for issue N)

1. Write the implementation plan to
   `/tmp/agent-loop-skill/{session-id}/plan-r{N}.md`, ending with:
   ```
   <!-- AGENT_PLAN_STATE: approved -->
   -- Anthropic Claude
   ```
2. Run one round. `skill_runner` handles resume, plan validation, attaching
   `AGENT_LOOP_META`, posting to GitHub, running each reviewer, rendering/
   validating responses, and writing session state:
   ```bash
   python -m helpers.skill_runner run-plan-round \
     --issue ISSUE --repo OWNER/REPO \
     --plan-file /tmp/agent-loop-skill/{session-id}/plan-r{N}.md \
     --reviewers codex gemini \
     [--workdir-codex /path/to/checkout] [--workdir-gemini /path/to/checkout] [--workdir-antigravity /path/to/checkout]
   ```
   It prints a JSON result:
   ```json
   { "state": "approved" | "blocking", "round_number": N,
     "blocking_items": [...], "approved_reviewers": [...] }
   ```
3. Decide:
   - `"blocking"` → address `blocking_items`, post a change-summary comment
     (template below), write a revised plan, and re-run. The round number
     increments automatically.
   - `"approved"` with empty `blocking_items` → **planning is complete.**
   - Clarification needed → post an `<!-- AGENT_CLARIFY -->` comment and stop.

Change-summary template (`EOF` must be flush-left when run in a shell):
```bash
gh issue comment ISSUE --repo OWNER/REPO --body "$(cat <<'EOF'
Addressed round-N feedback:

- **item-X**: <what was changed>
- **item-Y**: <what was changed>

-- <Your Name>
EOF
)"
```

### Implement step (after an approved plan)

Run this only when the user asked to implement (see **issue mode**):

1. If a PR for this issue already exists (e.g. you were interrupted), resume it —
   do **not** open a second one.
2. Implement the approved plan in your working tree on a feature branch and commit.
3. Open a PR that references the issue, and note the PR number. Hand off to the
   PR-loop.

### Answer-mode discussion summaries

When the CLI is used for `discuss --discuss-result-mode answer`, the public
issue comments lead with a concise state rather than the raw transcript. Each
completed interim round may expose cumulative consensus, active disagreements,
changes, missing facts, and next-round focus; a final comment exposes the fixed
mechanical outcome, agreed conclusions, remaining decisions, and next action.
The configured `--discuss-analyzer` is the only eligible synthesis agent.
Enriched agendas cost no additional round call; a legacy agenda permits one
bounded analyzer fallback, and exact/semantic/debater-confirmed final artifacts
are adapted without a redundant synthesis call. Missing analyzers, invalid or
unsupported claims, and transport failures retain the existing fail-closed
rendering. Partial rounds are labeled as covering responding debaters only and
cannot become final consensus. The latest validated snapshot is persisted for
resume, while full per-agent responses remain the audit record and synthesis
text/excerpts are bounded and spillable.

### External by-phase implementation (after an approved plan)

Use this when the user asks for skill-mode parity with
`plan_execution_mode="implement-by-phase"` and an external coder should perform
the first automated phase:

```bash
python -m helpers.skill_runner run-implement-by-phase \
  --issue ISSUE --repo OWNER/REPO \
  --coder codex \
  --plan-file /tmp/agent-loop-skill/{session-id}/approved-plan.md \
  --workdir /path/to/push-capable/clone \
  [--base main]
```

Live runs require a push-capable `--workdir` (or `--workdir-codex` /
`--workdir-gemini` / `--workdir-antigravity`). The command decomposes the
approved parent plan using an
`implement-by-phase` decomposition marker, creates or reuses child phase issues,
and then inspects phase 1:

- If phase 1 is `agent-pr`, it records a phase handoff marker on the parent and
  runs the external coder against the child issue, using that phase's
  `parent_context` as the approved implementation plan. It does not write the
  one-shot implementation marker used by `run-implement`.
- If phase 1 is `human-action` or `manual-close`, it prints JSON identifying the
  child issue and stops without posting a phase handoff or running the coder.
- If a matching phase handoff marker already exists, it prints a resume hint for
  the child issue and does not invoke the coder again.

`--dry-run` parses the decomposition and runs the implementation dry-run stub,
but it does not create child issues, post markers, push branches, or open a real
PR. Dry-run child issue numbers may be absent, so the JSON is a preview of the
phase that would be implemented.

### PR-loop (for PR N)

1. Run one round. The PR diff is fetched automatically — there is no plan-file
   step:
   ```bash
   python -m helpers.skill_runner run-pr-round \
     --pr PR_NUMBER --repo OWNER/REPO --reviewers codex gemini \
     [--head-sha SHA] [--workdir-codex /path/to/checkout] [--workdir-gemini /path/to/checkout] [--workdir-antigravity /path/to/checkout] \
     [--test-command "pytest -q"] [--test-workdir .] \
     [--approved-followups summarize|issue]
   ```
   The result shape matches plan rounds, plus the optional `tests` and
   `approved_followups` fields (see **Gates & guardrails**).
2. Decide:
   - `"blocking"` with a host-owned PR → fix the code, push, post a
     change-summary comment (template below), and re-run. A new head SHA starts
     a new round automatically.
   - `"blocking"` with an external-coder PR → have that coder address the
     settled blocking review and push to the same PR branch:
     ```bash
     python -m helpers.skill_runner run-pr-fix \
       --pr PR_NUMBER --repo OWNER/REPO \
       --coder codex \
       --reviewers claude gemini \
       --workdir /path/to/push-capable/pr-clone
     ```
     The PR must be open, `--reviewers` must exactly match the reviewer set used
     by the previous `run-pr-round`, and `--workdir` must be a clean,
     push-capable clone where the PR head branch can be checked out by name.
     Re-run `run-pr-round` after the coder follow-up posts.
   - `"approved"` → check the test gate, then **stop at "ready to merge — human
     decision."** The skill never merges.

Change-summary template:
```bash
gh pr comment PR --repo OWNER/REPO --body "$(cat <<'EOF'
Addressed round-N feedback:

- **item-X**: <what was changed>
- **item-Y**: <what was changed>

-- <Your Name>
EOF
)"
```

---

## Modes

### PR mode

Run the **PR-loop** on the given PR. Done when it approves (ready to merge —
human decision).

### Issue mode

1. **Plan-loop** on the issue until approved.
2. Then, based on the user's intent:
   - **"plan and implement"** → **Implement step** → **PR-loop** → ready to merge.
   - **"just plan"** (the default) → report the approved plan and stop.

This is the skill's equivalent of the CLI's `issue --plan-first
[--implement-after-approval]`. Because the host **is** the coder, "implement after
approval" is your stated intent, not a code flag.

### Task mode

For a free-form task with no issue yet:
```bash
python -m helpers.skill_runner run-task-round \
  --task "Add a --verbose flag to the CLI" \
  --repo OWNER/REPO \
  --plan-file /tmp/agent-loop-skill/{session-id}/plan-r{N}.md \
  --reviewers codex gemini
```
This creates (or idempotently reuses) a scratch issue from the task text, then
runs the first plan round on it. Use `--task-file PATH` (or `--task-file -` for
stdin) for longer descriptions; `--dry-run` previews the issue it would create
without creating it. From there, continue **exactly as issue mode** from the
Plan-loop onward (including the optional Implement step + PR-loop).

Task mode accepts the same coder roles as issue mode. The host coder remains the
default and requires `--plan-file`. To have an external coder produce the plan,
pass `--coder codex|gemini|antigravity` (or `agy`) and omit `--plan-file`:

```bash
python -m helpers.skill_runner run-task-round \
  --task "Add a --verbose flag to the CLI" \
  --repo OWNER/REPO \
  --coder codex \
  --reviewers gemini
```

---

## Gates & guardrails

- **Test gate** (PR-loop): `--test-command` runs after the reviewer turns in
  `--test-workdir` (default: the current directory, where you as the host coder
  have the PR branch checked out). The outcome is reported under `tests`:
  ```json
  "tests": { "command": "pytest -q", "passed": true, "exit_code": 0, "output_tail": "..." }
  ```
  A setup failure (empty/bad command, missing executable, or missing
  `--test-workdir`) is reported as
  `{"passed": false, "exit_code": null, "error": ...}` rather than crashing the
  round. **"Ready to merge" = `state == "approved"` AND `tests.passed`.** Treat a
  failing or errored gate as a hard stop, even when reviewers approved.
- **Approved-followups** (PR-loop): `--approved-followups summarize|issue`
  publishes reviewers' future follow-ups when (and only when) a round is
  **approved**. `summarize` posts one PR comment of the reconciled follow-ups;
  `issue` files up to three follow-up issues; `ignore` (default) discards them.
  The mode is also threaded into the reviewer prompt, so reviewers only surface
  future follow-ups when a non-`ignore` mode is set. Publishing is idempotent
  (one publish per PR head SHA + mode) and reported under `approved_followups`:
  ```json
  "approved_followups": { "mode": "summarize", "published": true, "count": 2 }
  ```
- **Agent memory** (plan-loop and PR-loop): repo-scoped orientation context
  (repo summary, architecture map, module index, test profile, toolchain,
  changed-file summaries) is generated deterministically (git + static analysis,
  no LLM) and included in the reviewer prompts so Codex/Gemini get the same
  context the CLI gives them. On by default; `--no-agent-memory` disables it,
  `--refresh-agent-memory` forces regeneration. The cache lives under the skill
  session dir and is incremental. Generation is advisory — if it fails, the round
  continues without memory.
- **Usage/cost** (plan-loop and PR-loop): the round result includes a `usage`
  field with token totals for the external reviewers (Codex/Gemini), aggregated
  per agent. It is **external-agents-only** — the host's Claude coder/plan turns
  run in the interactive session and have no programmatic token count, so the
  numbers are *not* a session total (the field's `scope`/`note` say so). Usage is
  persisted in `AGENT_LOOP_META`, so resumed rounds aggregate the full
  external-agent cost.
  ```json
  "usage": { "scope": "external-agents-only", "note": "...host turns not counted...",
             "totals": { "call_count": 2, "total_tokens": 250, ... },
             "per_agent": { "codex": {...}, "gemini": {...} } }
  ```
- **Reviewer resilience** (plan-loop and PR-loop): if an external reviewer's CLI
  fails to produce a usable review (an agent/tooling failure — e.g. an empty or
  malformed-tool-call response — *not* a fixable malformed review), the skill does
  **not** abort the round. It marks that reviewer **unavailable**, continues with
  the remaining reviewers, and lists it under `unavailable_reviewers`; the reviewer
  is re-attempted on the next run (or drop it from `--reviewers` to proceed). A
  round with an unavailable reviewer is never reported `approved`: its `state` is
  `incomplete` (or `blocking`/`pending` if those apply first). A genuinely
  malformed-but-content-bearing structured output is first recovered automatically
  when possible. The skill applies its safe reviewer normalizers, envelope cleanup,
  known-ledger unknown-disposition stripping, plan-revision human-requirements
  acknowledgement reconstruction, and finally a Gemini format-repair pass. Only
  genuinely unrecoverable output falls back to `retry-validate`.
- **Round states.** `approved` (all configured reviewers signed off) · `blocking`
  (a reviewer reported must-fix items) · `pending` (a host `claude` review handoff
  is outstanding — complete it with `complete-host-review`) · `incomplete` (a
  configured reviewer was unavailable; rerun). Precedence when several apply:
  `pending` > `blocking` > `incomplete` > `approved`.
- **Merge is always a human decision.** The skill never runs CI-wait or
  auto-merge; every mode stops at "ready to merge."
- **Merge conflicts route to the coder, not CI-wait.** The `coding_review_agent_loop`
  CLI orchestrator checks GitHub's own mergeability (`mergeStateStatus`/`mergeable`)
  before each review round and again before CI checks/auto-merge; a confirmed
  `dirty`/`CONFLICTING` state skips reviewers and any CI wait or merge attempt
  and routes the PR to the assigned coder to sync, resolve, and push instead
  (see [Merge conflicts](docs/local_agent_loop.md#merge-conflicts)). In
  skill-mode, if you find `gh pr view` reporting `mergeable: false` /
  `mergeStateStatus: DIRTY`, treat that the same

… (truncated)
Repository
11stars
4forks
View on GitHub
Details
DiscoveredJun 28, 2026
Last UpdatedSep 9, 2026
Author@wwind123
Quality Score
68/100