gauntlet 0.4.0 — campaign gates go mechanical
Highlights
- Resumable merge runner. Campaign finalization becomes a SHA-pinned, restartable tool (
merge.py): full validation on the cleanup/merge paths, identity and foreign-label refusal on the ledger-only and terminal paths, so an interrupted finalize resumes instead of restarting. (#134) A follow-up pair makes aBLOCKED-but-merely-behind PR rebase instead of parking for a human — first at the stage-3 merge gate (#137), then one layer down in the runner itself (#139), both via the base-ancestry probe the campaign already owns. - Mechanical tier derivation. Review-tier triage is now deterministic:
triage.pyclassifies each PR's diff (human / code / sensitive) into a mechanical floor, with the driver's semantic judgment layered only above it. A depth-raising escalation on unchanged content voids the tally and stops in-flight reviews, so a shallower pass can never count toward a deeper tier. (#135) - Verdicts gated on base preflight. The base-preflight
proceedbecomes a mechanical precondition: a new non-settablebase_ok_shaledger field is stamped only by a real preflight pass, verdicts are refused unless it matches the head under review, and any head move voids it. Review rounds are never spent over a conflicting or stale base. (#136) - Deterministic dispatch and repair prompts. Prompt assembly moves from prose instructions into executable owners: repair bundles built from validated review history and bound to the exact prompt, ledger, worktree, and head SHA (#122); a review dispatch materializer with attempt-scoped recovery (#123); and a fix-worker prompt materializer publishing host-neutral prompt bytes plus role/model metadata as one atomic bundle (#128).
- Strict readers for campaign state. The verifier now derives and strictly parses each attempt's review result, rejecting malformed reports (#126); gating-finding audits get a strict JSONL accessor with derived fix/refutation scopes (#121); and the run-scoped PR snapshot query has one executable owner that validates and atomically preserves
prs.json(#124). - Durable review-learnings store. A new
review-learnings.pyaccessor accumulates refuted and demoted finding classes across runs — consulted by the driver at adoption and finding-audit time, never injected into a review pass, with promotion left to the user. (#132)
What's Changed
- add canonical campaign PR snapshot fetch by @lestrrat in #124
- parse review results in verifier by @lestrrat in #126
- add review dispatch materializer by @lestrrat in #123
- add deterministic repair bundles by @lestrrat in #122
- add fix worker prompt materializer by @lestrrat in #128
- docs(campaign): note clean-rebase keeps verdicts by @lestrrat in #129
- add structured finding audit accessor by @lestrrat in #121
- docs(campaign): relabel on judgment-path rebase by @lestrrat in #130
- ci: derive pyright file count from the list by @lestrrat in #133
- docs(campaign): audit signals Non-goal residuals by @lestrrat in #131
- feat(campaign): add mechanical tier derivation by @lestrrat in #135
- feat(campaign): add resumable merge runner by @lestrrat in #134
- add durable review-learnings store by @lestrrat in #132
- feat(campaign): gate verdict on base-preflight by @lestrrat in #136
- fix(campaign): rebase behind PR at merge gate by @lestrrat in #137
- docs(campaign): drop stale openssl references by @lestrrat in #138
- fix(campaign): rebase behind PR at merge runner by @lestrrat in #139
- docs(campaign): class the finding-audit worker by @lestrrat in #140
- docs(campaign): one owner for head-move reset by @lestrrat in #142
- bump gauntlet to v0.4.0 by @lestrrat in #143
Full Changelog: gauntlet-v0.3.5...gauntlet-v0.4.0