Every ticket as the root of its provenance graph — goal, patch, approval, runs and (as the ticket-class build lands) mandate, manifestations, guarantees, journey, artifacts and children. Rendered through the <<<TicketGraphList>>> tag.
Regression-capture: auditor emits structured repro -> failure auto-populates a red, worker-immutable regression test in tests/regression/ (opt-in flag, red/green validation invariant, anti-gaming)
goal
Make a CONFIRMED auditor finding persist as a red regression test that the fix must turn green —
turning failure signal from lossy prose into a durable, worker-immutable guard. Opt-in, validated,
and hardened against gaming.
CONTEXT / WHY
Today a failed round journals FINDINGS as free-text and re-runs a fresh worker; nothing about the
failure is captured as a test, so the same defect can recur unguarded. The auditor already PROVES
the failure by executing the required behavior point-by-point (build/bug audit_focus), so at
judgment time it HOLDS the concrete {input, observed} — it just summarizes it to prose and drops
the repro. This ticket captures that repro and mints a regression test from it. The expected value
is FREE: forge rewrites are behavior-preserving against the original whose source is embedded in
the ticket, so the oracle is the original module, not the finding and not the worker.
DELIVERABLE (primary): checkouts/current/congruency/tools/regression_capture.py — a STANDALONE
module (pair_loop calls it via a thin hook; keep pair_loop.py edits minimal — the #279 regression
came from a large pair_loop rewrite, do not repeat that). It provides:
1. STRUCTURED REPRO SCHEMA. Extend the auditor verdict so a fail-finding may carry
{entrypoint, input, observed} (expected is DERIVED, see 2). Prose findings still allowed;
only findings that carry a structured repro mint a test. Backward compatible.
2. ORACLE = ORIGINAL. Compute `expected` by executing `entrypoint(input)` against the ORIGINAL
embedded module (from the ticket's ===ORIGINAL SOURCE===/===END SOURCE===), never from the
worker's output and never from the finding text. The worker cannot define correctness.
3. TEST EMISSION. Write a regression test asserting entrypoint(input) == expected into a
HARNESS-OWNED path tests/regression/ under the unit's package. This path MUST be excluded from
the worker's write scope (worker-immutable): the worker fixes the module, it may not touch,
weaken, or delete the guard. Verify pair_loop's deliverable/worker scoping enforces this.
4. VALIDATION INVARIANT (this is how we validate the method — REQUIRED, not optional):
* RED-ON-BUGGY: the minted test MUST fail against the exact worker blob that produced the
finding. If it passes there, the capture is bogus -> REJECT it, journal why, mint nothing.
* GREEN-ON-ORIGINAL: the minted test MUST pass against the original. If not, the oracle/
input is malformed -> REJECT.
* MUTATION-RESISTANT: re-introducing the captured defect must turn the test red.
Only a test that is red-on-buggy AND green-on-original is persisted. The harness self-checks
every test it mints.
5. ANTI-GAMING (hard requirements):
* The regression test is an ADDITIVE FLOOR, not the round gate. The adversarial auditor
still executes required behavior every round; overfitting the one captured input does NOT
pass the round. Do not replace or weaken the existing auditor loop.
* Keep the mechanism INVISIBLE to the worker: the worker sees the finding ("this behavior is
wrong"), never a literal "make this assertion pass". The capture machinery MUST NOT be
written into the worker-facing birth prompt OR leaked into docs/PLAYBOOK.md by the lesson
harvester. Add a guard/test that the playbook-compile path never emits capture details.
6. TOGGLE. Honor registry.json `regression_capture.enabled` (bool) AND a pair_loop flag
`--regression-capture on|off|auto`, DEFAULT OFF (current behavior byte-for-byte unchanged when
off). On/off must be instant and require no code edits, so we can A/B capture-on vs capture-off.
7. --selftest. On a THROWAWAY synthetic unit (a tiny original with a known bug + a repro),
prove: red-on-buggy, green-on-original, bogus-capture rejection, worker-scope exclusion of
tests/regression/, and that OFF changes nothing. No network, no live db (mirror pair_loop's
--selftest discipline).
pair_loop.py CHANGE (secondary, MINIMAL): a single hook after a fail verdict — if capture is on and
the finding carries a repro, call regression_capture and, on a validated test, stage it with the
package. No other behavioral change. Preserve the assign-before-ACTIVE ordering (do not reintroduce
the #279 regression); pair_loop --selftest must still pass AND a live dispatch must still reach
ACTIVE.
ACCEPTANCE:
* regression_capture.py --selftest passes (proves the red/green invariant + rejection + scope +
off-is-noop).
* With capture ON, a forge pair whose auditor files a structured repro produces a tests/regression/
test that is red on the pre-fix blob and green after the fix, and the worker could not modify it.
* With capture OFF, behavior is identical to today.
* pair_loop --selftest green AND a real --ticket dispatch reaches ACTIVE (no 500).
RUN THIS ON CLAUDE (orchestration-adjacent; not a GLM task).
patch
none
approval
unapproved
runs
no runs recorded
mandate (clauses)
not yet recorded — lands with the ticket-class build
manifestations
not yet recorded — lands with the ticket-class build
guarantees
not yet recorded — lands with the ticket-class build
journey (blunders & successes)
not yet recorded — lands with the ticket-class build
artifacts (forge)
not yet recorded — lands with the ticket-class build