Files
brain/tools/criterion-green.test.mjs
T

64 lines
4.2 KiB
JavaScript

// tools/criterion-green.test.mjs
// 5.6 (Машина 5 Пакет 5, Блок 3): по-критерийный производитель GREEN. Эмитит подписанный
// подписантом green ТОЛЬКО при настоящем зелёном прогоне — мутация P18 как условие (сломал
// изменённый код → тест обязан покраснеть; выжил → не проверяет → не green). code_fingerprint
// (Δ2) детерминирован над содержимым изменённых файлов + тестов. Интеграция с критерий-гейтом
// из judge-orchestrator (5.5): произведённый green проходит все 4 шага на свежем отпечатке.
import { describe, it, expect } from 'vitest';
import { codeFingerprint, produceGreen } from './criterion-green.mjs';
import { verifyGreen } from './floor-signer.mjs';
import { runCriterionGate } from './judge-orchestrator.mjs';
const SK = 'producer-signer-key';
describe('codeFingerprint (5.6, Δ2): детерминированный отпечаток изменённых файлов', () => {
it('детерминирован над одним содержимым, порядок ключей не важен', () => {
const a = codeFingerprint({ 'a.mjs': 'x', 'a.test.mjs': 'y' });
const b = codeFingerprint({ 'a.test.mjs': 'y', 'a.mjs': 'x' });
expect(a).toBe(b);
expect(a).toMatch(/^[0-9a-f]{64}$/);
});
it('правка содержимого файла → другой отпечаток (green аннулируется)', () => {
expect(codeFingerprint({ 'a.mjs': 'x' })).not.toBe(codeFingerprint({ 'a.mjs': 'x2' }));
});
});
describe('produceGreen (5.6): подписанный по-критерийный GREEN; мутация P18 — условие настоящего green', () => {
it('тест прошёл И мутация убита И ключ → green:true + валидная подпись подписанта', () => {
const fp = codeFingerprint({ 'a.mjs': 'code', 'a.test.mjs': 'test' });
const rec = produceGreen({ criterion_id: 'c1', occurrence: 1, code_fingerprint: fp, coverage_of_changed: 1, testPassed: true, mutationKilled: true, signerKey: SK });
expect(rec.green).toBe(true);
expect(rec.code_fingerprint).toBe(fp);
expect(rec.coverage_of_changed).toBe(1);
expect(verifyGreen({ criterion_id: rec.criterion_id, code_fingerprint: rec.code_fingerprint, occurrence: rec.occurrence, sig: rec.sig }, SK)).toBe(true);
});
it('P18: мутация ВЫЖИЛА (тест не проверяет) → green:false, нет подписи', () => {
const rec = produceGreen({ criterion_id: 'c1', occurrence: 1, code_fingerprint: 'fp', testPassed: true, mutationKilled: false, signerKey: SK });
expect(rec.green).toBe(false);
expect(rec.reason).toBe('mutation-survived');
expect(rec.sig).toBeUndefined();
});
it('тест не прошёл → green:false', () => {
const rec = produceGreen({ criterion_id: 'c1', occurrence: 1, code_fingerprint: 'fp', testPassed: false, mutationKilled: true, signerKey: SK });
expect(rec.green).toBe(false);
expect(rec.reason).toBe('test-not-passed');
});
it('настоящий green, но нет ключа подписанта → green:false (fail-CLOSE)', () => {
const rec = produceGreen({ criterion_id: 'c1', occurrence: 1, code_fingerprint: 'fp', testPassed: true, mutationKilled: true, signerKey: undefined });
expect(rec.green).toBe(false);
expect(rec.reason).toBe('no-signer-key');
});
it('произведённый green проходит весь критерий-гейт (5.5) на свежем отпечатке', () => {
const fp = codeFingerprint({ 'a.mjs': 'code' });
const rec = produceGreen({ criterion_id: 'c1', occurrence: 1, code_fingerprint: fp, testPassed: true, mutationKilled: true, signerKey: SK });
const gate = runCriterionGate({
criteria: [{ id: 'c1' }],
greenRuns: [rec],
sealedCriterionIds: ['c1'],
currentFingerprints: { c1: fp },
signerKey: SK,
});
expect(gate.passed).toBe(true);
});
});