fix(review): plan dedup keeps a lowered_from that is not a severity, so rule B counts it as blocker

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-16 16:36:38 +02:00
commit f70aed5d47
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
2 changed files with 39 additions and 3 deletions

View file

@ -1077,3 +1077,36 @@ test('28: the clauses with short texts (fewer than 6 content words): at its plac
assert.equal(hit[0].severity, 'major');
}
});
// ---- 29 ------------------------------------------------------------------------
test('29: a lowered_from that is not a severity reaches the gate and counts as blocker; a blank one is no lowering', () => {
const p0 = buildPlan();
const TEXT = 'Run one never states what it prints when the input file is missing';
const one = extra => [f('minor', at(p0, S1_CHANGES), TEXT, { caught_by: 'tests/mod1.test.mjs', ...extra })];
for (const bad of ['high', 'critical', 3, true]) {
const d = dd({ pc: one({ lowered_from: bad }) });
assert.equal(d.findings.length, 1);
assert.equal(d.findings[0].lowered_from, bad, `dedup keeps lowered_from ${JSON.stringify(bad)} as given`);
const r1 = rec(p0, d);
const v = r1.verdict;
const g0 = byText(v, TEXT);
assert.equal(g0.severity, 'blocker', `lowered_from ${JSON.stringify(bad)} counts as blocker`);
assert.equal(g0.lowering_refused, 'rule B: lowered_from is not a severity; counted as blocker');
assert.equal(v.verdict, 'BLOCK');
const g = gatePlan(r1.text);
assert.equal(g.code, 1);
assert.ok(g.reasons.some(x => x.code === 'PLAN_GATE_OPEN_BLOCKER'), JSON.stringify(g.reasons));
}
for (const blank of ['', ' ']) {
const d = dd({ pc: one({ lowered_from: blank }) });
assert.equal(d.findings.length, 1);
assert.equal('lowered_from' in d.findings[0], false, `a blank lowered_from ${JSON.stringify(blank)} leaves no key`);
const v = rec(p0, d).verdict;
const g0 = byText(v, TEXT);
assert.equal(g0.severity, 'minor');
assert.equal(g0.lowering_refused, undefined);
}
});