feat(ms-ai-architect): G3 gull-intern-konsistens-lint + G4 build-instruks-policy — §8 gap-lukk [skip-docs]
This commit is contained in:
parent
b9db0b2be2
commit
9b147b470f
6 changed files with 256 additions and 5 deletions
62
scripts/kb-eval/lib/gold-consistency.mjs
Normal file
62
scripts/kb-eval/lib/gold-consistency.mjs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// lib/gold-consistency.mjs — G3 (programdok §8): deterministisk gull-intern-
|
||||
// konsistens-vakt. Fanger FP1-klassen (Spor 2b): et claim med verdict=correct
|
||||
// hvis egen `notes` innrømmer at den påståtte verdien ikke er bekreftet mot
|
||||
// kilden («uverifisert / illustrativ / ikke i kilden»). Verdikten sier «matcher
|
||||
// kilden»; noten sier det motsatte — en selvmotsigende annotasjon.
|
||||
//
|
||||
// Tripwire-design: brede markører for recall, presisjon via en eksplisitt
|
||||
// `consistency_waiver`-escape-hatch (menneske-i-loop §4c). Linten klassifiserer
|
||||
// ikke — den surfacer kandidater et menneske enten relabel-er eller waiver-er
|
||||
// med begrunnelse. Ren funksjon, ingen I/O; testet i tests/kb-eval/.
|
||||
|
||||
// Markører som — i en note festet til et verdict=correct-claim — innrømmer at
|
||||
// den påståtte verdien IKKE er bekreftet mot den siterte kilden. Holdt brede med
|
||||
// vilje (recall); falske positive absorberes av waiver-hatchen, ikke av en
|
||||
// perfekt regex. Hver er en delstreng matchet case-insensitivt.
|
||||
export const CONTRADICTION_MARKERS = [
|
||||
'uverifisert',
|
||||
'ikke verifiser', // ikke verifisert / ikke verifiserbar
|
||||
'kan ikke verifiser',
|
||||
'illustrativ', // illustrativt / illustrative
|
||||
'ikke i kilden',
|
||||
'ikke nevnt i kild',
|
||||
'kilden oppgir ikke',
|
||||
'ikke bekreftet',
|
||||
'ubekreftet',
|
||||
'source_silent',
|
||||
'plassholder',
|
||||
'placeholder',
|
||||
'eksempel-tall',
|
||||
'eksempeltall',
|
||||
];
|
||||
|
||||
// Verdikter som hevder samsvar med dagens kilde. Kun disse kan motsi en
|
||||
// «ikke bekreftet»-note: outdated/wrong/unsourced anerkjenner allerede ikke-match.
|
||||
const ASSERTS_SOURCE_MATCH = new Set(['correct']);
|
||||
|
||||
export function findContradictionMarkers(notes) {
|
||||
if (!notes || typeof notes !== 'string') return [];
|
||||
const lc = notes.toLowerCase();
|
||||
return CONTRADICTION_MARKERS.filter((m) => lc.includes(m));
|
||||
}
|
||||
|
||||
function hasWaiver(claim) {
|
||||
return typeof claim.consistency_waiver === 'string' && claim.consistency_waiver.trim().length > 0;
|
||||
}
|
||||
|
||||
// Returnerer { ok, flagged: [{ id, verdict, notes, markers }] }.
|
||||
// Et claim flagges når: verdikten hevder kilde-samsvar, noten bærer en
|
||||
// motsigelses-markør, og det ikke finnes et ikke-tomt consistency_waiver.
|
||||
export function lintGoldConsistency(goldSet) {
|
||||
const claims = (goldSet && goldSet.claims) || [];
|
||||
const flagged = [];
|
||||
for (const c of claims) {
|
||||
if (!ASSERTS_SOURCE_MATCH.has(c.verdict)) continue;
|
||||
if (hasWaiver(c)) continue;
|
||||
const markers = findContradictionMarkers(c.notes);
|
||||
if (markers.length) {
|
||||
flagged.push({ id: c.id, verdict: c.verdict, notes: c.notes, markers });
|
||||
}
|
||||
}
|
||||
return { ok: flagged.length === 0, flagged };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue