Skip to content

Add run --baseline: execute every check against the unmodified tree#38

Merged
justfinethanku merged 3 commits into
NateBJones-Projects:mainfrom
mlava:feat/baseline-check-mode
Jul 16, 2026
Merged

Add run --baseline: execute every check against the unmodified tree#38
justfinethanku merged 3 commits into
NateBJones-Projects:mainfrom
mlava:feat/baseline-check-mode

Conversation

@mlava

@mlava mlava commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Independent of #35/#36/#37 — new function + one flag + one dispatch branch; no overlap with those diffs.

Problem

The check is the product — but nothing exercises the checks themselves before workers spawn. In a real 12-lane fix swarm (2026-07-14), two lanes failed on verify assertions that were wrong about the pre-change tree: one demanded a status its own lane spec forbade, and one was unsatisfiable on a pristine repo (a tsx -e CJS/ESM quirk). An honest worker burned ~100k tokens against the unsatisfiable one before anyone knew the check was the bug.

Feature

ringer.py run manifest.json --baseline executes every task's check against the unmodified tree and reports — spawning no workers:

Baseline: executing 12 check(s) with no workers spawned.
unchanged-behavior       baseline: pass (rc=0)
new-behavior             baseline: FAIL (rc=1)
    FAIL: built-by-worker.txt not present

baseline: 1 pass, 1 fail, 0 error of 2 check(s).
Reading the results: a FAIL is EXPECTED for assertions that demand the
NEW behavior workers will build. A FAIL on an assertion about UNCHANGED
behavior means the check itself is broken and will burn worker attempts
against something no model can satisfy — fix the check before spawning.

Design notes:

  • Spawns nothing — dispatches before preflight_engine_bins on purpose, so a missing engine binary can't block baseline
  • Fresh scratch taskdir per task (a detached worktree when the manifest uses worktrees), removed afterwards; nothing leaks into the manifest workdir or the repo
  • No model-log rows
  • Checks run for real, including any exports they perform — same semantics as at run time (reuses Verifier, including expect_files and CHECK_TIMEOUT_S)
  • Exit 0 regardless of failures: baseline reports; deciding which failures are expected is the orchestrator's judgment, and the report says exactly how to read it

Test

End-to-end (tests/test_baseline_mode.py): worktrees manifest on a temp git repo, a deliberately nonexistent engine binary, and two checks — one asserting current tree state (must pass), one demanding a worker-built file (expected FAIL). Asserts the report lines and excerpt, the guidance text, exit 0, an absent model log, and zero leaked taskdirs or worktrees. Full suite: no new failures (the pre-existing test_design_reference/test_scoreboard_page failures reproduce on clean main).

🤖 Generated with Claude Code

Two of twelve lanes in a real fix swarm failed on verify assertions that
were wrong about the PRE-change tree — one demanded a status its own lane
spec forbade, one was unsatisfiable on a pristine repo. An honest worker
burned ~100k tokens against the latter before anyone knew the check was the
bug.

run --baseline makes that question answerable in one command, before any
worker spawns: every task's check runs against a fresh scratch taskdir (a
detached worktree of the repo when the manifest uses worktrees), and the
report shows pass/FAIL with the check's own output excerpt. Reading it is
the orchestrator's judgment call, which the report spells out: a FAIL is
expected for assertions that demand the new behavior workers will build; a
FAIL on an assertion about unchanged behavior means the check itself is
broken and will burn worker attempts against something no model can
satisfy.

Design notes:
- spawns nothing: runs before preflight_engine_bins on purpose, so a
  missing engine binary cannot block baseline
- writes no model-log rows and touches neither the manifest workdir nor
  the repo (scratch worktrees are removed; the scratch root is deleted)
- checks run for real, including any exports they perform — same semantics
  as at run time
- exits 0 regardless of failures: baseline reports, the orchestrator judges

Test: end-to-end manifest with a deliberately nonexistent engine binary and
two checks — one asserting current tree state (must pass baseline), one
demanding a worker-built file (expected FAIL) — asserting the report lines,
the excerpt, the guidance, exit 0, an absent model log, and zero leaked
taskdirs or worktrees.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
justfinethanku and others added 2 commits July 16, 2026 12:05
Resolve each baseline taskdir and refuse keys that escape the scratch
root (same rule as the real run path), and surface failed worktree
removals per task and in the summary instead of letting a clean report
hide leaked state. Merge with current main keeps --baseline alongside
--allow-noncanonical-route.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@justfinethanku

Copy link
Copy Markdown
Contributor

Merging — thank you. This is the most doctrine-aligned PR in the queue: "a check that cannot fail is trusting the worker with extra steps" has been in the README for weeks, and --baseline makes it a one-command preflight instead of a lesson you learn at ~100k tokens a lane. The field story in your test docstring is exactly why we wanted it, and reusing the real Verifier so baseline semantics match run-time semantics was the right call.

Maintainer-side before merge (authorship stays yours): resolved the parser conflict with current main (--baseline now sits alongside --allow-noncanonical-route), added the same task-key containment rule the real run path enforces so a hostile key can't escape the baseline scratch root (with a regression test), and made failed worktree removals print per task plus a summary warning with the exact git worktree prune cleanup — a clean-looking report must not hide leaked state. Full suite green at 217 tests.

Also queued on our side, sparked partly by this: a structured failure-class field on eval rows so "the check was broken" vs "the model failed" vs "the engine was down" becomes sliceable scoreboard signal. Your #35/#36 verdicts feed the same taxonomy — the joint-design thread on #33/#36 is the place if you want in on that. Thanks again for the consistently excellent work.

@justfinethanku
justfinethanku merged commit 3de9b28 into NateBJones-Projects:main Jul 16, 2026
justfinethanku added a commit that referenced this pull request Jul 16, 2026
Every merged community contributor must appear in README Contributors —
tests/test_contributors.py audits git history (squash authors + merged-PR
handles) against the section and fails on any omission; CI checks out full
history for it. README refresh: all four merged contributors credited
(#24 #30 #4 #37 #38), --baseline documented, canonical-route enforcement
mentioned in the taxonomy section, CI badge added.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
adamreading pushed a commit to adamreading/AJO-ringer that referenced this pull request Jul 19, 2026
…ateBJones-Projects#38)

* Add run --baseline: execute every check against the unmodified tree

Two of twelve lanes in a real fix swarm failed on verify assertions that
were wrong about the PRE-change tree — one demanded a status its own lane
spec forbade, one was unsatisfiable on a pristine repo. An honest worker
burned ~100k tokens against the latter before anyone knew the check was the
bug.

run --baseline makes that question answerable in one command, before any
worker spawns: every task's check runs against a fresh scratch taskdir (a
detached worktree of the repo when the manifest uses worktrees), and the
report shows pass/FAIL with the check's own output excerpt. Reading it is
the orchestrator's judgment call, which the report spells out: a FAIL is
expected for assertions that demand the new behavior workers will build; a
FAIL on an assertion about unchanged behavior means the check itself is
broken and will burn worker attempts against something no model can
satisfy.

Design notes:
- spawns nothing: runs before preflight_engine_bins on purpose, so a
  missing engine binary cannot block baseline
- writes no model-log rows and touches neither the manifest workdir nor
  the repo (scratch worktrees are removed; the scratch root is deleted)
- checks run for real, including any exports they perform — same semantics
  as at run time
- exits 0 regardless of failures: baseline reports, the orchestrator judges

Test: end-to-end manifest with a deliberately nonexistent engine binary and
two checks — one asserting current tree state (must pass baseline), one
demanding a worker-built file (expected FAIL) — asserting the report lines,
the excerpt, the guidance, exit 0, an absent model log, and zero leaked
taskdirs or worktrees.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Baseline hardening: key containment + leaked-worktree reporting

Resolve each baseline taskdir and refuse keys that escape the scratch
root (same rule as the real run path), and surface failed worktree
removals per task and in the summary instead of letting a clean report
hide leaked state. Merge with current main keeps --baseline alongside
--allow-noncanonical-route.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Jonathan Edwards <justfinethanku@gmail.com>
(cherry picked from commit 3de9b28)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants