ccc-sol-loop · git:20261027.a49bba2 · 2026-10-27 · sha256 8278975d27107fce

ccc-sol-loop git:20261027.a49bba2A

Immutable. This exact content never changes and is served at /api/v1/blob/8278975d27107fce.

---
name: ccc-sol-loop
description: "Review a change in a bounded loop with an OpenAI reviewer through the Codex CLI, answer each finding with the smallest fix, and stop at agreement or budget. Use when the user says \"sol loop\" or wants a second-provider review before or after a PR."
allowed-tools:
  - Read
  - Bash(git status *)
  - Bash(git diff *)
  - Bash(git fetch *)
  - Bash(git merge-base *)
  - Bash(gh pr view *)
  - Bash(command -v codex)
  - AskUserQuestion
argument-hint: "[pr-number | base-ref] [--model <id>] [--rounds N]"
disable-model-invocation: true
---

# /ccc-sol-loop — Bounded second-provider review

**CC Commander** · /ccc-sol-loop · an OpenAI reviewer checks your change in a loop with a ledger, a round budget and minimal fixes.

> Adapted from [t3dotgg/tstack](https://github.com/t3dotgg/tstack) `skills/sol-loop/SKILL.md` at `92e38e2cf677a84a142e8df296861c588542135c`. MIT, Copyright (c) 2026 Theo Browne; see `LICENSE.txt`. Changes for CC Commander are marked "CCC safety:".

Make the most minimal changes that satisfy the reviewer. Watch for scope creep and push back when a finding is out of scope. The user's session model stays in place; only the reviewer is a different model.

## When to use / when not to

- Use before (or sometimes after) filing a pull request, to make a change more correct with an independent OpenAI reviewer.
- Not for a one-pass Claude review (ask the user to type `/ccc-review`), and not when no OpenAI route is available (see step 2).

## Budget

- Default: 3 rounds total. Round 1 is full. Later rounds check only changed code and open findings.
- Extend to 5 only for security, permissions, auth, data loss, or state/concurrency, while a blocker or should stays open with evidence, or when the user asks.
- Stop early if a round returns only nits. Declined nits and comment, doc or format-only fixes need no new round.
- One reviewer only. The reviewer must not start subagents or other reviewers.
- Keep a ledger: id, severity, outcome, usage if returned. Never guess usage.

## What happens

1. **Scope.** Run `git status --short`. Do not stash, discard, or include unrelated changes. Limit review to the change paths if they separate cleanly; otherwise stop and ask. Run `git fetch origin`, then find the base:
   - PR: `gh pr view <n> --json baseRefName,headRefOid`. Check out the branch only if clean. Confirm `HEAD` is the PR head, or ahead only by this change. Base: `git merge-base HEAD origin/<baseRefName>`.
   - Local: `git merge-base HEAD origin/<default-branch>`. No remote: a base the user names, or `HEAD` for uncommitted changes only.

   The change is base to working tree in those paths, with untracked files. Use one diff command in every round. State intent and out-of-scope in 1-2 sentences. Run the covering checks and do not send code this change breaks. Note missing or pre-failing checks in the brief.

2. **Start the reviewer.** CCC safety: the reviewer is OpenAI through the Codex CLI and runs read-only; no other provider is substituted. Check `command -v codex`. If it is missing, report the blocker and stop. Use `gpt-6.1-sol` unless the user names another model (role names and fallbacks live in `commander/adapters/codex/models.js`). Write the brief (step 3) to a file, then run:

   ```
   codex exec -m gpt-6.1-sol -s read-only --output-last-message <reply-file> "<brief>"
   ```

   Read `<reply-file>` for the reply. Inside Codex itself, run the reviewer as a subagent or a second `codex exec`. If the model is rejected or Codex is not signed in, report the blocker; never fall back to a non-OpenAI model. Do not edit scoped files while the review runs, and do not start a second reviewer. A timeout, error or empty reply is not approval: on failure, confirm the process stopped, then restart with the ledger.

3. **Round 1 brief** (the reviewer gets no history):

   ```
   Review only. Do not edit, commit, push, comment on PRs, or start subagents.
   Repo: <abs path> Base: <sha> Intent: <intent> Out of scope: <scope> Checks: <results>
   See: git diff <base> [-- <paths>]; git status --short (read untracked).
   Read surrounding code. Find bugs, broken callers, mismatch with intent.
   Skip style unless it hides a bug. Hold to the smallest change. Flag code,
   tests, or guards the intent does not need. Other paths, rare cases, small
   perf, extra compat: nits.
   blocker = intended case wrong. should = real bug callers will hit, in intent. nit = rest.
   Reply:
   VERDICT: APPROVE or CHANGES
   S1 [blocker|should|nit] <file>:<line> <claim>. Fix: <suggestion> (stable ids)
   ```

4. **Answer findings.** Check each finding and its severity yourself. Another path, rare case or small cost is a nit, whatever label it came with.
   - Agree: smallest fix. Prefer delete or narrow over a new lock, cache, helper or option. Fix the case that happened. Add one focused test that fails without the fix, if the intent needs it.
   - Disagree: say why, with evidence (file:line, test, output).
   - Out of scope or nit: decline in one line and list it as a follow-up.

   Update the ledger. Re-run the checks and `git diff --shortstat <base>`. If the review grew the diff, cut first. Do not agree just to end the loop.

5. **Next round.** Start one only if budget remains and a blocker or should is open, behavior code changed, or approval does not cover the current behavior diff. Use `codex exec resume --last` only when the last Codex session is the one you started; otherwise start a fresh `codex exec` with the brief. Send the round 1 brief, the ledger (`fixed:` / `disagree:` / `declined:` + evidence), the same base diff, and the change since last round. Tell the reviewer: open ids and changed code only; mark each old id `resolved` or `still open: <reason>`.

6. **Stop and ship.** Agreed means APPROVE on the current behavior diff, no blocker or should open, and no concern of your own. Stuck means an item stays disputed after two replies, or the budget ends; show both sides in 2-3 lines each and the user decides. Budget end is not approval.

   Do not push during the loop. CCC safety: push after agreement only if the user asked to push, ship or update the PR, and only after the repository's full local suite and lint are green on that head commit (CI is a signal, never the gate; never skip hooks; a normal push only). If you push to a PR, add above the model blurb:

   `Reviewed with /ccc-sol-loop: <N> rounds with <model>. Reviewer verdict: approved`

   Add `on <effort>` only if verified.

## Decision points

- Scope does not separate cleanly, or the base is unclear: AskUserQuestion with 🟢 stop and ask which paths and base to use, or review the whole working tree.
- Budget ends with a disputed item: AskUserQuestion with 🟢 accept the reviewer's fix, keep your position, or one more round (security-class only). Codex fallback: request_user_input or a plain-text question.

## Done when

- The reviewer returned APPROVE on the current behavior diff, or the user decided a stuck item.
- Report: rounds, model, what the reviewer changed, diff size before and after, fixed and declined findings with reasons, usage if returned (else say so), pushed or not.

## Guardrails

- Never substitute a non-OpenAI model; report the blocker.
- The reviewer is read-only (`-s read-only`) and never edits, commits or pushes.
- Never stash or discard user changes; never push mid-loop.
- Never skip hooks, secret scanning or checks to finish; a hook failure is fixed, not bypassed.
- Budget end, timeout or an empty reply is not approval.

## See also

- `/ccc-council` — three-provider review
- `/ccc-review` — branch review
- `/commander:ccc-deep-review` — adversarially verified branch review (workflow)

> ⚙️ **Fable contract:** plan before build · verifier ≠ worker · prove before alarm · loops need gates · leave durable state — `rules/fable-method.md`