feat(ms-ai-architect): Spor 1 — Port-1-substrat migrert på 4 ikke-advisor-skills (243 Source + 327 Type + 325 TOC + stale-verified poison fjernet) [skip-docs]
Steg 9 (R4): unified migrate-corpus.mjs --write over engineering/governance/ infrastructure/security. 327 filer mutert, verified=null, prosa byte-identisk (fra første ## seksjon), advisor urørt (0 endringer). To applier-fixes oppdaget under kjøring (TDD, RED→GREEN): - insertHeaderFields: anker faller nå tilbake når en meta-linje selv passerer 500B (2 filer pakket et avsnitt i **Status:** → Type/Source landet utenfor scan-vinduet, applierens post-write-assertion fanget + restaurerte). - normalizeStaleVerified: fjerner nå ALLE stale non-date **Verified:** i 500B-vinduet, inkl. stray body-dup rett under --- (9 mlops-genaiops-filer var ellers falskt "verified"/fresh, droppet fra worklist). Operatør-godkjent utvidelse av carve-out; kun stray metadata-linjer, aldri prosa. test-transform-criterion: precondition oppdatert til post-migrasjons-sannhet (fila bærer nå Source). Suite 728/728 grønn.
This commit is contained in:
parent
ed92d65385
commit
ddce43d8b2
330 changed files with 4643 additions and 83 deletions
|
|
@ -310,20 +310,25 @@ export function insertHeaderFields(content, meta) {
|
|||
if (needSource) toInsert.push(`**Source:** ${String(src).trim()}`);
|
||||
|
||||
const lines = s.split('\n');
|
||||
let anchorIdx = -1; // last line of the first contiguous meta run
|
||||
let anchorIdx = -1; // last line of the first contiguous meta run that 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;
|
||||
const nextCum = cum + line.length + 1; // byte offset just AFTER this line (= the insertion point)
|
||||
if (RE_META_LINE.test(line)) {
|
||||
// Anchor after this meta line ONLY if the insertion point still fits the scan window.
|
||||
// A meta line whose own length pushes the offset past 500B (a corpus file that packs a
|
||||
// paragraph into **Status:**) must NOT become the anchor — otherwise the inserted field
|
||||
// lands past the window and parseTypeHeader/parseSourceHeader miss it. Back off here.
|
||||
if (nextCum > HEADER_REGION_BYTES) break;
|
||||
anchorIdx = i; // extend the contiguous meta run
|
||||
} else if (anchorIdx !== -1) {
|
||||
break; // first non-meta line after the run — the run is over (contiguous only)
|
||||
}
|
||||
cum += line.length + 1;
|
||||
if (cum > HEADER_REGION_BYTES) break; // never place fields past the scan window
|
||||
cum = nextCum;
|
||||
}
|
||||
// "None" dialect (no bold-label meta): anchor on the title line so the fields still
|
||||
// land in the header region, before the first section. (-1 → very top if no title.)
|
||||
|
|
@ -333,52 +338,59 @@ export function insertHeaderFields(content, meta) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Surgically strip a STALE `**Verified:**` value from a legacy KB file's header — the
|
||||
* bounded Spor 1 carve-out for the 14 files carrying `**Verified:** MCP <date>`. That
|
||||
* non-date value is read by parseVerifiedHeader as a bogus "verified" stamp, which drops
|
||||
* the file out of the full-pass worklist AND marks it falsely verified; stripping it is
|
||||
* the OPPOSITE of stamping verified. Acts ONLY on the first header-region `**Verified:**`
|
||||
* (the exact occurrence parseVerifiedHeader reads) and ONLY when its value is not a clean
|
||||
* YYYY-MM(-DD) date. It never touches anything at or below the first `---` rule, so a
|
||||
* body-duplicate survives (removing body content is NOT part of the blessed byte-identity
|
||||
* carve-out). On a pipe-delimited meta row it removes only the `**Verified:** <value>`
|
||||
* 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
|
||||
* value is read by parseVerifiedHeader as a bogus "verified" stamp, which drops the file
|
||||
* out of the full-pass worklist AND marks it falsely verified; stripping it is the OPPOSITE
|
||||
* of stamping verified. Acts on EVERY stale `**Verified:**` inside the 500-byte scan window
|
||||
* (the region parseVerifiedHeader actually reads) whose value is not a clean YYYY-MM(-DD)
|
||||
* date — including a stray duplicate sitting just below the first `---` rule, a corpus
|
||||
* artifact (9 mlops-genaiops files) that still poisons the read once the header copy is
|
||||
* gone. A clean date at the first scanned position stops the pass (a legitimately verified
|
||||
* file is left alone), and anything PAST the 500-byte window is genuine body content and is
|
||||
* never touched. On a pipe-delimited meta row it removes only the `**Verified:** <value>`
|
||||
* token plus one adjacent ` | ` separator, preserving the sibling tokens
|
||||
* (**Sist oppdatert:** etc.); on a standalone line it drops the whole line. Idempotent.
|
||||
* (**Sist oppdatert:** etc.); on a standalone line it drops the whole line. Idempotent
|
||||
* (each pass removes one match; a re-run finds nothing to strip).
|
||||
*
|
||||
* @param {string} content — full existing file content
|
||||
* @returns {string} content with the stale header Verified removed, or unchanged
|
||||
* @returns {string} content with the stale in-window Verified value(s) removed, or unchanged
|
||||
*/
|
||||
export function normalizeStaleVerified(content) {
|
||||
const s = String(content ?? '');
|
||||
const head = s.slice(0, HEADER_REGION_BYTES);
|
||||
const m = /\*\*Verified:\*\*\s*(\S+)/i.exec(head);
|
||||
if (!m) return s; // no header Verified
|
||||
if (DATE_RE.test(m[1])) return s; // clean date → leave untouched
|
||||
const matchStart = m.index; // index of "**Verified:**" in s
|
||||
// Guard: never act at or below the first `---` rule — body content is off-limits.
|
||||
const rule = /^---\s*$/m.exec(s);
|
||||
if (rule && matchStart >= rule.index) return s; // defensive (parser scans header, but be sure)
|
||||
let s = String(content ?? '');
|
||||
// Remove every stale (non-date) **Verified:** inside the scan window. Loop because a file
|
||||
// can carry two (header copy + stray body-dup below ---); each pass drops one, so it
|
||||
// terminates. A clean date at the first position ends the pass — parseVerifiedHeader reads
|
||||
// that first occurrence, so a dated first Verified means the file is legitimately verified.
|
||||
for (;;) {
|
||||
const head = s.slice(0, HEADER_REGION_BYTES);
|
||||
const m = /\*\*Verified:\*\*\s*(\S+)/i.exec(head);
|
||||
if (!m) return s; // nothing stale left in the window
|
||||
if (DATE_RE.test(m[1])) return s; // clean date at the read position → leave untouched
|
||||
const matchStart = m.index; // index of "**Verified:**" in s
|
||||
|
||||
const lineStart = s.lastIndexOf('\n', matchStart - 1) + 1; // 0 if no preceding newline
|
||||
let lineEnd = s.indexOf('\n', matchStart);
|
||||
if (lineEnd === -1) lineEnd = s.length;
|
||||
const line = s.slice(lineStart, lineEnd);
|
||||
const lineStart = s.lastIndexOf('\n', matchStart - 1) + 1; // 0 if no preceding newline
|
||||
let lineEnd = s.indexOf('\n', matchStart);
|
||||
if (lineEnd === -1) lineEnd = s.length;
|
||||
const line = s.slice(lineStart, lineEnd);
|
||||
|
||||
if (!line.includes(' | ')) {
|
||||
// Standalone `**Verified:** …` line — drop the whole line, including its newline.
|
||||
const cutEnd = lineEnd < s.length ? lineEnd + 1 : lineEnd;
|
||||
return s.slice(0, lineStart) + s.slice(cutEnd);
|
||||
if (!line.includes(' | ')) {
|
||||
// Standalone `**Verified:** …` line — drop the whole line, including its newline.
|
||||
const cutEnd = lineEnd < s.length ? lineEnd + 1 : lineEnd;
|
||||
s = s.slice(0, lineStart) + s.slice(cutEnd);
|
||||
continue;
|
||||
}
|
||||
// Pipe row: remove only the `**Verified:** <value>` token + one adjacent ` | `.
|
||||
const nextSepRel = s.slice(matchStart, lineEnd).indexOf(' | ');
|
||||
const tokenEnd = nextSepRel === -1 ? lineEnd : matchStart + nextSepRel;
|
||||
if (s.slice(matchStart - 3, matchStart) === ' | ') {
|
||||
s = s.slice(0, matchStart - 3) + s.slice(tokenEnd); // drop the preceding separator
|
||||
} else if (nextSepRel !== -1) {
|
||||
s = s.slice(0, matchStart) + s.slice(tokenEnd + 3); // drop the following separator
|
||||
} else {
|
||||
s = s.slice(0, matchStart) + s.slice(tokenEnd); // degenerate — token only
|
||||
}
|
||||
}
|
||||
// Pipe row: remove only the `**Verified:** <value>` token + one adjacent ` | `.
|
||||
const nextSepRel = s.slice(matchStart, lineEnd).indexOf(' | ');
|
||||
const tokenEnd = nextSepRel === -1 ? lineEnd : matchStart + nextSepRel;
|
||||
if (s.slice(matchStart - 3, matchStart) === ' | ') {
|
||||
return s.slice(0, matchStart - 3) + s.slice(tokenEnd); // drop the preceding separator
|
||||
}
|
||||
if (nextSepRel !== -1) {
|
||||
return s.slice(0, matchStart) + s.slice(tokenEnd + 3); // drop the following separator
|
||||
}
|
||||
return s.slice(0, matchStart) + s.slice(tokenEnd); // degenerate — token only
|
||||
}
|
||||
|
||||
const RE_TITLE = /^#\s+\S/m;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue