test(red-proof): the two regression guards that pass at be0b631 get their own mutation ids

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-26 20:18:23 +01:00
commit 76f74793e9
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
6 changed files with 34 additions and 9 deletions

View file

@ -34,7 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
### Fixed
Fix round 4.5b (decisions 80 to 87): the round's 39 findings, from the 4.5a review and its execution and three the operator added. Each is fixed, and each has a test seen failing first: on the code at the round's start point (`be0b631`), or, for the 12 ids whose code was already right or lives under `tests/`, under a named mutation (`tests/fix-round-4-5b-red.sh` proves both).
Fix round 4.5b (decisions 80 to 87): the round's 39 findings, from the 4.5a review and its execution and three the operator added, proven by 41 test ids. Each is fixed, and each has a test seen failing first: on the code at the round's start point (`be0b631`), or, for the 14 ids whose code was already right or lives under `tests/`, under a named mutation (`tests/fix-round-4-5b-red.sh` proves both).
**Verdict gate**

View file

@ -234,4 +234,28 @@ run_tagged "$TMP/base.jsonl" --test-timeout=300000 --test-force-exit $PATS`,
},
],
},
{
key: 'M7r',
id: 'M7r',
what: 'a HEAD read that fails (exit 128, as on an unborn HEAD) counts as in HEAD, so nothing is parked',
spans: [
{
file: 'lib/util/park-attempt-files.mjs',
find: 'return r.status === 0;',
replace: 'return r.status === 0 || r.status === 128;',
},
],
},
{
key: 'DJ4r',
id: 'DJ4r',
what: 'the lesson write returns when the lessons directory is missing, so the first lesson is never written',
spans: [
{
file: 'lib/review/recurrence.mjs',
find: 'mkdirSync(dirname(path), { recursive: true });',
replace: 'if (!existsSync(dirname(path))) return;',
},
],
},
];

View file

@ -6,7 +6,7 @@
# at the round's start point be0b631, or, for an id a mutation names, under
# that mutation.
# This wrapper passes the shared script:
# --base BASE, --ids IDS (the round's 39 ids), the round's FILES;
# --base BASE, --ids IDS (the round's 41 ids), the round's FILES;
# --other-ids: the ids of fix round 4-5a, read with sed from the IDS= line
# of tests/fix-round-4-5a-red.sh (a tag on that list is not judged);
# --mutations tests/fix-round-4-5b-mutations.mjs (its ids are pass-ids at
@ -28,7 +28,7 @@ cd "$(dirname "$0")/.." || { echo "red script: setup failure: cannot cd to the r
ROOT="$(pwd -P)"
BASE=be0b631fed21942b6c0fdae570b58e4112f8242d
IDS='M6 M11 M4 m4 M3 M7 E22c E22e M5 S3 E20 M9 M2 K3 M1 M1r E23a E23b E23d E23f M8 M10 DJ5 M13 K2 DJ1 DJ2 DJ4 E14 E16a E17a E17b E18a Da Db K4 ARG PTR RS'
IDS='M6 M11 M4 m4 M3 M7 M7r E22c E22e M5 S3 E20 M9 M2 K3 M1 M1r E23a E23b E23d E23f M8 M10 DJ5 M13 K2 DJ1 DJ2 DJ4 DJ4r E14 E16a E17a E17b E18a Da Db K4 ARG PTR RS'
FILES='tests/lib/verdict-gate.test.mjs tests/lib/done-line.test.mjs tests/lib/park-attempt-files.test.mjs tests/scripts/trekreview-armb-workflow.test.mjs tests/lib/coordinator-contract.test.mjs tests/lib/red-judge.test.mjs tests/lib/red-script.test.mjs tests/lib/review-recurrence.test.mjs tests/lib/arg-parser.test.mjs tests/commands/trekendsession.test.mjs tests/validators/next-session-prompt-validator.test.mjs tests/lib/fix-round-4-5b-prose.test.mjs tests/lib/fix-round-4-5a-prose.test.mjs tests/scripts/release-check.test.mjs'
OTHER=$(sed -n "s/^IDS='\(.*\)'\$/\1/p" "$ROOT/tests/fix-round-4-5a-red.sh")

View file

@ -467,7 +467,7 @@ test('[M7] a corrupt branch ref is a failed HEAD read: exit 2, nothing unindexed
}
});
test('[M7] an unborn HEAD parks the attempt\'s files', () => {
test('[M7r] an unborn HEAD parks the attempt\'s files', () => {
const dir = mkdtempSync(join(tmpdir(), 'voyage-park-unborn-'));
try {
git(dir, 'init', '-q');

View file

@ -366,8 +366,8 @@ const WRAP_B = {
'tests/commands/trekendsession.test.mjs', 'tests/validators/next-session-prompt-validator.test.mjs',
'tests/lib/fix-round-4-5b-prose.test.mjs', 'tests/lib/fix-round-4-5a-prose.test.mjs', 'tests/scripts/release-check.test.mjs'],
};
const IDS_B = ['M6', 'M11', 'M4', 'm4', 'M3', 'M7', 'E22c', 'E22e', 'M5', 'S3', 'E20', 'M9', 'M2', 'K3', 'M1', 'M1r', 'E23a',
'E23b', 'E23d', 'E23f', 'M8', 'M10', 'DJ5', 'M13', 'K2', 'DJ1', 'DJ2', 'DJ4', 'E14', 'E16a', 'E17a', 'E17b', 'E18a', 'Da',
const IDS_B = ['M6', 'M11', 'M4', 'm4', 'M3', 'M7', 'M7r', 'E22c', 'E22e', 'M5', 'S3', 'E20', 'M9', 'M2', 'K3', 'M1', 'M1r', 'E23a',
'E23b', 'E23d', 'E23f', 'M8', 'M10', 'DJ5', 'M13', 'K2', 'DJ1', 'DJ2', 'DJ4', 'DJ4r', 'E14', 'E16a', 'E17a', 'E17b', 'E18a', 'Da',
'Db', 'K4', 'ARG', 'PTR', 'RS'];
/** A wrapper's text; asserts first that it exists. */
@ -475,9 +475,9 @@ test('[RS] each wrapper reads the other round\'s ids from its IDS line, no copie
}
});
test('[RS] the 4.5b IDS line holds exactly the 39 ids', () => {
test('[RS] the 4.5b IDS line holds exactly the 41 ids', () => {
const ids = quotedList(wrapperText(WRAP_B), 'IDS', WRAP_B.rel);
assert.equal(IDS_B.length, 39, 'control: the expected list is not 39 ids');
assert.equal(IDS_B.length, 41, 'control: the expected list is not 41 ids');
assert.deepEqual(ids, IDS_B);
assert.equal(new Set(ids).size, ids.length, 'an id is on the 4.5b IDS= line twice');
});

View file

@ -446,7 +446,7 @@ test('[DJ4] sibling: a symlinked .claude directory pointing outside the repo get
}
});
test('[DJ4] sibling: the first lesson creates the missing lessons directory, one level after its parent, and is written', () => {
test('[DJ4r] the first lesson creates the missing lessons directory, one level after its parent, and is written', () => {
const repo = repoWith([
{ slug: 'one', sha: 'aaa', findings: [finding('a1', 'MISSING_TEST')] },
{ slug: 'two', sha: 'bbb', findings: [finding('b1', 'MISSING_TEST')] },
@ -455,6 +455,7 @@ test('[DJ4] sibling: the first lesson creates the missing lessons directory, one
assert.ok(!existsSync(join(repo, '.claude', 'rules')), 'fixture: no .claude/rules yet');
const r = mod.applyLesson(repo, 'MISSING_TEST');
assert.equal(r.written, true, JSON.stringify(r));
assert.ok(existsSync(join(repo, '.claude', 'rules', mod.LESSONS_FILE_NAME)), 'the first lesson is not written');
assert.ok(lstatSync(join(repo, '.claude', 'rules')).isDirectory(), '.claude/rules is created as a directory');
assert.match(readFileSync(join(repo, '.claude', 'rules', mod.LESSONS_FILE_NAME), 'utf-8'), /MISSING_TEST/);
} finally { rmSync(repo, { recursive: true, force: true }); }