fix(review): original_severity names what the kept finding asserted

Review finding 08deae68.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-14 11:09:01 +02:00
commit 9529df7665
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
2 changed files with 93 additions and 6 deletions

View file

@ -611,3 +611,66 @@ test('own property — toReviewerPayload refuses engine toString with the "engin
assert.equal(r.errors.length, 1);
assert.match(r.errors[0], /^engine must be one of code-review\|security-review, got "toString"$/);
});
// ---- original_severity names what the kept finding asserted (review 08deae68) --
//
// Pass 1 writes the survivor at its group's highest asserted severity. When
// Pass 3 then resets it to the catalogue tier, `original_severity` must name
// what the kept finding itself asserted, never the severity a duplicate lent
// it. The Pass-1 bookkeeping never leaves the contract.
// A reviewer copy at `reviewerSeverity` and an engine CODE_REVIEW_DEFECT at
// `engineSeverity` on one triplet, in `order`.
function reviewerAndEngine(order, reviewerSeverity, engineSeverity, reviewerExtra = {}) {
const reviewerPayload = { reviewer: 'code-correctness-reviewer', findings: [reviewerCopy({ severity: reviewerSeverity, ...reviewerExtra })] };
const enginePayload = { reviewer: 'claude-code-review', findings: [codeReviewDefect({ severity: engineSeverity })] };
return order === 'reviewer first' ? [reviewerPayload, enginePayload] : [enginePayload, reviewerPayload];
}
function assertNoPass1Field(result) {
for (const f of [...result.findings, ...result.suppressed, ...result.unverified]) {
assert.equal('pass1_raised_from' in f, false, `pass1_raised_from leaked: ${JSON.stringify(f)}`);
}
assert.equal(JSON.stringify(result).includes('pass1_raised_from'), false,
'no part of the result carries pass1_raised_from');
}
for (const order of ['reviewer first', 'engine first']) {
test(`08deae68 — a reviewer MAJOR raised by an engine BLOCKER ends at MAJOR with no original_severity (${order}) → WARN`, () => {
const result = m.runContract(reviewerAndEngine(order, 'MAJOR', 'BLOCKER'));
assert.equal(result.findings.length, 1);
const out = result.findings[0];
assert.equal('engine' in out, false, 'the survivor is the reviewer finding');
assert.equal(out.severity, 'MAJOR', 'the catalogue tier of CODE_REVIEW_DEFECT');
assert.equal('original_severity' in out, false,
'the kept finding asserted MAJOR, its tier; the BLOCKER was the engine duplicate\'s');
assert.equal(result.verdict, 'WARN');
assertAllOutputLegal(result);
assertNoPass1Field(result);
});
test(`08deae68 — a reviewer MINOR raised by an engine MAJOR ends at MAJOR with original_severity MINOR (${order})`, () => {
const result = m.runContract(reviewerAndEngine(order, 'MINOR', 'MAJOR'));
assert.equal(result.findings.length, 1);
const out = result.findings[0];
assert.equal('engine' in out, false, 'the survivor is the reviewer finding');
assert.equal(out.severity, 'MAJOR');
assert.equal(out.original_severity, 'MINOR', 'the kept finding itself asserted MINOR');
assert.equal(result.verdict, 'WARN');
assertAllOutputLegal(result);
assertNoPass1Field(result);
});
test(`08deae68 — a raised survivor set aside by Pass 2 (empty recommended_action) carries no pass1_raised_from (${order})`, () => {
const result = m.runContract(reviewerAndEngine(order, 'MAJOR', 'BLOCKER', { recommended_action: '' }));
assert.equal(result.findings.length, 0);
assert.equal(result.unverified.length, 1);
const u = result.unverified[0];
assert.equal(u.suppressed_reason, 'actionability:empty');
assert.equal(u.reviewer, 'code-correctness-reviewer', 'the raised survivor is the reviewer finding');
assert.equal(u.severity, 'BLOCKER', 'Pass 1 raised it to its group\'s severity');
assert.equal(result.suppressed.length, 1);
assert.equal(result.verdict, 'WARN');
assertNoPass1Field(result);
});
}