import test from 'node:test'; import assert from 'node:assert/strict'; import { buildReport, containsImageBytes, evaluateCase, latencyPercentiles, redactImageBytes, releaseVerdict } from '../src/release-security-gate.js'; test('latency percentiles use nearest-rank so p95 is an observed sample, not an interpolation', () => { const samples = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]; assert.deepEqual(latencyPercentiles(samples), { count: 10, p50: 50, p95: 100, max: 100 }); }); // A case is a promise the suite makes before it runs: this input must land here, and the provider // must (or must not) see exactly this many calls. The verdict is derived, never typed. const polyglot = { id: 'ingress-polyglot-html', severity: 'P0', expected: { status: 400, providerCalls: 0 }, observed: { status: 400, providerCalls: 0 }, }; test('a case whose observation matches its expectation passes', () => { assert.equal(evaluateCase(polyglot).status, 'pass'); }); test('a case that reached the provider is a failure that names the field that broke', () => { const result = evaluateCase({ ...polyglot, observed: { status: 200, providerCalls: 1 } }); assert.equal(result.status, 'fail'); assert.match(result.mismatch, /status 400 expected, observed 200/); assert.match(result.mismatch, /providerCalls 0 expected, observed 1/); }); test('a P0 failure blocks the release, and a P1 failure only holds it', () => { const leaked = { ...polyglot, observed: { status: 200, providerCalls: 1 } }; const blocked = releaseVerdict({ cases: [leaked, { ...polyglot, id: 'flood', severity: 'P1', observed: { status: 200, providerCalls: 12 } }] }); assert.equal(blocked.verdict, 'BLOCKED'); assert.deepEqual(blocked.blocking.map(item => item.id), ['ingress-polyglot-html']); assert.deepEqual(blocked.holds.map(item => item.id), ['flood']); }); test('a suite with no failures is a GO, and counts say how many cases were proven', () => { const verdict = releaseVerdict({ cases: [polyglot] }); assert.equal(verdict.verdict, 'GO'); assert.deepEqual(verdict.blocking, []); assert.equal(verdict.proven, 1); }); test('a required category that no case exercised blocks the release instead of passing by omission', () => { const deletion = { id: 'deletion-withdrawal', severity: 'P0', surface: 'out-of-surface', evidence: 'tests/training-contribution.test.js', evidenceVerified: false }; const verdict = releaseVerdict({ cases: [polyglot, deletion] }); assert.equal(verdict.verdict, 'BLOCKED'); assert.deepEqual(verdict.unproven.map(item => item.id), ['deletion-withdrawal']); }); test('coverage borrowed from another test file only counts once the runner verified that file exists', () => { const verified = { id: 'deletion-withdrawal', severity: 'P0', surface: 'out-of-surface', evidence: 'tests/training-contribution.test.js', evidenceVerified: true }; const verdict = releaseVerdict({ cases: [polyglot, verified] }); assert.equal(verdict.verdict, 'GO'); assert.deepEqual(verdict.coveredElsewhere, ['deletion-withdrawal']); }); // The report and the server log are shipped as release evidence. Neither may carry a photo. const JPEG_DATA_URI = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAABAAEBAREA/8QAFQABAQAAAAAAAAAAAAAAAAAAAAn/xAAUEAEAAAAAAAAAAAAAAAAAAAAJ/9oACAEBAAA/AKp//9k='; test('a data URI or a long base64 run is recognised as image bytes', () => { assert.equal(containsImageBytes(`posted ${JPEG_DATA_URI} to the worker`), true); assert.equal(containsImageBytes('chunk ' + 'A'.repeat(64) + 'yQ'.repeat(200)), true); }); test('ordinary log lines, hex digests, and short tokens are not image bytes', () => { assert.equal(containsImageBytes('Timmy is listening on http://127.0.0.1:4173 · vision configured · Hermes locked and ready'), false); assert.equal(containsImageBytes('sha256 ' + 'a1b2c3d4'.repeat(8)), false); assert.equal(containsImageBytes('case ingress-polyglot-html observed status 200'), false); }); test('redaction removes the bytes and keeps the sentence around them honest', () => { const redacted = redactImageBytes(`provider received ${JPEG_DATA_URI} at 12:01`); assert.equal(containsImageBytes(redacted), false); assert.match(redacted, /\[redacted image bytes\]/); assert.match(redacted, /^provider received .* at 12:01$/); }); test('the report carries the verdict, the target it ran against, and the measured load numbers', () => { const report = buildReport({ generatedAt: '2026-10-30T10:48:00.000Z', target: { baseUrl: 'http://127.0.0.1:4173', provider: 'stub counting worker' }, cases: [polyglot], load: { requests: 8, errors: 0, abstentions: 8, p50: 12, p95: 40, max: 40 }, }); assert.equal(report.schema, 'timmy-rc-security-attack/1'); assert.equal(report.verdict, 'GO'); assert.equal(report.generatedAt, '2026-10-30T10:48:00.000Z'); assert.equal(report.target.provider, 'stub counting worker'); assert.equal(report.load.p95, 40); assert.equal(containsImageBytes(JSON.stringify(report)), false); }); test('a case that quotes a response body cannot smuggle the photo into the report', () => { const report = buildReport({ generatedAt: '2026-10-30T10:48:00.000Z', target: { baseUrl: 'http://127.0.0.1:4173', provider: 'stub' }, cases: [{ ...polyglot, observed: { status: 400, providerCalls: 0 }, snippet: `refused ${JPEG_DATA_URI}` }], load: null, }); assert.equal(containsImageBytes(JSON.stringify(report)), false); assert.match(JSON.stringify(report), /redacted image bytes/); });