feat(ms-ai-architect): R20 — Category-backfill på 25 kategorisløse ref-filer via insertMetaField [skip-docs]
Ny testet primitiv transform.insertMetaField (anker + 500B-back-off som insertHeaderFields, idempotent på eksakt label, body byte-identisk; 6 tester) + backfill-category.mjs (deterministisk folder->category-regel, hard per-fil-invariant, insert-only, aborterer for skriving ved avvik). Fordeling: 14 Solution Architecture & Advisory (architecture/), 6 Microsoft AI Platforms (platforms/+development/), 4 Responsible AI & Governance, 1 MLOps & GenAIOps. Label = engelsk Category (322 vs 42 Kategori). Eksisterende recommended-mcp-servers/rag-maturity-model urort. Roadmap: R20 done + R21 (Status/Last-updated not-due) encoded. Verifisering: 0 kategorislose filer (var 25); diff +25/-0; idempotent re-run; suite 764/764 exit 0.
This commit is contained in:
parent
655f60a40d
commit
a583599ab1
29 changed files with 262 additions and 1 deletions
|
|
@ -25,6 +25,7 @@ import {
|
|||
composeKbFile,
|
||||
insertToc,
|
||||
insertHeaderFields,
|
||||
insertMetaField,
|
||||
insertVerifiedFields,
|
||||
normalizeStaleVerified,
|
||||
stampVerifiedMeta,
|
||||
|
|
@ -690,6 +691,81 @@ test('insertHeaderFields rejects an unknown type', () => {
|
|||
assert.throws(() => insertHeaderFields(HDR_CATEGORY, { type: 'blogpost' }), /type/i);
|
||||
});
|
||||
|
||||
// --- insertMetaField: the R20/R21 base-field backfill primitive ------------------
|
||||
// Inserts ONE bold-label meta line (**<Label>:** <value>) into an EXISTING file that
|
||||
// lacks it, using the same anchor + 500-byte back-off discipline as insertHeaderFields
|
||||
// (last line of the first contiguous meta run that fits the window; title fallback for
|
||||
// the "None" dialect). Body byte-identical; idempotent on the exact label. Serves R20
|
||||
// (**Category:**) and R21 (**Status:**, **Last updated:**).
|
||||
|
||||
// A file with a meta run but NO **Category:** (the R20 target shape).
|
||||
const NOCAT =
|
||||
'# Decision Trees\n\n' +
|
||||
'**Last updated:** 2026-06-19\n' +
|
||||
'**Status:** Established Practice\n\n' +
|
||||
'---\n\n' +
|
||||
'## Introduksjon\n\nBrødtekst.\n';
|
||||
|
||||
// The "None" dialect: a platform ref with NO bold-label meta line at all.
|
||||
const NOMETA =
|
||||
'# Azure AI Foundry\n\n' +
|
||||
'Foundry er Microsofts plattform.\n\n' +
|
||||
'## Oversikt\n\nBrødtekst.\n';
|
||||
|
||||
test('insertMetaField inserts **Category:** after the meta run, before the rule, body byte-identical', () => {
|
||||
const out = insertMetaField(NOCAT, 'Category', 'Solution Architecture & Advisory');
|
||||
assert.match(out, /\*\*Category:\*\* Solution Architecture & Advisory/);
|
||||
// lands inside the meta run: after Status, before the `---` rule
|
||||
assert.ok(out.indexOf('**Status:**') < out.indexOf('**Category:**'));
|
||||
assert.ok(out.indexOf('**Category:**') < out.indexOf('\n---'));
|
||||
const tail = (s) => s.slice(s.indexOf('## Introduksjon'));
|
||||
assert.equal(tail(out), tail(NOCAT));
|
||||
});
|
||||
|
||||
test('insertMetaField anchors on the title for the "None" dialect (no meta lines), before the first ## section', () => {
|
||||
const out = insertMetaField(NOMETA, 'Category', 'Microsoft AI Platforms');
|
||||
assert.match(out, /\*\*Category:\*\* Microsoft AI Platforms/);
|
||||
assert.ok(out.indexOf('# Azure AI Foundry') < out.indexOf('**Category:**'));
|
||||
assert.ok(out.indexOf('**Category:**') < out.indexOf('## Oversikt'));
|
||||
const tail = (s) => s.slice(s.indexOf('## Oversikt'));
|
||||
assert.equal(tail(out), tail(NOMETA));
|
||||
});
|
||||
|
||||
test('insertMetaField is idempotent on the exact label (a re-run inserts nothing)', () => {
|
||||
const once = insertMetaField(NOCAT, 'Category', 'Solution Architecture & Advisory');
|
||||
const twice = insertMetaField(once, 'Category', 'Solution Architecture & Advisory');
|
||||
assert.equal(twice, once);
|
||||
assert.equal((once.match(/\*\*Category:\*\*/g) || []).length, 1);
|
||||
});
|
||||
|
||||
test('insertMetaField keeps the field inside the 500-byte window when a meta line is itself >500B (anchor backs off)', () => {
|
||||
const giant =
|
||||
'# Big\n\n' +
|
||||
'**Status:** ' + 'GA; '.repeat(140) + 'slutt\n\n' + // single meta line ~560 bytes
|
||||
'---\n\n' +
|
||||
'## A\n\ntekst\n';
|
||||
const out = insertMetaField(giant, 'Category', 'X');
|
||||
// backed off to the title anchor — Category lands BEFORE the giant Status line, in-window
|
||||
assert.ok(out.indexOf('# Big') < out.indexOf('**Category:**'));
|
||||
assert.ok(out.indexOf('**Category:**') < out.indexOf('**Status:**'));
|
||||
assert.ok(out.indexOf('**Category:**') < 500, 'Category fell outside the 500-byte window');
|
||||
const tail = (s) => s.slice(s.indexOf('## A'));
|
||||
assert.equal(tail(out), tail(giant));
|
||||
});
|
||||
|
||||
test('insertMetaField preserves a pipe-delimited meta row (siblings untouched)', () => {
|
||||
const out = insertMetaField(HDR_PIPE, 'Type', 'reference');
|
||||
assert.match(out, /\*\*Opprettet:\*\* 2026-04 \| \*\*Sist oppdatert:\*\* 2026-06-19/);
|
||||
assert.ok(out.indexOf('**Confidence:**') < out.indexOf('**Type:**'));
|
||||
const tail = (s) => s.slice(s.indexOf('## Introduksjon'));
|
||||
assert.equal(tail(out), tail(HDR_PIPE));
|
||||
});
|
||||
|
||||
test('insertMetaField rejects a blank label or blank value', () => {
|
||||
assert.throws(() => insertMetaField(NOCAT, '', 'x'), /label/i);
|
||||
assert.throws(() => insertMetaField(NOCAT, 'Category', ' '), /value/i);
|
||||
});
|
||||
|
||||
test('insertToc(insertHeaderFields(large)) → Type+Source+TOC, passes real checkN4, body byte-identical except header + one ## Innhold', () => {
|
||||
const withHdr = insertHeaderFields(HDR_LARGE, { type: 'reference', source: MS_URL });
|
||||
const out = insertToc(withHdr);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue