Install
$ agentstack add skill-gzaripov-agent-skills-critique-loop ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Use this skill when the user wants an adversarial cross-model review. Two flows:
- Full flow — plan → navigator reviews → (fix or ask user) → user approves the plan → implement → navigator reviews the diff → (fix or ask user) → done. All four phases share a single navigator session (tracked by UUID in
.critique-loop/.session-id, resumed on every subsequent call) so the navigator remembers the plan discussion when it reviews the code. Trigger phrases: "critique-loop on ", "pair with Codex/Cursor on this", "plan and have Codex review", "do this with cross-model review". - Review-only flow — skip planning and implementation; run just the navigator code-review loop against an existing diff. Trigger phrases: "review my changes with Codex/Cursor", "critique-review this branch", "have the navigator look at my diff". See the Review-only flow section at the end of this document.
Configuration
Defaults live here — edit to override. Everything below reads from these.
- Navigator CLI:
codex(options:codex|cursor) - Artifact directory:
.critique-loop/— local working state only, gitignored. Not committed; not part of the PR. Add to.gitignoreon first run (Step 1). - Slug: current git branch name, or a kebab-case identifier derived from the task if on
main/master - Plan file path:
.critique-loop/-plan.md(default — ephemeral mode, lives under the gitignored artifact directory, never committed).
Override to a repo path like docs/plans/.md to use repo mode — the plan becomes a first-class committed design doc (skill commits the initial file and each revision as docs: plan for / docs: revise plan for (round N)). Pick repo mode when you want the plan reviewable as part of the PR; pick ephemeral mode when the plan is just scratch for the navigator loop.
Session-id file: .critique-loop/.session-id (created on first call, reused on every resume).
Navigator adapter
The skill body below refers to two abstract operations: START-SESSION (first call, creates the session) and RESUME-SESSION (every follow-up call). Each navigator below supplies both, plus its session-id-capture strategy. Pick one set based on the Navigator CLI value above.
Session reuse is mandatory. Before any START-SESSION, look for .critique-loop/.session-id. If a non-empty ID belongs to the same task/slug and the selected CLI can resume it, use RESUME-SESSION instead and never overwrite it. This applies across plan review, re-reviews, implementation, code review, review-only follow-ups, and a later skill invocation that returns to the same work. Preserving the conversation carries decisions and prior asks forward, avoids repeated discovery, and may reduce duplicate token use. Start a new chat only for a different task or an unrecoverable session ID.
All navigators accept the same inputs:
- `` — the prompt text (passed via a heredoc in the actual steps).
- `` — where the navigator's review is written.
- `` — the task slug (used in the session-id path).
If Navigator CLI = codex (default)
- Model:
gpt-5.5(latest) - Reasoning effort:
xhigh - Sandbox:
read-only(navigator reviews; does not write code)
START-SESSION (tee the log, grep the session ID after the call):
codex exec \
-m gpt-5.5 \
-c model_reasoning_effort=xhigh \
--sandbox read-only \
-o \
"" \
&1 | tee .critique-loop/.nav.log
grep -oE 'session id: [0-9a-f-]{36}' .critique-loop/.nav.log \
| head -1 | awk '{print $3}' > .critique-loop/.session-id
RESUME-SESSION:
SID=$(cat .critique-loop/.session-id)
codex exec resume "$SID" \
-m gpt-5.5 \
-c model_reasoning_effort=xhigh \
-c sandbox_mode='"read-only"' \
-o \
"" \
**Why ` **Why `-c sandbox_mode` on resume but `--sandbox` on the first call?** `codex exec` accepts the `--sandbox` flag; `codex exec resume` does NOT — it only takes `-c` config overrides, so the equivalent is `-c sandbox_mode='"read-only"'` (the value is parsed as TOML, hence the inner quotes). Passing `--sandbox` to `resume` errors out with a help dump and no review is generated.
#### If Navigator CLI = `cursor`
- **Model:** `gpt-5.3-codex-xhigh` (latest Codex-series GPT on Cursor, extra-high effort)
- **Mode:** `plan` (read-only; equivalent to Codex's `--sandbox read-only`)
- **Output format:** `text`
- **Headless trust:** `--trust` (required for non-interactive; equivalent to Codex's sandbox approval)
Cursor is cleaner than Codex for session tracking: `cursor-agent create-chat` returns the UUID *before* the first message, so **START-SESSION** and **RESUME-SESSION** use identical invocations; only START creates the chat ID first.
**START-SESSION** (pre-create chat, then run with `--resume`):
```bash
cursor-agent create-chat > .critique-loop/.session-id
SID=$(cat .critique-loop/.session-id)
cursor-agent -p --trust \
--model gpt-5.3-codex-xhigh \
--mode plan \
--output-format text \
--resume "$SID" \
"" \
>
RESUME-SESSION:
SID=$(cat .critique-loop/.session-id)
cursor-agent -p --trust \
--model gpt-5.3-codex-xhigh \
--mode plan \
--output-format text \
--resume "$SID" \
"" \
>
After either START-SESSION, verify .critique-loop/.session-id is non-empty before continuing. If empty, surface the raw output to the user and stop.
Prerequisites
- Navigator CLI is installed and authenticated:
- Codex:
codex --versionsucceeds,codex logindone. Smoke test: `codex exec -m gpt-5.5 --sandbox read-only "reply OK" /dev/null; then
echo ".critique-loop/" >> .gitignore git add .gitignore git commit -m "chore: gitignore .critique-loop artifacts" fi
The `.gitignore` commit is the only critique-loop-related commit that ever lands in the PR **from ephemeral mode**. In repo mode (see Configuration → Plan file path) the plan file itself is also committed (see Step 3).
### Step 2: Write the plan
Write the plan to the configured **Plan file path** (default `.critique-loop/-plan.md`). If the path is outside `.critique-loop/`, make sure the parent directory exists:
```bash
PLAN_FILE_PATH=".critique-loop/-plan.md" # or the user-configured repo path
mkdir -p "$(dirname "$PLAN_FILE_PATH")"
Sections:
- Task — one paragraph in your own words.
- Context — what the repo constrains (existing patterns, relevant files, prior art).
- Approach — numbered steps at the level of "edit function X in file Y to do Z".
- Files to modify — paths with one-line reason each.
- Verification — how you'll know it worked (commands to run, manual checks).
- Open questions — things the user or navigator should weigh in on; don't invent answers.
Step 3: Commit the plan (repo mode only)
If the plan file lives outside .critique-loop/ (repo mode), commit it:
if [[ "$PLAN_FILE_PATH" != .critique-loop/* ]]; then
git add "$PLAN_FILE_PATH"
git commit -m "docs: plan for "
fi
Skip this step in ephemeral mode — the plan is gitignored working state.
Phase 2: Navigator reviews the plan
Step 4: First review call
Apply the session-reuse invariant, then run START-SESSION only if this task has no usable session ID; otherwise run RESUME-SESSION. Use:
- `` = the task slug
- `
=.critique-loop/-plan-review.md` - ``:
You are the navigator in an XP pair-programming session. The driver (Claude Code) has written a plan for a task.
Read the plan at `${PLAN_FILE_PATH}` and any referenced code in the repo. Be adversarial — probe for:
- missing edge cases and error paths
- risky assumptions or unstated dependencies
- scope that does not match the stated task (too broad, too narrow, misaligned)
- simpler alternatives the driver may have missed
- verification steps that would not actually catch regressions
Output format:
1. One-sentence summary of your overall take.
2. Numbered list of specific asks. For each: **what** is wrong, **why** it matters, and (if you can) **how** you would address it. Reference file paths and line numbers when relevant.
3. End with EXACTLY one of these lines on its own line, nothing after:
- `VERDICT: APPROVE` — plan is solid; driver may implement.
- `VERDICT: CHANGES_REQUESTED` — the numbered asks above must be resolved.
- `VERDICT: BLOCK` — the plan has a fundamental problem needing human input.
Do not write code. Do not modify files. Review only.
Substitute ` and ${PLANFILEPATH} literally before passing. Verify .critique-loop/.session-id` is non-empty before continuing.
Step 5: Read the verdict
Read .critique-loop/-plan-review.md. Last line is the verdict.
VERDICT: APPROVE→ Step 5b (user-approval gate).VERDICT: CHANGES_REQUESTED→ Step 6.VERDICT: BLOCK→ Step 7.- No
VERDICT:line → resume with "please restate your review ending with a singleVERDICT:line". If it fails again, stop.
Step 5b: Wait for user approval
The navigator approved, but the user has final say before implementation starts. Present a short approval request:
- Slug and current branch.
- One-sentence summary of what will be implemented.
- Decisions made during review — list any user answers from Step 6 that shaped the plan (e.g. "strict
h→m→sorder chosen; bare numbers rejected"). Skip this bullet if there were none. - Open questions still unresolved — read the current plan file's Open questions section. List any items not answered by a user decision above. If all are resolved (or the section is empty), skip this bullet. Do NOT silently proceed with unresolved open questions in the plan.
- Plan file path (the user can open it to inspect before saying go).
- Explicit prompt: "Ready to implement? Say 'go' to proceed, or tell me what to change."
Wait for the user's response before doing anything else.
- User says "go" / approves → Phase 3.
- User requests minor changes (wording, small scope trim, ergonomic tweaks) → revise the plan file, show the updated summary again. No navigator round — these are user-preference edits, not correctness changes.
- User requests substantive changes (new requirement, different approach, new concern the navigator didn't raise) → revise the plan file and go back to Step 6b for another navigator round. The user's change shifted the design; the navigator should re-bless it before Phase 3.
- User wants to pivot or stop → stop. The plan file stays on disk (gitignored in ephemeral mode, or committed in repo mode) so they can come back to it later.
Use judgment on the minor-vs-substantive split. If unsure, prefer another navigator round over skipping straight to implementation.
Step 6: Resolve CHANGES_REQUESTED
Classify each numbered ask:
Claude resolves directly (no user input):
- Missing edge case, error path, or failure mode
- Unclear or out-of-order steps
- Wrong file paths, wrong function names, stale references
- Missing test or verification step
- Simpler alternative that preserves the user's stated goal
- Scope trim that stays inside the task
Surface to the user (Claude lacks the authority):
- Product decisions ("should this feature exist?", "setting X vs. Y?")
- Architecture tradeoffs with no obvious right answer
- Business rules or domain judgements
- Anything depending on information outside the repo
Apply:
- If any user-surface asks exist, pause. Summarize each for the user in 2–3 bullets (the ask, why it matters, the navigator's suggested options if any). Wait for the user's answer. Fix Claude-resolvable asks in the same revision pass once the user answers.
- If all asks are Claude-resolvable, fix them in
.critique-loop/-plan.mddirectly.
Write a short note to .critique-loop/-driver-response.md:
- Which numbered asks were addressed and how (one line each).
- Any user answers verbatim.
- Any asks you are pushing back on, and why.
Round number N for file naming is tracked by file count in .critique-loop/ (e.g., look for the highest -plan-review-.md). Review files and driver-response are always gitignored regardless of plan mode.
Repo-mode only: if the plan lives outside .critique-loop/, commit the revision so the navigator in the next round reads the updated file from a real commit:
if [[ "$PLAN_FILE_PATH" != .critique-loop/* ]]; then
git add "$PLAN_FILE_PATH"
git commit -m "docs: revise plan for (round N)"
fi
In ephemeral mode, skip — the navigator reads the working-tree file directly.
Step 6b: Re-review (resume the same session)
Run RESUME-SESSION from the navigator adapter with:
- `` = the task slug
- `
=.critique-loop/-plan-review-.md(incrementeach round:-plan-review-2.md,-plan-review-3.md`, …) - `
(substitute${PLANFILEPATH}` before passing):
I revised the plan based on your review. Updated plan: `${PLAN_FILE_PATH}`. My response to each ask: `.critique-loop/-driver-response.md`.
Re-review. Note which prior asks are resolved and which remain open. Same output format, end with `VERDICT:`.
Go back to Step 5.
Step 7: Handle BLOCK
Do not loop. Summarize the blocker for the user in 2–4 sentences, include the navigator's suggested direction, stop. Do not re-invoke the navigator until the user responds.
Phase 3: Implement the approved plan
Step 8: Record the plan SHA
After the user approves in Step 5b, capture the current HEAD SHA. This is the baseline the implementation will diff against in Phase 4 — everything committed after this point is considered "the implementation":
git rev-parse HEAD > .critique-loop/.plan-sha
In ephemeral mode the plan is gitignored, so HEAD is the last real commit on the branch. In repo mode the plan's revision commits are included in ..HEAD, which is fine — the navigator already approved them in Phase 2, so they don't show up as asks in Phase 4.
Step 9: Implement
Implement exactly what the approved plan describes. Do not expand scope — if you find something the plan missed, note it for the code-review phase and either (a) fix it if it's a minor oversight in the same area or (b) stop and ask the user if it's a scope question.
Use conventional commits (feat:, fix:, refactor:, etc.), one logical change per commit. Run the project's lint + tests before the last commit. If lint or tests fail and the fix isn't trivial, stop and ask the user.
Step 10: Write the diff summary
After the final implementation commit, write .critique-loop/-diff-summary.md:
- Commit range:
..HEAD(use the SHA from Step 8). - What changed: 2–5 bullets, one per significant change.
- Files touched: bullet list.
- Tests added / updated: bullet list.
- Anything deferred or out of scope: bullets (if any).
This file is gitignored working state — do not commit it.
Phase 4: Navigator reviews the diff
Step 11: Resume the session for code review
Read the plan SHA first, then interpolate it into the prompt:
PLAN_SHA=$(cat .critique-loop/.plan-sha)
Run RESUME-SESSION from the navigator adapter with:
- `` = the task slug
- `
=.critique-loop/-code-review.md` - `
(substitute${PLANSHA}and${PLANFILE_PATH}` before passing):
The plan you approved is implemented. Review the diff.
- Plan: `${PLAN_FILE_PATH}`
- Diff summary: `.critique-loop/-diff-summary.md`
- Commit range: `${PLAN_SHA}..HEAD`
Run `git diff ${PLAN_SHA}..HEAD` and read the changed files. Verify:
(a) Implementation matches the approved plan.
(b) No scope creep beyond what the plan approved.
(c) No introduced bugs, regressions, or missed edge cases.
(d) Tests cover the changes adequately.
Output format: same as before — numbered asks with file:line references where possible, ending with `VERDICT: APPROVE | CHANGES_REQUESTED | BLOCK`.
Do not write code. Do not modify files. Review only.
Step 12: Read the verdict
Read .critique-loop/-code-review.md.
VERDICT: APPROVE
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: gzaripov
- Source: gzaripov/agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.