test(ms-ai-architect): RX-REG-KB lint — regresjonsvern for AI Act-korrektheter [skip-docs]
10 tester laaser Art. 5(1)-bokstaver, Art. 6(2)/(3), Art. 99(3)-(6), Art. 49-timing, bokfoeringslov 5 aar, Nkom-navngiving, og forbyr «fremskynde»/«under etablering» i hele governance-korpuset. Gap-disiplin: dette er den forhindrende mekanismen for RX-REG-KB. Suite: 825/825 (815 baseline + 10 nye), exit 0.
This commit is contained in:
parent
3ea3608a8d
commit
1f80574d0d
1 changed files with 132 additions and 0 deletions
132
tests/kb-update/test-governance-refs-reg-lint.test.mjs
Normal file
132
tests/kb-update/test-governance-refs-reg-lint.test.mjs
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
// tests/kb-update/test-governance-refs-reg-lint.test.mjs
|
||||
// TDD for RX-REG-KB (kryssmodell-review 2026-07-09, replan §RX-REG-KB): the
|
||||
// governance reference corpus carried EU AI Act errors that ground-truth
|
||||
// verification (EUR-Lex CELEX:32024R1689, AI Act Explorer, regjeringen.no)
|
||||
// confirmed as factually wrong. This lint is the *preventive mechanism*
|
||||
// (gap-disiplin): once the surgical fixes land, these literals must never
|
||||
// re-enter the corpus.
|
||||
//
|
||||
// Ground truth locked this session:
|
||||
// - Art. 5(1) letters: (c) social scoring is NOT public-authority-limited;
|
||||
// (d) crime-risk prediction by profiling; (e) untargeted facial-image
|
||||
// scraping; (h) real-time RBI for law enforcement. The old table
|
||||
// scrambled (c)/(d)/(e)/(h) and omitted scraping. (EUR-Lex art. 5(1).)
|
||||
// - Art. 6(2): Annex III = high-risk MAIN RULE; Art. 6(3): narrow 4-condition
|
||||
// exception; profiling ⇒ ALWAYS high-risk. The old decision tree inverted
|
||||
// this (profiling as the sole trigger). (EUR-Lex art. 6(2)-(3).)
|
||||
// - Art. 99 fines: (3) €35M/7 %; (4) incl. Art. 50 transparency (4)(g) €15M/3 %;
|
||||
// (5) incorrect info €7,5M/1 %; (6) SMEs = «whichever is LOWER», NO separate
|
||||
// reduced amounts. The old table put transparency at 7,5M/1,5 %, false-info
|
||||
// at 1,5 %, and fabricated an SMB column. (EUR-Lex art. 99(3)-(6).)
|
||||
// - Art. 49 registration timing = before placing on market / putting into
|
||||
// service — NOT a fixed «fra august 2026». High-risk applicability deferred
|
||||
// to 2027-12-02 (Annex III) / 2028-08-02 (Annex I) via Digital Omnibus.
|
||||
// - Bokføringsloven § 13: 5 år (not «7 år»).
|
||||
// - Nkom is the DESIGNATED coordinating market-surveillance authority
|
||||
// (regjeringen besluttet) — «under etablering» is stale.
|
||||
// - Digital Omnibus dropped any acceleration trigger → «fremskynde» must go.
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
const pluginRoot = new URL('../../', import.meta.url);
|
||||
const REF = 'skills/ms-ai-governance/references/responsible-ai/';
|
||||
const read = (rel) => readFileSync(new URL(REF + rel, pluginRoot), 'utf8');
|
||||
|
||||
// Files in scope for this session's RX-REG-KB fixes.
|
||||
const GOVERNANCE_FILES = [
|
||||
'ai-act-classification-methodology.md',
|
||||
'ai-act-compliance-guide.md',
|
||||
'ai-act-conformity-assessment.md',
|
||||
'ai-act-provider-obligations.md',
|
||||
'ai-act-fria-template.md',
|
||||
'ai-act-deployer-obligations.md',
|
||||
];
|
||||
|
||||
// --- 0. Cross-file guards (apply to every governance ref) ---
|
||||
|
||||
test('no refuted Omnibus-acceleration claim survives anywhere', () => {
|
||||
for (const f of GOVERNANCE_FILES) {
|
||||
assert.ok(!/fremskynde/i.test(read(f)),
|
||||
`${f}: «fremskynde» — the final Omnibus dropped the acceleration trigger`);
|
||||
}
|
||||
});
|
||||
|
||||
test('no stale «under etablering» authority phrasing survives (Nkom is designated)', () => {
|
||||
for (const f of GOVERNANCE_FILES) {
|
||||
assert.ok(!/under etablering/i.test(read(f)),
|
||||
`${f}: «under etablering» — Nkom is the designated coordinating authority`);
|
||||
}
|
||||
});
|
||||
|
||||
// --- 1. Art. 5(1) prohibited-practices table (classification-methodology) ---
|
||||
|
||||
test('classification-methodology: Art. 5(1) letters are correctly assigned', () => {
|
||||
const md = read('ai-act-classification-methodology.md');
|
||||
// Forbidden: the old scrambled letter↔content pairings.
|
||||
assert.ok(!md.includes('Sosial scoring av enkeltpersoner av offentlige myndigheter'),
|
||||
'(c) social scoring is not limited to public authorities');
|
||||
assert.ok(!md.includes('Sanntids biometrisk fjernidentifikasjon i offentlig rom (Art. 5(1)(d))'),
|
||||
'real-time RBI is (h), not (d)');
|
||||
assert.ok(!md.includes('Retrospektiv biometrisk identifikasjon uten lovhjemmel'),
|
||||
'(e) is untargeted facial-image scraping, not retrospective ID');
|
||||
assert.ok(!/basert på profiling \(Art\. 5\(1\)\(h\)\)/.test(md),
|
||||
'crime prediction by profiling is (d), not (h)');
|
||||
// Required: the correct pairings + the missing scraping row.
|
||||
assert.ok(/skraping av ansiktsbilder/i.test(md), '(e) scraping row must exist');
|
||||
assert.ok(/profilering \(Art\. 5\(1\)\(d\)\)/.test(md), '(d) crime-risk prediction by profiling');
|
||||
assert.ok(/rettshåndhevelse \(Art\. 5\(1\)\(h\)\)/.test(md), '(h) real-time RBI for law enforcement');
|
||||
});
|
||||
|
||||
// --- 2. Art. 6(2)/(3) high-risk classification (compliance-guide decision tree) ---
|
||||
|
||||
test('compliance-guide: Annex III is high-risk by default (Art. 6(2)/(3))', () => {
|
||||
const md = read('ai-act-compliance-guide.md');
|
||||
assert.ok(md.includes('Art. 6(2)'), 'Annex III = high-risk main rule (Art. 6(2))');
|
||||
assert.ok(md.includes('Art. 6(3)'), 'narrow exception cited (Art. 6(3))');
|
||||
});
|
||||
|
||||
// --- 3. Art. 99 administrative fines (compliance-guide) ---
|
||||
|
||||
test('compliance-guide: Art. 99 fine figures are correct + SMB rule cited', () => {
|
||||
const md = read('ai-act-compliance-guide.md');
|
||||
// Forbidden: wrong transparency %, wrong false-info %, fabricated SMB column.
|
||||
assert.ok(!/1,5\s?%/.test(md), 'no 1,5 % anywhere (transparency=3 %, false-info=1 %)');
|
||||
assert.ok(!/0,6\s?%/.test(md), 'no fabricated SMB 0,6 %');
|
||||
assert.ok(!/0,3\s?%/.test(md), 'no fabricated SMB 0,3 %');
|
||||
// Required: Art. 99(6) SMB rule = «whichever is lower».
|
||||
assert.ok(md.includes('Art. 99(6)'), 'SMB rule Art. 99(6) must be cited');
|
||||
assert.ok(/laveste/i.test(md), 'SMB = «whichever thereof is lower»');
|
||||
});
|
||||
|
||||
// --- 4. AI Act applicability dates (compliance-guide): no stale «august 2026» ---
|
||||
|
||||
test('compliance-guide: no stale «august 2026» high-risk applicability strings', () => {
|
||||
const md = read('ai-act-compliance-guide.md');
|
||||
assert.ok(!/2\.?\s*august 2026:\*\* Providers må registrere/.test(md),
|
||||
'registration is Art. 49 timing, not a fixed aug-2026 date');
|
||||
assert.ok(!/august 2027:\*\* Full compliance/.test(md), 'high-risk deferred to 2027-12-02');
|
||||
assert.ok(!/fra aug\.? 2026/i.test(md), 'no «fra aug 2026» registration string');
|
||||
assert.ok(!/\(påkrevd fra august 2026\)/.test(md), 'no «påkrevd fra august 2026»');
|
||||
assert.ok(!/fra før august 2026/.test(md), 'transition cutoff = applicability date, not aug 2026');
|
||||
assert.ok(!/Før august 2026: mindre press/.test(md), 'stale advisory date');
|
||||
// Required: the corrected deferred date.
|
||||
assert.ok(md.includes('2. desember 2027'), 'Annex III high-risk applies 2027-12-02');
|
||||
});
|
||||
|
||||
// --- 5. Bokføringsloven retention (compliance-guide): 5 år, not 7 år ---
|
||||
|
||||
test('compliance-guide: log retention is 5 år (bokføringsloven § 13), not 7 år', () => {
|
||||
const md = read('ai-act-compliance-guide.md');
|
||||
assert.ok(!/7 år/.test(md), 'bokføringsloven § 13 = 5 år primær, not 7 år');
|
||||
assert.ok(/5 år/.test(md), 'corrected retention present');
|
||||
});
|
||||
|
||||
// --- 6. Nkom named in the three files that carried «under etablering» ---
|
||||
|
||||
for (const f of ['ai-act-provider-obligations.md', 'ai-act-fria-template.md', 'ai-act-deployer-obligations.md']) {
|
||||
test(`${f}: names Nkom as designated authority`, () => {
|
||||
assert.ok(read(f).includes('Nkom'), 'Nkom (koordinerende markedstilsynsmyndighet) must be named');
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue