// tests/kb-update/test-dedup-plain-header.test.mjs // TDD for Enhet 3 Op B — the dual-header plain→bold dedup on the 4 ms-ai-governance // ai-act-* files. Those files carry an authored, PLAIN-TEXT block // Last updated: // Status: GA // Category: ← redundant: a bold **Category:** already exists // (R20 inserted the bold Category; the plain block is the original dual header). This is NOT a // derive-a-value backfill (backfill-status.mjs owns that) — the authored values are PRESERVED // byte-exact; only their label decoration is normalized to bold, and the provably-redundant // plain Category line is removed. Two new pure primitives + a pure composition are pinned here. import { test } from 'node:test'; import assert from 'node:assert/strict'; import { boldifyPlainField, dropRedundantPlainField } from '../../scripts/kb-update/lib/transform.mjs'; import { dedupPlainHeader, MANIFEST } from '../../scripts/kb-update/dedup-plain-header.mjs'; // An ai-act-shaped fixture: bold Type+Category (Category from R20), then the plain block, // then a body that itself mentions "Status:" in prose (must never be touched). const FIXTURE = [ '# EU AI Act — Systematisk Klassifiseringsmetodikk', '**Type:** regulatory', '**Category:** Responsible AI & Governance', '', 'Last updated: 2026-06-18', 'Status: GA', 'Category: Responsible AI & Governance', '', '---', '', '## Innhold', '', 'A body paragraph that says Status: draft in prose — must be left alone.', '', ].join('\n'); // ── boldifyPlainField ──────────────────────────────────────────────────────── test('boldifyPlainField: plain header field → bold, value preserved byte-exact', () => { const out = boldifyPlainField(FIXTURE, 'Last updated'); assert.ok(out.includes('**Last updated:** 2026-06-18'), 'bold line present'); assert.ok(!/^Last updated:/m.test(out.split('\n---')[0]), 'plain header line gone'); }); test('boldifyPlainField: idempotent — a bold field already present is unchanged', () => { const once = boldifyPlainField(FIXTURE, 'Status'); const twice = boldifyPlainField(once, 'Status'); assert.equal(twice, once); }); test('boldifyPlainField: no plain field in header → unchanged', () => { assert.equal(boldifyPlainField(FIXTURE, 'Nonexistent'), FIXTURE); }); test('boldifyPlainField: never touches a match in the body (below the header region)', () => { const out = boldifyPlainField(FIXTURE, 'Status'); assert.ok(out.includes('says Status: draft in prose'), 'body prose untouched'); // exactly one bold Status inserted (the header one), body "Status:" not bolded assert.equal((out.match(/\*\*Status:\*\*/g) || []).length, 1); }); test('boldifyPlainField: body byte-identical (only the header line changes)', () => { const out = boldifyPlainField(FIXTURE, 'Status'); const bodyOf = (c) => c.slice(c.indexOf('\n---')); assert.equal(bodyOf(out), bodyOf(FIXTURE)); }); // ── dropRedundantPlainField ────────────────────────────────────────────────── test('dropRedundantPlainField: drops the plain line when a bold field with the same value exists', () => { const out = dropRedundantPlainField(FIXTURE, 'Category'); const header = out.split('\n---')[0]; assert.ok(/\*\*Category:\*\* Responsible AI & Governance/.test(header), 'bold Category kept'); assert.ok(!/^Category:/m.test(header), 'plain Category removed'); assert.equal(out.split('\n').length, FIXTURE.split('\n').length - 1, 'exactly one line removed'); }); test('dropRedundantPlainField: throws when plain value ≠ bold value (not redundant, human decision)', () => { const mismatched = FIXTURE.replace('Category: Responsible AI & Governance', 'Category: Something Else'); assert.throws(() => dropRedundantPlainField(mismatched, 'Category'), /not redundant|≠/); }); test('dropRedundantPlainField: throws when no bold field exists to prove redundancy', () => { const noBold = FIXTURE.replace('**Category:** Responsible AI & Governance\n', ''); assert.throws(() => dropRedundantPlainField(noBold, 'Category'), /no bold/i); }); test('dropRedundantPlainField: no-op when the plain line is absent (idempotent)', () => { const once = dropRedundantPlainField(FIXTURE, 'Category'); assert.equal(dropRedundantPlainField(once, 'Category'), once); }); // ── dedupPlainHeader (full composition) ────────────────────────────────────── test('dedupPlainHeader: boldifies Last updated + Status, drops redundant plain Category', () => { const out = dedupPlainHeader(FIXTURE); const header = out.split('\n---')[0]; assert.ok(/\*\*Last updated:\*\* 2026-06-18/.test(header), 'Last updated bolded, value preserved'); assert.ok(/\*\*Status:\*\* GA/.test(header), 'Status bolded, GA preserved'); assert.equal((header.match(/\*\*Category:\*\*/g) || []).length, 1, 'exactly one bold Category'); assert.ok(!/^(Last updated|Status|Category):/m.test(header), 'no plain header fields remain'); }); test('dedupPlainHeader: net one line removed, body byte-identical', () => { const out = dedupPlainHeader(FIXTURE); assert.equal(out.split('\n').length, FIXTURE.split('\n').length - 1); const bodyOf = (c) => c.slice(c.indexOf('\n---')); assert.equal(bodyOf(out), bodyOf(FIXTURE)); }); test('dedupPlainHeader: idempotent — a second pass is a no-op', () => { const once = dedupPlainHeader(FIXTURE); assert.equal(dedupPlainHeader(once), once); }); // ── MANIFEST ───────────────────────────────────────────────────────────────── test('MANIFEST: exactly the 4 dual-header ai-act-* files', () => { assert.equal(MANIFEST.length, 4); assert.equal(new Set(MANIFEST).size, 4, 'no duplicates'); const expected = [ 'skills/ms-ai-governance/references/responsible-ai/ai-act-classification-methodology.md', 'skills/ms-ai-governance/references/responsible-ai/ai-act-deployer-obligations.md', 'skills/ms-ai-governance/references/responsible-ai/ai-act-fria-template.md', 'skills/ms-ai-governance/references/responsible-ai/ai-act-provider-obligations.md', ]; for (const p of expected) assert.ok(MANIFEST.includes(p), `missing ${p}`); });