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
|
|
@ -98,7 +98,12 @@ Status-nøkkel: 🔴 ikke startet · 🟡 pågår · 🟢 lukket.
|
|||
|---|---|---|---|---|---|
|
||||
| **G1** | Judgen er ikke herdet mot de 8 dokumenterte feilmodusene (`source_silent`-maskerer-fravær, legacy-rad-match, ramme-skifte-tall-overlever, nedre-grense-understatement, eksakt-streng-pedanteri, taksonomi-nyanse, kapabilitet-bom) | Judge-FN/FP påvist i Spor 2b (8 mål, se `ref-kb-gold-reconciliation-2026-06.md`) | **Spor 2a** — judge-prompt-v3, MÅLT single vs v3/ensemble på herdet gull; adopter kun ved målt forbedring (ad-hoc-patch overfitter + bytter P/R) | 🔴 | Spor 1 korpus-pass (judgen brukes i ~2700 fetches) |
|
||||
| **G2** | Herdet judge er ikke wired inn i Port 2 (born-verified create-guard) + Port 3 (kadens) — uten innplugging binder ikke hardningen mekanisk | Re-introdusert drift ved nye/regenererte filer + kadens-bom | Del av Spor 2a→3: bytt ut v2 med v3 i `transform.mjs`-judge-passet + kadens-runneren | 🔴 (avh. G1) | Spor 1 |
|
||||
| **G3** | Ingen deterministisk gull-intern-konsistens-vakt (`verdict=correct` mens egen `notes` sier «uverifisert/illustrativ») | Gull-labeling-feil av FP1-klassen (selvmotsigende annotasjon) | Liten TDD-lint over `gold-correctness-set.json` (+ kjøres på fremtidige gull-bygg) | 🔴 | Spor 1 (nytt gull bygges) / §7 friskt utvalg |
|
||||
| **G4** | Nedre-grense-policyen lever kun i prosa (denne dok + reconciliation-logg) — ikke kodet i judge-prompt ELLER `build-gold-set`-instruks | Re-introdusert nedre-grense-ambivalens i fremtidige gull-bygg + judge-kjøringer | Kod policyen inn i judge-prompt-v3 (G1) + build-gold-set-instruks | 🔴 | Spor 1 / §7 friskt utvalg |
|
||||
| **G3** | Ingen deterministisk gull-intern-konsistens-vakt (`verdict=correct` mens egen `notes` sier «uverifisert/illustrativ») | Gull-labeling-feil av FP1-klassen (selvmotsigende annotasjon) | Liten TDD-lint over `gold-correctness-set.json` (+ kjøres på fremtidige gull-bygg) | 🟢 **lukket 2026-06-30** | Spor 1 (nytt gull bygges) / §7 friskt utvalg |
|
||||
| **G4** | Nedre-grense-policyen lever kun i prosa (denne dok + reconciliation-logg) — ikke kodet i judge-prompt ELLER `build-gold-set`-instruks | Re-introdusert nedre-grense-ambivalens i fremtidige gull-bygg + judge-kjøringer | Kod policyen inn i judge-prompt-v3 (G1) + build-gold-set-instruks | 🟡 **build-instruks ✅ (2026-06-30); judge-prompt-v3-del i G1** | Spor 1 / §7 friskt utvalg |
|
||||
|
||||
**Ikke mekanisme-gap, men sporet backlog (innhold, ikke loop):** reference-`.md`-fil-fiksene fra Spor 2b (FP1 11000+/40+, FP2 «kun», FP6 Preview/Norway-East, FN2–FN6 utdaterte tall) er **Spor 0/1**-innholdsarbeid — pekt per-claim i `notes`, ikke gjentakelses-mekanisme. Føres i Spor 0-manifest / Spor 1-korpus-pass, ikke her.
|
||||
|
||||
### Lukke-logg
|
||||
|
||||
- **G3 🟢 lukket (2026-06-30).** Deterministisk lint `lib/gold-consistency.mjs` + CLI `lint-gold-consistency.mjs` + TDD `tests/kb-eval/test-gold-consistency.test.mjs` (4 tester); wiret som hard gate på `build-gold-set.mjs --write` (dry-run forhåndsviser ikke-fatalt). De 3 nåværende shippet-gull-treffene resolvert med `consistency_waiver` (én — `reserved-capacity-planning#5` — live kilde-bekreftet FØR waiver, verifiseringsplikt). **Bevist mot FP1:** rebuild fra batch-returns flagger `azure-ai-foundry.md#2` (verdict=correct, note «11000+/40+ uverifisert») — nøyaktig claimen Spor 2b fant via dyr live re-fetch. Linten fanger klassen gratis ved bygg.
|
||||
- **G4 🟡 build-instruks ✅ (2026-06-30).** Nedre-grense-policyen + konsistens-policyen kodet inn i `build-gold-set.mjs` `_meta.lower_bound_policy` / `_meta.consistency_policy` (instruks subagenter følger ved fremtidig gull-bygg). Resterende halvdel — policyen inn i `judge-claim-prompt-v3.md` — lukkes i G1 når v3 forfattes.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import fs from 'node:fs';
|
|||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { parseLastUpdated, fileLastmodChanged } from './lib/base-rate.mjs';
|
||||
import { lintGoldConsistency } from './lib/gold-consistency.mjs';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const ROOT = path.resolve(__dirname, '..', '..');
|
||||
|
|
@ -86,12 +87,39 @@ const goldSet = {
|
|||
raw_returns: 'fase0-returns/batch-*.json',
|
||||
note_evidence_quote:
|
||||
'Per-claim evidence_quote omitted here to bound size; full verbatim quotes live in the session transcript. notes + evidence_url capture each verdict basis.',
|
||||
// G4 (programdok §8 / §3-kjennelse 2026-06-30): nedre-grense-policy for
|
||||
// subagenter som bygger fremtidig gull. En nedre-grense-påstand («100+»,
|
||||
// «200k+») teller som FEIL (outdated/wrong) hvis den GROVT understater
|
||||
// (>~2x, beslutnings-endrende) den sanne verdien; en STRAM nedre grense (sann
|
||||
// verdi i samme størrelsesorden) blir stående correct. Anvendt på FN2 (Spor 2b).
|
||||
lower_bound_policy:
|
||||
'Lower-bound claims (e.g. "100+", "200k+"): verdict=outdated/wrong if the bound grossly understates (>~2x, decision-changing) the true value; a tight bound (true value within the same order of magnitude) stays correct.',
|
||||
// G3 (programdok §8): gull-intern-konsistens. Et verdict=correct-claim hvis
|
||||
// egen `notes` innrømmer at verdien ikke er bekreftet mot kilden («uverifisert
|
||||
// / illustrativ / ikke i kilden») MÅ enten relabel-es ELLER bære et
|
||||
// `consistency_waiver` med begrunnelse. Håndhevet av lint-gold-consistency.mjs.
|
||||
consistency_policy:
|
||||
'verdict=correct claims whose notes admit the value is unverified/illustrative/not-in-source must be relabeled OR carry a consistency_waiver. Enforced by lint-gold-consistency.mjs.',
|
||||
claim_count: claims.length,
|
||||
},
|
||||
claims,
|
||||
};
|
||||
|
||||
// G3 (programdok §8): gull fødes konsistent. Hard gate kun på --write — et
|
||||
// nybygget gull med uwaived selvmotsigende correct-claims (verdict=correct mens
|
||||
// noten innrømmer ikke-bekreftet: «uverifisert/illustrativ/ikke i kilden») nektes
|
||||
// SKREVET; relabel eller waiver først. Dry-run forhåndsviser (advarer, blokkerer
|
||||
// ikke). Escape-hatch --allow-inconsistent (samme idiom som
|
||||
// run-judge-bakeoff --allow-incomplete) for bevisst override.
|
||||
const consistency = lintGoldConsistency(goldSet);
|
||||
|
||||
if (process.argv.includes('--write')) {
|
||||
if (!consistency.ok && !process.argv.includes('--allow-inconsistent')) {
|
||||
console.error(`error: ${consistency.flagged.length} uwaived selvmotsigende correct-claim(s) — gull nektes skrevet (G3):`);
|
||||
for (const f of consistency.flagged) console.error(` - ${f.id} [${f.markers.join(', ')}]: ${f.notes}`);
|
||||
console.error('Resolver hver (relabel ELLER consistency_waiver), eller --allow-inconsistent for å overstyre.');
|
||||
process.exit(2);
|
||||
}
|
||||
const out = path.join(DATA, 'gold-correctness-set.json');
|
||||
fs.writeFileSync(out, JSON.stringify(goldSet, null, 2) + '\n');
|
||||
console.log(`wrote ${out} (${claims.length} claims)`);
|
||||
|
|
@ -101,5 +129,11 @@ if (process.argv.includes('--write')) {
|
|||
const filesUnknown = Object.entries(fileMeta).filter(([, m]) => m.lastmod_changed === null).length;
|
||||
console.log(`claims: ${claims.length} | files: ${Object.keys(fileMeta).length}`);
|
||||
console.log(`file lastmod_changed: true=${filesWithChange} false=${filesNoChange} unknown(null date)=${filesUnknown}`);
|
||||
if (consistency.ok) {
|
||||
console.log('G3 gull-konsistens: OK (0 uwaived selvmotsigende correct-claims)');
|
||||
} else {
|
||||
console.log(`G3 gull-konsistens: ⚠ ${consistency.flagged.length} uwaived selvmotsigende correct-claim(s) — --write vil nektes:`);
|
||||
for (const f of consistency.flagged) console.log(` - ${f.id} [${f.markers.join(', ')}]`);
|
||||
}
|
||||
console.log('(dry run — pass --write to persist gold-correctness-set.json)');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3451,7 +3451,8 @@
|
|||
"evidence_url": "https://learn.microsoft.com/azure/reliability/reliability-ai-search",
|
||||
"lastmod_changed": false,
|
||||
"file_last_updated": "2026-02-01",
|
||||
"notes": "AI Search single-region; manuell multi-region matcher MS-veiledning. RTO 15 min illustrativ."
|
||||
"notes": "AI Search single-region; manuell multi-region matcher MS-veiledning. RTO 15 min illustrativ.",
|
||||
"consistency_waiver": "G3: 'RTO 15 min illustrativ' er en note-aside om et tidstall utenfor den vurderte claim-en (claim = 'ingen built-in cross-region', grunnet mot reliability-ai-search). Kapabiliteten korrekt; ikke FP1."
|
||||
},
|
||||
{
|
||||
"id": "ms-ai-infrastructure/bcdr/service-level-documentation-dr.md#5",
|
||||
|
|
@ -3477,7 +3478,8 @@
|
|||
"evidence_url": "https://learn.microsoft.com/azure/cosmos-db/continuous-backup-restore-introduction",
|
||||
"lastmod_changed": false,
|
||||
"file_last_updated": "2026-02-01",
|
||||
"notes": "Multi-write reell active-active; ~0-tall illustrative men kapabiliteten korrekt."
|
||||
"notes": "Multi-write reell active-active; ~0-tall illustrative men kapabiliteten korrekt.",
|
||||
"consistency_waiver": "G3/FP5 (Spor 2b reconciled): multi-region-write active-active grunnet (cosmos-db/distribute-data-globally); '~0'-RTO/RPO-tall illustrative, ikke kilde-siterte. Kapabilitet korrekt — behold correct."
|
||||
},
|
||||
{
|
||||
"id": "ms-ai-infrastructure/bcdr/service-level-documentation-dr.md#7",
|
||||
|
|
@ -4296,7 +4298,8 @@
|
|||
"evidence_url": "https://learn.microsoft.com/azure/cost-management-billing/reservations/azure-openai",
|
||||
"lastmod_changed": false,
|
||||
"file_last_updated": "2026-06-01",
|
||||
"notes": "Cross-model-sharing + per-time matching bekreftet. 'mai 2025' ikke i kilden."
|
||||
"notes": "Cross-model-sharing + per-time matching bekreftet. 'mai 2025' ikke i kilden.",
|
||||
"consistency_waiver": "G3: kjerne-kapabilitet (cross-model PTU-deling + per-minutt pro-rata matching) bekreftet live mot Foundry PTU-reservasjons-siden 2026-06-30; 'mai 2025'-ikrafttredelsesdato IKKE i kilden (ikke-materiell, ikke beslutnings-endrende). Behold correct; fjern/merk datoen i .md = Spor 0/1-fil-fiks."
|
||||
},
|
||||
{
|
||||
"id": "ms-ai-security/cost-optimization/reserved-capacity-planning.md#6",
|
||||
|
|
|
|||
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 };
|
||||
}
|
||||
47
scripts/kb-eval/lint-gold-consistency.mjs
Normal file
47
scripts/kb-eval/lint-gold-consistency.mjs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env node
|
||||
// lint-gold-consistency.mjs — G3 (programdok §8) CLI: kjør gull-intern-
|
||||
// konsistens-vakten over gold-correctness-set.json. Tynn wiring; all logikk i
|
||||
// testet lib/gold-consistency.mjs (samme form som run-judge-bakeoff.mjs).
|
||||
//
|
||||
// Flagger verdict=correct-claims hvis egen `notes` innrømmer at verdien ikke er
|
||||
// bekreftet mot kilden («uverifisert / illustrativ / ikke i kilden») og mangler
|
||||
// et `consistency_waiver`. Exit 1 hvis noen uwaived → hard gate for gull-bygg.
|
||||
//
|
||||
// Usage:
|
||||
// node scripts/kb-eval/lint-gold-consistency.mjs [--gold <path>] [--json]
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { lintGoldConsistency } from './lib/gold-consistency.mjs';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const DATA = path.join(__dirname, 'data');
|
||||
|
||||
function flag(name) {
|
||||
const i = process.argv.indexOf(name);
|
||||
return i >= 0 ? process.argv[i + 1] : undefined;
|
||||
}
|
||||
|
||||
const goldPath = flag('--gold') || path.join(DATA, 'gold-correctness-set.json');
|
||||
if (!fs.existsSync(goldPath)) {
|
||||
console.error(`error: ${goldPath} not found`);
|
||||
process.exit(2);
|
||||
}
|
||||
const gold = JSON.parse(fs.readFileSync(goldPath, 'utf8'));
|
||||
const r = lintGoldConsistency(gold);
|
||||
|
||||
if (process.argv.includes('--json')) {
|
||||
console.log(JSON.stringify(r, null, 2));
|
||||
} else if (r.ok) {
|
||||
console.log(`gull-konsistens OK — 0 uwaived selvmotsigende correct-claims (${(gold.claims || []).length} claims)`);
|
||||
} else {
|
||||
console.error(`gull-konsistens FEIL — ${r.flagged.length} uwaived selvmotsigende correct-claim(s):`);
|
||||
for (const f of r.flagged) {
|
||||
console.error(` - ${f.id} [${f.markers.join(', ')}]`);
|
||||
console.error(` notes: ${f.notes}`);
|
||||
}
|
||||
console.error('\nResolver hver: relabel verdikten ELLER legg til et consistency_waiver med begrunnelse (menneske-i-loop §4c).');
|
||||
}
|
||||
|
||||
process.exit(r.ok ? 0 : 1);
|
||||
100
tests/kb-eval/test-gold-consistency.test.mjs
Normal file
100
tests/kb-eval/test-gold-consistency.test.mjs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// tests/kb-eval/test-gold-consistency.test.mjs
|
||||
// G3 (programdok §8 mekanisme-gap-register) — deterministisk gull-intern-konsistens-vakt.
|
||||
//
|
||||
// Feilklassen (FP1, Spor 2b): et gull-claim bærer verdict=correct mens dens egen
|
||||
// `notes` innrømmer at den påståtte verdien IKKE er bekreftet mot kilden
|
||||
// («uverifisert / illustrativ / ikke i kilden»). Det er en selvmotsigende
|
||||
// annotasjon — verdikten sier «matcher kilden i dag», noten sier «gjorde det ikke».
|
||||
// Reconciliation fant FP1 dyrt (live re-fetch). En deterministisk lint fanger
|
||||
// klassen gratis ved hvert gull-bygg.
|
||||
//
|
||||
// Designet er en TRIPWIRE, ikke en auto-klassifiserer: brede markører (recall),
|
||||
// presisjon via en eksplisitt `consistency_waiver`-escape-hatch (menneske-i-loop
|
||||
// §4c — relabel ELLER waiver-med-begrunnelse, aldri auto-fiks). Et waiver er den
|
||||
// varige menneske-bekreftelses-loggen.
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import {
|
||||
lintGoldConsistency,
|
||||
findContradictionMarkers,
|
||||
} from '../../scripts/kb-eval/lib/gold-consistency.mjs';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const PLUGIN_ROOT = join(__dirname, '..', '..');
|
||||
|
||||
// --- (1) marker-deteksjon ------------------------------------------------------
|
||||
|
||||
test('findContradictionMarkers detects unverified/illustrative admissions', () => {
|
||||
assert.ok(findContradictionMarkers('RTO 15 min illustrativ.').length > 0);
|
||||
assert.ok(findContradictionMarkers("'mai 2025' ikke i kilden.").length > 0);
|
||||
assert.ok(findContradictionMarkers('Tallet er uverifisert mot kilden.').length > 0);
|
||||
assert.ok(findContradictionMarkers('kan ikke verifisere mot kilden').length > 0);
|
||||
// clean note → no markers
|
||||
assert.equal(findContradictionMarkers('GA-dato og kontekstvindu matcher modell-siden eksakt.').length, 0);
|
||||
assert.equal(findContradictionMarkers('').length, 0);
|
||||
assert.equal(findContradictionMarkers(undefined).length, 0);
|
||||
});
|
||||
|
||||
// --- (2) lint over en konstruert gull-fixture ----------------------------------
|
||||
|
||||
const fixture = {
|
||||
claims: [
|
||||
// FP1-klasse: correct, men noten innrømmer verdien ikke er i kilden, ingen waiver → FLAGGET
|
||||
{ id: 'a#1', verdict: 'correct', notes: "'11000+ modeller' ikke i kilden; '40+ regioner' finnes ikke." },
|
||||
// correct + illustrativ-innrømmelse, ingen waiver → FLAGGET
|
||||
{ id: 'a#2', verdict: 'correct', notes: 'RTO 15 min illustrativ.' },
|
||||
// correct + selvmotsigende note MEN waiver til stede → IKKE flagget
|
||||
{ id: 'a#3', verdict: 'correct', notes: '~0-tall illustrative men kapabiliteten korrekt.', consistency_waiver: 'FP5: kapabilitet grunnet, tall illustrativt.' },
|
||||
// correct + ren note → IKKE flagget
|
||||
{ id: 'a#4', verdict: 'correct', notes: 'Matcher modell-siden eksakt.' },
|
||||
// verdict=wrong med samme markør → IKKE flagget (verdikten er allerede uenig med kilden)
|
||||
{ id: 'a#5', verdict: 'wrong', notes: 'tallet er ikke i kilden.' },
|
||||
// verdict=outdated → IKKE flagget (anerkjenner allerede ikke-match)
|
||||
{ id: 'a#6', verdict: 'outdated', notes: 'verdien er ikke i kilden lenger.' },
|
||||
// verdict=unsourced → IKKE flagget (ærlig merket)
|
||||
{ id: 'a#7', verdict: 'unsourced', notes: 'kan ikke verifisere; pris JS-rendret.' },
|
||||
// tom waiver (whitespace) teller ikke som waiver → FLAGGET
|
||||
{ id: 'a#8', verdict: 'correct', notes: 'uverifisert.', consistency_waiver: ' ' },
|
||||
],
|
||||
};
|
||||
|
||||
test('lintGoldConsistency flags only un-waived contradictory correct-claims', () => {
|
||||
const r = lintGoldConsistency(fixture);
|
||||
const flaggedIds = r.flagged.map((f) => f.id).sort();
|
||||
assert.deepEqual(flaggedIds, ['a#1', 'a#2', 'a#8']);
|
||||
assert.equal(r.ok, false);
|
||||
});
|
||||
|
||||
test('lintGoldConsistency returns ok:true on a fully-waived/clean set', () => {
|
||||
const clean = {
|
||||
claims: [
|
||||
{ id: 'b#1', verdict: 'correct', notes: 'matcher kilden eksakt.' },
|
||||
{ id: 'b#2', verdict: 'correct', notes: 'illustrativt tall.', consistency_waiver: 'kapabilitet grunnet.' },
|
||||
{ id: 'b#3', verdict: 'wrong', notes: 'ikke i kilden.' },
|
||||
],
|
||||
};
|
||||
const r = lintGoldConsistency(clean);
|
||||
assert.equal(r.ok, true);
|
||||
assert.equal(r.flagged.length, 0);
|
||||
});
|
||||
|
||||
// --- (3) live-gull-vakt: den shippede fasiten har INGEN uwaived motsigelse ------
|
||||
// Dette kobler suiten til gold-correctness-set.json — invarianten «kjøres på
|
||||
// fremtidige gull-bygg». RØD til de 3 nåværende treffene er waivet/adjudisert.
|
||||
|
||||
test('shipped gold-correctness-set.json is internally consistent (no un-waived contradictions)', () => {
|
||||
const gold = JSON.parse(
|
||||
readFileSync(join(PLUGIN_ROOT, 'scripts/kb-eval/data/gold-correctness-set.json'), 'utf8'),
|
||||
);
|
||||
const r = lintGoldConsistency(gold);
|
||||
assert.equal(
|
||||
r.ok,
|
||||
true,
|
||||
`gull har ${r.flagged.length} uwaived selvmotsigende correct-claim(s): ` +
|
||||
r.flagged.map((f) => `${f.id} [${f.markers.join(',')}]`).join('; '),
|
||||
);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue