audit: testsAfter is 84, and the record now names the tree it holds at - #118
Conversation
`summary.testsAfter` read 102, a test count no tree in the range the record covers has ever had. It is 84, the count at `ae21818` — the merge of #39, the last of the three coverage PRs the record lists. The record now carries `testsAfterCommit` alongside `commit`, so the after- campaign counts name the tree they hold at and can be checked against it. `commit` remains the tree the scan ran against and `testsBefore` is measured at. Field name and position match the shared-schema change proposed in rainlanguage/adversarial-mutation-test#23. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 42 minutes Limit details: You’ve used all 1 included review currently available under your plan. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes #86
audit/mutation-test-scans.jsonclaimedsummary.testsAfter: 102. No tree inthe range the record covers has ever had 102 tests, and the record carried no
field naming the tree the count was supposed to hold at — so the number could
not be checked against anything.
Two changes, both to the one record:
summary.testsAfter:102→84."testsAfterCommit": "ae21818a51d1b8c7df14d8c32eb39521e9c1a146",placed immediately after
commit.ae21818is the merge of #39, the last of the threecoveragePrsthe recorditself lists (#36, #37, #39). It is the tree on which the campaign's whole
output had landed, so it is the tree every after number in
summaryismeasured at.
commit(c72eb89) stays what it is: the tree the scan ranagainst, and the tree
testsBeforeis measured at.Re-derived from scratch, not taken from the issue
The issue's numbers were re-derived independently before being used, by
counting
function test…declarations across everytest/**/*.t.solat everycommit from
c72eb89toHEAD:102 occurs nowhere in the range.
Declaration counting is only a proxy for what
forge testruns, so the threeloadbearing values were then re-measured with
forge test --list --json, whichis the actual oracle — a worktree per SHA, deps installed, the run's own count:
forge test --listc72eb89commitae21818935c725HEADat time of writingforge test --listagrees with the declaration count at all three, and everytest function at both
ae21818andHEADisexternal, so there is nointernal/privatedeclaration inflating either figure.9matches therecord's existing
testsBefore, which independently confirms the record'scommitfield is the before-tree it claims to be.Where the issue's proposed fix was corrected
The issue proposed
"testsAfterCommit": "ae21818"— a 7-character prefix. Thislands the full 40-character SHA instead, matching the existing
commitfield in the same record and the "exact SHA" wording in the tool's README. A
short prefix is a weaker anchor than a full SHA and grows ambiguous as history
grows, which is the same class of defect the field exists to close.
Field name and position are deliberately identical to what
rainlanguage/adversarial-mutation-test#23 proposes for the shared schema
(top-level, immediately after
commit), so this record already conforms whenthat lands. That issue is still open with no PR against it as of this writing.
Decision: no CI validator in this repo, and its ledger
The obvious next step is a CI check that re-counts the two trees and fails when
the ledger disagrees. This PR deliberately does not add one.
run below as this PR's own harness.
fetch-depth: 0plus twoextra full
forgebuilds of historical trees on every CI run. Worse, thosetrees are frozen while solc/foundry/deps move underneath them, so the check
reds
mainthe first time an old tree stops building — for a reason that hasnothing to do with whether the ledger is right.
tool already knows the SHA it measured at, and expensive and rotting at read
time. That is the tool's job, which is what
Scan record schema has no field naming the tree its after-campaign counts describe, so testsAfter is unfalsifiable in place adversarial-mutation-test#23 is for. Vendoring a per-repo
validator into one consumer would leave the next repo's ledger just as
unfalsifiable.
The correction landed here is a data fix; the enforcement that stops it
recurring is upstream, and this record is now shaped so that upstream check can
run against it.
QA
audit/mutation-test-scans.json(reads the record's owncommit/testsAfterCommit, countsforge test --list --jsonat each named tree,compares to
testsBefore/testsAfter) — fails on base withFAIL testsAfter: ledger claims 102 but names no commit -- unfalsifiable,exit 1, verified by running it against
git show origin/main:audit/mutation-test-scans.jsonbefore the fix and against the fixed file after (exit 0). Not committed to the
repo; see the decision and its ledger above.
"testsAfter": 84→102→ harness FAILs(
at ae21818… = 84, ledger says 102, exit 1);"testsAfterCommit"→a003022→ harness FAILs (at a003022 = 42, ledger says 84, exit 1);"testsAfterCommit"line deleted → harness FAILs (claims 84 but names no commit -- unfalsifiable, exit 1). All three killed; each run printed realper-tree counts first, proving it reached
forgerather than short-circuiting.forge test --list --jsonat each SHA in a fresh worktree — therunner's own enumeration, independent of the ledger and of any
grepoversources. Cross-checked against
function test…declaration counts at everycommit from
c72eb89to HEAD (agreement at all three loadbearing trees:9 / 84 / 134), and against the fact that every test function at
ae21818andHEAD is
external.testsAfter, and add a field naming the tree it holds at. Both covered.The issue's second half (the shared schema in
Scan record schema has no field naming the tree its after-campaign counts describe, so testsAfter is unfalsifiable in place adversarial-mutation-test#23) is explicitly not this repo's to
land; the field name and position here are chosen to match it.
The record is data, not Solidity, so the reproducing "test" is a harness that
reads the ledger's own commit fields, counts what
forge test --listreports ateach named tree, and compares. It was run against the pre-fix ledger (red)
before the fix, then against the fixed ledger (green), then against three
mutants.
RED — harness against
origin/main's ledger, before the fix:GREEN — same harness against the ledger as this PR lands it:
Mutation matrix — each mutant is a single-value break of exactly what this
PR changed. Every run printed a real
forge test --listcount for both treesfirst, which is the proof the harness actually ran rather than short-circuiting;
a harness that never reached a tree could not have printed
= 9and= 84.testsAfter84→102(the original wrong value)FAIL testsAfter: forge test --list at ae21818… = 84, ledger says 102, exit 1testsAfterCommit→a003022(merge of #37, a real commit in the same range)FAIL testsAfter: forge test --list at a003022 = 42, ledger says 84, exit 1testsAfterCommitline deletedFAIL testsAfter: ledger claims 84 but names no commit -- unfalsifiable, exit 1M2 is the mutant that proves the new field is load-bearing rather than
decorative: point it at a different real tree in the same range and the count
stops matching.
Full suite and formatter, in the flake shell, run on the merge commit
e768b2c(origin/mainmerged in, not rebased) so semantic conflicts outsidethe diff markers are covered:
(133, not the 134 measured for the table above: #97 landed on
mainbetweenthe two runs and deleted a longhand duplicate of
assertRejected. The 134 inthe table is
935c725, the tree the counts were taken at.)No Solidity changed in this PR, so the suite is a regression guard rather than
the fix's own evidence; the fix's evidence is the RED/GREEN pair and the
mutation matrix above.