Imported from zjunlp/Mechanist (
skills/auto/SKILL.md). Install upstream withnpx skills add zjunlp/Mechanist --skill auto. Copyright stays with the author.
Auto Pipeline: Idea → Experiments → Verify → Review
End-to-end autonomous run for: $ARGUMENTS (when provided) or the project's task.md (when $ARGUMENTS is empty).
Each stage runs in a dedicated agent (isolated context + configurable model). The orchestrator only sees each agent's final summary and the files on disk — it uses those to fire the gates between stages.
⏰ First action — register the hourly notification timer. Before any pipeline work, if
task.mdopts into notifications (see the Notifications rule in Key Rules), register a recurring scheduled task withCronCreate(cron<off-minute> * * * *— one call per hour, pick a minute ≠ 0/30; prompt:/notify hourly). This fires the hourly briefing on a real wall-clock timer instead of relying on the orchestrator remembering to poll during long waits. The timer is the sole source of the hourly cadence — the orchestrator never separately polls or manually fires/notify hourly. Register it once, up front — firstCronListto check an equivalent/notify hourlyjob is not already scheduled (e.g. on resume), and skip if so. Whentask.mddoes not opt into notifications, skip this entirely (no timer). The timer covers only the hourly cadence; the event-driven/notifytouchpoints (progress / done / halted / approval-needed) are separate and stay orchestrator-initiated (see Key Rules).
Direction source resolution:
$ARGUMENTSnon-empty → use it as the research direction; iftask.mdalso exists, the claim agent treatstask.mdas authoritative detailed context (current behavior).$ARGUMENTSempty +task.mdexists → usetask.mdas the sole direction source; passdirection: ""to the claim agent so it relies entirely ontask.md.$ARGUMENTSempty +task.mdabsent → stop and report[direction] no input — provide $ARGUMENTS or create task.md. Do not invent a direction.
Defaults
| Flag | Default | Effect |
|---|---|---|
AUTO_PROCEED |
true |
When true, gates skip the UI prompt entirely and directly pick the recommended option. When false, the orchestrator calls AskUserQuestion and waits for the user. |
RESUME |
false |
When true, the orchestrator skips any stage whose final artifacts already exist non-empty on disk, and forwards resume: true to each invoked agent so sub-skills can do phase-level skipping too. Useful for picking up after a crash, or for re-running only the missing stages. Default false = always run every stage from scratch (and overwrite previous artifacts). |
REVIEW_LOOP |
true |
Run iteration after verify; set false to stop at verify. |
MODEL |
none | Global model family alias applied to every stage whose <STAGE>_MODEL is unset. Accepts opus / sonnet / haiku (case-insensitive). Per-stage <STAGE>_MODEL always wins over this. When both are unset, the stage uses its frontmatter model: line if present, else inherits the session model (claude --model …). |
<STAGE>_MODEL |
none | Per-stage model family override for any of CLAIM, EXPERIMENT, VERIFY, ITERATION. Accepts only family aliases: opus, sonnet, haiku (case-insensitive). When unset, falls back to the global MODEL, then the agent's frontmatter model: line if present, else the session model (claude --model …). Pinning lives only in agents/<name>.md frontmatter — add a model: line to pin a stage, leave it absent to inherit the session model. CLI/frontmatter aliases resolve to the family's latest version (opus → newest opus, not claude-opus-4-x), so running a stage at exactly the session model requires an absent frontmatter model:. |
DIMENSIONS |
model |
Verify swap axes — and therefore the variant count per picked claim, since verify runs exactly one swap per listed axis. List or comma-separated subset of {method, dataset, model}. Default model → 1 variant/picked-claim (fast, single-axis model swap). Broaden with dimensions: method,dataset,model → 3 variants/picked-claim (full stress test). Forwarded to verify agent. |
TARGET_CLAIMS |
all |
Which claims verify stress-tests: all (default; covers both main-experiment-supported and main-experiment-rejected claims so robustness is checked in both directions) / passed (only main-experiment-supported = claim_supported = pass) / failed (only main-experiment-rejected = claim_supported = fail) / a specific claim id. Note passed ∪ failed = all. Forwarded to verify agent. |
MAX_VERIFY_CLAIMS |
1 |
Cap on how many Stage-1-admitted claims proceed into Stage 2 (swap variants). Stage 1 (main-experiment integrity audit) always audits every target claim regardless — the cap only gates Stage 2 entry. When the admitted pool exceeds the cap, /auto-verify's Phase 3 step 0 picks the top-K by importance judgment (reading each admitted claim's statement against upstream narrative like IDEA_REPORT.md / ## Rationale; row order is NOT a priority signal). Un-picked admitted claims are marked INTEGRITY_ONLY with stage2_skip_reason: max_verify_claims_cap in VERIFY_REPORT.md; user can swap-test them later via /auto-verify <id> — resume: true (Stage 1 audit is reused via RESUME). Forwarded to verify agent. At the default cap of 1 with default DIMENSIONS=model, verify launches 1 × 1 = 1 variant run per /auto pass. |
ROBUSTNESS_THRESHOLD |
0.5 |
A claim PASSes verify iff robustness ≥ ROBUSTNESS_THRESHOLD. Set higher (e.g., 0.67) for stricter publication-ready verification, lower (0.33) for exploratory work. Forwarded to verify agent. |
MIN_VARIANTS_FOR_VERDICT |
1 |
Minimum number of integrity-clean variants required to issue a PASS / FAIL verdict on a claim. Default 1 means a single eligible variant still yields a verdict; N_eligible < MIN_VARIANTS_FOR_VERDICT triggers ZERO_ELIGIBLE_VARIANTS (a distinct terminal state from INCONCLUSIVE — see auto-verify/SKILL.md Phase 10). Raise to 2/3 for stricter projects where you want multiple independent axes to agree before issuing PASS / FAIL. Forwarded to verify agent. |
BASE_REPO |
none | GitHub repo URL to clone before implementing. |
RESEARCH_DOMAIN |
auto |
Project domain tag (e.g. mechanistic-interpretability, vision-encoders, rl-policy-eval). Used to gate mechanism-family routing and downstream auxiliary decisions. Default auto: orchestrator forwards auto to the experiment agent and the sub-skill infers from FINAL_PROPOSAL.md; if inference is ambiguous, silently falls back to general regardless of AUTO_PROCEED (no UI prompt). To force a specific domain, set this flag explicitly on the CLI. |
COMPACT |
false |
Generate compact summary artifacts: idea-stage/IDEA_CANDIDATES.md after claim, refine-logs/EXPERIMENT_LOG.md after experiment, skip per-claim verify/<claim_dir>/ROBUSTNESS.md (where <claim_dir> = <claim_id>_<short_claim> on disk; see skills/auto-verify/SKILL.md "Directory Layout"). Forwarded to claim / experiment / verify agents. |
CODE_REVIEW |
true |
External LLM reviewer checks experiment + verify-variant code before deployment. Set false to skip. Forwarded to experiment + verify agents. |
SANITY_FIRST |
true |
Run the smallest/cheapest run first to catch setup bugs before launching the full suite. Forwarded to experiment + verify agents. |
AUTO_DEPLOY |
true |
Auto-deploy after implementation + review; set false to pause for manual inspection. Forwarded to experiment + verify agents. |
MAX_PARALLEL_RUNS |
4 |
Max concurrent /run-experiment calls dispatched within the experiment / verify stages. Becomes max_parallel: in the /experiment-queue manifest when Phase 4 of experiment routes to the queue path. Forwarded to experiment + verify agents. |
BATCH_DISPATCH |
auto |
Phase 4 dispatch routing rule (experiment stage). auto (default) lets /auto-experiment auto-pick /run-experiment for small milestones (≤ 5 ad-hoc runs) and /experiment-queue for large or dependency-laden ones (≥ 10 runs, depends_on, grid expansions, ≥ 3-seed × ≥ 3-config sweeps). queue forces every milestone to /experiment-queue; direct forces every milestone to /run-experiment (debug-only — emits a warning if it overrides the queue rule). Forwarded to experiment agent. |
REF_PAPER |
false |
Reference paper for the claim stage to summarize first. Accepts a local PDF path, an arXiv abs URL, or any paper URL. When set, claim Phase 0.5 writes idea-stage/REF_PAPER_SUMMARY.md and downstream idea generation builds on it. Forwarded to claim agent as ref_paper:. |
BEHAVIOR_SOURCE |
given |
Behavior stage — controls where the behavior to study comes from and whether it is validated. Three values: given (default): the behavior is already specified in the direction / task.md and assumed to hold — no ideation, no novelty check, no M0 validation; the claim stage faithfully captures it and goes straight to the mechanism. Precondition enforced by the Given-Behavior Comprehension Gate (see the claim stage): task.md must name a concrete behavior; if it names only a topic, the orchestrator asks the user to specify a behavior or switch to discovery (this gate always waits — even in full-auto). given-validation: the behavior is given the same way (faithfully captured from task.md, no mining, no ideation, no novelty) but its existence is validated first — the experiment plan opens with a hard M0 phenomenon-validation gate that the experiment stage runs before any mechanism compute. discovery: the behavior itself is mined — load /mechanism-behavior-discovery to sharpen a new candidate phenomenon and run the full ideation pipeline (research-lit → idea-creator → novelty-check → impact-check → research-review → research-refine-pipeline; final idea chosen by impact-first, novelty-second), then the experiment plan opens with the M0 gate too. The M0 four-state verdict (established/conditional proceed; not-established ends the pipeline with a negative-result report skipping verify+iteration; inconclusive re-runs M0) applies to both given-validation and discovery. Accepts given / given-validation / discovery (case-insensitive). Forwarded to the claim agent as behavior_source:. |
MECHANISM |
discovery |
Mechanism stage — controls who picks the mechanism method. discovery (default): the system selects the mechanism family — the experiment stage runs /mechanism-skills routing (route_only → auto-select the recommended candidate, or the family mini-prompt when AUTO_PROCEED=false) and the claim stage loads /mechanism-explore to shape the hypothesis direction + experiment plan. given: the user has specified the mechanism method/family in task.md — the claim stage captures it and the experiment stage commits it directly (Phase 1.5 Mode B, CHOSEN_FAMILY=<the method>), bypassing routing and the family mini-prompt; task.md must name a concrete mechanism method/family, else the claim stage halts (report it back). Accepts given / discovery (case-insensitive). Forwarded to the claim agent as mechanism:. Resource fidelity: the claim stage stamps resource_fidelity: strict into FINAL_PROPOSAL.md + EXPERIMENT_PLAN.md iff BEHAVIOR_SOURCE=given AND MECHANISM=given (the reproduction combination) — the experiment stage then enforces the Resource-Fidelity Harness on the main experiment (exact models/datasets at full scale — no smaller-model swap, no data subsetting, no skipped must-run runs; OOM handled by batch↓/grad-accum/sharding/offload, HALT rather than downscale; verify is exempt, its swaps are intentional). Every other combination leaves the marker unstamped, so model/dataset choice is unconstrained (cost-aware). |
MAX_ITERATIONS |
6 |
Iteration agent: max total back-edge actions (variant fix / plan+script fix / claim-stage re-entry) before stopping. Counts every back-edge uniformly; new claims produced by claim-stage re-entry inherit the same budget (no fresh allocation). Forwarded to iteration agent. Legacy alias MAX_ROUNDS is accepted at the CLI for one release and silently normalized to MAX_ITERATIONS. |
MAX_CLAIM_REENTRIES |
2 |
Iteration agent: sub-budget within MAX_ITERATIONS for claim-stage re-entries (action type ③ — see auto-iteration-loop/SKILL.md). Prevents the failure mode where the reviewer keeps requesting claim rewrites without anyone fixing the experiments behind them. When exhausted, the iteration loop refuses further ③ actions even if iterations remain. Forwarded to iteration agent. |
TARGET_SCORE |
6 |
Iteration agent: stop early when score ≥ this AND verdict is ready/almost AND no FAIL / INCONCLUSIVE / ZERO_ELIGIBLE_VARIANTS claim remains (three-dimensional STOP rule). |
GPU_ID |
auto |
GPU device(s) to pin every experiment / verify-variant / iteration-round run to. auto lets each sub-skill inherit from the environment / launcher (no pinning). A single id (0) or comma-list (4,5,6,7) causes the sub-skill to pass CUDA_VISIBLE_DEVICES=<GPU_ID> as the first positional argument to /run-experiment (and sanity runs); /run-experiment is a Skill, not a shell command, so it cannot accept a shell prefix — instead it parses this positional arg and exports CUDA_VISIBLE_DEVICES itself before launching the experiment subprocess. Forwarded to experiment + verify + iteration agents (iteration's Phase-C /run-experiment dispatches inherit the same pin). |
OOM_MAX_GPUS |
4 |
resource_fidelity: strict only (the BEHAVIOR_SOURCE=given + MECHANISM=given reproduction combo). Upper bound on how many free GPUs the Resource-Fidelity Harness may auto-add to a single OOM'd run before halting. On OOM the harness queries free GPUs (memory.used < 500 MiB), auto-adds them to the run and enables sharding — auto-converting a single-GPU script (model.cuda() / .to(device)) to device_map="auto" / FSDP / CPU-or-disk offload, first verified numerically equivalent on a fit-on-one-GPU proxy slice — repeating up to this cap while leaving MAX_PARALLEL_RUNS headroom for sibling runs. Only after the cap is hit (or no free GPU remains) and CPU/disk offload is exhausted does it HALT — and never by downscaling (smaller model / subset data stay forbidden, even in full-auto). Set higher to let one big run spread across more devices; auto lets it use all currently-free GPUs. Forwarded to experiment + verify + iteration agents. Ignored when the strict marker is absent (every non-reproduction combination). |
UNDERPOWER |
tag |
Active whenever the strict marker is absent (ignored under resource_fidelity: strict — the reproduction combo — which already forbids subsetting). Guards against an under-powered cheap run's weak/negative verdict being mistaken for a real negative. After the experiment, a claim whose main-experiment verdict is weak (not-supported / partial / null) and whose realized scale is materially below the plan (used_n shortfall, fewer seeds, or fewer grid/checkpoint points than EXPERIMENT_PLAN.md) is flagged suspected under-power. tag (default): tag the claim [suspected under-power: used_n X/Y, seeds A/B, grid P/Q] (recorded as a provisional caveat carried into the ledger + verify + iteration, so the negative is treated as provisional, not a confirmed falsification) and proceed — respecting the cost-aware design; under AUTO_PROCEED=false the experiment agent instead asks (full re-run / targeted-milestone re-run / accept demo-scale). stop: treat a suspected-under-power claim as a Round-End Decision (ended-needs-decision (experiment: suspected-under-power)) even under AUTO_PROCEED=true, so you decide whether to re-run at full scale before verify trusts it. off: disable the check. Forwarded to experiment agent. |
LEDGER_FIGURES |
auto |
Whether the final ledger render should call /paper-figure to produce per-claim plots and tables embedded into CLAIMS_LEDGER.md (image figures = PNG inline + PDF link; tables = Markdown inline + .tex link). Tri-state: auto (default) generates figures only for claims with at least one plottable or tabulable data source; true forces an attempt for every non-deferred claim (an unsupported claim still degrades to a skipped entry, never a halt); false disables the hook entirely and the ledger renders without a Figures bullet. Fires once per pipeline run, at the final ledger hook only (iteration:final, or verify when REVIEW_LOOP=false); intermediate hooks never re-invoke /paper-figure. See Ledger Figures hook. |
Override on the CLI, e.g. /auto "direction" — auto-proceed: false, claim-model: opus, verify-model: sonnet, dimensions: method,dataset, code-review: false. Canonical CLI form is hyphen-separated (auto-proceed, claim-model, code-review, ...). The parser also accepts underscore (auto_proceed) and uppercase env-style (AUTO_PROCEED) for compatibility — see "Argument parsing" below.
Pass each flag to the agent(s) listed in its "Forwarded to" hint as the corresponding arg in agents/<name>.md's Invocation contract (e.g., COMPACT → compact:, CODE_REVIEW → code_review:).
Argument parsing
$ARGUMENTS is shaped as "<direction>" — <key>: <value>, <key>: <value>, .... Both the direction and the option list are independently optional. The orchestrator parses it as follows:
- Direction (positional, optional) — everything before the first
—(em dash with spaces) or--is the research direction; pass it to the claim agent asdirection:. When omitted (empty$ARGUMENTS, or$ARGUMENTSstarts directly with—/--), passdirection: ""and rely ontask.md(see "Direction source resolution" above). If both are absent, stop and report rather than inventing a direction. - Options (after
—or--) — comma-separatedkey: valuepairs. Whitespace around:and,is ignored. Quoted strings keep their content. - Key normalization — lower-case, hyphens → underscores, then upper-case for the env-style flag (
auto-proceed/auto_proceed→AUTO_PROCEED;verify-model→VERIFY_MODEL). - Model values — for both
MODEL(global) and<STAGE>_MODEL(per-stage), the value must be one of the family aliasesopus/sonnet/haiku(case-insensitive; lowercase before passing through). Anything else is a parse error — log[arg-parse] <key>: "<value>" is not a family alias (opus|sonnet|haiku) — version pinning is managed in agents/<name>.md frontmatter, not on the CLIand stop. To change the pinned version of a stage, edit that agent file directly. - Bool values —
true/false/1/0/yes/no. Anything else is a parse error. - Enum string values — documented set or fall back to default with a log line:
BATCH_DISPATCHacceptsauto/queue/direct(case-insensitive; lowercase before passing through). On unknown value: log[arg-parse] BATCH_DISPATCH: "<value>" not in {auto, queue, direct} — falling back to default 'auto'and continue with the default.BEHAVIOR_SOURCEacceptsgiven/given-validation/discovery(case-insensitive; lowercase before passing through). On unknown value: log[arg-parse] BEHAVIOR_SOURCE: "<value>" not in {given, given-validation, discovery} — falling back to default 'given'and continue with the default.MECHANISMacceptsgiven/discovery(case-insensitive; lowercase before passing through). On unknown value: log[arg-parse] MECHANISM: "<value>" not in {given, discovery} — falling back to default 'discovery'and continue with the default.- Other future enum flags follow the same pattern.
- Unknown keys — log
[arg-parse] unknown key: <name> — ignoringand continue. The legacyMODEflag is removed: a passedmode:is an unknown key (ignored with the log line) — usebehavior-source+mechanisminstead (oldmode: reproduction≡behavior-source: given, mechanism: given; oldmode: discoveryis the default and implied by any non-reproduction combination).
All three of these invocations resolve to the same flags. The first (hyphen-separated) is the canonical form; the other two are accepted for compatibility — prefer the canonical form when writing new docs / examples / scripts.
# Canonical: hyphen-separated, lowercase
/auto "direction" — auto-proceed: false, claim-model: opus, verify-model: sonnet, dimensions: method,dataset
# Also accepted: underscore form
/auto "direction" -- auto_proceed: false, claim_model: opus, verify_model: sonnet, dimensions: method,dataset
# Also accepted: uppercase env-style
/auto "direction" — AUTO_PROCEED: false, CLAIM_MODEL: opus, VERIFY_MODEL: sonnet, DIMENSIONS: method,dataset
Retrieval rule
The claim agent's Phase 1 research-lit step must follow the requirements in skills/research-lit/SKILL.md, and mechanic-db-search must be executed, not skipable.
In other subagents, they may freely choose any retrieval source — WebSearch, WebFetch, MCP tools, or their own bundled scripts/ helpers. The orchestrator does not constrain the tool.
Overview
/auto (orchestrator)
│
├─ claim [session model] → idea-stage/IDEA_REPORT.md
│ │ refine-logs/FINAL_PROPOSAL.md
│ │ refine-logs/EXPERIMENT_PLAN.md
│ │ (internal chain depends on BEHAVIOR_SOURCE (behavior origin + ideation + M0) and
│ │ MECHANISM (routing vs. user-given family; when MECHANISM=discovery the chain loads
│ │ /mechanism-explore to shape the hypothesis direction + experiment plan):
│ │ given — [Given-Behavior Comprehension Gate: concrete behavior in task.md? no → ask user: switch-to-discovery (default) | specify-behavior]
│ │ research-lit → faithful behavior capture → [MECHANISM=discovery: /mechanism-explore] → research-refine-pipeline (no ideation, no novelty, NO M0)
│ │ given-validation — [Given-Behavior Comprehension Gate] research-lit → faithful behavior capture → [MECHANISM=discovery: /mechanism-explore] → research-refine-pipeline (plan opens with M0 gate; no ideation, no novelty)
│ │ discovery — research-lit → /mechanism-behavior-discovery → idea-creator → novelty-check → impact-check → research-review → [MECHANISM=discovery: /mechanism-explore] → research-refine-pipeline (plan opens with M0 gate)
│ │ resource_fidelity: strict is stamped iff BEHAVIOR_SOURCE=given AND MECHANISM=given (the reproduction combo).
│ │ MECHANISM=given captures the user's mechanism method from task.md → forwarded to experiment as CHOSEN_FAMILY.)
│ └─ Claim Gate
│
├─ experiment [session model]
│ ├─ Phase 1.25 (BEHAVIOR_SOURCE ∈ {given-validation, discovery} — fires on the plan's M0 marker): Phenomenon-Validation Gate M0 — run M0 first → 4-state:
│ │ established/conditional → continue ; not-established → 🛑 end pipeline (negative report, skip verify+iteration) ; inconclusive → fix & re-run M0
│ ├─ (MECHANISM=given → skip Call A + mini-prompt; read chosen_mechanism: from EXPERIMENT_PLAN.md → Call B with CHOSEN_FAMILY=that value, or MECHANISM_ROUTING=not-applicable when it is behavioral-only)
│ ├─ Call A (mode=route_only) → refine-logs/MECHANISM_ROUTING.md (2–3 candidates) [MECHANISM=discovery only]
│ ├─ 🔸 Mini-prompt: pick mechanism family (AUTO_PROCEED=true → skip prompt, pick recommended) [MECHANISM=discovery only]
│ └─ Call B (mode=build, chosen_family=X)
│ → Phase 4 dispatch fork (per-milestone routing):
│ ├─ ≥10 runs / depends_on / grid → /experiment-queue (batch scheduler with OOM retry, stale cleanup, GPU gate, phase deps)
│ └─ else → /run-experiment per run (direct dispatch)
│ → refine-logs/EXPERIMENT_RESULTS.md, refine-logs/EXPERIMENT_TRACKER.md
│ → MECHANISM_ROUTING.md with committed: true
│ └─ Experiment Gate (inside agent)
│
├─ verify [session model]
│ ├─ Phase 2 : per-claim main-experiment integrity audit (Stage 1 gate)
│ │ — /experiment-audit + /mechanism-audit on refine-logs/
│ ├─ Phase 3–7 : pick within-family method swap (+ data/model swaps), run variants
│ ├─ Phase 8 : /result-to-claim per variant → consistent_with_main_experiment
│ ├─ Phase 9 : per-claim variant integrity audit (symmetric to Phase 2)
│ ├─ Phase 10 : compute robustness → PASS / FAIL / ZERO_ELIGIBLE_VARIANTS
│ └─ write verify/VERIFY_REPORT.md, verify/INTEGRITY_AUDIT.md, verify/<claim_dir>/ROBUSTNESS.md
│ └─ Verify Gate (AUTO_PROCEED-governed, same as Claim/Experiment gates)
│
└─ iteration [session model] → review-stage/AUTO_REVIEW.md, REVIEW_STATE.json,
(skipped when REVIEW_LOOP=false) REVIEWER_MEMORY.md, AUTO_ITERATION_FINAL_REPORT.md
Pipeline
Multi-round guard (run first)
Before anything else, protect a prior round's outputs from being silently overwritten. When RESUME=false (a fresh run) AND un-archived prior-round artifacts are present at the project root — test [ -s CLAIMS_LEDGER.md ] or [ -s refine-logs/FINAL_PROPOSAL.md ] existing outside any rounds/ folder — a previous round's outputs have not been archived, and starting fresh would overwrite them. Do not proceed silently. Halt with:
[multi-round] un-archived prior-round artifacts detected (CLAIMS_LEDGER.md / refine-logs/...).
A fresh /auto would overwrite them. Choose one:
• /next-round — archive this round into rounds/round_<N>/ and draft the next task.md (recommended)
• RESUME=true — continue the existing (unfinished) round instead of starting fresh
• delete the listed artifacts manually to intentionally overwrite
Aborting.
This guard is independent of AUTO_PROCEED — it is data-protective and the remedy is a single user action, so it halts rather than auto-overwriting even in full-auto mode. It is skipped when RESUME=true (continuing is the intent) and when no such artifacts exist (a true first round). See Global Exploration Memory and the /next-round skill.
Resume-mode setup (only when RESUME=true)
Skip entirely if RESUME=false (default). When true:
Before invoking each stage's agent, check whether the stage is already complete by testing the existence and non-emptiness ([ -s <path> ]) of its stage-completion artifacts:
| Stage | Stage-completion artifacts (all must exist non-empty to count as "done") |
|---|---|
| claim | idea-stage/IDEA_REPORT.md, refine-logs/FINAL_PROPOSAL.md, refine-logs/EXPERIMENT_PLAN.md. |
| experiment | refine-logs/MECHANISM_ROUTING.md (with committed: true), refine-logs/EXPERIMENT_RESULTS.md, refine-logs/EXPERIMENT_TRACKER.md. Exception (phenomenon-terminated): if EXPERIMENT_RESULTS.md carries phenomenon_status: not-established (or terminal inconclusive), the stage counts as done with no MECHANISM_ROUTING.md/EXPERIMENT_TRACKER.md required — the M0 gate ended the run before mechanism work (see the experiment resume branch's case 0). |
| verify | verify/VERIFY_REPORT.md AND verify/INTEGRITY_AUDIT.md — both required, AND INTEGRITY_AUDIT.md must contain a non-empty ## Variant integrity (Phase 9) section (a file with only the ## Main-experiment integrity (Phase 2, per-claim) section is an incomplete run and must re-execute Phase 9). When Phase 2 returned fail on every target claim and Phase 9 was legitimately short-circuited, the Phase 9 section still exists, populated as [skipped — all main-experiment audits FAIL]. Per-claim main-experiment audit JSON verify/<claim_dir>/main_experiment_audit/EXPERIMENT_AUDIT.json must exist non-empty for every target claim — glob-expand verify/<claim_id>_*/main_experiment_audit/ for each. ("at least one" is too weak: the [skipped — all main-experiment audits FAIL] short-circuit asserts all main experiments failed, so if any target claim has no main-experiment audit on disk the prior run was partial — re-run, don't skip.) Do not test the bare verify/main_experiment_audit/ (the legacy flat layout). |
| iteration | review-stage/AUTO_REVIEW.md, review-stage/REVIEW_STATE.json, review-stage/AUTO_ITERATION_FINAL_REPORT.md (written by the iteration agent's Termination once status=completed; absence with status=completed means the agent crashed before report assembly and the stage must be resumed) |
If every artifact for a stage is present non-empty, the orchestrator:
- Does not invoke that stage's agent.
- Logs
[resume] stage=<name> skipped — artifacts present: <comma-separated list>. - Reads the stage's existing artifacts as if the agent had just produced them, fires the stage's Gate normally (which under
AUTO_PROCEED=trueis a no-op), and moves to the next stage.
If any artifact is missing or empty, the stage's agent is invoked, with resume: true forwarded so the agent can still apply phase-level skipping inside the skill. This way a half-done stage finishes the remaining phases instead of restarting from scratch.
Log on entry:
[resume-mode] resume=true — completed stages: <claim,experiment,...>; will resume from: <first-incomplete-stage>
Note: RESUME=true never deletes or overwrites pre-existing artifacts on its own. If you want a clean run, either set RESUME=false (default) or remove the relevant files manually.
Resolve per-agent models
Resolution order (per stage, evaluated independently for claim / experiment / verify / iteration):
- If the user passed
<STAGE>_MODEL=<alias>on the CLI (opus/sonnet/haikuonly), use it. Pass the alias as-is to the Agent tool'smodelparameter. The Agent tool then routes to the alias's current latest version. - Else if the user passed the global
MODEL=<alias>on the CLI, use that alias for this stage. - Else omit the
modelparameter. The agent uses its frontmattermodel:line if it pins one; with nomodel:line (the current default for all four agents) it inherits the session model (claude --model …). This is the only way to run a stage at exactly the session model — an alias likeopuswould resolve to the family's latest version instead.
| Agent | Frontmatter model: |
Effective model when unpinned | CLI override accepted |
|---|---|---|---|
| claim | none | session model (claude --model …) |
claim-model: opus | sonnet | haiku (or global model:) |
| experiment | none | session model (claude --model …) |
experiment-model: opus | sonnet | haiku (or global model:) |
| verify | none | session model (claude --model …) |
verify-model: opus | sonnet | haiku (or global model:) |
| iteration | none | session model (claude --model …) |
iteration-model: opus | sonnet | haiku (or global model:) |
To pin a stage instead, add a model: line to that agents/<name>.md frontmatter.
Log on entry:
[models] claim=<pin | CLI-alias | session> experiment=... verify=... iteration=... (source: CLI-stage | CLI-global | frontmatter-pin | session)
Report the actual resolved model — a CLI alias, a frontmatter pin, or the inherited session model — never a stale documented pin.
claim — Idea Discovery
Resume check (only when RESUME=true): if all three claim stage-completion artifacts exist non-empty, log [resume] stage=claim skipped — IDEA_REPORT.md, FINAL_PROPOSAL.md, EXPERIMENT_PLAN.md present and do not invoke the claim agent; jump straight to the Claim Gate using the existing files. Otherwise invoke the agent with resume: true forwarded so it can phase-skip internally.
Invoke the claim agent with a self-contained natural-language prompt that opens with the two injected blocks — ## HARD CONSTRAINTS (from task.md — non-negotiable) then ## NOTICE (from task.md — informational) (see the Key Rules "Injecting task.md" bullet; the claim agent receives the full union of both — every stage's items — because it authors EXPERIMENT_PLAN.md for all downstream stages) and then includes: the research direction, a pointer to task.md if it exists, the retrieval rule, AUTO_PROCEED, RESUME, and the expected output paths. The same two blocks are prepended to every other stage agent's dispatch prompt (experiment / verify / iteration) — but stage-scoped: each downstream agent gets only the items routed to it (per the targeting rules), re-injected on every stage and every resume.
↳ Global memory read (default on; no-op only in the reproduction combo BEHAVIOR_SOURCE=given + MECHANISM=given). When research_memory.json exists at the project root, pass research_memory: research_memory.json to the claim agent so the strategy skills avoid re-doing concluded work — BEHAVIOR_SOURCE=discovery avoids behaviors whose status ∈ {established, conditional, not-established} (all settled; inconclusive stays a retry candidate); BEHAVIOR_SOURCE ∈ {given, given-validation} avoids, for the matched behavior, any (mechanism direction, family) whose headline + claims[].conclusion prose reads as stable positive or stable negative per Rule 1 (mixed / deferred / integrity-broken / under-power all stay retry candidates). An explicit pin in task.md (behavior / direction / family) overrides this avoidance (Rule 2). Before dispatching the claim agent, the orchestrator checks for a settled-pin conflict here (it already holds both task.md and research_memory.json): scan task.md for the pinned behavior (the given behavior) and any mechanism direction: / family: line, and — for direction/family pins — read the matched behavior's mechanisms[] entries (headline + claims[].conclusion) to decide whether the pinned pair is already settled per Rule 1. On a hit, resolution respects AUTO_PROCEED and keys on the retry-settled marker in task.md (see Rule 2): when task.md carries retry-settled: true, resolve to honor-pin (the user explicitly authorized re-doing settled work); otherwise — AUTO_PROCEED=true resolves to pick-fresh silently (log [settled-pin] <pinned item> already settled in round <N>, no retry-settled marker — picking a fresh untried <level>), AUTO_PROCEED=false calls AskUserQuestion (honor-pin vs pick-fresh, recommended pick-fresh) and blocks. Pass the resolved decision into the claim agent's prompt as pin_resolution: honor-pin | pick-fresh. When no conflict is detected (pin present but not settled, or no pin), pass no pin_resolution — the claim agent then honors any pin as written (Rule 2). (The claim agent re-checks settled status as a backstop against a missed semantic match — see agents/claim.md step 0.5.) No flag governs the read (on by default); pass research_memory: false only in the reproduction combo (BEHAVIOR_SOURCE=given + MECHANISM=given) or when the file is absent (round 1). See Global Exploration Memory.
↳ Given-Behavior Comprehension Gate (BEHAVIOR_SOURCE ∈ {given, given-validation} only; fires independent of AUTO_PROCEED — always waits for the user, like the multi-round guard; note the settled-pin gate does NOT, it respects AUTO_PROCEED). Both given and given-validation take the behavior as written in task.md / the inline direction (they differ only in whether M0 later validates it) — so before dispatching the claim agent, the orchestrator (it already holds task.md) checks that a concrete behavior is actually present. A concrete behavior names a specific, falsifiable model-observable output pattern, ideally with its triggering condition — e.g. "the model rates first-person I believe X as less likely true than the matched third-person assertion" — as opposed to a bare topic / research direction — e.g. "explore the mechanics of LLM beliefs". An explicit Rule-2 pinned behavior in task.md always counts as concrete.
-
PASS (a concrete behavior is present) → proceed with the requested
behavior_sourceas-is; pass no extra field. -
FAIL (only a topic / direction, no concrete behavior) → halt and
AskUserQuestion(independent ofAUTO_PROCEED), two options:- switch to discovery (recommended) → re-dispatch the claim stage with
behavior_source: discovery, so the phenomenon is mined (/mechanism-behavior-discovery) and then hard-gated by M0 before any mechanism work.
This gate always waits for the user's answer — there is no timeout, no auto-abort, and no silent auto-fallback even under
AUTO_PROCEED=true(AskUserQuestionblocks indefinitely; a vague given direction is a decision only the user can make).- specify the behavior → the user supplies the concrete phenomenon as free text; inject it into the claim agent's prompt as
given_behavior: "<text>"and proceed with the requestedbehavior_source.
Rationale: running
given/given-validationon a vague direction would make the claim stage silently invent a behavior — this gate forces either a user-pinned/clarified behavior or the M0-protecteddiscoverypath. The claim agent re-checks this as a backstop (seeagents/claim.mdstep 0.6), so standalone/auto-claimcallers are covered too. Ignored whenBEHAVIOR_SOURCE=discovery(discovery mines + M0-validates the phenomenon by design). - switch to discovery (recommended) → re-dispatch the claim stage with
Expected artifacts: idea-stage/IDEA_REPORT.md, refine-logs/FINAL_PROPOSAL.md, refine-logs/EXPERIMENT_PLAN.md.
↳ Claim Ledger update: after the Claim Gate fires, seed the ledger from refine-logs/EXPERIMENT_PLAN.md — one row per claim id with statement, origin, and the planned data (set provenance, source, available_n, and the planned used_n), models, method; final_status = "planned". Set the global header (project, direction, models). See Claim Ledger.
🚦 Claim Gate: Echo the agent's top-3 idea list, then branch on AUTO_PROCEED before any UI call:
AUTO_PROCEED=true(default) → do NOT callAskUserQuestion. Directly accept the top-ranked idea fromIDEA_REPORT.mdand proceed to the experiment routing call. LogAUTO_PROCEED: accepted top idea — [title] (no prompt shown).AUTO_PROCEED=false→ callAskUserQuestionwith the four choices (approve / switch / re-run / stop) and block:- approve → continue to the experiment stage with the top idea.
- switch → re-invoke the claim agent with
chosen_idea: <N>so it rewritesrefine-logs/FINAL_PROPOSAL.mdandrefine-logs/EXPERIMENT_PLAN.mdfor idea #N (leavingIDEA_REPORT.mdintact), then re-open the gate. - re-run → re-invoke the claim agent with the same arguments plus the user's free-form feedback.
- stop → halt the pipeline.
If IDEA_REPORT.md is missing, empty, or only a placeholder, re-invoke the agent with corrective context before opening the gate.
experiment — Mechanism Routing + Build + Deploy
Resume check (only when RESUME=true). Note on committed flag semantics: Mode A (route_only) writes the routing candidates with committed: false; Mode B (build) flips it to committed: true once its Phase 0 has locked in chosen_family. The exception is a routing: not-applicable (behavioral-only) proposal — Mode A writes committed: true immediately with no mechanism family, because such a proposal is by definition "committed" to having none. So committed:true means either "Mode B has at least started" or "Mode A wrote the not-applicable stub"; the two are disambiguated by checking for a routing: not-applicable line in the file.
Pre-branch parse step (mandatory for cases 1 / 2 below): before classifying, extract from refine-logs/MECHANISM_ROUTING.md:
# committed flag (last occurrence wins so Mode-B overwrites Mode-A)
committed=$(grep -E '^committed:' refine-logs/MECHANISM_ROUTING.md | tail -1 | awk '{print $2}')
# not-applicable marker
not_applicable=$(grep -cE '^routing:[[:space:]]*not-applicable' refine-logs/MECHANISM_ROUTING.md)
# chosen_family value (may be absent on a not-applicable stub)
chosen_family=$(grep -E '^chosen_family:' refine-logs/MECHANISM_ROUTING.md | tail -1 | sed 's/^chosen_family:[[:space:]]*//')
Then derive the value to forward to Mode B's chosen_family: arg:
- If
not_applicable > 0→chosen_family_for_mode_b = "not-applicable"(overrides whatever thechosen_family:line says; not-applicable is the canonical sentinel Mode B's invocation contract accepts). - Else if
chosen_familyis non-empty and not literalnone→ use it verbatim. - Else (
committed:truebut no usablechosen_familyand norouting: not-applicablemarker) → the file is malformed; fall back to case 3 (re-run both calls) rather than invoking Mode B with a missing required arg. Log[resume] MECHANISM_ROUTING.md committed:true but chosen_family missing — falling back to fresh routing.
Branch as follows (using committed and chosen_family_for_mode_b from the parse step):
-
Phenomenon-terminated run (check first, before the
committedcases). Ifrefine-logs/EXPERIMENT_RESULTS.mdexists non-empty AND its top metadata hasphenomenon_status: not-established(or a terminalphenomenon_status: inconclusive), the experiment stage's Phase 1.25 M0 gate already ended the pipeline on a prior run —MECHANISM_ROUTING.mdmay be absent or uncommitted, which is expected (the run stopped before mechanism routing). Do not re-run the experiment agent. Log[resume] stage=experiment skipped — phenomenon_status=<not-established|inconclusive>, pipeline already ended at M0, then re-apply the phenomenon early exit: skip the verify and iteration stages, and finalize state into the Ledger — setclaims_ledger.json'spipeline_status = ended-phenomenon-not-established(orended-phenomenon-inconclusive), populatejourney_summary/open_items[]per the Terminal-state writeback rule, set each affected claim'sfinal_statusto✗ phenomenon not established/phenomenon validation inconclusive — fix M0, and re-renderCLAIMS_LEDGER.md. This branch takes precedence over cases 1–4 below — a terminalphenomenon_statusis checked before thecommitted-flag parse, since on a clean negative finding there is intentionally no committed routing. -
committed: trueANDEXPERIMENT_RESULTS.md+EXPERIMENT_TRACKER.mdexist non-empty → log[resume] stage=experiment skipped — routing committed, results presentand skip all call(s). -
committed: truebut no (or empty) results files → either build previously started, locked the routing, then crashed before producing results, or the proposal isrouting: not-applicableand build has never been invoked. Either way: invoke the experiment agent in build-only mode withchosen_family: <chosen_family_for_mode_b>andresume: true. Phase 0 will either resume from where it crashed (chosen_family was a real family) or take the no-mechanism path (chosen_family wasnot-applicable). This holds regardless ofAUTO_PROCEED— the routing decision is already persisted in the file, so there is nothing to mini-prompt about. -
MECHANISM_ROUTING.mdexists withcommitted: false(a previous Mode A finished but build never reached its commit step — only reachable under the legacyAUTO_PROCEED=falsetwo-call flow) → re-run per the Call-count rule below. UnderAUTO_PROCEED=truethis means a single combined call (Phase 0 will overwrite the stale candidates as needed); underAUTO_PROCEED=falseit means re-running the route_only call, re-prompting the user, then the build call. -
No
MECHANISM_ROUTING.mdat all → run per the Call-count rule below from scratch.
In all cases forward resume: true to whichever calls are invoked.
MECHANISM=given short-circuit (both AUTO_PROCEED modes). When MECHANISM=given, the user specified the mechanism method/family in task.md and the claim stage stamped it as chosen_mechanism: in the top metadata of refine-logs/EXPERIMENT_PLAN.md (and FINAL_PROPOSAL.md). The orchestrator reads that value:
chosen_mechanism=$(grep -E '^chosen_mechanism:' refine-logs/EXPERIMENT_PLAN.md | tail -1 | sed 's/^chosen_mechanism:[[:space:]]*//')
Then branch on the value, in both AUTO_PROCEED modes (no routing call, no family mini-prompt — the mechanism is already user-decided):
- A real method/family → forward
CHOSEN_FAMILY=<chosen_mechanism>to the experiment agent and use the build path directly (Phase 1.5 Mode B). This is the first-class form of the family-pin short-circuit below; both resolve to the same Mode-B direct commit. not-applicable(a behavioral-only reproduction — the user declared no mechanism claim) → forwardCHOSEN_FAMILY=not-applicableto the experiment agent's build call — the same behavioral-only sentinel the post-routing build call already accepts (see "Special case — behavioral-only proposal" below). The experiment writes therouting: not-applicablestub and runs no mechanism milestone.- Marker absent (
MECHANISM=givenbut nothing stamped — a malformed claim output) → fall back to the normal routing branch below and log[mechanism] MECHANISM=given but no chosen_mechanism stamped — falling back to routing.
Family pin short-circuit (Rule 2, both AUTO_PROCEED modes). (Applies when MECHANISM=discovery but task.md still pins a family:.) If task.md pins a family: and the orchestrator's settled-pin gate (claim-stage setup) resolved it to honor-pin (or there was no conflict), forward CHOSEN_FAMILY=<pinned family> to the experiment agent and use the build path directly (Phase 1.5 Mode B) — this bypasses both the combined-call auto-select and the AUTO_PROCEED=false mini-prompt, since the family is already user-chosen. (A pick-fresh resolution leaves CHOSEN_FAMILY unset, falling through to the normal branch below, where the avoid-set excludes the settled family.)
Call count (branch on AUTO_PROCEED, when neither the MECHANISM=given short-circuit nor a family pin short-circuit applies — i.e. MECHANISM=discovery with no pin):
AUTO_PROCEED=true(default) → one combined call. Invoke the experiment agent once withCHOSEN_FAMILYunset; the agent's Phase 0 Step 4 auto-selects the[recommended]candidate and proceeds straight into build. No orchestrator-side mini-prompt.AUTO_PROCEED=false→ two calls: route_only → mini-prompt → build (sections below). The human picks the family.
Routing call (mode: route_only) — only when AUTO_PROCEED=false
Invoke the experiment agent. It reads FINAL_PROPOSAL.md + EXPERIMENT_PLAN.md, runs /mechanism-skills, and writes refine-logs/MECHANISM_ROUTING.md with 2–3 candidates (recommended one marked, committed: false).
Special case — behavioral-only proposal: if the agent's notes say routing: not-applicable, skip the mini-prompt and go straight to the build call with chosen_family: not-applicable.
🔸 Mini-prompt — Family selection (only when AUTO_PROCEED=false)
Call AskUserQuestion and wait for the user to pick:
question: "Which mechanism family should the experiment commit to?"
header: "Mech family"
options: [candidate 1 (recommended), candidate 2, candidate 3]
ℹ️ Implementation note:
AskUserQuestionblocks until the user responds — there is no timer mechanism behind it, and that is intentional under the binaryAUTO_PROCEEDmodel:AUTO_PROCEED=trueskips this prompt entirely via the Combined call above (full auto, no human needed);AUTO_PROCEED=falsewaits indefinitely for the human (human-in-the-loop, waiting is the desired behavior). There is no third "auto-proceed after timeout" mode — the two are mutually exclusive by design.
This is a single-question selection, not a full gate.
Build call (mode: build) — only when AUTO_PROCEED=false
Before invoking Mode B, extract chosen_idea_title from the claim agent's return message (cached from the Claim Gate). The claim agent's output contract (see agents/claim.md's "Output contract") guarantees a line of the shape **Recommended:** #<n> — <title> — parse the title from that line:
chosen_idea_title=$(printf '%s\n' "$claim_agent_return" \
| grep -E '^\*\*Recommended:\*\*' \
| head -1 \
| sed -E 's/^\*\*Recommended:\*\*[[:space:]]*#[0-9]+[[:space:]]*—[[:space:]]*//')
If the parse yields an empty string (claim agent's return is malformed, or the switch <N> branch produced a re-run that re-wrote the report), fall back to reading the title from idea-stage/IDEA_REPORT.md — find the ### 🏆 Idea <CHOSEN_IDEA>: heading (or ### Idea <CHOSEN_IDEA>: for non-top-ranked) and take the title after the colon. If both sources fail, log [build-call] chosen_idea_title unresolved — passing "n/a" and forward chosen_idea_title: n/a (Mode B's contract says this field is for logging only, so it does not gate behavior).
Invoke the experiment agent with the chosen family and chosen_idea_title. It commits the routing, implements code, runs cross-model code review, runs sanity, deploys the full suite, and collects results.
Expected artifacts: refine-logs/EXPERIMENT_RESULTS.md, refine-logs/EXPERIMENT_TRACKER.md, MECHANISM_ROUTING.md with committed: true.
↳ Claim Ledger update: after the Experiment Gate returns, fill each claim's actual data (overwrite used_n with the amount actually used in the runs; correct available_n/provenance/source and set subset_note if the realized data differs from plan), models, method, and the main_experiment block (verdict, key_stats, headline) from refine-logs/EXPERIMENT_RESULTS.md (+ MECHANISM_ROUTING.md for the method/family). When a claim carries suspected_under_power: true (Power-Fidelity check, UNDERPOWER=tag), append [suspected under-power: used_n X/Y, seeds A/B, grid P/Q] to its caveats[] and mark its main_experiment.verdict provisional (e.g. not-supported [provisional — suspected under-power]) so verify + iteration treat the negative as provisional, not a confirmed falsification. See Claim Ledger.
🚦 Experiment Gate (inside the agent): After code review and sanity pass, before launching the full suite, the agent decides on AUTO_PROCEED × AUTO_DEPLOY — same binary-binary matrix as the Verify Gate:
AUTO_PROCEED=true(default) → the agent proceeds without UI prompt regardless ofAUTO_DEPLOY. Log on return:AUTO_PROCEED: deployed [N] experiments, ~[X] GPU-hours.AUTO_PROCEED=falseANDAUTO_DEPLOY=true→ the agent proceeds without UI prompt;AUTO_DEPLOY=trueacts as standing approval for the deploy step.AUTO_PROCEED=falseANDAUTO_DEPLOY=false→ the agent callsAskUserQuestionwith the deploy plan (approve / narrow scope / abort) and blocks indefinitely until the user answers. This is the intended human-in-the-loop behavior — no timeout.
🚦 Plan-reconciliation conflict → Round-End Decision. When the experiment agent returns reconciliation_status: escalate (its Phase 1.5 Step 7 found that the committed submethod cannot satisfy a method_sensitive field — e.g. the planned metric or sites — without changing the plan's scientific intent), it stops before building, since this stage may not rewrite the claim-authored EXPERIMENT_PLAN.md. Because the fix would have to alter scientific intent, the orchestrator does not auto-rewrite the plan (that risks silently changing the question the claim asserts — safety-first). Instead it writes a Round-End Decision (ended-needs-decision (experiment: plan-reconciliation-conflict), see Round-End Decision) naming the conflicting milestone field and pointing at MECHANISM_ROUTING.md's ## Plan reconciliation, then stops. Repair is the plan owner's job: the user fixes the conflicting milestone field in EXPERIMENT_PLAN.md (or picks a submethod that fits, or re-scopes the claim) and re-runs. A plain re-bind (no conflict) is not a stop — the agent absorbs it in routing and proceeds normally.
🛑 Phenomenon-Validation early exit (BEHAVIOR_SOURCE ∈ {given-validation, discovery} runs). When the experiment agent returns Phenomenon status: not-established (or a terminal inconclusive), the experiment stage's Phase 1.25 gate already stopped before any mechanism milestone (see /auto-experiment Phase 1.25). The orchestrator then ends the pipeline early:
- Skip the verify and iteration stages entirely — there is no established phenomenon to stress-test or iterate on.
- Update the Claim Ledger: set the affected claim(s)'
final_statusto✗ phenomenon not established(fornot-established) orphenomenon validation inconclusive — fix M0(for terminalinconclusive), pulling the M0 evidence fromrefine-logs/EXPERIMENT_RESULTS.md(phenomenon_statusmetadata). Treat this as the run's final ledger hook, so the maintenance protocol's step (6) fires the Ledger Figures hook here (a negative finding still gets a clean record). - Set
claims_ledger.json'spipeline_status = ended-phenomenon-not-established(orended-phenomenon-inconclusive) per the Terminal-state writeback rule, populatejourney_summary(experiment: negative headline + M0 evidence) andopen_items[](any surfaced caveats — under-power, unmatched distributions, missing cross-check tools, etc.), and re-renderCLAIMS_LEDGER.md. The M0 result is framed as a valid negative finding, not an error. - This is governed by
AUTO_PROCEEDat the experiment-stage gate (Phase 1.1): underAUTO_PROCEED=falsethe agent already presented verdict-appropriate options (terminate — accept & write report/re-run M0 — adjust the test/plan first) before returning; the orchestrator only seesnot-established(or terminalinconclusive) once that choice resolved to terminate.established/conditionalreturns proceed to verify normally (conditionalhaving restricted mechanism analysis to the holding conditions at runtime — the plan file is not rewritten by the experiment stage).
🚦 Power-Fidelity Gate (strict marker absent — every non-reproduction combination; UNDERPOWER != off). Cost-aware runs use (often reduced) scale, so a not-supported / partial / null main-experiment verdict can be an under-power artifact (too little data/seeds/grid to detect a real effect) rather than a genuine negative — and a false negative propagating to verify can get a true claim wrongly "falsified". After the experiment results land, the experiment agent flags any claim whose verdict is weak and whose realized scale is materially below EXPERIMENT_PLAN.md (used_n shortfall, fewer seeds, or fewer grid/checkpoint points) as suspected_under_power, with the X/Y figures. The orchestrator then, per UNDERPOWER:
tag(default) → tag the claim[suspected under-power: used_n X/Y, seeds A/B, grid P/Q]as a provisional caveat (carried into the ledgercaveats[], and forwarded to verify + iteration so the negative is treated as provisional, not a confirmed falsification) and proceed to verify (respecting discovery's cost-aware design). This is theAUTO_PROCEED=truebehavior; underAUTO_PROCEED=falsethe experiment agent insteadAskUserQuestions (full re-run at plan scale / targeted re-run of the suspect milestone / accept demo-scale & proceed) and blocks.stop→ treat it as a Round-End Decision (ended-needs-decision (experiment: suspected-under-power), see Round-End Decision) even underAUTO_PROCEED=true, withdetail= which claims/milestones look under-powered and by how much,remedy= re-run at plan scale (or accept & re-run withUNDERPOWER=tag). For users who never want a suspected artifact to silently reach verify.off→ no check (full cost-aware behavior).
verify — Claim Verification
Resume check (only when RESUME=true): skip verify only if all of these hold — verify/VERIFY_REPORT.md non-empty, verify/INTEGRITY_AUDIT.md non-empty with a populated ## Variant integrity (Phase 9) section (which may be [skipped — all main-experiment audits FAIL] for the legitimate short-circuit), and every target claim has a non-empty verify/<claim_id>_*/main_experiment_audit/EXPERIMENT_AUDIT.json (glob-expand the per-claim directory for each; the legacy flat verify/main_experiment_audit/ path no longer applies). If any target claim is missing its main-experiment audit, the prior run was partial (it never audited that claim) — do not trust an [skipped — all main-experiment audits FAIL] marker; re-run verify. Log [resume] stage=verify skipped — Phase 2 + Phase 9 both finalized. Otherwise invoke the agent with resume: true forwarded so partially-completed variants and partially-done integrity audit can be reused. Guards against a common failure mode: Phase 2 finishes and writes INTEGRITY_AUDIT.md with only the main-experiment section, then the process dies during Phase 9 — without the Phase-9-section check, resume would wrongly think verify is done.
Invoke the verify agent. It runs /auto-verify, whose full state machine — target selection (Stage 1 audits every target claim), the mandatory Phase 2 per-claim main-experiment integrity gate, the Phase 3 step 0 Stage-2 pick (top-K by importance judgment from the Stage-1-admitted pool; K = MAX_VERIFY_CLAIMS), within-family method swaps along DIMENSIONS on the picked set, the robustness = #pass / N_eligible formula, the mandatory Phase 9 per-claim variant integrity gate, and final state assignment — is owned by skills/auto-verify/SKILL.md (single source of truth). Do not re-derive that logic here; this orchestrator only consumes the outputs below.
What the orchestrator acts on (everything else is skill-internal):
- Five per-claim terminal states, read from
verify/VERIFY_REPORT.md(trust-the-files): PASS / FAIL / INCONCLUSIVE (Phase 2 main-experiment integrity FAIL — variants never ran) / ZERO_ELIGIBLE_VARIANTS (variants ran but all failed Phase 9 integrity) / INTEGRITY_ONLY (Phase 2 pass/warn but Stage 2 intentionally skipped; per-claimstage2_skip_reason∈ {swap_variants_false,max_verify_claims_cap}). All five are valid; INCONCLUSIVE and ZERO_ELIGIBLE_VARIANTS route to different iteration surfaces (fix main experiment vs. fix variants); INTEGRITY_ONLY is a no-op-with-upgrade-suggestion bucket. These map to the five iteration context buckets below and to the ledgerverify.verdict. - Two integrity verdicts for logging / the Verify Gate: main-experiment integrity (Phase 2) and variant integrity (Phase 9), each
PASS|WARN|FAIL. - All-integrity-broken outcome (see Key Rules → "All-integrity-broke
*Truncated - read the full file at https://github.com/zjunlp/Mechanist/blob/ec95171ef7026fba5079b250c2afd253510a74b0/skills/auto/S