fix(ci): fail closed on newest full release proof (#656)

Issue: #656
User-Visible: no
This commit is contained in:
Sergey Matyunin
2026-09-26 10:02:40 +03:00
parent 9287f798b3
commit 43fab645b0
9 changed files with 59 additions and 21 deletions
+3 -3
View File
@@ -126,7 +126,7 @@ test('#541 AC: one state machine gives review, merge and release the same termin
}
});
test('#541 AC: full red followed by light green still blocks release; a later full green refreshes it', () => {
test('#656 AC: newest compatible full proof decides; light proofs do not', () => {
const redFull = proofFixture({ id: 20, conclusion: 'failure' });
const lightGreen = proofFixture({ id: 21, full: false, backend: false, integration: false });
const red = evaluateCiProof({ ...redFull, policy: CI_PROOF_POLICIES.release });
@@ -135,8 +135,8 @@ test('#541 AC: full red followed by light green still blocks release; a later fu
assert.equal(selectCiProofVerdict([light, red]).status, 'failed');
const newerFull = evaluateCiProof({ ...proofFixture({ id: 22 }), policy: CI_PROOF_POLICIES.release });
assert.equal(selectCiProofVerdict([newerFull, light, red]).status, 'green');
assert.equal(selectCiProofVerdict([red, newerFull]).status, 'green',
'#619: a failed duplicate cannot hide a complete green proof for the same candidate');
assert.equal(selectCiProofVerdict([red, newerFull]).status, 'failed',
'#656: a newer failed full run must block an older green proof for the same candidate');
});
test('#601 AC3: release policy accepts a full proof without requested mutants; light stays stale; review/merge still demand them', () => {
+3
View File
@@ -32,6 +32,9 @@ test('full performance is isolated to stable, scheduled and manual entry points'
'name: Полные бенчмарки производительности',
'branches:',
'- main',
'paths-ignore:',
'- ".github/workflows/**"',
'- "docs/**"',
'schedule:',
'workflow_dispatch:',
'Capture base and candidate profile',
+17 -4
View File
@@ -93,6 +93,18 @@ test('#541: release skips a newer light proof but does not let it hide an older
assert.equal(verdict.url, 'https://run/10');
});
test('#656: a newer failed light proof cannot hide an older compatible green proof', async () => {
const older = proofContext({ id: 10 });
const newer = proofContext({ id: 11, full: false, conclusion: 'failure' });
const contexts = new Map([[10, older.context], [11, newer.context]]);
const verdict = await classifyValidateProofs({
runs: [older.run, newer.run], repo: 'x/y', sha: SHA, tree: TREE, token: 'x',
loadContext: async (run) => contexts.get(run.databaseId),
});
assert.equal(verdict.status, 'green');
assert.equal(verdict.url, 'https://run/10');
});
test('#541: a later complete full proof refreshes an older red release candidate', async () => {
const older = proofContext({ id: 10, conclusion: 'failure' });
const newer = proofContext({ id: 12 });
@@ -105,7 +117,7 @@ test('#541: a later complete full proof refreshes an older red release candidate
assert.equal(verdict.url, 'https://run/12');
});
test('#619: any complete green proof on the exact SHA survives a newer failed duplicate', async () => {
test('#656: a newer failed full proof blocks an older green proof on the exact SHA', async () => {
const older = proofContext({ id: 13 });
const newer = proofContext({ id: 14, conclusion: 'failure' });
const contexts = new Map([[13, older.context], [14, newer.context]]);
@@ -113,8 +125,8 @@ test('#619: any complete green proof on the exact SHA survives a newer failed du
runs: [newer.run, older.run], repo: 'x/y', sha: SHA, tree: TREE, token: 'x',
loadContext: async (run) => contexts.get(run.databaseId),
});
assert.equal(verdict.status, 'green');
assert.equal(verdict.url, 'https://run/13');
assert.equal(verdict.status, 'failed');
assert.equal(verdict.url, 'https://run/14');
});
test('release gate can target the dedicated exact-SHA performance workflow', () => {
@@ -127,7 +139,8 @@ test('release gate can target the dedicated exact-SHA performance workflow', ()
test('#541: the release documents describe proof semantics', () => {
const development = readFileSync(new URL('../docs/DEVELOPMENT.md', import.meta.url), 'utf8');
assert.match(development, /requires a complete Validate proof for its SHA and\nGit tree/);
assert.match(development, /Any complete green full proof on the exact SHA\n\s*is sufficient/);
assert.match(development, /The newest compatible full run is the verdict/);
assert.match(development, /a later failed full run blocks an older green proof/);
assert.match(development, /Review, merge and release use the\nsame `missing` \/ `pending` \/ `cancelled` \/ `stale` \/ `failed` state machine/);
const performance = readFileSync(new URL('../demo/performance/README.md', import.meta.url), 'utf8');
assert.match(performance, /latest\nnon-cancelled run on the SHA/);