fix(review): the payload decides the engine, and a tie keeps the reviewer finding

An engine's brief-conflict mark could lower a reviewer agent's MAJOR: ingest kept an engine field a reviewer wrote on its own finding, and on a severity tie the survivor depended on payload order (engine first gave ALLOW, reviewer first WARN). ingest now takes engine from the payload source; Pass 1 and the workflow dedup keep the reviewer-agent finding on a tie. Prose (coordinator Pass 1, Handover 6) follows. Decision 13, operator 12.10.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-12 18:50:56 +02:00
commit 305ac9284f
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
6 changed files with 140 additions and 12 deletions

View file

@ -321,3 +321,22 @@ test('armB brief rule — VERDICT_SCHEMA declares engine, contradicts_brief and
assert.ok(/only an engine finding/i.test(prompt), 'engine findings only');
assert.ok(/kept and marked, never removed/i.test(prompt));
});
// Decision 13 (operator 12.10): on a severity tie a reviewer-agent finding
// survives dedup over an engine finding, so the engine's mark can never lower
// what a reviewer agent asserted (the same rule as coordinator-contract Pass 1).
test('armB brief rule (15) — a tie between a reviewer MAJOR and a /code-review MAJOR keeps the reviewer: the legal shape returned with ALLOW → WARN, no engine', async () => {
const c = await floorCase({
reviewerFindings: [F('CODE_REVIEW_DEFECT', 'MAJOR')],
codeFindings: [F('CODE_REVIEW_DEFECT', 'MAJOR')],
returned: [F('CODE_REVIEW_DEFECT', 'MINOR', { contradicts_brief: MARK, brief_lowered_from: 'MAJOR', engine: 'code-review' })],
verdict: 'ALLOW',
});
assert.equal(c.merged.length, 1);
assert.equal(c.merged[0].severity, 'MAJOR');
assert.equal('engine' in c.merged[0], false, 'the tie keeps the reviewer finding');
assert.equal(c.r.verdict, 'WARN');
assert.equal(c.r.findings[0].severity, 'MAJOR');
assert.equal('engine' in c.r.findings[0], false);
checkRaise(c, true);
});