#!/usr/bin/env node // apply-verified-stamp.mjs — R7–R10 surgical born-verified stamp driver. // // Applies the judge-pass ledger's `pass` verdicts (scripts/kb-eval/data/judge-pass-manifest.json, // R6 Step 4) to disk: for every record with per_file_verdict='pass', insert/update ONLY the // **Verified:** and **Verified by:** header lines via transform.insertVerifiedFields — the body // below the header is byte-identical (NFR non-destruktivt; composeKbFile would rebuild the file // and diff the body, which is why this driver exists — R6 plan Step 2). `flagged` records are // never touched. An unstampable file (stamp would land past the 500-byte window — // insertVerifiedFields throws) is collected as an error and reported; R7 flips that record to // flagged «header-slanking kreves», never a forced stamp. Other files still stamp (exit 1). // // INVARIANT (asserted per file BEFORE any write; breach aborts that file, never writes): // - body (from first `## `/`---`) byte-identical // - header minus Verified/Verified by-lines byte-identical (only the stamp lines differ) // - parseVerifiedHeader/parseVerifiedByHeader read back exactly the stamped values // Idempotent: a re-run finds the stamp in place and is a no-op. Crash-safe: atomicWriteSync // (tmp+rename) — a reader sees the old file or the new one, never a partial. // // Usage: node scripts/kb-update/apply-verified-stamp.mjs [--manifest ] [--root ] [--write] // (default: dry-run — prints the plan, writes nothing) // Exit codes: 0 ok · 1 one or more files failed (unstampable/missing/invariant) · 2 usage import { readFileSync, existsSync, realpathSync } from 'node:fs'; import { join, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { insertVerifiedFields } from './lib/transform.mjs'; import { parseVerifiedHeader, parseVerifiedByHeader } from './lib/kb-headers.mjs'; import { atomicWriteSync } from './lib/atomic-write.mjs'; const __dirname = dirname(fileURLToPath(import.meta.url)); const PLUGIN_ROOT = join(__dirname, '..', '..'); const DEFAULT_MANIFEST = join(__dirname, '..', 'kb-eval', 'data', 'judge-pass-manifest.json'); /** * Pure stamp plan for one file: returns { content, changed }. `changed:false` means the exact * stamp is already in place (idempotent re-run). Throws when the stamp cannot land inside the * 500-byte header window (caller records the failure — the R7 «header-slanking kreves» path). */ export function planVerifiedStamp(content, { verified, verified_by }) { const stamped = insertVerifiedFields(content, { verified, verified_by }); return { content: stamped, changed: stamped !== String(content) }; } // Header/body split mirroring strip-stale-verified-pipe.mjs / transform.mjs headerEndIndex. function splitHeaderBody(content) { const lines = String(content).split('\n'); let i = 0; for (; i < lines.length; i++) { if (/^##\s/.test(lines[i]) || /^---\s*$/.test(lines[i])) break; } return { header: lines.slice(0, i).join('\n'), body: lines.slice(i).join('\n') }; } const RE_STAMP_LINE = /^\*\*Verified(?: by)?:\*\*/i; // The hard per-file invariant: only the stamp lines may differ; the body never. function assertInvariant(rel, oldC, newC, { verified, verified_by }) { const o = splitHeaderBody(oldC); const n = splitHeaderBody(newC); if (o.body !== n.body) throw new Error(`${rel}: body changed — refusing to write`); const strip = (h) => h.split('\n').filter((l) => !RE_STAMP_LINE.test(l)).join('\n'); if (strip(o.header) !== strip(n.header)) { throw new Error(`${rel}: header lines other than Verified/Verified by changed — refusing to write`); } if (parseVerifiedHeader(newC) !== verified || parseVerifiedByHeader(newC) !== verified_by) { throw new Error(`${rel}: stamped values do not read back — refusing to write`); } } function usageExit(msg) { process.stderr.write(`${msg}\nusage: apply-verified-stamp.mjs [--manifest ] [--root ] [--write]\n`); process.exit(2); } function main(argv) { const args = argv.slice(2); let manifestPath = DEFAULT_MANIFEST; let root = PLUGIN_ROOT; let write = false; for (let i = 0; i < args.length; i++) { if (args[i] === '--manifest') { if (!args[i + 1]) usageExit('--manifest requires a path'); manifestPath = args[++i]; } else if (args[i] === '--root') { if (!args[i + 1]) usageExit('--root requires a dir'); root = args[++i]; } else if (args[i] === '--write') write = true; else usageExit(`unknown flag: ${args[i]}`); } if (!existsSync(manifestPath)) usageExit(`manifest not found: ${manifestPath}`); const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')); const passRecs = (manifest.files ?? []).filter((r) => r?.per_file_verdict === 'pass'); let stamped = 0, noop = 0; const failed = []; for (const rec of passRecs) { const abs = join(root, rec.file); try { if (!rec.verified || !rec.verified_by) throw new Error('pass record missing verified/verified_by'); if (!existsSync(abs)) throw new Error('file not found'); const oldC = readFileSync(abs, 'utf8'); const { content: newC, changed } = planVerifiedStamp(oldC, { verified: rec.verified, verified_by: rec.verified_by }); if (!changed) { noop++; continue; } assertInvariant(rec.file, oldC, newC, { verified: rec.verified, verified_by: rec.verified_by }); if (write) atomicWriteSync(abs, newC); stamped++; console.log(`${write ? 'stamped' : 'would stamp'} ${rec.file}`); } catch (e) { failed.push([rec.file, e.message]); console.error(`FAILED ${rec.file} — ${e.message}`); } } console.log(`\n${write ? '' : '(dry-run) '}pass records: ${passRecs.length} · stamped: ${write ? stamped : 0}${write ? '' : ` (would stamp: ${stamped})`} · already stamped: ${noop} · failed: ${failed.length}`); if (failed.length > 0) process.exit(1); } const isMain = (() => { try { return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url)); } catch { return false; } })(); if (isMain) main(process.argv);