feat(baseline): record the findings that already exist, so only new ones fail - #460
Merged
wenzowski merged 4 commits intoAug 14, 2026
Conversation
CLOUD-67 Add a `baseline` command for already-dirty repos
Why Acceptance
Refinement — Ready Refinement gate: Definition of Ready & Done. This body carries only specializations.
Inherited constraints from the identity decision (CLOUD-123) — a baseline is a persisted set of finding identities, and its governance is part of the threat model:
|
wenzowski
marked this pull request as ready for review
August 14, 2026 20:47
wenzowski
force-pushed
the
wenzowski/cloud-67-add-a-baseline-command-for-already-dirty-repos
branch
from
August 14, 2026 20:47
990978a to
c625ffd
Compare
…nes fail A repository adopting Batten had two routes to green: fix every existing violation at once, or weaken policy. This is the third — a baseline, the persisted set of finding identities that already existed, so `check` stops failing on them and still fails on anything new. A baseline is a bulk waiver by another name, and the agent running it is both the finding's subject and the store's writer, so the load-bearing part is not the filter but the minting predicate: only landed, committed state may be baselined. It is spelled `worktree::status` — patch identity through `git::landing` — because `no_ancestry_decides_merged_ness` forbids a reachability verdict crate-wide, and a rebased landing is invisible to ancestry anyway. An unresolvable target refuses too: unproven is not clean. Drift reuses CLOUD-123's direction-aware counts wholesale — an increase re-raises, a decrease ratchets and surfaces only as prune staleness, zero resolves — and staleness is an ordinary Finding joined where budget and defects join, so it inherits waivers, -J, the exit contract and the store. The filter sits immediately before the waiver filter, and that order is load-bearing: waivers first would make a live entry read as unmatched. Two fail-closed holds, neither ever pruned: a rule in not_evaluated holds its entries, and an entry minted under a superseded identity_version holds rather than silently unmatching. Refs: CLOUD-67
`run_rules` is the one funnel `check` and `enforce` share, and it was already at the line bound; the filter reads better as its own function anyway, where the one thing a reader must not get wrong — that it runs BEFORE waivers, because a waiver removes a finding and would make a live entry read as unmatched — is stated at the definition rather than buried mid-funnel. Refs: CLOUD-67
… forbids `no_ancestry_decides_merged_ness` scans src/ including comments, and the paragraph explaining why reachability is forbidden spelled the vocabulary out to explain it. The gate was right: one that exempted the prose describing it would have a hole shaped exactly like a comment. Refs: CLOUD-67
perf-gate measured what the first draft cost: putting `store::resolve` on every `check` took p50 from 3.25ms to 24.93ms, a 7.7x regression on the workhorse verb — the resolution spawns git three times and may walk every store, to answer a question that is almost always "no baseline". The guard is exact rather than a heuristic: every directory `bound_dir` can name is a store directory under the state root, so if none of them carries a baseline.json there is nothing this checkout could load. One read_dir, no process spawn, and a false is a proof. It guards `load` rather than `path` because the two callers want opposite things from an empty machine: `check` wants to spend nothing finding out there is no baseline, and `save` is on its way to writing the first one. Refs: CLOUD-67
wenzowski
force-pushed
the
wenzowski/cloud-67-add-a-baseline-command-for-already-dirty-repos
branch
from
August 14, 2026 21:16
c625ffd to
91e3d9a
Compare
|
Contributor
Author
|
/fast-forward |
wenzowski
deleted the
wenzowski/cloud-67-add-a-baseline-command-for-already-dirty-repos
branch
August 14, 2026 21:28
This was referenced Aug 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Closes CLOUD-67.
Adopting Batten in an existing repository had two routes to green: fix every
pre-existing violation at once, or weaken policy. This adds the third — a
baseline, the persisted set of finding identities that already existed, so
checkstops failing on them and still fails on anything new.What keeps this inside the threat model
A baseline is a bulk waiver by another name, and the agent running it is both the
finding's subject and the store's writer — the issue's own adversarial review
ranks that the top risk. So the load-bearing part is not the filter, it is the
minting predicate: only landed, committed state may be baselined.
The Ready block asks for "an ancestor of the authoritative ref". That cannot be
written as stated —
git.rs'sno_ancestry_decides_merged_nessforbids areachability verdict crate-wide, and a rebased or squashed landing is invisible
to ancestry on a fast-forward trunk anyway. The predicate is therefore spelled as
patch identity, reusing
worktree::status(git::landingplus theuncommitted and unpushed facts). Any at-risk work refuses the mint, exit
2,writing nothing.
Unlanded::NotComputablerefuses too: unproven is not clean.The rest of the shape
run_rules, immediately before the waiver filter.The order is load-bearing in one direction: a waiver removes a finding, so
waivers first would make a live baseline entry read as unmatched.
re-raises (new evidence fails), a decrease ratchets and surfaces only as prune
staleness, zero resolves.
Finding(Scope,baseline.stale), joinedwhere
budgetanddefectsjoin, so it inherits waivers,-J, the exitcontract and the store rather than re-implementing them.
not_evaluatedholdsits entries (silence is not evidence), and an entry minted under a superseded
identity_versionholds asbaseline.version-driftinstead of silentlyunmatching — the issue's "a bump must not invalidate every adopter's baseline".
severity.rs's deferred invariant, nowlanded. Structural:
applyonly removes elements and never builds or mutates aFinding.findings/and
journal/, rather than a plainrepo_state_dirjoin like every otherstore here: it keys on finding identities, so a baseline surviving a
state adoptwould describe a store the checkout no longer owns.rule <digest12>, never a baselined line.Two things the gates caught, worth reading
no_ancestry_decides_merged_nessfailed on the module header, whichspelled the forbidden vocabulary out in order to explain it. The gate was
right; one that exempted the prose describing it would have a hole shaped
exactly like a comment.
perf-gatemeasured the first draft puttingstore::resolveon everycheck:p50 3.25ms → 24.93ms, a 7.7x regression on the workhorse verb. The guard added
for it is exact rather than a heuristic — every directory
bound_dircan nameis a store directory under the state root, so if none carries a
baseline.jsonthere is nothing to load. One
read_dir, no process spawn.Verification
mise run verifygreen (the earliersonar-gaterefusal was "not pushed yet").813 lib tests, every integration suite, 1815 bats cases,
perf-gateback withinthreshold. The e2e suite is
crates/batten/tests/baseline.rs— kept out oftests/cli.rsperwaivers.rs's stated precedent — and each refusal caseasserts the absence of the artifact as well as the exit code, because
asserting the code alone would pass for an implementation that refuses and writes
anyway.
House style §2's command tree gained the
baselinerow in the same change, whichis what
the_emitted_surface_is_exactly_the_committed_row_setexists to prompt.