ms-ai-architect/scripts/kb-eval/check-g7-queue.mjs
Kjell Tore Guttormsen 59c6c280b1 feat(ms-ai-architect): G7 lukket som mekanisme — navngitt review-kø (form b), valgt på måling
Operatør-ratifisert 2026-08-03. G7 var gapet for korreksjoner som er RIKTIGE
men større enn O2-konvolutten (én lokator + kun-sletting). Uten eier falt de
stille ut: O2-triagen avviser dem, O3 dekker dem ikke, og review-sporet hadde
ingen inngangskø.

Formvalget ble tatt på §9.6-målingen, ikke på preferanse:
- 2 av 4 anvendte subtraksjoner etterlot en rest -> rester er delete-only-
  konvoluttens NORMALE biprodukt, ikke et unntak.
- 2 av 5 medlemmer (idx 17, 33) er ERSTATNINGER, ikke fler-lokator. En
  delete-orientert O4-klasse med egen retur-kontrakt ville ikke fikset dem —
  altså feil dimensjonert mot evidensen. Køen absorberer begge klasser.

Artefakter (TDD, test-først):
- data/g7-review-queue.json — 6 entries, tracked
- lib/g7-queue.mjs — validateQueue, lukkede vokabular
- check-g7-queue.mjs — exit 1 ved drift eller skjemafeil
- tests/kb-eval/test-g7-queue.test.mjs — 15 tester

Kontrakten: ankere er ORDRETTE strenger, aldri linjenummer (line != real_line
i 9 av 17 R11-records). En åpen entry hvis anker slutter å matche gir
anchor_drift og exit 1 — den kan ikke falle stille ut, som er hele hensikten.
En resolved entry MÅ føre resolution, ellers er "resolved" ikke til å skille
fra "stille droppet". Ingenting i køen er maskin-anvendbart per definisjon.

Innhold: 5 åpne (26, 27, 33, 36, 18), 1 lukket (17). idx 27 kom hit ved å
falle ut av O2 på cond 3; idx 26 ved operatørens avvisning av delvis fiks.

Suite 1047/1047. [skip-docs]
2026-08-03 21:10:00 +02:00

64 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
/**
* Check the G7 review queue against the live corpus.
*
* Exit 0 = every open entry still anchors to real text; exit 1 = drift or a
* schema fault. Drift is a finding, never a silent pass: an entry that stops
* matching is exactly the case G7 exists to prevent — a real defect leaving the
* programme unnoticed because someone edited around it.
*
* Read-only. Nothing in the queue is machine-appliable; resolution is a human
* review act (form b, ratified 2026-08-03).
*
* node scripts/kb-eval/check-g7-queue.mjs [--json]
*/
import { readFileSync } from 'node:fs';
import { validateQueue } from './lib/g7-queue.mjs';
const QUEUE = 'scripts/kb-eval/data/g7-review-queue.json';
const asJson = process.argv.includes('--json');
let queue;
try {
queue = JSON.parse(readFileSync(QUEUE, 'utf8'));
} catch (err) {
console.error(`cannot read ${QUEUE}: ${err.message}`);
process.exit(1);
}
const entries = queue.entries ?? [];
const { ok, findings } = validateQueue(entries, (p) => readFileSync(p, 'utf8'));
const open = entries.filter((e) => e.status === 'open');
const resolved = entries.filter((e) => e.status === 'resolved');
if (asJson) {
console.log(JSON.stringify({ ok, open: open.length, resolved: resolved.length, findings }, null, 2));
process.exit(ok ? 0 : 1);
}
console.log(`G7 review queue — ${open.length} open, ${resolved.length} resolved\n`);
const byClass = (cls) => open.filter((e) => e.class === cls);
for (const cls of ['multi-locator', 'replacement']) {
const rows = byClass(cls);
if (rows.length === 0) continue;
console.log(` ${cls} (${rows.length}):`);
for (const e of rows) {
console.log(` ${e.id.padEnd(8)} ${e.file.split('/').pop()}`);
}
console.log();
}
if (findings.length > 0) {
console.log(`FINDINGS (${findings.length}):`);
for (const f of findings) {
console.log(` [${f.kind}] ${f.id ?? ''} ${f.message}`);
}
console.log('\nA drifted anchor means the file changed under a queued defect.');
console.log('Re-derive the anchor from the live file — do not delete the entry.');
process.exit(1);
}
console.log('All open entries still anchor to live corpus text. exit 0');