feat(ms-ai-architect): surgical insertVerifiedFields stamp (byte-identisk body, NFR non-destruktivt, TDD) [skip-docs]
This commit is contained in:
parent
6f82572dba
commit
b5c44e6c6e
2 changed files with 161 additions and 0 deletions
|
|
@ -359,6 +359,92 @@ export function insertHeaderFields(content, meta) {
|
|||
return lines.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Surgically insert-or-update ONLY the `**Verified:**` and `**Verified by:**` header lines
|
||||
* on an EXISTING KB file — the R7–R10 born-verified STAMP primitive. Unlike composeKbFile
|
||||
* (which rebuilds the whole header and may insert a `## Innhold` → body diff), this touches
|
||||
* nothing but the two stamp lines: the body is byte-identical, no TOC is ever added, and a
|
||||
* large file's structure is otherwise unchanged. It is the mirror image of
|
||||
* normalizeStaleVerified — that strips a stale stamp; this writes a fresh, judge-cleared one.
|
||||
*
|
||||
* Insert vs update: a stamp line already inside the 500-byte scan window has ONLY its value
|
||||
* token replaced in place (so re-stamping the same value is a byte-identical no-op —
|
||||
* idempotent, and a pipe row's sibling tokens survive); an absent stamp line is inserted
|
||||
* immediately after the last line of the first contiguous bold-label meta run that still
|
||||
* leaves room in the window (the same anchor + back-off discipline as insertHeaderFields),
|
||||
* ordered `**Verified:**` then `**Verified by:**` to match buildKbHeader.
|
||||
*
|
||||
* THROWS if either stamp would land past the 500-byte window — a header so full the stamp
|
||||
* would be invisible to parseVerified*Header. A silent, unparseable stamp is worse than none
|
||||
* (the file would read as unverified while carrying a verified line); R7 treats this throw as
|
||||
* "flagged: header-slanking kreves", never a forced stamp.
|
||||
*
|
||||
* @param {string} content — full existing file content
|
||||
* @param {{verified: string, verified_by: string}} fields — both required
|
||||
* @returns {string} content with the two stamp lines inserted/updated, body byte-identical
|
||||
* @throws if verified/verified_by is blank, or a stamp lands past the 500-byte window
|
||||
*/
|
||||
export function insertVerifiedFields(content, fields) {
|
||||
const s = String(content ?? '');
|
||||
const f = fields ?? {};
|
||||
const blank = (v) => v === undefined || v === null || String(v).trim() === '';
|
||||
if (blank(f.verified) || blank(f.verified_by)) {
|
||||
throw new Error('insertVerifiedFields: both verified and verified_by are required');
|
||||
}
|
||||
const vStr = String(f.verified).trim();
|
||||
const vbStr = String(f.verified_by).trim();
|
||||
|
||||
const lines = s.split('\n');
|
||||
let vIdx = -1; // existing **Verified:** line (update target)
|
||||
let vbIdx = -1; // existing **Verified by:** line (update target)
|
||||
let anchorIdx = -1; // last contiguous meta line whose insertion point still fits the window
|
||||
let titleIdx = -1; // fallback anchor for the "no meta line" dialect
|
||||
let cum = 0;
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (/^##\s/.test(line) || /^---\s*$/.test(line)) break; // reached body / rule
|
||||
if (titleIdx === -1 && /^#\s+\S/.test(line)) titleIdx = i;
|
||||
if (cum < HEADER_REGION_BYTES) {
|
||||
// Only recognise an existing stamp the parsers can actually read (inside the window).
|
||||
// `**Verified:**` (colon straight after) never matches the `**Verified by:**` line.
|
||||
if (vIdx === -1 && /\*\*Verified:\*\*/i.test(line)) vIdx = i;
|
||||
if (vbIdx === -1 && /\*\*Verified by:\*\*/i.test(line)) vbIdx = i;
|
||||
}
|
||||
const nextCum = cum + line.length + 1; // byte offset just AFTER this line
|
||||
if (RE_META_LINE.test(line)) {
|
||||
if (nextCum > HEADER_REGION_BYTES) break; // back off — insertion point past the window
|
||||
anchorIdx = i;
|
||||
} else if (anchorIdx !== -1) {
|
||||
break; // first non-meta line after the run — the contiguous run is over
|
||||
}
|
||||
cum = nextCum;
|
||||
}
|
||||
|
||||
// Update present stamp lines in place — replace ONLY the value token (function replacer so a
|
||||
// `$` in the value is never treated as a backreference); a pipe row's siblings are preserved.
|
||||
if (vIdx !== -1) lines[vIdx] = lines[vIdx].replace(/(\*\*Verified:\*\*\s*)\S+/i, (_m, p1) => p1 + vStr);
|
||||
if (vbIdx !== -1) lines[vbIdx] = lines[vbIdx].replace(/(\*\*Verified by:\*\*\s*)\S+/i, (_m, p1) => p1 + vbStr);
|
||||
|
||||
// Insert absent stamp lines after the meta-run anchor (title fallback for the no-meta
|
||||
// dialect; -1 + 1 = 0 → very top if there is no title either), Verified then Verified by.
|
||||
const toInsert = [];
|
||||
if (vIdx === -1) toInsert.push(`**Verified:** ${vStr}`);
|
||||
if (vbIdx === -1) toInsert.push(`**Verified by:** ${vbStr}`);
|
||||
if (toInsert.length) {
|
||||
lines.splice((anchorIdx !== -1 ? anchorIdx : titleIdx) + 1, 0, ...toInsert);
|
||||
}
|
||||
|
||||
const out = lines.join('\n');
|
||||
// Post-write invariant: both stamps must be visible to the header parsers (inside 500B).
|
||||
// A stamp that landed past the window is a silent lie — refuse it (header-slanking needed).
|
||||
if (parseVerifiedHeader(out) !== vStr || parseVerifiedByHeader(out) !== vbStr) {
|
||||
throw new Error(
|
||||
'insertVerifiedFields: stamp would land past the 500-byte header window (header-slanking required)',
|
||||
);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Surgically strip STALE `**Verified:**` value(s) from a legacy KB file — the bounded
|
||||
* Spor 1 carve-out for the 14 files carrying `**Verified:** MCP <date>`. That non-date
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue