import { test } from 'node:test'; import assert from 'node:assert/strict'; import { validateQueue, ENTRY_CLASSES, ENTRY_STATES } from '../../scripts/kb-eval/lib/g7-queue.mjs'; // A queue entry is the ONLY thing standing between a real defect and silent loss, // so the checks here are deliberately unforgiving about shape and about anchors // that no longer exist in the corpus. const okEntry = () => ({ id: 'idx-99', file: 'skills/x/references/y.md', class: 'multi-locator', status: 'open', raised: '2026-08-03', summary: 'Something the file asserts in two places.', evidence: 'docs/r11-pilot-results.md §9.6', anchors: ['the exact text'], }); const stub = (contents) => (p) => { if (!(p in contents)) throw new Error(`ENOENT ${p}`); return contents[p]; }; test('a well-formed open entry whose anchor is present passes', () => { const r = validateQueue([okEntry()], stub({ 'skills/x/references/y.md': 'aaa the exact text bbb' })); assert.equal(r.ok, true); assert.deepEqual(r.findings, []); }); test('vocabularies are closed', () => { assert.deepEqual([...ENTRY_CLASSES].sort(), ['multi-locator', 'replacement']); assert.deepEqual([...ENTRY_STATES].sort(), ['open', 'resolved']); }); test('unknown class is rejected', () => { const e = { ...okEntry(), class: 'deletion' }; const r = validateQueue([e], stub({ 'skills/x/references/y.md': 'the exact text' })); assert.equal(r.ok, false); assert.match(r.findings[0].message, /class/); }); test('unknown status is rejected', () => { const e = { ...okEntry(), status: 'wontfix' }; const r = validateQueue([e], stub({ 'skills/x/references/y.md': 'the exact text' })); assert.equal(r.ok, false); assert.match(r.findings[0].message, /status/); }); test('a missing required field is reported by name', () => { const e = okEntry(); delete e.evidence; const r = validateQueue([e], stub({ 'skills/x/references/y.md': 'the exact text' })); assert.equal(r.ok, false); assert.match(r.findings[0].message, /evidence/); }); test('an open entry MUST carry at least one anchor', () => { const e = { ...okEntry(), anchors: [] }; const r = validateQueue([e], stub({ 'skills/x/references/y.md': 'the exact text' })); assert.equal(r.ok, false); assert.match(r.findings[0].message, /anchor/i); }); // The point of the whole mechanism: a defect must not be able to leave the queue // just because someone edited the file around it. test('an open entry whose anchor no longer occurs is a DRIFT finding, not a pass', () => { const r = validateQueue([okEntry()], stub({ 'skills/x/references/y.md': 'nothing matching here' })); assert.equal(r.ok, false); assert.equal(r.findings[0].kind, 'anchor_drift'); assert.match(r.findings[0].message, /the exact text/); }); test('every anchor is checked, not just the first', () => { const e = { ...okEntry(), anchors: ['present', 'absent'] }; const r = validateQueue([e], stub({ 'skills/x/references/y.md': 'present only' })); assert.equal(r.ok, false); assert.equal(r.findings.length, 1); assert.match(r.findings[0].message, /absent/); }); test('a missing file is reported rather than thrown', () => { const r = validateQueue([okEntry()], stub({})); assert.equal(r.ok, false); assert.equal(r.findings[0].kind, 'file_unreadable'); }); test('a resolved entry MUST record how it was resolved', () => { const e = { ...okEntry(), status: 'resolved' }; const r = validateQueue([e], stub({ 'skills/x/references/y.md': 'whatever' })); assert.equal(r.ok, false); assert.match(r.findings[0].message, /resolution/); }); test('a resolved entry is exempt from anchor checking', () => { const e = { ...okEntry(), status: 'resolved', resolution: 'colon -> period, ratified 2026-08-03' }; const r = validateQueue([e], stub({ 'skills/x/references/y.md': 'anchor is long gone' })); assert.equal(r.ok, true); }); test('duplicate ids are rejected', () => { const r = validateQueue([okEntry(), okEntry()], stub({ 'skills/x/references/y.md': 'the exact text' })); assert.equal(r.ok, false); assert.match(r.findings[0].message, /duplicate/i); }); test('findings from several entries are all reported', () => { const a = { ...okEntry(), id: 'idx-1' }; const b = { ...okEntry(), id: 'idx-2', anchors: ['gone'] }; const r = validateQueue([a, b], stub({ 'skills/x/references/y.md': 'the exact text' })); assert.equal(r.ok, false); assert.equal(r.findings.length, 1); assert.equal(r.findings[0].id, 'idx-2'); }); test('a non-array queue is rejected without throwing', () => { const r = validateQueue({ entries: [] }, stub({})); assert.equal(r.ok, false); assert.match(r.findings[0].message, /array/i); }); // A class-wide entry books ONE finding that lives in many files. Booking it as a // single-file entry was measured to hide 41 of 42 locators from the gate — the // 795d494 failure, a locator alive only in prose while both gates go green. So an // anchor may also be a { file, text } pair, checked against ITS OWN file. test('a { file, text } anchor is checked against its own file, not entry.file', () => { const e = { ...okEntry(), anchors: [{ file: 'skills/x/references/other.md', text: 'over here' }] }; const r = validateQueue( [e], stub({ 'skills/x/references/y.md': 'nothing matching', 'skills/x/references/other.md': 'aaa over here bbb' }), ); assert.equal(r.ok, true); assert.deepEqual(r.findings, []); }); test('a { file, text } anchor absent from its own file DRIFTS, and the finding names that file', () => { const e = { ...okEntry(), anchors: [{ file: 'skills/x/references/other.md', text: 'over here' }] }; const r = validateQueue( [e], stub({ 'skills/x/references/y.md': 'over here', 'skills/x/references/other.md': 'empty' }), ); assert.equal(r.ok, false); assert.equal(r.findings[0].kind, 'anchor_drift'); assert.match(r.findings[0].message, /other\.md/); // Discriminating: entry.file DOES contain the text, so a message blaming y.md // would mean the anchor was looked up in the wrong file. Without this line the // test passes against the old code, which serialises the object into the // message and matches /other\.md/ by accident. assert.doesNotMatch(r.findings[0].message, /y\.md/); }); test('string and { file, text } anchors mix in one entry, and BOTH are checked', () => { const e = { ...okEntry(), anchors: ['the exact text', { file: 'skills/x/references/other.md', text: 'gone' }] }; const r = validateQueue( [e], stub({ 'skills/x/references/y.md': 'the exact text', 'skills/x/references/other.md': 'not it' }), ); assert.equal(r.ok, false); assert.equal(r.findings.length, 1); assert.match(r.findings[0].message, /gone/); // Discriminating, for the same reason: the surviving string anchor is present // in entry.file, so the drift must be reported against other.md. assert.match(r.findings[0].message, /other\.md/); assert.doesNotMatch(r.findings[0].message, /y\.md/); }); test('an unreadable per-anchor file is reported, not thrown, and names that file', () => { const e = { ...okEntry(), anchors: [{ file: 'skills/x/references/missing.md', text: 'whatever' }] }; const r = validateQueue([e], stub({ 'skills/x/references/y.md': 'the exact text' })); assert.equal(r.ok, false); assert.equal(r.findings[0].kind, 'file_unreadable'); assert.match(r.findings[0].message, /missing\.md/); }); // Without this, a typo'd anchor object would be checked against nothing and the // entry would pass — a defect leaving the programme unnoticed, which is the one // outcome the queue exists to prevent. test('a malformed anchor object is a schema fault, never a silent pass', () => { const e = { ...okEntry(), anchors: [{ file: 'skills/x/references/other.md' }] }; const r = validateQueue([e], stub({ 'skills/x/references/y.md': 'x', 'skills/x/references/other.md': 'x' })); assert.equal(r.ok, false); assert.equal(r.findings[0].kind, 'schema'); assert.match(r.findings[0].message, /anchor/i); }); test('the real queue file validates against the live corpus', async () => { const { readFileSync } = await import('node:fs'); const queue = JSON.parse(readFileSync('scripts/kb-eval/data/g7-review-queue.json', 'utf8')); const r = validateQueue(queue.entries, (p) => readFileSync(p, 'utf8')); assert.deepEqual(r.findings, [], `G7 queue drifted: ${JSON.stringify(r.findings, null, 2)}`); assert.equal(r.ok, true); });