zjunlp/Mechanist/skills/auto-iteration-loop/SKILL.md
auto-iteration-loop
Autonomous research review loop that consumes /auto-verify's four-state output (PASS / FAIL / INCONCLUSIVE / ZERO_ELIGIBLE_VARIANTS / deferred) and routes each claim to the right back-edge — brief audit, two-phase FAIL handling (variant-integrity fix then optional claim-stage re-entry), main-experiment-script fix, or variant-only fix — under a unified iteration budget. Configure the reviewer LLM via llm-chat MCP server or environment variables. Trigger with "auto review loop llm" or "llm review"
- Source repository stars
- 48
- Declared platforms
- 0
- Static risk flags
- 4
- Last source update
- 2026-08-25
- Source checked
- 2026-08-25
Decision brief
What it does: where it fits
Autonomously iterate over /auto-verify's per-claim verdicts: review → implement fixes (variant-integrity, main-experiment-script, or claim-stage rewrite) → re-review, until the external reviewer gives a positive assessment with all FAIL / INCONCLUSIVE / ZEROELIGIBLEVARIANTS clai…
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/zjunlp/Mechanist --skill "skills/auto-iteration-loop"Inspect the Agent Skill "auto-iteration-loop" from https://github.com/zjunlp/Mechanist/blob/407b0ca20c50dafd666e889868617c5095f4b5a8/skills/auto-iteration-loop/SKILL.md at commit 407b0ca20c50dafd666e889868617c5095f4b5a8. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
Pre-flight check (run before Phase A of every iteration, mandatory)
Hard-fail rule: If LLMMODEL is empty after this resolution (none of the three sources provides it), the skill MUST abort with: "Reviewer model not configured. Add mcpServers.llm-chat.env.{LLMMODEL,LLMBASEURL,LLMAPIKEY} to .mcp.json (project) or /.claude/settings.json (user)."
Hard-fail rule: If LLMMODEL is empty after this resolution (none of the three sources provides it), the skill MUST abort with: "Reviewer model not configured. Add mcpServers.llm-chat.env.{LLMMODEL,LLMBASEURL,LLMAPIKEY}…Do not guess a default. Do not fall back to a model name read from task.md or any other project file.The earlier LLM Configuration example block in older versions of this skill (which duplicated the same llm-chat MCP setup) has been removed — the authoritative config resolution is the priority order above. For a worked… - 02
Workflow
This skill iterates over existing artifacts produced by upstream stages — it does not generate them from scratch. $ARGUMENTS (the optional research-direction string) is treated as reviewer context only, never as a starting point.
idea-stage/IDEAREPORT.mdrefine-logs/FINALPROPOSAL.mdrefine-logs/EXPERIMENTRESULTS.md - 03
Phase A reviewer prompt — explicit bucket list
When constructing Phase A's reviewer prompt, include all five state buckets explicitly so the reviewer can address them separately. Empty buckets are stated as none, not omitted (the reviewer needs to know "no claims FAILed" is different from "I forgot to tell you"):
When constructing Phase A's reviewer prompt, include all five state buckets explicitly so the reviewer can address them separately. Empty buckets are stated as none, not omitted (the reviewer needs to know "no claims FA…deferredclaims is a legacy empty bucket in new runs and is not part of the reviewer prompt. - 04
Phase A: Review
Iteration 1 uses the prompt shape below (no Reviewer Memory yet — file is created at the end of iteration 1 by Phase B.5). The budget line at the top of the prompt reads 0/ used for both budgets on iteration 1; that is correct and expected, not an error. Iteration 2+ prepends th…
Iteration 1 uses the prompt shape below (no Reviewer Memory yet — file is created at the end of iteration 1 by Phase B.5). The budget line at the top of the prompt reads 0/ used for both budgets on iteration 1; that is…The reviewer prompt must include the five state buckets explicitly per the contract in "Build five disjoint claim buckets" above. The reviewer is told which routing options are available per bucket and which are forbidd…Iteration 1 — save threadid. When the MCP call returns, capture the response's threadid (or equivalent conversation handle the MCP server uses) and persist it to REVIEWSTATE.json's threadid field. This is what iteration… - 05
Phase B: Parse Assessment
CRITICAL: Save the FULL raw response verbatim. Then extract: - Score (numeric 1-10) - Verdict — canonicalize the reviewer's free-form verdict to one of {ready, almost, not ready}. Map synonyms: accept / sufficient / good enough / looks ready → ready; nearly ready / close / minor…
Score (numeric 1-10)Verdict — canonicalize the reviewer's free-form verdict to one of {ready, almost, not ready}. Map synonyms: accept / sufficient / good enough / looks ready → ready; nearly ready / close / minor revision → almost; everyt…Per-claim action items — for each claim id in verifyfailed / verifyinconclusive / verifyzeroeligiblevariants, the reviewer's chosen routing type (①/②/③) and the minimum fix. Reject the reviewer's choice and substitute n…
Permission review
Static risk signals and limitations
Network access
The documentation includes network, browsing, or remote request actions.
curl -s "${LLM_BASE_URL}/chat/completions" \Writes files
The documentation asks the agent to create, modify, or delete local files.
*Write this file at the end of every Phase E** (after documenting the iteration).Network access
The documentation includes network, browsing, or remote request actions.
curl -s "${LLM_BASE_URL}/chat/completions" \Reads files
The documentation asks the agent to read local files, directories, or repositories.
**Iteration 2+**: open the existing file and append; do not touch prior iteration sections.Writes files
The documentation asks the agent to create, modify, or delete local files.
For each variant whose fix is targeted, edit the variant's `eval.py` / mechanism harness in `verify/<claim_dir>/variants/<variant-tag>/` (or delete the variant directory if the fix is "this variant is unsalvageable, re-pick"). Record a BefoRuns scripts
The documentation asks the agent to run terminal commands or scripts.
*GPU pinning.** If `GPU_ID` is anything other than `auto`, pass `CUDA_VISIBLE_DEVICES=<GPU_ID>` as the first positional arg to every `/run-experiment` invocation dispatched above (the run-experiment skill exports it in the experiment subproEvidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 95/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 48 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- zjunlp/Mechanist
- Skill path
- skills/auto-iteration-loop/SKILL.md
- Commit
- 407b0ca20c50dafd666e889868617c5095f4b5a8
- License
- MIT
- Collected
- 2026-08-25
- Default branch
- main
View the original SKILL.md
Auto Iteration Loop: Adversarial Review with Bounded Back-Edges
Autonomously iterate over /auto-verify's per-claim verdicts: review → implement fixes (variant-integrity, main-experiment-script, or claim-stage rewrite) → re-review, until the external reviewer gives a positive assessment with all FAIL / INCONCLUSIVE / ZERO_ELIGIBLE_VARIANTS claims resolved, or the iteration budget is exhausted.
Context: $ARGUMENTS
Constants
-
MAX_ITERATIONS = 6 — Hard upper bound on total back-edge actions across the whole loop. Each of the following consumes 1 iteration, regardless of which Phase A→E cycle they fall in:
- ① variant-only fix → re-run
/auto-verify <claim-id> — resume: true - ② main-experiment-script /
EXPERIMENT_PLAN.mdfix → re-run/auto-experiment(optionally followed by/auto-verifychain) - ③ claim-stage re-entry → rewrite claim (full
/auto-claiminvocation OR lightweight in-loop rewrite) → re-run downstream stages
Pure reviewer cycles that change nothing on disk (no new experiments, no claim changes) do not consume iterations. PASS-claim consistency checks and deferred-claim recording do not consume iterations. New claims produced by ③ inherit the same budget — they do not get a fresh
MAX_ITERATIONSof their own. Override viaMAX_ITERATIONS:arg fromagents/iteration.md.Resource-Fidelity invariant (all back-edges). If
refine-logs/FINAL_PROPOSAL.md/refine-logs/EXPERIMENT_PLAN.mdcarry aresource_fidelity: strictmarker (the reproduction combination —behavior-source:given+mechanism:given), every back-edge MUST preserve it: when editingEXPERIMENT_PLAN.md(type ②) or any claim rewrite (type ③), keep the top-of-fileresource_fidelity:line verbatim — never drop, comment out, or change it. Dropping the marker silently disables the harness, re-opening the door to smaller-model swaps and data subsetting the harness exists to prevent. For type-③ full re-entry, detect the original run's axes fromidea-stage/IDEA_REPORT.md's**Behavior-source**:/**Mechanism**:headers (or directly from theresource_fidelity: strictmarker) and pass bothbehavior_sourceandmechanisminto the queuedauto-claimcall so a reproduction-combo re-entry staysgiven+given(the new run re-stamps theresource_fidelity: strictmarker automatically — it is marker-driven, not a flag). - ① variant-only fix → re-run
-
MAX_CLAIM_REENTRIES = 2 — Sub-budget within
MAX_ITERATIONSfor action type ③ (claim-stage re-entry). Prevents the failure mode where the reviewer keeps asking "rewrite the claim" without anyone actually fixing the experiments behind it. Whenclaim_reentries_consumed >= MAX_CLAIM_REENTRIES, the loop refuses further ③ actions even if iterations remain — at that point the only legal back-edges are ① and ②, and if those are also exhausted the loop terminates and writes the final report. -
TARGET_SCORE = 6 — Stop when reviewer score >= this AND verdict matches a
POSITIVE_VERDICT_TERMSentry AND no claim is still in FAIL / INCONCLUSIVE / ZERO_ELIGIBLE_VARIANTS (three-dimensional STOP rule — see Phase B). -
POSITIVE_VERDICT_TERMS = [ready, almost] — Case-insensitive substrings that count the verdict as positive. Phase B canonicalizes the reviewer's free-form verdict to one of
{ready, almost, not ready}before this check, so any reviewer-supplied synonym (e.g.,accept,sufficient,good enough) must be mapped toready/almostby Phase B's parser — see Phase B's STOP rule for the canonical check. -
REVIEW_DOC =
review-stage/AUTO_REVIEW.md— Per-iteration append-only audit log (fall back to./AUTO_REVIEW.mdfor legacy projects). This is the raw audit trail; the narrative report isFINAL_REPORT_DOCbelow. -
REVIEWER_MEMORY_DOC =
review-stage/REVIEWER_MEMORY.md— Reviewer's persistent suspicion log across iterations. Append-only: each iteration's Phase B.5 adds a section under## Iteration N, never deletes prior iterations (audit trail). Phase A of iteration 2+ prepends the full file to the reviewer prompt so the reviewer can check whether prior-iteration suspicions were genuinely addressed or sidestepped. Counters the failure mode where Claude curates a comfortable subset of context for the reviewer each iteration. -
FINAL_REPORT_DOC =
review-stage/AUTO_ITERATION_FINAL_REPORT.md— Narrative final report written once in Termination (after the loop ends for any reason). Organized per-claim by their original/auto-verifycategory (PASS / FAIL / INCONCLUSIVE / ZERO_ELIGIBLE_VARIANTS / DEFERRED), with the per-claim iteration journey, experiment/script diffs, and any claim rewrites laid out inside each claim's section. Distinct fromREVIEW_DOC(which is the chronological audit log). See "Final Report" section below for the full template. -
GPU_ID =
auto— GPU device(s) to pin every Phase-C/run-experimentdispatch to.autolets the launcher / environment decide (no extra export). A single id (0) or comma-list (4,5,6,7) causes this skill to passCUDA_VISIBLE_DEVICES=<GPU_ID>as the first positional arg to every/run-experimentinvocation (the run-experiment skill exports it internally; do not treat as a shell prefix), and record the effectiveCUDA_VISIBLE_DEVICESin each run'srun.sh. Forwarded fromagents/iteration.md'sgpu_id:arg (which the orchestrator forwards from/auto'sGPU_ID). -
RESUME = false — When
true, readreview-stage/REVIEW_STATE.jsonand pick up fromiterations_consumed + 1instead of starting fresh. Append new iterations to the existingAUTO_REVIEW.mdrather than overwriting it. Iteration budget and claim-reentry sub-budget are inherited across resume — they are never reset. IfREVIEW_STATE.jsonalready showsstatus: completed(positive verdict, iterations exhausted, or claim-reentry budget exhausted), return immediately without running another iteration. Ifstatus: awaiting_upstream, the orchestrator (seeauto/SKILL.md) is expected to run the pending upstream calls first, then resume this loop. Defaultfalse= always start fresh and overwrite prior review state. Resume never deletes pre-existing review state. Schema fields read here:iterations_consumed,claim_reentries_consumed,status,last_verdict,last_score— see "State Persistence" below.
Reviewer LLM Configuration (mandatory, read first)
This skill calls an external LLM reviewer. Never hardcode a model name and never read the reviewer model from task.md / project READMEs / source comments. Project-level files may list available API keys for unrelated purposes (e.g., LLM-as-judge inside experiment code); those are not the reviewer config.
Resolve LLM_MODEL, LLM_BASE_URL, LLM_API_KEY strictly in this priority order before any reviewer call:
- Project MCP config —
${PROJECT_ROOT}/.mcp.json, fieldmcpServers["llm-chat"].env.{LLM_MODEL,LLM_BASE_URL,LLM_API_KEY}. - User MCP config —
~/.claude/settings.json, same field. - Shell environment —
$LLM_MODEL,$LLM_BASE_URL,$LLM_API_KEY.
Pre-flight check (run before Phase A of every iteration, mandatory)
LLM_MODEL_SRC=""
if [ -f .mcp.json ] && jq -e '.mcpServers["llm-chat"].env.LLM_MODEL' .mcp.json >/dev/null 2>&1 ; then
export LLM_MODEL=$(jq -r '.mcpServers["llm-chat"].env.LLM_MODEL' .mcp.json)
export LLM_BASE_URL=$(jq -r '.mcpServers["llm-chat"].env.LLM_BASE_URL' .mcp.json)
export LLM_API_KEY=$(jq -r '.mcpServers["llm-chat"].env.LLM_API_KEY' .mcp.json)
LLM_MODEL_SRC="project .mcp.json"
elif [ -f ~/.claude/settings.json ] && jq -e '.mcpServers["llm-chat"].env.LLM_MODEL' ~/.claude/settings.json >/dev/null 2>&1 ; then
export LLM_MODEL=$(jq -r '.mcpServers["llm-chat"].env.LLM_MODEL' ~/.claude/settings.json)
export LLM_BASE_URL=$(jq -r '.mcpServers["llm-chat"].env.LLM_BASE_URL' ~/.claude/settings.json)
export LLM_API_KEY=$(jq -r '.mcpServers["llm-chat"].env.LLM_API_KEY' ~/.claude/settings.json)
LLM_MODEL_SRC="user ~/.claude/settings.json"
elif [ -n "$LLM_MODEL" ] && [ -n "$LLM_BASE_URL" ] && [ -n "$LLM_API_KEY" ] ; then
LLM_MODEL_SRC="shell env"
fi
echo "[reviewer-config] LLM_MODEL=$LLM_MODEL LLM_BASE_URL=$LLM_BASE_URL source=$LLM_MODEL_SRC"
Hard-fail rule: If LLM_MODEL is empty after this resolution (none of the three sources provides it), the skill MUST abort with:
"Reviewer model not configured. Add
mcpServers.llm-chat.env.{LLM_MODEL,LLM_BASE_URL,LLM_API_KEY}to.mcp.json(project) or~/.claude/settings.json(user)."
Do not guess a default. Do not fall back to a model name read from task.md or any other project file.
The earlier
## LLM Configurationexample block in older versions of this skill (which duplicated the samellm-chatMCP setup) has been removed — the authoritative config resolution is the priority order above. For a worked.mcp.jsonexample, seemcp-servers/llm-chat/in the project repo.
API Call Method
Primary: MCP Tool
mcp__llm-chat__chat:
prompt: |
[Review prompt content]
model: "${LLM_MODEL}" # resolved per "Reviewer LLM Configuration" priority order above — never hardcode
system: "You are a senior ML reviewer..."
Fallback: curl
curl -s "${LLM_BASE_URL}/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${LLM_API_KEY}" \
-d '{
"model": "${LLM_MODEL}",
"messages": [
{"role": "system", "content": "You are a senior ML reviewer..."},
{"role": "user", "content": "[review prompt]"}
],
"max_tokens": 4096
}'
State Persistence (Compact Recovery)
Persist state to review-stage/REVIEW_STATE.json after each iteration (i.e., every Phase E):
{
"iterations_consumed": 2,
"claim_reentries_consumed": 1,
"status": "in_progress",
"last_score": 5.0,
"last_verdict": "not ready",
"consecutive_noop_count": 0,
"iteration_breakdown": [
{"i": 1, "type": "variant_fix", "target_claims": ["C1"], "produced_claims": []},
{"i": 2, "type": "claim_reentry", "target_claims": ["C2"], "produced_claims": ["C2_v2"]}
],
"claim_stage_reentries": ["C2"],
"pending_upstream_calls": [],
"runs_total": 5,
"gpu_hours_total": 12.4,
"thread_id": "th_01ABC123def456",
"timestamp": "2026-03-15T10:00:00"
}
iterations_consumedis the cumulative count of back-edge actions (types ①/②/③) since iteration 1 — what's compared againstMAX_ITERATIONS.claim_reentries_consumedis the cumulative count of type ③ actions only — what's compared againstMAX_CLAIM_REENTRIES.iteration_breakdownrecords each iteration's action type, the claim(s) it targeted, and any new claim ids produced by claim-stage re-entry (so the final report can attribute new claims to the right ancestor).claim_stage_reentriesis the flat list of claim ids that triggered ③ — surfaced toagents/iteration.mdso the orchestrator can record which original claims got rewritten in the Ledger'sjourney_summary.iterationline andopen_items[].pending_upstream_callsis non-empty only whenstatus = awaiting_upstream: a list of{skill, args}calls the orchestrator must execute before resuming this loop.runs_total/gpu_hours_totalare cumulative across all iterations; they monotonically increase and are the canonical budget sourceagents/iteration.mdreports back to the orchestrator.
Field consumer map (so future maintainers know which fields are external API vs internal state):
| Field | Written by | Read by | Notes |
|---|---|---|---|
iterations_consumed | this skill | auto/SKILL.md (inherits on resume), agents/iteration.md | external; compared against MAX_ITERATIONS |
claim_reentries_consumed | this skill | auto/SKILL.md (inherits on resume), agents/iteration.md | external; compared against MAX_CLAIM_REENTRIES |
status | this skill | auto/SKILL.md resume check, agents/iteration.md | external; values in_progress / awaiting_upstream / completed |
last_verdict | this skill | auto/SKILL.md resume check | external; matched against POSITIVE_VERDICT_TERMS |
last_score | this skill | auto/SKILL.md resume check | external; numeric 1–10 |
iteration_breakdown | this skill | this skill (Termination, final-report assembly); agents/iteration.md summary | external; ordered list, append-only |
claim_stage_reentries | this skill | auto/SKILL.md (for CLAIMS_LEDGER.md journey_summary + open_items[]), Termination | external |
pending_upstream_calls | this skill | auto/SKILL.md orchestrator only | external; consumed (cleared) by orchestrator before resuming this skill |
runs_total | this skill | agents/iteration.md summary, auto/SKILL.md budget tracking | external |
gpu_hours_total | this skill | agents/iteration.md summary, auto/SKILL.md budget tracking | external |
timestamp | this skill | this skill's resume gate (24h staleness check — see Workflow Initialization) | internal — drives the stale-state cutoff; archive instead of delete on age-out |
thread_id | this skill (Phase A iteration 1) | this skill (Phase A iteration 2+) | internal — opaque conversation handle returned by mcp__llm-chat__chat after iteration 1's call. Phase A iteration 2+ passes it back to the MCP server so the reviewer keeps the same conversation thread (cheaper context + better cross-iteration coherence than re-pasting summaries). Absent / null when the iteration-1 reviewer call used the curl fallback (curl doesn't return a thread handle), or when the MCP server rejected thread continuation — in either case Phase A iteration 2+ silently falls back to the paste-summary path. |
Write this file at the end of every Phase E (after documenting the iteration).
On completion, set "status": "completed" and continue to Termination (which generates FINAL_REPORT_DOC).
On back-edge handoff to orchestrator (Phase C decided a fix requires upstream skills the iteration loop cannot run inline — e.g., full /auto-claim re-invocation), set "status": "awaiting_upstream", populate pending_upstream_calls, and return. The orchestrator runs them, then resumes this skill with RESUME=true.
Workflow
Upstream artifacts pre-flight (mandatory, run first)
This skill iterates over existing artifacts produced by upstream stages — it does not generate them from scratch. $ARGUMENTS (the optional research-direction string) is treated as reviewer context only, never as a starting point.
Before doing anything else, verify the project root contains at least one of:
idea-stage/IDEA_REPORT.mdrefine-logs/FINAL_PROPOSAL.mdrefine-logs/EXPERIMENT_RESULTS.mdverify/VERIFY_REPORT.md
If none of these exist, abort with:
[pre-flight] no upstream artifacts found at idea-stage/ refine-logs/ verify/.
/auto-iteration-loop reviews existing work — it does not start from a topic.
Run /auto (or at minimum /auto-claim then /auto-experiment) first.
Aborting.
Do not invoke the reviewer, do not write review-stage/AUTO_REVIEW.md. Abort cleanly.
Build five disjoint claim buckets from verify/VERIFY_REPORT.md
If verify/VERIFY_REPORT.md is present, read it once at the top of every iteration alongside verify/INTEGRITY_AUDIT.md and build five disjoint claim buckets that drive Phase A's reviewer prompt. The five states mirror /auto-verify's terminal states exactly (see auto-verify/SKILL.md Phase 11 column glossary):
verify_passed— claim ids whose state isPASS. Main-experiment verdict is robust under swaps. Routing: brief consistency check only (see below). No experiments fired.verify_failed— claim ids whose state isFAIL(robustness < ROBUSTNESS_THRESHOLDover enough eligible variants; the main experiment was fragile). Routing: two-phase (variant-integrity fix → optional claim-stage re-entry).verify_inconclusive— claim ids whose state isINCONCLUSIVE(Phase 2 main-experiment-integrity FAIL; variants never ran, or were policy-skipped under audit-only mode — semantics identical). Routing: fix the main experiment only (EXPERIMENT_PLAN.mdstep or main-experiment script).verify_zero_eligible_variants— claim ids whose state isZERO_ELIGIBLE_VARIANTS(Phase 2 the main experiment was clean, but every Phase 9 variant FAILed integrity). Routing: fix variant scripts only (do not touch the main experiment).verify_integrity_only— claim ids whose state isINTEGRITY_ONLY(Phase 2 pass/warn, Stage 2 intentionally skipped). Two producers, distinguished per-claim bystage2_skip_reasoninROBUSTNESS.md:swap_variants_false(global audit-only mode) ormax_verify_claims_cap(this claim was admitted by Stage 1 but not the top-K picked at Phase 3 step 0). Routing: no back-edge action — record in Open Items with per-stage2_skip_reasonupgrade suggestion. See per-bucket contract below.
Plus the orthogonal (legacy):
deferred_claims— Legacy bucket, always empty under the current architecture. Verify no longer cuts claims before audit; claims that would have been cut byMAX_VERIFY_CLAIMSin the old design now land inverify_integrity_onlywithstage2_skip_reason: max_verify_claims_cap. Retained as an empty placeholder for backward compatibility with olderVERIFY_REPORT.mdfiles. New runs never populate it.
The five state buckets are disjoint by construction (a claim has exactly one /auto-verify state); the legacy deferred_claims bucket is empty in new runs, so no overlap concerns arise. Under SWAP_VARIANTS=false, only two buckets can be non-empty: verify_inconclusive and verify_integrity_only (with stage2_skip_reason: swap_variants_false) — verify_passed / verify_failed / verify_zero_eligible_variants all require Phase 9 to have run and are always empty.
Per-bucket routing contract
verify_passed — brief consistency check. For each claim id in verify_passed, the reviewer does narrative + numeric consistency only:
- Does the claim wording match the supporting numbers in
refine-logs/EXPERIMENT_RESULTS.mdandverify/<claim_dir>/ROBUSTNESS.md? - Are there caveats (main-experiment-WARN tag) that need to surface in the final paper but not in the iteration loop's actions?
Record one line per claim under the iteration's ### Verify-Passed Claims (brief audit) section in AUTO_REVIEW.md. Does NOT consume an iteration — the reviewer's consistency check is part of the same Phase A reviewer call.
verify_failed — two-phase routing. For each claim id in verify_failed:
-
Phase 1 — Variant integrity check. Read this claim's
verify/<claim_dir>/variant_audit/{EXPERIMENT,MECHANISM}_AUDIT.mdand each surviving variant'sverdict.json.integrity_breakdown. If any surviving variant had a WARN/FAIL that could have biased the consistency check, that's the lead — fix that variant's script (deletion + targeted re-run is fine; full sweep is not required) and re-invoke/auto-verify <claim-id> — resume: true. Consumes 1 iteration (type ①). -
Phase 2 — Claim-stage re-entry. If Phase 1 was clean (or Phase 1 was already executed in a prior iteration and the claim still came back FAIL with clean variants), the divergence is real and the claim itself needs work. Choose one of:
- Lightweight in-loop rewrite (preferred when the reviewer has a concrete narrower claim in mind): write the new claim text directly into a
claim_rewrite:block inAUTO_REVIEW.md, then chain/auto-experiment+/auto-verifytargeted to the rewritten claim only. No/auto-claiminvocation. - Full claim-stage re-entry: set
status = awaiting_upstreamand queuepending_upstream_calls = [{skill: "auto-claim", args: {focus: "<claim-id> — verify-failed context: ...", behavior_source: "<inherit original>", mechanism: "<inherit original>"}}, {skill: "auto-experiment", args: {target_claims: ["<new-id>"]}}, {skill: "auto-verify", args: {target_claims: ["<new-id>"]}}]. Carry the original run'sbehavior_source+mechanisminto theauto-claimargs so a reproduction-combo (given+given) re-entry re-stampsresource_fidelity: strictautomatically (marker-driven — per the invariant above). The orchestrator runs them and resumes this loop with the new claim's/auto-verifyresult.
Either form consumes 1 iteration (type ③) AND 1 claim-reentry sub-budget. The new claim id (when produced) is recorded in
iteration_breakdown[i].produced_claimsso the final report attributes it to the original claim's section, not a fresh top-level entry.Crucially: when
claim_reentries_consumed >= MAX_CLAIM_REENTRIES, Phase 2 is not allowed even if the reviewer requests it — record the request, decline it in the iteration's writeup, and either return to Phase 1 (if there are still dirty variants left to fix) or terminate with the claim still in FAIL state (it gets surfaced in the final report'sOpen Itemssection).The reviewer may NOT choose "narrow scope" or "pivot" as standalone local actions — those are subsumed by Phase 2's claim rewrite.
- Lightweight in-loop rewrite (preferred when the reviewer has a concrete narrower claim in mind): write the new claim text directly into a
verify_inconclusive — main-experiment-only fix. For each claim id in verify_inconclusive:
- Read this claim's
verify/<claim_dir>/main_experiment_audit/{EXPERIMENT,MECHANISM}_AUDIT.mdto identify which sub-audit FAILed (theROBUSTNESS.mdstub'sinconclusive_reasonfield summarizes this). - Fix the failing main-experiment surface: edit the relevant step in
refine-logs/EXPERIMENT_PLAN.md(preserving the top-of-fileresource_fidelity:marker verbatim — see the Resource-Fidelity invariant above), modify the main-experiment script (experiments/<name>/), then re-invoke/auto-experiment(withtarget_claims: [<id>]so only this claim's runs re-execute, if supported by the upstream skill) followed by/auto-verify. Consumes 1 iteration (type ②). - The reviewer is not allowed to "narrow scope", "pivot", or rewrite the claim for an INCONCLUSIVE — the main-experiment methodology is what's broken, not the claim's framing. To rewrite the claim, the claim must first become FAIL (i.e., the main experiment must be fixed so a robustness verdict is computable).
- Per-claim ② cap (mirror of
MAX_CLAIM_REENTRIESfor ③). A stubborn INCONCLUSIVE main experiment must not monopolise the sharedMAX_ITERATIONSbudget and starve other claims. Count this claim's prior type-② actions initeration_breakdown(no separate counter needed). If it has already had 2 ② attempts and is still INCONCLUSIVE, do not attempt a 3rd: record the reviewer's request, decline it in the iteration writeup, and leave the claim INCONCLUSIVE in the final report'sOpen Items(requires manual main-experiment repair). This frees the remaining budget for other claims; if no other claim has an actionable fix, terminate. (The cap is on iteration-loop ② attempts — at most 2 — not on the original original /auto-experiment run.)
verify_zero_eligible_variants — variant-only fix. For each claim id in verify_zero_eligible_variants:
- Read this claim's
verify/<claim_dir>/variant_audit/{EXPERIMENT,MECHANISM}_AUDIT.mdand thezero_eligible_reasonfield inROBUSTNESS.md. - Fix each failing variant's script (variant
eval.py, mechanism harness, etc.), delete the failed variant directories underverify/<claim_dir>/variants/, then re-invoke/auto-verify <claim-id> — resume: truestandalone (Phase 1's argument parser and Phase 2's main-experiment audit will skip on resume; only variant phases re-execute). Consumes 1 iteration (type ①, same as FAIL Phase 1). - Do NOT invoke
/auto-experiment— the the main experiment already passed Phase 2; rerunning it wastes compute and risks main-experiment drift.
verify_integrity_only — no-action-with-upgrade-suggestion contract. For each claim id in verify_integrity_only the reviewer must NOT propose any back-edge action — main-experiment integrity was validated at Phase 2 (main_experiment_integrity ∈ {pass, warn} in ROBUSTNESS.md) and the swap stress test was intentionally skipped. Read the per-claim stage2_skip_reason field to pick the right upgrade string:
stage2_skip_reason: swap_variants_false(global audit-only mode) → upgrade suggestion:to stress-test under method/dataset/model swaps: /auto-verify <id> — swap-variants: true, resume: true (Phase 2 audits reused via RESUME; only Stages 2–3 run)stage2_skip_reason: max_verify_claims_cap(Stage 1 admitted but not top-K picked) → upgrade suggestion:to stress-test this admitted claim: /auto-verify <id> — resume: true (single-claim mode; Phase 2 audit reused via RESUME; only Stages 2–3 run for this claim)
Three requirements: (a) record each claim under ### Open Items — Unverified Under Swaps in AUTO_REVIEW.md with its stage2_skip_reason and the matching upgrade suggestion; (b) when main_experiment_integrity: warn, surface warn_source on the same line so the paper text can carry the caveat; (c) exclude from score-weighting reasoning — neither a positive nor a negative signal, just unfinished. The iteration agent's final return message surfaces this list to the orchestrator so it lands in CLAIMS_LEDGER.md's open_items[]. Does NOT consume an iteration.
deferred_claims — legacy no-op. New verify runs never populate this bucket (cap-cut claims land in verify_integrity_only with stage2_skip_reason: max_verify_claims_cap). On a legacy VERIFY_REPORT.md that still carries a ## Deferred Claims section, treat each id under the same no-action contract as verify_integrity_only (record under ### Open Items — Unverified Under Swaps with requires standalone /auto-verify <id> before this claim can enter the iteration loop; exclude from score-weighting). Does NOT consume an iteration.
Phase A reviewer prompt — explicit bucket list
When constructing Phase A's reviewer prompt, include all five state buckets explicitly so the reviewer can address them separately. Empty buckets are stated as none, not omitted (the reviewer needs to know "no claims FAILed" is different from "I forgot to tell you"):
verify_passed: [<comma-separated claim ids, or "none">] # brief consistency check only, no experiment action
verify_failed: [<comma-separated claim ids, or "none">] # two-phase routing — see contract
verify_inconclusive: [<comma-separated claim ids, or "none">] # main-experiment-only fix
verify_zero_eligible_variants: [<comma-separated claim ids, or "none">] # variant-only fix
verify_integrity_only: [<comma-separated claim ids, or "none">] # NO back-edge; record in Open Items with stage2_skip_reason-dispatched upgrade suggestion
deferred_claims is a legacy empty bucket in new runs and is not part of the reviewer prompt.
Flexibility note on upstream back-edges
When this loop triggers a back-edge (variant re-run, main-experiment re-run, or claim-stage re-entry), the iteration agent may choose to run a lightweight subset rather than the full upstream skill:
- For
/auto-experiment: only the runs corresponding to the target claim need re-execute. Iftarget_claimsis honored by the upstream skill, pass it; if not, the lightweight path is to manually re-run the specific experiment scripts and update the correspondingruns/iteration_round_<N>/<run-id>/directory. - For
/auto-verify: pass— resume: trueso completed phases skip. (Iteration-loop invocations are always single-claim —/auto-verify <claim-id>— so the claim scoping is already implicit.) - For
/auto-claim: lightweight path is to write the rewritten claim text directly intoAUTO_REVIEW.mdand bypass the/auto-claimcall entirely.
Write results back, every time. A lightweight path skips the owning skill, so the skill's own supersede-in-place never fires — the iteration agent inherits it. Whenever a re-run changes a claim's numbers or verdict, update that stage's documents in place before calling anything downstream: refine-logs/ for a main-experiment re-run, verify/ for a verify re-run, review-stage/ for this loop's own record. Keep a failed pre-registered test on the record as a failure; never relabel it.
Each lightweight or full variant of these actions consumes the same iteration count (and the same claim-reentry sub-budget when applicable). The agent is given the choice for compute efficiency, not for budget gaming.
Initialization
- Run the Pre-flight check in the "Reviewer LLM Configuration" section above. Abort with the hard-fail message if
LLM_MODELcannot be resolved. Log the resolved values and source. - Check
review-stage/REVIEW_STATE.jsonfor recovery (fall back to./REVIEW_STATE.jsonif not found — legacy path) - Resume gate (only when
RESUME = true). Read fields from the schema documented under "State Persistence" above (iterations_consumed,claim_reentries_consumed,status,last_verdict,last_score,timestamp):- If
REVIEW_STATE.jsonis missing or empty → start fresh (iterations_consumed = 0,claim_reentries_consumed = 0), log[resume] no prior state — starting fresh. - Staleness check (first, before any other branch — but exempt
awaiting_upstream): parsetimestampas ISO 8601. Skip this check entirely whenstatus == "awaiting_upstream"— that is a deliberate, live handoff waiting on orchestrator-run upstream calls (a type-③ claim re-entry's/auto-claim → /auto-experiment → /auto-verify, which routinely exceeds 24h on GPU experiments). Ageing it out would discard the just-produced upstream results and reset the inherited budget counters, orphaning live work; the long elapsed time is expected and the upstream calls produced fresh results, so the drift rationale does not apply. For any other status, ifnow - timestamp > 24h(86400 seconds), the prior state is too old to safely resume — log[resume] state older than 24h (timestamp=<ts>, age=<H>h) — treating as stale, ignoring REVIEW_STATE.json and starting fresh, archive the stale file asREVIEW_STATE.<ts>.stale.json(so the audit trail survives — don't delete it), and proceed as ifRESUME=false. Rationale: beyond a day the codebase, results files, and reviewer model versions have likely drifted enough that "picking up from iteration N" would conflate stale context with fresh work — a concern that applies to an interruptedin_progressrun, not to a deliberateawaiting_upstreamhandoff. If thetimestampfield is absent (legacy state files), skip the staleness check and continue to the branches below — the caller accepts the risk. - If
status == "completed"ANDlast_verdictmatches aPOSITIVE_VERDICT_TERMSentry ANDlast_score >= TARGET_SCORE→ log[resume] prior run already satisfied target (score=<last_score>, verdict=<last_verdict>) — returning without invoking reviewerand return immediately with the existing state. (Termination should already have producedFINAL_REPORT_DOCin this case; if missing, re-run Termination's report-assembly step before returning.) - Else if
status == "completed"ANDiterations_consumed >= MAX_ITERATIONS→ log[resume] prior run exhausted MAX_ITERATIONS (iterations_consumed=<n>) — returning without invoking reviewerand return. - Else if
status == "completed"ANDclaim_reentries_consumed >= MAX_CLAIM_REENTRIESAND the only remaining unresolved claims would require action type ③ → log[resume] prior run exhausted MAX_CLAIM_REENTRIES — returning without invoking reviewerand return. - Else if
status == "awaiting_upstream"→ the orchestrator should have runpending_upstream_callsbefore resuming. Verify they completed (all expected output artifacts present on disk per the upstream skills' own contracts). If they did, clearpending_upstream_calls, flipstatusto"in_progress", and continue into Phase A of the next iteration withiterations_consumedandclaim_reentries_consumedalready incremented (Phase C of the prior iteration incremented them when it queued the upstream calls). If they did not, abort with[resume] awaiting_upstream but pending_upstream_calls outputs missing — orchestrator did not complete upstream work; aborting. Do not silently retry — the orchestrator failure must be visible. - Else if
status == "in_progress"ANDiterations_consumed >= MAX_ITERATIONS→ no iterations left; flipstatusto"completed", log[resume] in-progress at MAX_ITERATIONS — closing out without new iteration, run Termination, and return. - Otherwise (
status == "in_progress"ANDiterations_consumed < MAX_ITERATIONS) → the next iteration's display number isiterations_consumed + 1(this is a working value for logs / Phase E heading only — it is never persisted; the only persistent counter isiterations_consumed, which Phase C increments at its end after a real ①/②/③ action). OpenAUTO_REVIEW.mdin append mode and continue. Log[resume] picking up from iteration <iterations_consumed+1>/<MAX_ITERATIONS> (claim-reentry sub-budget: <claim_reentries_consumed>/<MAX_CLAIM_REENTRIES>).
- If
- Read project context and prior reviews
- Initialize iteration counter (skip if step 2 already set it)
Loop (up to MAX_ITERATIONS)
Each cycle below is one Phase A→E iteration. The iteration counter (iterations_consumed) is incremented at the end of Phase C, only if Phase C actually queued or executed a back-edge action of type ① / ② / ③. A pure-review iteration whose only action is type ⓪ (narrative-only) or has no action at all does not consume budget. Stall guard against ⓪-only spin. Because ⓪ is free (it does not consume budget and runs no experiment), a reviewer that keeps proposing narrative-only fixes for a still-unresolved weakness would loop forever — burning a reviewer call each round while neither the STOP rule (score below target) nor the budget exit (iterations_consumed frozen) ever fires. The consecutive_noop_count field in REVIEW_STATE.json closes this: at Phase E, increment it when this iteration was ⓪-only (or had no action) and last_score + last_verdict are unchanged from the prior persisted state; reset it to 0 whenever a real ①/②/③ action ran or the score/verdict changed. When it reaches 2 (two consecutive non-converging no-op iterations), the loop is stalled on the reviewer side — terminate it (see Phase B's STOP conditions). The common legitimate case for a ⓪-only iteration is the final one that confirms a positive verdict after a real ①/②/③ in the prior iteration — that single ⓪ is fine; only an unchanged-score repeat trips the guard.
Phase A: Review
Iteration 1 uses the prompt shape below (no Reviewer Memory yet — file is created at the end of iteration 1 by Phase B.5). The budget line at the top of the prompt reads 0/<MAX> used for both budgets on iteration 1; that is correct and expected, not an error.
Iteration 2+ prepends the contents of REVIEWER_MEMORY_DOC plus a "Previous Review Summary" block before the body — see "Prompt Template for Iteration 2+" near the end of this file for the full shape. The memory block is mandatory from iteration 2 onward and is what gives this loop adversarial continuity across iterations.
The reviewer prompt must include the five state buckets explicitly per the contract in "Build five disjoint claim buckets" above. The reviewer is told which routing options are available per bucket and which are forbidden (e.g., no claim rewrite for INCONCLUSIVE; no action for INTEGRITY_ONLY).
If MCP available:
mcp__llm-chat__chat:
system: "You are a senior ML reviewer (NeurIPS/ICML level)."
prompt: |
[Iteration N/MAX_ITERATIONS of autonomous review loop]
[Iteration budget: <iterations_consumed>/<MAX_ITERATIONS> used; claim-reentry sub-budget: <claim_reentries_consumed>/<MAX_CLAIM_REENTRIES> used]
[Full research context: claims, methods, results, known weaknesses]
[Changes since last iteration, if any]
## Per-claim verify state (from /auto-verify)
verify_passed: [<ids or "none">] # brief consistency check only
verify_failed: [<ids or "none">] # two-phase: variant-integrity check, then optional claim rewrite
verify_inconclusive: [<ids or "none">] # main-experiment-only fix; you may NOT rewrite the claim
verify_zero_eligible_variants: [<ids or "none">] # variant-only fix; do NOT touch the main experiment
verify_integrity_only: [<ids or "none">] # NO back-edge action; record in Open Items with stage2_skip_reason-dispatched upgrade suggestion
Tasks:
1. Score this work 1-10 for a top venue.
2. For each FAIL / INCONCLUSIVE / ZERO_ELIGIBLE_VARIANTS claim, name the MINIMUM
fix and tag it with the routing type (①/②/③). If you want to use ③ (claim rewrite)
on a FAIL claim, also provide the proposed new claim text — verify that the
claim-reentry sub-budget has remaining capacity before recommending ③.
Do NOT propose fixes or ①/②/③ actions for INTEGRITY_ONLY claims — those are
swap-test-skipped outputs (audit passed) with no robustness data to fix; iteration
records them as unfinished stress-tests, not as findings that need repair.
3. For each PASS claim, do a brief narrative + numeric consistency check.
Flag any caveat (main-experiment-WARN) that should surface in the final paper.
4. State clearly: is this READY for submission? Yes/No/Almost. READY requires all
FAIL / INCONCLUSIVE / ZERO_ELIGIBLE_VARIANTS claims to be resolved.
INTEGRITY_ONLY claims do NOT block READY (they are outside the stress-test
scope by policy or cap) — but note their presence as a caveat in the assessment.
5. (Iteration 1 only) Record any initial suspicions or concerns you want to
track in future iterations — output as a `## Memory update` section so
Phase B.5 can seed `REVIEWER_MEMORY.md` with them.
Be brutally honest. If the work is ready, say so clearly.
Iteration 1 — save thread_id. When the MCP call returns, capture the response's thread_id (or equivalent conversation handle the MCP server uses) and persist it to REVIEW_STATE.json's thread_id field. This is what iteration 2+ uses to continue the same reviewer thread instead of pasting summaries. If the MCP server does not return a thread handle (some configurations don't), or the call used the curl fallback, write null and let iteration 2+ fall back to the paste-summary path.
Iteration 2+ — pass thread_id back when present. If REVIEW_STATE.json has a non-null thread_id, pass it as the thread_id arg on the mcp__llm-chat__chat call. The iteration-2+ prompt body becomes shorter (no need to re-paste prior reviews — the thread already has them), but the Reviewer Memory prepend block is still mandatory (it carries the structured suspicion account that the thread itself doesn't make queryable). On any error indicating the thread is unknown / expired (server returns 4xx with a thread-related message), clear thread_id to null in state and retry once without it — falling back to the paste-summary template at the end of this file.
If MCP NOT available:
curl -s "${LLM_BASE_URL}/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${LLM_API_KEY}" \
-d '{
"model": "${LLM_MODEL}",
"messages": [
{"role": "system", "content": "You are a senior ML reviewer (NeurIPS/ICML level)."},
{"role": "user", "content": "[Full review prompt with all four buckets explicit]"}
],
"max_tokens": 4096
}'
Phase B: Parse Assessment
CRITICAL: Save the FULL raw response verbatim. Then extract:
- Score (numeric 1-10)
- Verdict — canonicalize the reviewer's free-form verdict to one of
{ready, almost, not ready}. Map synonyms:accept/sufficient/good enough/looks ready→ready;nearly ready/close/minor revision→almost; everything else (incl.revise,weak,reject,needs major work) →not ready. This canonical value is what gets written toREVIEW_STATE.jsonaslast_verdictand is what the agent's output contract promises. - Per-claim action items — for each claim id in
verify_failed/verify_inconclusive/verify_zero_eligible_variants, the reviewer's chosen routing type (①/②/③) and the minimum fix. Reject the reviewer's choice and substitutenone — pending budgetif the request violates the routing contract (e.g., ③ on an INCONCLUSIVE claim, or ③ whenclaim_reentries_consumed >= MAX_CLAIM_REENTRIES). Reviewer proposals forverify_integrity_onlyaction items are always rejected as contract violations (no-action by design); log[verify] rejected reviewer action on verify_integrity_only claim <id> — bucket is no-action-onlyand record no action.
STOP (three-dimensional): Terminate the loop when all of the following hold:
score >= TARGET_SCORE- canonical verdict ∈
POSITIVE_VERDICT_TERMS(i.e.,readyoralmost) verify_failed,verify_inconclusive, andverify_zero_eligible_variantsare all empty (every claim is either PASS or INTEGRITY_ONLY).verify_integrity_onlydoes NOT block STOP — it is a no-action bucket carried forward as Open Items.
The third condition is critical — without it the loop would terminate with the reviewer giving high marks while some claim is still officially FAIL/INCONCLUSIVE/ZERO_ELIGIBLE_VARIANTS, leaving an inconsistent record. If the reviewer scores high but a non-PASS claim remains, log [stop] reviewer says ready (score=<X>, verdict=<V>) but <K> claim(s) still unresolved (<bucket=ids>) — continuing loop and proceed to Phase C.
Two further termination paths (not satisfaction-based — budget-exhaustion):
iterations_consumed >= MAX_ITERATIONSafter this iteration's Phase C increment → terminate, write final report with status "exhausted iterations".claim_reentries_consumed >= MAX_CLAIM_REENTRIESAND the only unresolved claims would require type ③ → terminate, write final report with status "exhausted claim-reentry budget".consecutive_noop_count >= 2→ terminate (the reviewer kept proposing narrative-only fixes with no score/verdict change — non-converging on the reviewer side; see the stall guard in the Loop header). Log[loop] two consecutive no-op iterations — stalled, returning, setstatus = "completed", write final report with status "stalled — two consecutive no-op iterations".
Phase B.5: Reviewer Memory Update
After Phase B, append a new section to REVIEWER_MEMORY_DOC (review-stage/REVIEWER_MEMORY.md). This file is the reviewer's persistent brain across iterations; Phase A of the next iteration prepends it to the prompt.
If the reviewer's raw response included a ## Memory update (or similar) section, copy it verbatim. Otherwise, infer the four sub-sections below from the parsed weaknesses + canonical verdict — be conservative, only record what the reviewer actually flagged (do not invent suspicions).
Append shape (iteration N, where the file already contains iterations 1..N-1):
## Iteration N — Score: <X>/10, Verdict: <canonical>
- **New suspicions**: <bullets — concerns the reviewer raised this iteration for the first time>
- **Previous suspicions addressed?**: <yes/no per item, with the reviewer's judgment if stated; on iteration 1 write `n/a (first iteration)`>
- **Unresolved (carried forward)**: <bullets — prior suspicions still open + any new ones not yet acted on>
- **Patterns**: <recurring issues across iterations, if any — e.g. "metrics keep being computed against model output, not GT">
Rules:
- Append-only. Never rewrite or delete prior iterations — the audit trail must survive even after the loop terminates.
- Iteration 1: the file does not yet exist; create it with a top-level
# Reviewer Memoryheader and the iteration-1 section. - Iteration 2+: open the existing file and append; do not touch prior iteration sections.
- Resume: if
RESUME=trueand the iteration being re-run already has its## Iteration Nsection in the file (e.g., crashed during Phase C of iteration N after Phase B.5 completed), do not append a duplicate — log[reviewer-memory] iteration N section already present — skipping appendand continue. - Honesty constraint: this file is for the reviewer's perspective. Do not edit it on Claude's behalf to soften criticism; if a suspicion is later resolved, that gets recorded in the next iteration's
Previous suspicions addressed?line, not by rewriting history.
If the LLM call in Phase A failed entirely (no raw response to parse), skip Phase B.5 for this iteration — there is nothing to record. Log [reviewer-memory] skipped — no reviewer response this iteration.
Phase C: Implement Fixes (dispatch by action type)
Each unresolved claim's reviewer-chosen routing type from Phase B dispatches to one of the three back-edge action types:
Action type ① — variant-only fix (FAIL Phase 1, or any ZERO_ELIGIBLE_VARIANTS)
For each claim id needing ①:
- Read
verify/<claim_dir>/variant_audit/{EXPERIMENT,MECHANISM}_AUDIT.mdand each failed variant'sverdict.json.integrity_breakdown. - For each variant whose fix is targeted, edit the variant's
eval.py/ mechanism harness inverify/<claim_dir>/variants/<variant-tag>/(or delete the variant directory if the fix is "this variant is unsalvageable, re-pick"). Record a Before/After summary of the change. - Re-invoke
/auto-verify <claim-id> — resume: true. Withresume: true, Phase 1 argument parsing and Phase 2 main-experiment audit skip (main experiment already passed); only variant-side phases re-execute. - Wait for
/auto-verifyto complete; the new per-claimROBUSTNESS.mdbecomes this claim's input for the next iteration.
Action type ② — main-experiment-script / plan fix (INCONCLUSIVE only)
For each claim id needing ②:
- Read
verify/<claim_dir>/main_experiment_audit/{EXPERIMENT,MECHANISM}_AUDIT.mdto find the broken methodology line(s). - Edit the affected step in
refine-logs/EXPERIMENT_PLAN.mdand the corresponding main-experiment script underexperiments/<name>/. Record Before/After diffs for both. - Choose lightweight or full path (same iteration cost either way; pick by compute efficiency):
- Lightweight: manually re-run only the affected
runs/<run-id>/for this claim, then re-invoke/auto-verify <claim-id>. Use this when only one or two main-experiment runs need redoing. - Full: re-invoke
/auto-experiment(withtarget_claims: [<id>]if supported) followed by/auto-verify <claim-id>. Use this when the plan diff cascades across runs.
- Lightweight: manually re-run only the affected
- Wait for completion; the new
ROBUSTNESS.mdis this claim's next-iteration input.
Action type ③ — claim-stage re-entry (FAIL Phase 2 only)
For each claim id needing ③:
- Pre-flight budget check: if
claim_reentries_consumed >= MAX_CLAIM_REENTRIES, refuse — record[claim-reentry] declined — sub-budget exhausted (<n>/<MAX_CLAIM_REENTRIES>)under this iteration's### Actions Taken, and either fall back to ① (if Phase 1 still has unfixed variants for this claim) or leave the claim unresolved for the final report. - Choose lightweight or full path (same iteration cost AND same claim-reentry sub-budget cost):
- Lightweight in-loop rewrite: the reviewer must already have provided proposed new claim text in Phase A. Write the new claim text into
AUTO_REVIEW.mdunder the iteration's### Claim Rewritessection (also assign a new claim id, by convention<original-id>_v2/_v3/ …). Then dispatch/auto-experimentand/auto-verifyscoped to the new id, in-loop. The orchestrator is not involved. - Full claim-stage re-entry: set
status = "awaiting_upstream", populatepending_upstream_callswith[{skill: "auto-claim", args: {focus: "<claim-id> — verify-failed context: <summary>"}}, {skill: "auto-experiment", args: {target_claims: ["<new-id>"]}}, {skill: "auto-verify", args: {target_claims: ["<new-id>"]}}], incrementiterations_consumedandclaim_reentries_consumed, write Phase E (state + AUTO_REVIEW append) including the queued calls, and return. The orchestrator runs the calls, then resumes this skill withRESUME=true.
- Lightweight in-loop rewrite: the reviewer must already have provided proposed new claim text in Phase A. Write the new claim text into
- Record the new claim id under
iteration_breakdown[i].produced_claimsso the final report attributes the new claim to the original claim's journey section.
Counter increment + bookkeeping (after ① / ② / ③ — skipped for ⓪)
After the dispatched action completes (lightweight path) OR after queuing it for the orchestrator (③ full path), increment:
iterations_consumed += 1claim_reentries_consumed += 1(only if the action was type ③)runs_total += <K>whereKis the total number of/run-experimentcalls newly fired this iteration, counted across all three cost-manifest surfaces:- Surface A — variant re-runs (action ①):
verify/<claim_dir>/variants/<v>/cost.json(written by/auto-verify's downstream/run-experimentcalls). Iterate the variants this iteration re-ran and read eachcost.json. - Surface B — main-experiment runs from full
/auto-experiment(action ② full path):runs/<run-id>/cost.json(the standard auto-experiment surface). Read theruns_total_deltafrom auto-experiment's return summary, or enumerate the run-ids it produced. - Surface C — iteration-local ad-hoc or lightweight ② re-runs:
runs/iteration_round_<N>/<run-id>/cost.json(this skill's convention, where<N>is the iteration number — see below).
- Surface A — variant re-runs (action ①):
gpu_hours_total += <H>whereHis the sum ofgpu_hoursfrom everycost.jsonenumerated above. If anycost.jsonis missing or hasstatus: running, block on/monitor-experimentto finalize it before reading — do not guess from deploy logs.- Append a new entry to
iteration_breakdownwith{i, type, target_claims, produced_claims}. For type ⓪, this section is not executed at all:iteration_breakdowndoes not get a new entry, and none of the counters change — the only persistent trace of a ⓪ action is the### Actions Takenline inAUTO_REVIEW.mdfor that iteration.
Output directories
New experiments deployed in iteration N go under:
runs/iteration_round_<N>/
(The legacy directory name remains iteration_round_<N> for compatibility with prior tooling, even though we now count "iterations" rather than "review rounds". <N> is the 1-indexed iteration number the run belongs to — i.e., iterations_consumed + 1 at the moment the run is launched mid-Phase-C, equivalently iterations_consumed after Phase C's end-of-iteration increment runs. Both expressions name the same iteration; pick whichever is clearer at the call site.)
Do not mix new runs into the original runs/<run_id>_<short_purpose>/ directories (those are frozen artifacts from /auto-experiment). Inside iteration_round_<N>/, name files by what they produce (e.g., bootstrap_layer_sweep.json, cross_seed_function.json) rather than synthetic IDs — these are reviewer-driven one-offs, not plan-tracked runs.
Iteration runs are NOT added to refine-logs/EXPERIMENT_TRACKER.md. The tracker is frozen the moment /auto-experiment returns — it represents the plan-driven runs. Iteration runs are tracked here in review-stage/AUTO_REVIEW.md under the iteration's ### Results section and in review-stage/REVIEW_STATE.json (runs_total, gpu_hours_total, iteration_breakdown). When you cite an iteration result in AUTO_REVIEW.md, use the path runs/iteration_round_<N>/<file> directly — do not retro-add a synthetic Run-ID and append to the tracker. This keeps the experiment-stage and iteration-stage audit trails separable.
GPU pinning + cost manifest read
GPU pinning. If GPU_ID is anything other than auto, pass CUDA_VISIBLE_DEVICES=<GPU_ID> as the first positional arg to every /run-experiment invocation dispatched above (the run-experiment skill exports it in the experiment subprocess; do not treat as a shell prefix — /run-experiment is a Skill, not a shell command). Record the effective CUDA_VISIBLE_DEVICES in each run's run.sh so reproductions land on the same devices. This mirrors the GPU_ID handling in /auto-experiment Phase 3.
Each new experiment is typically launched through /run-experiment — one call per logical run. Queue path (rare). If a single iteration's fix requires ≥ 10 runs (e.g., reviewer asks for a 21-seed × 4-size grid), prefer /experiment-queue with a one-phase manifest instead — it brings the same OOM retry / stale-screen / GPU-gate protections as the experiment-stage Phase 4.B. The iteration output directory runs/iteration_round_<N>/ still applies; queue_state.json lives next to it under the local run dir per /experiment-queue convention. After the queue batch completes, invoke /monitor-experiment per job to finalize each runs/iteration_round_<N>/<job-id>/cost.json, then continue with bookkeeping.
After each run completes (confirmed via /monitor-experiment, which finalizes the cost manifest in its Step 3.6), read its gpu_hours from runs/iteration_round_<N>/<run-id>/cost.json — this is the canonical source written by /run-experiment Step 5.5 (initial stub) and finalized by /monitor-experiment Step 3.6. Do not parse free-form deploy logs as a substitute; if cost.json is missing or has status: running (run not yet finalized), wait for /monitor-experiment to complete the finalization rather than guessing. Append one line to AUTO_REVIEW.md under the iteration's ### Results section:
[run-experiment] iteration=N runs_this_iteration=K gpu_hours_this_iteration=X cumulative_gpu_hours=Y
If the iteration's fixes are purely reviewer-narrative (no back-edge action of any type — e.g., the reviewer asked only for a clarifying caveat in the paper), Phase C is a no-op and iterations_consumed is NOT incremented (see the Loop header note).
Phase D: Wait for Results
Monitor remote experiments via /monitor-experiment. For type ③ full claim-stage re-entry, the orchestrator handles waiting — this skill does not block; it sets awaiting_upstream and returns.
Phase E: Document Iteration
Append to review-stage/AUTO_REVIEW.md. The template is per-category-structured (not flat) so the Termination step can assemble FINAL_REPORT_DOC by reading these sections directly — keep each subsection self-contained:
## Iteration N (timestamp)
### Assessment (Summary)
- Score: X/10
- Verdict: [ready/almost/not ready]
- Budget after this iteration: iterations <iterations_consumed>/<MAX_ITERATIONS>, claim-reentries <claim_reentries_consumed>/<MAX_CLAIM_REENTRIES>
- Key criticisms: [bullet list]
### Reviewer Raw Response
<details>
<summary>Click to expand full reviewer response</summary>
[Paste the COMPLETE raw response here — verbatim, unedited.]
</details>
### Verify-Passed Claims (brief audit)
- <claim-id>: <one-line consistency check result, or caveat for the paper>
- [or "none" when the iteration's verify_passed bucket was empty]
### Actions Taken (per claim, per type)
Format each entry as: `<claim-id> — type <⓪|①|②|③> — <one-line summary>`. The four types:
- **⓪ narrative-only** — reviewer asked for a paper-side caveat / reframing only, no script or data changes. Does NOT consume an iteration; the entry still exists for audit (so the final report can attribute the caveat to a claim). Allowed only as the **sole** action of an iteration if the loop is otherwise converged.
- **① variant-only fix** — dispatched into the variant-script surface (`verify/<claim_dir>/variants/<v>/`); consumes 1 iteration.
- **② main-experiment-script / plan fix** — dispatched into `refine-logs/EXPERIMENT_PLAN.md` + `experiments/<name>/`; consumes 1 iteration.
- **③ claim-stage re-entry** — claim rewrite (lightweight or full path); consumes 1 iteration + 1 claim-reentry sub-budget.
Include the Before/After diffs of any experiment_plan / script / variant changes under nested bullets:
- <claim-id> — type ① — fixed variant `model-swap-X` (mechanism integrity FAIL)
- **Variant script Before/After** (`verify/<claim_dir>/variants/model-swap-X/eval.py:L42`):
- Before: `score / scores.max()`
- After: `score / train_stats.max`
- Re-invoked: `/auto-verify <claim-id> — resume: true`
- <claim-id> — type ② — fixed main-experiment plan step 3.2 + main-experiment `eval.py`
- **Plan Before/After** (`refine-logs/EXPERIMENT_PLAN.md:L87`):
- Before: "evaluate on val"
- After: "evaluate on held-out test, normalize with train stats only"
- **Main-experiment script Before/After** (`experiments/<name>/eval.py:L120`): ...
- Re-invoked: `/auto-experiment — target_claims: [<id>]` then `/auto-verify <claim-id>`
- <claim-id> — type ⓪ — added paper-side caveat "within-domain only"; no scripts touched, no runs fired
### Claim Rewrites (type ③ — empty when no rewrite this iteration)
- Original claim id: `<original-id>` — text: "<original claim text>"
- New claim id: `<new-id>` — text: "<new claim text>"
- Path: lightweight in-loop | full claim-stage re-entry (awaiting_upstream)
- Reason: <one paragraph — why narrow / why pivot / why rewrite>
- Claim-reentry sub-budget consumed: 1 (now <claim_reentries_consumed>/<MAX_CLAIM_REENTRIES>)
### Claim-Stage Re-entries Triggered (orchestrator handoff — empty unless type ③ full path used this iteration)
- <claim-id>: queued `pending_upstream_calls = [/auto-claim, /auto-experiment, /auto-verify]`; reason: <variants clean, main experiment still not robust>
- [or "none"]
### Open Items — Unverified Under Swaps (from verify_integrity_only)
- <claim-id> [stage2_skip_reason: swap_variants_false | max_verify_claims_cap]:
* `swap_variants_false` → `/auto-verify <id> — swap-variants: true, resume: true` (Phase 2 audits reused via RESUME; only Stages 2–3 run)
* `max_verify_claims_cap` → `/auto-verify <id> — resume: true` (single-claim mode; Phase 2 audit reused via RESUME; only Stages 2–3 run)
[main-experiment integrity: <pass|warn>[; warn_source: <experiment|mechanism|experiment+mechanism>]]
- [or "none" when the iteration's verify_integrity_only context list was empty]
### Results
- [run-experiment] iteration=N runs_this_iteration=K gpu_hours_this_iteration=X cumulative_gpu_hours=Y
- [per-claim outcome lines — e.g. "C1 → /auto-verify rerun → PASS (robustness=0.67)"]
### Status
- [continuing to iteration N+1 / awaiting_upstream / completed]
Per-category contract. Every iteration's Phase E writeup must include all nine subsections in this exact order: Assessment, Reviewer Raw Response, Verify-Passed Claims, Actions Taken, Claim Rewrites, Claim-Stage Re-entries Triggered, Open Items — Unverified Under Swaps, Results, Status. Empty subsections write
nonerather than being omitted — Termination's final-report assembly reads them by header and silently skipped headers would drop claims from the final report.
Write review-stage/REVIEW_STATE.json with current state (status, all counters, iteration_breakdown, etc.).
Termination
Triggered by any of:
- Positive verdict — Phase B's three-dimensional STOP fired this iteration.
- Iterations exhausted —
iterations_consumed >= MAX_ITERATIONSafter this iteration's Phase C. - Claim-reentry budget exhausted —
claim_reentries_consumed >= MAX_CLAIM_REENTRIESAND the only remaining unresolved claims would require type ③.
Steps:
- Set
review-stage/REVIEW_STATE.jsonstatusto"completed". - Record the termination reason as a top-level field
"termination_reason"∈{positive_verdict, iterations_exhausted, claim_reentry_exhausted}. - Assemble
FINAL_REPORT_DOC=review-stage/AUTO_ITERATION_FINAL_REPORT.mdby reading every iteration's per-category Phase E sections and folding them into the per-claim narrative structure described in "Final Report" below. The iteration agent (this skill) synthesizes the Executive Summary itself — do not invoke the reviewer for it. - Return to the caller (orchestrator or user). The agent's return message includes
termination_reason, the five per-category claim counts (PASS / FAIL / INCONCLUSIVE / ZERO_ELIGIBLE_VARIANTS / INTEGRITY_ONLY),iterations_consumed / MAX_ITERATIONS,claim_reentries_consumed / MAX_CLAIM_REENTRIES, and the paths toAUTO_REVIEW.md+FINAL_REPORT_DOC+REVIEWER_MEMORY.md.
Final Report
FINAL_REPORT_DOC = review-stage/AUTO_ITERATION_FINAL_REPORT.md is the narrative output of the whole loop. It is not an append log (that's AUTO_REVIEW.md); it is a one-shot synthesis written at Termination from material already on disk.
Source mapping
| Section | Source(s) |
|---|---|
| Header & disposition overview | REVIEW_STATE.json (counters, termination_reason, last_score, last_verdict); count claim ids per bucket from verify/VERIFY_REPORT.md + each iteration's Verify-Passed Claims / Actions Taken |
| Per-category claim sections | Per-iteration Actions Taken / Claim Rewrites / Results from AUTO_REVIEW.md, joined by claim id |
| Per-claim journey tables | iteration_breakdown[] filtered to each claim's id (and to any _v2 / _v3 descendants from claim rewrites) |
| Experiment & script modifications (FAIL/INCONCLUSIVE/ZERO_ELIGIBLE_VARIANTS sections) | Before/After bullets inside ### Actions Taken of the iteration that fixed the claim |
| Cross-cutting patterns | - **Patterns**: bullets inside each ## Iteration N block of REVIEWER_MEMORY.md, deduped across iterations |
| Iteration budget & pipeline (per-iteration table) | iteration_breakdown[] + per-iteration ### Results |
| Open items | Union of per-iteration ### Open Items — Unverified Under Swaps (deduped) + any FAIL/INCONCLUSIVE/ZERO_ELIGIBLE_VARIANTS claims still unresolved at termination. INTEGRITY_ONLY claims are always listed here (they never resolve within the iteration loop). |
Report skeleton
# Auto Iteration Final Report — <project name>
- **Generated**: <ISO timestamp>
- **Iterations consumed**: <iterations_consumed> / <MAX_ITERATIONS>
- **Claim-reentries consumed**: <claim_reentries_consumed> / <MAX_CLAIM_REENTRIES>
- **Final reviewer score**: <last_score> / 10
- **Final canonical verdict**: <ready | almost | not ready>
- **Termination reason**: <positive_verdict | iterations_exhausted | claim_reentry_exhausted>
- **Cumulative cost**: runs_total=<K>, gpu_hours_total=<H>
- **Source audit trail**: [`AUTO_REVIEW.md`](./AUTO_REVIEW.md), [`REVIEWER_MEMORY.md`](./REVIEWER_MEMORY.md)
---
## Executive Summary
<2–4 sentences synthesized by the iteration agent itself (no extra reviewer call). What the loop addressed, which claims converged, which were rewritten, which remain open.>
### Claim Disposition Overview
| Original state | # Claims | Final status after iteration |
|---|---|---|
| PASS | a | a PASS (held) |
| FAIL | b | b₁ PASS (variant fix) / b₂ PASS (new claim via ③) / b₃ still FAIL |
| INCONCLUSIVE | c | c₁ PASS / c₂ FAIL / c₃ still INCONCLUSIVE |
| ZERO_ELIGIBLE_VARIANTS | d | d₁ PASS / d₂ FAIL / d₃ still ZERO_ELIGIBLE_VARIANTS |
| DEFERRED | e | e queued for standalone `/auto-verify` |
---
## Section 1 — PASS Claims (brief audit)
For each claim id in the original `verify_passed` bucket:
### 1.x `<claim-id>` — <one-line statement>
- **Original robustness signal**: robustness=<r>, variants_passed=<x>/<y>
- **Reviewer consistency check**: <one-line — narrative / numeric / caveat>
- **Touched in iterations**: <[1] or [1,3]>
- **Final status**: PASS (held)
- **Notes for downstream**: <any paper-side caveat, or "none">
---
## Section 2 — FAIL Claims (full journey)
For each claim id in the original `verify_failed` bucket:
### 2.x `<claim-id>` — <one-line statement>
**Original FAIL signal**
- robustness=<r> (threshold=<θ>)
- Inconsistent dimensions: <e.g. "seed sensitivity, scale generalization">
- Variant integrity at entry: <"all clean" | "k of n had integrity issues">
**Iteration journey**
| Iter | Type | Reviewer flag | Action | Outcome |
|---|---|---|---|---|
| 1 | ① | variant `vN` mechanism-FAIL | rewrote `verify/<dir>/variants/vN/eval.py:L42`; reran `/auto-verify <id> — resume: true` | variant `vN` integrity clean; robustness <r₀>→<r₁> |
| 2 | ③ | clean variants, still below threshold | claim rewrite (lightweight, narrowed to "within-domain"); chained `/auto-experiment` + `/auto-verify` | new claim `<id>_v2` produced; `/auto-verify` PASS at <r₂> |
**Path taken (summary)**: variant-integrity fix → claim-stage re-entry (1 hop) — claim-reentry sub-budget used: 1
**Experiment & script modifications** (cumulative across all iterations on this claim)
| Iter | Component | Before | After |
|---|---|---|---|
| 1 | `verify/<dir>/variants/vN/eval.py:L42` | `scores / scores.max()` | `scores / train_stats.max` |
| 2 | (lightweight rewrite — no script edits beyond rerunning the rewritten claim's pipeline) | — | — |
**Claim modifications** (mandatory subsection — write `none — variant fix path only` if no rewrite happened)
- Original claim id `<id>`: "<original text>"
- After iteration 2 → new claim id `<id>_v2`: "<new text>"
- Scope change: <e.g. "removed cross-domain assertion, kept within-domain">
**Final experiment summary**
- New runs cited: `runs/iteration_round_1/<file>`, `runs/iteration_round_2/<file>`
- Final robustness: <r₂>
- Final variant pass rate: <x>/<y>
- Final status: **PASS (under new claim `<id>_v2`)** | **still FAIL — flagged in Open Items**
**Reviewer memory thread** (cross-iteration suspicions filtered to this claim's pattern)
- <verbatim bullets from REVIEWER_MEMORY.md>
- Resolved: <yes/no per item>
---
## Section 3 — INCONCLUSIVE Claims (main-experiment-fix journey)
For each claim id in the original `verify_inconclusive` bucket:
### 3.x `<claim-id>` — <one-line statement>
**Original INCONCLUSIVE reason** (from `verify/<dir>/ROBUSTNESS.md`'s `inconclusive_reason`):
- <verbatim, e.g. "main-experiment integrity broken — see verify/<dir>/main_experiment_audit/EXPERIMENT_AUDIT.md">
**Experiment plan & script modifications**
| Iter | Component | Before | After |
|---|---|---|---|
| 1 | `refine-logs/EXPERIMENT_PLAN.md` step 3.2 | "evaluate on val" | "evaluate on held-out test, normalize with train stats only" |
| 1 | `experiments/<name>/eval.py:L42` | `scores / scores.max()` | `scores / train_stats.max` |
**Re-experiment outcome**
| Iter | Path | New runs | Result |
|---|---|---|---|
| 1 | full re-run: `/auto-experiment` + `/auto-verify` | `runs/iteration_round_1/<run-id>/` | main-experiment integrity PASS, variants ran, verdict=PASS, robustness=<r> |
**Final status**: **PASS** | **FAIL after fix** | **still INCONCLUSIVE — flagged in Open Items**
**Reviewer memory thread**:
- <related bullets, if any>
---
## Section 4 — ZERO_ELIGIBLE_VARIANTS Claims (variant-fix journey)
For each claim id in the original `verify_zero_eligible_variants` bucket. Structure mirrors Section 3 but diffs target variant scripts (`verify/<dir>/variants/<v>/...`), not main-experiment scripts.
### 4.x `<claim-id>` — <one-line statement>
**Original ZERO_ELIGIBLE_VARIANTS reason** (from `verify/<dir>/ROBUSTNESS.md`'s `zero_eligible_reason`):
- <verbatim breakdown — N_exp_fail / N_mech_fail / N_both_fail>
**Variant script modifications**
| Iter | Variant | Component | Before | After |
|---|---|---|---|---|
| 1 | method-swap-X | `verify/<dir>/variants/method-swap-X/eval.py:L87` | <…> | <…> |
| 1 | model-swap-Y | `verify/<dir>/variants/model-swap-Y/mechanism.py:L24` | <…> | <…> |
**Re-verify outcome**
| Iter | Path | Action | Result |
|---|---|---|---|
| 1 | `/auto-verify <id> — resume: true` | only variant phases re-ran | N_eligible=2/3, robustness=<r>, verdict=PASS |
**Final status**: **PASS** | **FAIL after fix** | **still ZERO_ELIGIBLE_VARIANTS — flagged in Open Items**
---
## Section 5 — Legacy DEFERRED Claims (empty under current architecture)
> New verify runs never populate this section — `MAX_VERIFY_CLAIMS` cap-cut claims now land in Section 4b (INTEGRITY_ONLY, stage2_skip_reason: max_verify_claims_cap) with their Stage 1 audit results on disk. Section 5 is retained only for backward compatibility with legacy `VERIFY_REPORT.md` files that still carry a `## Deferred Claims` section.
For each claim id in a legacy `deferred_claims` list (if any):
### 5.x `<claim-id>` — <one-line statement>
- **Required next step**: standalone `/auto-verify <claim-id>` before re-entering iteration
- **Why deferred**: legacy `MAX_VERIFY_CLAIMS` cap (pre-restructure — verify ran only a subset)
---
## Section 6 — Cross-Cutting Patterns
> Patterns the reviewer kept flagging across iterations — surfaced separately because they often point to systemic methodology issues rather than per-claim problems.
- <verbatim `- **Patterns**:` bullets from each `## Iteration N` block of REVIEWER_MEMORY.md, deduped across iterations>
- For each pattern: which claims it touched, and whether it was resolved at termination
> This section is **inclusive** — every pattern the reviewer ever flagged appears here, whether or not it was eventually resolved. Section 8 ("Open Items") repeats only the still-unresolved subset.
---
## Section 7 — Iteration Budget & Pipeline
- **Iterations consumed**: <iterations_consumed> / <MAX_ITERATIONS>
- **Claim-reentries consumed**: <claim_reentries_consumed> / <MAX_CLAIM_REENTRIES>
- **Iteration `/run-experiment` calls**: runs_total = <K>
- **Iteration GPU-hours**: gpu_hours_total = <H>
### Per-iteration breakdown (from `iteration_breakdown[]`)
| Iter | Type | Target claims | Produced claims | Runs | GPU-hours | Score after | Verdict after |
|---|---|---|---|---|---|---|---|
| 1 | ① variant_fix | C1 | — | 1 | 2.1 | 5 | not ready |
| 2 | ② plan_script_rerun | C2 | — | 3 | 6.3 | 6 | almost |
| 3 | ③ claim_reentry | C1 | C1_v2 | 2 | 4.0 | 7 | almost |
---
## Section 8 — Open Items for Human Reviewer
> Items the loop could not close. These need a human or a separate pipeline.
- **Still-FAIL claims** (after exhausting routing options): <list with one-line why>
- **Still-INCONCLUSIVE claims**: <list>
- **Still-ZERO_ELIGIBLE_VARIANTS claims**: <list>
- **INTEGRITY_ONLY claims (Stage 2 skipped — not stress-tested)**: <list — surfaced verbatim from each iteration's "Unverified Under Swaps" subsection; each entry names the claim id, its `stage2_skip_reason` (`swap_variants_false` or `max_verify_claims_cap`), the matching upgrade instruction, plus the `main_experiment_integrity` level and any `warn_source`>
- **Legacy deferred claims (empty in new runs)**: <list — surfaced only when a legacy `VERIFY_REPORT.md` still carries a `## Deferred Claims` section>
- **Recurring unresolved patterns**: <list>
- **Claim-reentry refusals** (where reviewer requested ③ but sub-budget was exhausted): <list>
Key Rules
- Five-bucket discipline. Every iteration's reviewer prompt must include all five verify-state buckets (
verify_passed,verify_failed,verify_inconclusive,verify_zero_eligible_variants,verify_integrity_only) explicitly. Reviewers are not allowed to rewrite INCONCLUSIVE claims (rewrite is a FAIL-Phase-2 action only), nor to propose any back-edge action on INTEGRITY_ONLY claims (that bucket is no-action-with-upgrade-suggestion — the fix is to re-run verify with the per-stage2_skip_reasonupgrade command, not to touch the main experiment or the claim). The legacydeferred_claimsbucket is empty in new runs and does not appear in the reviewer prompt. - Unified iteration budget.
MAX_ITERATIONScounts every back-edge action (① variant fix / ② plan+script fix / ③ claim re-entry) uniformly. New claims produced by ③ inherit the same budget — they do not get a fresh allocation.MAX_CLAIM_REENTRIESis a sub-budget withinMAX_ITERATIONSspecifically for ③. - State-machine status values:
in_progress/awaiting_upstream/completed.awaiting_upstreamis the handoff signal to the orchestrator; onlycompletedtriggersFINAL_REPORT_DOCassembly. - Append-only audit chain.
AUTO_REVIEW.md(per-iteration log),REVIEWER_MEMORY.md(cross-iteration suspicions), anditeration_breakdown[]inREVIEW_STATE.jsonare all append-only.FINAL_REPORT_DOCis the one-shot synthesis written at Termination — never appended to. - Large file handling: If the Write tool fails due to file size, immediately retry using Bash (
cat << 'EOF' > file) to write in chunks. Do NOT ask the user for permission — just do it silently. - Anti-hallucination citations: When adding references, NEVER fabricate BibTeX. Use DBLP → CrossRef →
[VERIFY]chain. Do NOT generate BibTeX from memory. - Be honest about weaknesses.
- Implement real fixes (①/②/③) BEFORE re-reviewing whenever the reviewer flagged a non-narrative weakness. Type ⓪ (narrative-only) is allowed as an iteration's sole action only when every weakness the reviewer named is genuinely a paper-presentation issue, not a methodology or data issue dressed up as one.
- Document everything per the per-category Phase E template (every subsection, even when
none). - Include previous context in iteration 2+ prompts.
- Prefer MCP tool over curl when available.
Prompt Template for Iteration 2+
The iteration-2+ prompt has two prepended blocks before the body: Reviewer Memory (verbatim contents of REVIEWER_MEMORY_DOC) and Previous Review Summary (parsed from the prior iteration). The memory block is what gives this loop its adversarial edge — the reviewer sees its own prior suspicions and can check whether they were genuinely addressed.
Path selection. This template is used when REVIEW_STATE.json's thread_id is null (curl fallback was used in iteration 1, or the MCP server doesn't support thread continuation) — both blocks are concatenated into a fresh prompt with no server-side conversation state. When thread_id is non-null, prefer the thread-continuation path: pass thread_id to mcp__llm-chat__chat so the reviewer keeps its prior conversation, drop the "Previous Review Summary" block (the server already has it), but keep the Reviewer Memory prepend (it's structured suspicions, not dialog history). The template below covers the no-thread case; the thread case is just "Reviewer Memory + body, no summary block, thread_id passed as a call arg."
mcp__llm-chat__chat:
system: "You are a senior ML reviewer (NeurIPS/ICML level)."
prompt: |
[Iteration N/MAX_ITERATIONS of autonomous review loop]
[Iteration budget: <iterations_consumed>/<MAX_ITERATIONS> used;
claim-reentry sub-budget: <claim_reentries_consumed>/<MAX_CLAIM_REENTRIES> used]
## Your Reviewer Memory (persistent across iterations)
[Paste the FULL contents of review-stage/REVIEWER_MEMORY.md here — do not summarize]
IMPORTANT: You have memory from prior iterations. Check whether your previous
suspicions were genuinely addressed or merely sidestepped. The author
(Claude) controls what context you see in the iteration body below — be
skeptical of convenient omissions. If a prior suspicion is not mentioned
in this iteration's "Changes Since Last Review", that itself is a signal.
## Previous Review Summary (Iteration N-1)
- Previous Score: X/10
- Previous Verdict: [ready/almost/not ready]
- Previous Key Weaknesses: [list]
## Per-claim verify state (from /auto-verify, refreshed for this iteration)
verify_passed: [<ids or "none">]
verify_failed: [<ids or "none">]
verify_inconclusive: [<ids or "none">]
verify_zero_eligible_variants: [<ids or "none">]
verify_integrity_only: [<ids or "none">] # Stage 2 skipped; no back-edge action (upgrade dispatched by stage2_skip_reason)
## Changes Since Last Review
1. [Action 1]: [result]
2. [Action 2]: [result]
## Updated Results
[paste updated metrics/tables]
Please re-score and re-assess:
1. Score this work 1-10 for a top venue.
2. For each FAIL / INCONCLUSIVE / ZERO_ELIGIBLE_VARIANTS claim, name the MINIMUM
fix and tag it with routing type (①/②/③). Reject ③ on INCONCLUSIVE claims.
Reject ③ if claim-reentry sub-budget is exhausted.
3. State clearly: is this READY for submission? Yes/No/Almost. READY requires all
non-deferred claims in PASS state.
4. **Memory update**: list any new suspicions, unresolved concerns,
or patterns you want to track in future iterations. Output as a
`## Memory update` section so Phase B.5 can copy it verbatim.
Be brutally honest. Actively look for things the author might be hiding.
The same prepend rule applies when Phase A uses the curl fallback instead of MCP — concatenate the memory block + previous-review-summary block before the iteration body in the messages[].content field. The memory block is skipped only on iteration 1 (no file yet); from iteration 2 onward it is mandatory whenever REVIEWER_MEMORY_DOC exists non-empty.
Frequently asked questions
What to verify before installation and use
What does the auto-iteration-loop source document cover?
Autonomously iterate over /auto-verify's per-claim verdicts: review → implement fixes (variant-integrity, main-experiment-script, or claim-stage rewrite) → re-review, until the external reviewer gives a positive assessment with all FAIL / INCONCLUSIVE / ZEROELIGIBLEVARIANTS clai…
How do I install auto-iteration-loop?
The source record exposes this install command: npx skills add https://github.com/zjunlp/Mechanist --skill "skills/auto-iteration-loop". Inspect the command and pinned source before running it.
Which permission-related actions were detected?
Static rules flagged network, write-files, read-files, exec-script in the source; the page lists the matching lines and excerpts.
Alternatives
Compare before choosing
coreyhaines31/marketingskills
ab-testing
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
coreyhaines31/marketingskills
churn-prevention
When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o
alirezarezvani/claude-skills
app-store-optimization
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
wanshuiyin/Auto-claude-code-research-in-sleep
citation-audit
Use it for operations and research tasks; the detail page covers purpose, installation, and practical steps.