verify_plan.py: mechanical pre-pass gate for experiment plans at adversarial-planner Phase 1.5
Highlight text on any card (body, plan, or an event) to anchor a comment, or leave a whole-task comment here. Mention @claude to summon a reply.
No comments yet.
Motivation
Clean-result bodies have a 17-check mechanical verifier (verify_task_body.py); plans have none, yet the plan critic is the most expensive and most load-bearing review site (a missed structural gap costs GPU-hours downstream). Literature basis for the design: grounded mechanical verification beats free-form critique at any reviewer tier (Stechly & Kambhampati 2024, arXiv:2402.08115; McAleese et al. 2024, arXiv:2407.00215). This is token-audit fix #21 (2026-06-12).
Deliverable
scripts/verify_plan.py --issue <N> [--plan-file <path>] — parses the newest plans/v{N}.md (or the given file) and reports PASS/FAIL per check + an exit code. Pure structural/presence checks only — NO LLM calls, no judgment. Mirror verify_task_body.py's architecture (numbered checks, FAIL blocks / WARN ships-if-acknowledged, JSON output mode).
Checks (initial set — derive exact predicates from CLAUDE.md Critical Rules + planner.md)
- §11 hyperparameter table exists; every load-bearing row carries a
Source:(arXiv id / paper table / prior issue#<M>) or an explicitungrounded — needs smoke-testmarker; no blank sources. - Per-DV measurement-validity declaration present (
kind: experimentonly): construct named, metric named, on-distribution status stated; off-distribution proxies carry the required validation-or-argument text. - Data-source tier named in §4 (real-world / established dataset / diverse-LLM-synthetic / programmatic) with the justification required for tiers 3-4.
- Behavior-implantation plans: contrastive-negative set present (panel + ratio + disjointness check named) OR one of the two named exemptions stated.
- GPU-hour estimate present (needed by the Step 2c auto-approval cap).
- Reused-trained-artifact sections: fitness attestations (a)-(g) each present for every artifact recorded as reused.
- Replication plans (Goal mentions replicating a paper): replication-fidelity section present (paper recipe vs deviations table).
- Kill criteria / success criteria section present and non-contradictory in form (both present, neither empty).
- Plan declares conditions/cells table and seeds (the consistency-checker's input surface).
- Marker-leakage plans: the marker-recipe acknowledgment line present (the rules were read; anchor band + bystander gating stated).
Checks must be skippable by kind: (analysis/infra/batch/survey exempt where CLAUDE.md says so).
Integration
/adversarial-plannerSKILL.md: run at Phase 1.5 alongside the fact-checker; FAIL bounces the plan back to the planner BEFORE the critic ensemble spawns (critics then review substance, not structure).workflow.yaml: add the gate reference; post a marker (epm:plan-verify v1) with the check results.- Tests:
tests/test_verify_plan.pywith fixture plans (passing, each-check-failing). Follow the test style oftests/test_verify_task_body.py.
Acceptance criteria
- Script + tests merged,
uv run pytest tests/test_verify_plan.pygreen; ruff clean. - Phase 1.5 wiring in adversarial-planner SKILL.md + workflow.yaml marker documented.
- Run against the 3 most recent approved plans retroactively; report (do not fix) any FAILs they would have raised — this calibrates the checks against reality.
- No LLM calls anywhere in the script.