255 lines
35 KiB
JavaScript
255 lines
35 KiB
JavaScript
#!/usr/bin/env node
|
|
// The acceptance layer's recorder (the founder's Test and Acceptance Standard, 8 October 2026; main through the coordinator, 18:2x UK).
|
|
// The registry docs/plans/igneum-2.0-test-registry.json holds the cases; tools/ci/test-map.json maps every case whose method includes
|
|
// "Automated" to the harness or suite that answers it (the command, the box class, the fixture ids it needs). A run batch writes
|
|
// status, run id, evidence path and the pinned manifest sha back into the registry for the cases it covered; a case's accept text is
|
|
// never edited (the self-test diffs every accept field before and after); a case with no harness reads NOT RUN with the reason,
|
|
// never PASS by inference.
|
|
//
|
|
// node tools/ci/test-record.mjs --check every Automated case has a map entry or a NOT RUN reason; the map's ids exist
|
|
// node tools/ci/test-record.mjs --record <batch.json> batch: {run_id, manifest_sha, evidence_dir, cells:[{cell, status, evidence}]}
|
|
// each cell's case ids come from the map; the registry gains status/run/evidence/manifest
|
|
// node tools/ci/test-record.mjs --cases <cell> the case ids a matrix cell answers (for the matrix scripts' column)
|
|
// node tools/ci/test-record.mjs --note <suite code> "<text>" append a dated note to a suite's notes (a ruling, a review finding's
|
|
// disposition); never a case's accept text
|
|
// node tools/ci/test-record.mjs --self-test
|
|
import fs from 'node:fs'; import path from 'node:path'; import child_process from 'node:child_process';
|
|
const args = process.argv.slice(2); const arg = (n) => { const i = args.indexOf(n); return i >= 0 ? args[i + 1] : undefined; };
|
|
const ROOT = process.env.TEST_RECORD_ROOT || path.resolve(path.dirname(new URL(import.meta.url).pathname), '..', '..');
|
|
const REG = process.env.TEST_REGISTRY || path.join(ROOT, 'docs/plans/igneum-2.0-test-registry.json');
|
|
const MAP = process.env.TEST_MAP || path.join(ROOT, 'tools/ci/test-map.json');
|
|
const ACCEPT_KEYS = ['accept', 'acceptance', 'accept_text', 'criteria', 'expected']; // whichever the registry uses; all are frozen
|
|
const DECISIONS = new Set(['NOT RUN', 'BLOCKED', 'FAIL', 'PASS']);
|
|
const METHODS = new Set(['native', 'GPU', 'SP1', 'model', 'static', 'team-reported']);
|
|
export const ISLAND_LABEL = 'on an island, not a network';
|
|
export const ISLAND_SINCE = '2026-10-08T19:00:00Z'; // 20:00 UK on 8 October 2026: devnet-4 has been seventeen islands since the epoch-3 cut (main's word through the coordinator, 22:2x UK)
|
|
const ISLAND_RE = /devnet-4|devnet 4|2\.0 devnet|chain id 4465|igneum-devnet-4/i;
|
|
export function labelIslands(reg, since = ISLAND_SINCE, label = ISLAND_LABEL) { // every record measured on the 2.0 devnet after `since` carries the label until the fleet is one chain
|
|
let n = 0;
|
|
for (const c of casesOf(reg)) {
|
|
for (const r of Object.values(c.evidence_records || {})) {
|
|
if (!r || typeof r !== 'object') continue;
|
|
const at = String(r.at || ''); if (!at || at < since) continue;
|
|
if (!(r.decision === 'PASS' || r.decision === 'FAIL') || r.method === 'static') { if (r.network_label === label) { delete r.network_label; r.note = String(r.note || '').replace(/ ?\(on an island, not a network: devnet-4 has been islands[^)]*\)/, ''); } continue; } // a measurement is a verdict from a run; a build fact, a reason or a BLOCKED placeholder is not on any network
|
|
if (r.network_label === label) continue;
|
|
const txt = JSON.stringify([r.release_identity?.network_object, r.evidence, r.note, r.cell, c.evidence_path]);
|
|
if (!ISLAND_RE.test(txt)) continue;
|
|
r.network_label = label; r.note = (r.note ? r.note + ' ' : '') + `(${label}: devnet-4 has been islands since the epoch-3 cut; labelled ${new Date().toISOString()}.)`; c.updated = new Date().toISOString(); n++;
|
|
}
|
|
}
|
|
return n;
|
|
}
|
|
export function normalize(reg) { // the one-time pass over rows written before the vocabulary: RUNNING -> NOT RUN in progress; DEFERRED -> NOT RUN with the note
|
|
let n = 0; const now = new Date().toISOString();
|
|
for (const c of casesOf(reg)) {
|
|
if (c.run_status === 'RUNNING') { c.run_status = 'NOT RUN'; c.in_progress_since = c.in_progress_since || c.updated || now; n++; }
|
|
else if (c.run_status === 'DEFERRED' || /^DEFERRED/.test(String(c.run_status || ''))) { c.deferral_note = c.deferral_note || 'P13 deferred by the founder (8 October 2026, 18:2x UK: "forget P13 for now")'; c.run_status = 'NOT RUN'; n++; }
|
|
else if (c.run_status && !DECISIONS.has(c.run_status)) { c.status_note = c.run_status; c.run_status = 'NOT RUN'; n++; }
|
|
if (c.evidence_record && !c.evidence_record.method) { const cell = String(c.evidence_record.cell || ''); c.evidence_record.method = /^(suite|check|gate|crosscheck)/.test(cell) ? 'native' : /pods|fleet|bench:|p01-vectors/.test(cell) ? 'GPU' : /proving|zkp/.test(cell) ? 'SP1' : /model|economics|eco|sim/.test(cell) ? 'model' : /study/.test(cell) ? 'team-reported' : 'static'; c.evidence_record.requirement_id = c.evidence_record.requirement_id || c.id; c.evidence_record.decision = c.run_status; c.evidence_record.reviewer = c.evidence_record.reviewer ?? ''; c.evidence_record.claim_impact = c.evidence_record.claim_impact ?? ''; c.evidence_record.release_identity = c.evidence_record.release_identity || { commit: c.evidence_record.manifest_sha || '', lockfile: '', binary: '', network_object: '', activation: '', profile_hashes: '' }; n++; }
|
|
c.approvals = c.approvals || { scope_approved: null, implementation_complete: null, evidence_reproduced: null, claim_authorised: null };
|
|
if (c.evidence_record && !c.evidence_records) { c.evidence_records = { [c.evidence_record.cell || 'record']: { ...c.evidence_record, run_id: c.evidence_record.run_id || c.run_id, evidence: c.evidence_record.evidence || c.evidence_path, in_progress: !!c.in_progress_since } }; n++; }
|
|
}
|
|
if (reg.live_fields) reg.live_fields.run_status = 'NOT RUN | BLOCKED | FAIL | PASS (the master, p. 139; in_progress_since marks work under way; deferral_note a founder deferral)';
|
|
return n;
|
|
}
|
|
const load = (p) => JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
const casesOf = (reg) => Array.isArray(reg) ? reg : (reg.cases || reg.tests || (reg.suites || []).flatMap((s) => s.tests || s.cases || []));
|
|
const isAutomated = (c) => /automated/i.test(String(c.method ?? c.methods ?? ''));
|
|
const idOf = (c) => String(c.id ?? c.case ?? c.case_id);
|
|
function check(reg, map) {
|
|
const cases = casesOf(reg); const ids = new Set(cases.map(idOf)); const out = []; let bad = 0;
|
|
for (const [cell, m] of Object.entries(map.cells || {})) for (const id of m.cases || []) if (!ids.has(id)) { out.push(`map: cell ${cell} names an unknown case ${id}`); bad++; }
|
|
const mapped = new Set(Object.values(map.cells || {}).flatMap((m) => m.cases || []));
|
|
const notRun = map.not_run || {};
|
|
for (const c of cases) {
|
|
if (!isAutomated(c)) continue; const id = idOf(c);
|
|
if (!mapped.has(id) && !notRun[id]) { out.push(`case ${id} (Automated) has no harness in the map and no NOT RUN reason`); bad++; }
|
|
}
|
|
for (const c of cases) { const st = c.run_status; if (st && !DECISIONS.has(st)) { out.push(`case ${idOf(c)} reads ${st}: the decision vocabulary is NOT RUN, BLOCKED, FAIL, PASS (run --normalize)`); bad++; } }
|
|
for (const [cell, m] of Object.entries(map.cells || {})) { if (!m.command) { out.push(`map: cell ${cell} has no command`); bad++; } if (!m.box_class) { out.push(`map: cell ${cell} has no box class`); bad++; } if (!Array.isArray(m.fixtures)) { out.push(`map: cell ${cell} has no fixtures list (F0 onward, or empty)`); bad++; } }
|
|
return { bad, lines: out, automated: cases.filter(isAutomated).length, mapped: [...mapped].length, notRun: Object.keys(notRun).length };
|
|
}
|
|
function record(reg, map, batch) {
|
|
// the founder's word (8 October 2026, 20:21 UK): a sha is "cut" only when its binary exists on build-1 with its commit string read
|
|
// back, and a fleet binary only from the cross-build kit scanned clean of AVX-512; a batch that declares a cut carries all three
|
|
if (batch.cut) {
|
|
const c = batch.cut; const errs = [];
|
|
if (!/^build-\d+:\/srv\//.test(String(c.binary || ''))) errs.push('cut.binary must be a build-N:/srv/... path on a build box');
|
|
if (!c.commit_string || !(String(c.commit_string).startsWith(String(batch.manifest_sha)) || String(batch.manifest_sha).startsWith(String(c.commit_string)))) errs.push(`cut.commit_string (${c.commit_string}) must be the read-back of the batch's manifest sha (${batch.manifest_sha})`);
|
|
if (!/every binary is clean of AVX-512/.test(String(c.kit_isa || ''))) errs.push('cut.kit_isa must carry tools/ci/kit-isa-check.sh\'s clean line over the kit');
|
|
if (errs.length) throw new Error(`a cut batch is refused: ${errs.join('; ')}`);
|
|
}
|
|
const cases = casesOf(reg); const byId = new Map(cases.map((c) => [idOf(c), c])); const touched = [];
|
|
const now = new Date().toISOString();
|
|
for (const cell of batch.cells || []) {
|
|
const m = (map.cells || {})[cell.cell]; if (!m) throw new Error(`batch names a cell not in the map: ${cell.cell}`);
|
|
// INT-17 (the master edition, 8 October 2026 20:1x UK): a cell that declares its prerequisites (prereqs: {oracle, pinned_keys,
|
|
// real_proof_fixture}, each "present" or "missing") with any one missing is BLOCKED, never PASS, with the missing ones named
|
|
// the decision vocabulary is exactly NOT RUN, BLOCKED, FAIL, PASS (the master, p. 139; main through the coordinator, 8 October 2026,
|
|
// 20:3x UK): RUNNING is not a state and becomes NOT RUN with in_progress_since; DEFERRED becomes NOT RUN with the deferral note
|
|
let status = String(cell.status || '').toUpperCase(); let inProgress = false, deferral = null;
|
|
if (status === 'RUNNING') { status = 'NOT RUN'; inProgress = true; }
|
|
if (status === 'DEFERRED') { status = 'NOT RUN'; deferral = cell.deferral || 'deferred by the founder'; }
|
|
if (!DECISIONS.has(status)) throw new Error(`cell ${cell.cell}: status ${cell.status} is not one of NOT RUN, BLOCKED, FAIL, PASS (RUNNING reads as NOT RUN in progress; DEFERRED as NOT RUN with a deferral note)`);
|
|
const method = cell.method || batch.method; if (!METHODS.has(method)) throw new Error(`cell ${cell.cell}: method must be one of ${[...METHODS].join(', ')} (never conflated); got ${method}`);
|
|
// evidence paths (the coordinator's and lane D's classes, 8 October 2026 21:3x UK): a tree path must exist at record time and name a file,
|
|
// never a directory (a directory citation makes every file beneath it the row's evidence and trips the move-together rule on every
|
|
// other lane's landing); an absolute path or a box path (host:/path) is outside the tree and is not checked here (rule 1 reads it at the merge)
|
|
for (const one of String(cell.evidence || '').split(';').map((x) => x.trim()).filter(Boolean)) {
|
|
if (one.startsWith('/') || one.includes(':/')) continue;
|
|
if (process.env.TEST_RECORD_NO_TREE === '1') continue;
|
|
const abs = path.resolve(ROOT, one);
|
|
if (!fs.existsSync(abs)) throw new Error(`cell ${cell.cell}: evidence ${one} is not in the tree at record time (cite only files that exist here; another lane's unlanded file is cited after it lands)`);
|
|
if (fs.statSync(abs).isDirectory()) throw new Error(`cell ${cell.cell}: evidence ${one} is a directory; name the file (a directory citation binds every file beneath it to this row)`);
|
|
}
|
|
const missing = Object.entries(cell.prereqs || {}).filter(([, v]) => v !== 'present').map(([k]) => k);
|
|
if (missing.length) status = 'BLOCKED';
|
|
// a cell may narrow its write to named cases of the cell ("cases": [...]) so an incident on one case never writes a cell's other cases
|
|
// (the shipper, 8 October 2026, 20:2x UK: UX-06's overflow FAIL must not touch UX-04 or POW-01 under suite:miner)
|
|
const only = Array.isArray(cell.cases) ? new Set(cell.cases) : null;
|
|
if (only) for (const id of only) if (!(m.cases || []).includes(id)) throw new Error(`cell ${cell.cell} does not map case ${id}`);
|
|
for (const id of m.cases || []) {
|
|
if (only && !only.has(id)) continue;
|
|
const c = byId.get(id); if (!c) throw new Error(`map names an unknown case ${id}`);
|
|
// several cells may answer one case (the fleet's 4090 cell and the AMD/Intel lane's bench on GPU-03): every cell's record is kept
|
|
// in evidence_records keyed by cell, the case's decision is combined (FAIL if any cell failed, else BLOCKED if any is blocked, else
|
|
// PASS only when every cell passed, else NOT RUN), evidence_path lists every cell's path, run_id the latest
|
|
c.evidence_records = c.evidence_records || {};
|
|
if (deferral) c.deferral_note = deferral;
|
|
// the record schema (the master, p. 139): release identity, requirement id, method, decision, claim impact, reviewer (empty allowed,
|
|
// never inferred); the four approval layers (p. 18) are separate fields a batch sets explicitly, none inferred from another
|
|
const ri = batch.release_identity || {};
|
|
c.evidence_record = { requirement_id: id, decision: status, method, cell: cell.cell, manifest_sha: batch.manifest_sha, run_id: batch.run_id, evidence: cell.evidence || batch.evidence_dir, in_progress: inProgress, coverage: (m.coverage || {})[id] || m.coverage || {},
|
|
release_identity: { commit: ri.commit || batch.manifest_sha || '', lockfile: ri.lockfile || '', binary: ri.binary || '', network_object: ri.network_object || '', activation: ri.activation || '', profile_hashes: ri.profile_hashes || '' },
|
|
claim_impact: cell.claim_impact || batch.claim_impact || '', reviewer: cell.reviewer || batch.reviewer || '', at: now,
|
|
...(missing.length ? { blocked_on: missing, reason: `INT-17: missing ${missing.join(', ')}; never PASS without them` } : {}) };
|
|
if (cell.network_label) c.evidence_record.network_label = cell.network_label;
|
|
if (!c.evidence_record.network_label && (status === 'PASS' || status === 'FAIL') && method !== 'static' && ISLAND_RE.test(JSON.stringify([c.evidence_record.release_identity?.network_object, c.evidence_record.evidence, c.evidence_record.note]))) c.evidence_record.network_label = ISLAND_LABEL;
|
|
c.evidence_records[cell.cell] = c.evidence_record;
|
|
// a lifted legacy 'record' entry that carries only a no-harness reason (no run) is not a run: it never counts in the combined
|
|
// decision and is dropped once a real cell lands (8 October 2026, 21:5x UK: R2-F03-R01 read NOT RUN on master beside its PASS cell)
|
|
for (const [k, r] of Object.entries(c.evidence_records)) if (k !== cell.cell && !r.run_id && !r.evidence && r.reason) delete c.evidence_records[k];
|
|
const decs = Object.values(c.evidence_records).filter((r) => r.run_id || r.evidence || r.decision === 'BLOCKED').map((r) => r.decision);
|
|
const combined = decs.includes('FAIL') ? 'FAIL' : decs.includes('BLOCKED') ? 'BLOCKED' : decs.every((d) => d === 'PASS') ? 'PASS' : 'NOT RUN';
|
|
c.run_status = combined; c.run_id = batch.run_id; c.updated = now;
|
|
c.evidence_path = [...new Set(Object.values(c.evidence_records).map((r) => r.evidence).filter(Boolean))].join('; ');
|
|
if (combined !== 'NOT RUN') delete c.in_progress_since; else if (decs.some(() => true) && Object.values(c.evidence_records).some((r) => r.in_progress)) c.in_progress_since = c.in_progress_since || now;
|
|
const ap = cell.approvals || batch.approvals || {}; c.approvals = { scope_approved: ap.scope_approved ?? c.approvals?.scope_approved ?? null, implementation_complete: ap.implementation_complete ?? c.approvals?.implementation_complete ?? null, evidence_reproduced: ap.evidence_reproduced ?? c.approvals?.evidence_reproduced ?? null, claim_authorised: ap.claim_authorised ?? c.approvals?.claim_authorised ?? null };
|
|
touched.push(id);
|
|
}
|
|
}
|
|
// a NOT RUN row is stamped only when its status or reason changes (8 October 2026, 20:1x UK: re-stamping every NOT RUN row on every
|
|
// run made each lane's landing collide on 39 rows it never touched)
|
|
for (const [id, reason] of Object.entries(map.not_run || {})) { const c = byId.get(id); if (c && (!c.run_status || c.run_status === 'NOT RUN') && !(c.run_status === 'NOT RUN' && c.evidence_record?.reason === reason)) { c.run_status = 'NOT RUN'; c.evidence_record = { reason, at: now }; c.updated = now; } }
|
|
return touched;
|
|
}
|
|
const acceptSnapshot = (reg) => JSON.stringify(casesOf(reg).map((c) => { const o = { id: idOf(c) }; for (const k of ACCEPT_KEYS) if (k in c) o[k] = c[k]; return o; }));
|
|
if (args.includes('--self-test')) {
|
|
const d = fs.mkdtempSync('/tmp/test-record-'); let fails = 0; process.env.TEST_RECORD_NO_TREE = '1'; // the fixture cells cite fake paths; the tree rule is exercised by its own cases below
|
|
const reg = { cases: [
|
|
{ id: 'C1', method: 'Automated', accept: 'one million vectors agree' }, { id: 'C2', method: 'Automated', accept: 'parser refuses ten thousand malformed' },
|
|
{ id: 'C3', method: 'Manual review', accept: 'the reviewer signs' }, { id: 'C4', method: 'Automated; manual', accept: 'frozen verify time holds' } ] };
|
|
const map = { cells: { 'pow': { command: 'cargo test --release', box_class: 'suite', fixtures: ['F0'], cases: ['C1'] } }, not_run: { C2: 'no malformed-case corpus yet', C4: 'the hostile-load rig is not built' } };
|
|
fs.writeFileSync(`${d}/reg.json`, JSON.stringify(reg)); fs.writeFileSync(`${d}/map.json`, JSON.stringify(map));
|
|
let r = check(reg, map); if (r.bad !== 0) { console.log(`self-test failed: a complete map was refused: ${r.lines.join('; ')}`); fails = 1; }
|
|
const regV = { cases: [{ id: 'V1', method: 'Automated', accept: 'a', run_status: 'RUNNING' }] }; const rv = check(regV, { cells: { c: { command: 'x', box_class: 'b', fixtures: [], cases: ['V1'] } }, not_run: {} });
|
|
if (!(rv.bad === 1 && /vocabulary/.test(rv.lines[0]))) { console.log(`self-test failed: a RUNNING row passed --check: ${rv.lines}`); fails = 1; }
|
|
const map2 = { cells: { pow: { ...map.cells.pow, cases: ['C1', 'C9'] } }, not_run: {} };
|
|
r = check(reg, map2); if (!(r.bad >= 2 && r.lines.some((l) => l.includes('unknown case C9')) && r.lines.some((l) => l.includes('C2') && l.includes('no harness')))) { console.log(`self-test failed: an unknown id or an unmapped Automated case was not refused: ${r.lines.join('; ')}`); fails = 1; }
|
|
const before = acceptSnapshot(reg); const touched = record(reg, map, { run_id: 'r1', manifest_sha: 'abc', evidence_dir: '/e', method: 'native', cells: [{ cell: 'pow', status: 'PASS', evidence: '/e/pow.log' }] });
|
|
if (!(reg.cases[0].evidence_record.method === 'native' && reg.cases[0].evidence_record.decision === 'PASS' && reg.cases[0].evidence_record.requirement_id === 'C1' && reg.cases[0].evidence_record.reviewer === '' && reg.cases[0].approvals.claim_authorised === null)) { console.log(`self-test failed: the p.139 record fields or the four approvals (never inferred) are wrong: ${JSON.stringify(reg.cases[0].evidence_record)} ${JSON.stringify(reg.cases[0].approvals)}`); fails = 1; }
|
|
record(reg, map, { run_id: 'r1r', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'RUNNING', evidence: '/e/pow.log' }] });
|
|
if (!(reg.cases[0].run_status === 'NOT RUN' && reg.cases[0].in_progress_since)) { console.log('self-test failed: RUNNING did not become NOT RUN with in_progress_since'); fails = 1; }
|
|
let badStatus = false; try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'GREEN' }] }); } catch { badStatus = true; }
|
|
delete process.env.TEST_RECORD_NO_TREE; let badPath = ''; try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'FAIL', evidence: `${d}/missing.log`.replace(/^\//, 'rel/') }] }); } catch (e) { badPath = String(e.message); }
|
|
if (!/not in the tree at record time/.test(badPath)) { console.log(`self-test failed: an evidence path not in the tree was accepted at record time: ${badPath}`); fails = 1; }
|
|
fs.mkdirSync(`${d}/dir`); const relDir = path.relative(ROOT, `${d}/dir`); let badDir = '';
|
|
try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'FAIL', evidence: relDir }] }); } catch (e) { badDir = String(e.message); }
|
|
if (!/is a directory/.test(badDir)) { console.log(`self-test failed: a directory cited as evidence was accepted: ${badDir}`); fails = 1; }
|
|
fs.writeFileSync(`${d}/dir/f.log`, 'x'); let okFile = true; try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'FAIL', evidence: `${relDir}/f.log` }] }); } catch { okFile = false; }
|
|
if (!okFile) { console.log('self-test failed: a tree file that exists was refused as evidence'); fails = 1; }
|
|
process.env.TEST_RECORD_NO_TREE = '1';
|
|
if (!badStatus) { console.log('self-test failed: a status outside the vocabulary was accepted'); fails = 1; }
|
|
let badMethod = false; try { record(reg, map, { run_id: 'x', manifest_sha: 'abc', cells: [{ cell: 'pow', status: 'PASS' }] }); } catch { badMethod = true; }
|
|
if (!badMethod) { console.log('self-test failed: a batch with no method was accepted (methods are never conflated)'); fails = 1; }
|
|
const regO = { cases: [{ id: 'O1', method: 'Automated', accept: 'a', run_status: 'RUNNING', updated: 't', evidence_record: { cell: 'suite:x' } }, { id: 'O2', method: 'Automated', accept: 'b', run_status: 'DEFERRED' }] }; normalize(regO);
|
|
if (!(regO.cases[0].run_status === 'NOT RUN' && regO.cases[0].in_progress_since === 't' && regO.cases[0].evidence_record.method === 'native' && regO.cases[1].run_status === 'NOT RUN' && /deferred/.test(regO.cases[1].deferral_note))) { console.log(`self-test failed: normalize: ${JSON.stringify(regO)}`); fails = 1; }
|
|
// the island label: a record on the 2.0 devnet after the cut takes the label; one before it, or off the devnet, does not; a cell may carry it
|
|
const regI = { cases: [
|
|
{ id: 'I1', method: 'Automated', accept: 'a', run_status: 'PASS', evidence_records: { x: { decision: 'PASS', at: '2026-10-08T21:00:00Z', release_identity: { network_object: 'igneum-devnet-4, chain id 4465' }, evidence: '/e' } } },
|
|
{ id: 'I2', method: 'Automated', accept: 'b', run_status: 'PASS', evidence_records: { x: { decision: 'PASS', at: '2026-10-08T18:00:00Z', release_identity: { network_object: 'igneum-devnet-4' }, evidence: '/e' } } },
|
|
{ id: 'I3', method: 'Automated', accept: 'c', run_status: 'PASS', evidence_records: { x: { decision: 'PASS', at: '2026-10-08T21:00:00Z', release_identity: { network_object: 'a research object' }, evidence: '/e' } } },
|
|
{ id: 'I4', method: 'Automated', accept: 'd', run_status: 'PASS', evidence_records: { x: { decision: 'PASS', method: 'static', at: '2026-10-08T21:00:00Z', release_identity: { network_object: 'igneum-devnet-4, chain id 4465' }, evidence: '/e' } } },
|
|
{ id: 'I5', method: 'Automated', accept: 'e', run_status: 'BLOCKED', evidence_records: { x: { decision: 'BLOCKED', method: 'team-reported', at: '2026-10-08T21:00:00Z', release_identity: { network_object: 'igneum-devnet-4' }, evidence: '/e', network_label: 'on an island, not a network' } } } ] };
|
|
const ni = labelIslands(regI);
|
|
if (!(ni === 1 && regI.cases[0].evidence_records.x.network_label === ISLAND_LABEL && !regI.cases[1].evidence_records.x.network_label && !regI.cases[2].evidence_records.x.network_label && !regI.cases[3].evidence_records.x.network_label && !regI.cases[4].evidence_records.x.network_label)) { console.log(`self-test failed: the island label did not land on the devnet-4 record after the cut alone: ${ni}`); fails = 1; }
|
|
if (labelIslands(regI) !== 0) { console.log('self-test failed: the island label was applied twice'); fails = 1; }
|
|
const regC = { cases: [{ id: 'C9', method: 'Automated', accept: 'a' }] };
|
|
record(regC, { cells: { dn: { command: 'x', box_class: 'b', fixtures: [], cases: ['C9'] } }, not_run: {} }, { run_id: 'rdn', manifest_sha: 'abc', method: 'native', release_identity: { network_object: 'igneum-devnet-4, chain id 4465' }, cells: [{ cell: 'dn', status: 'PASS', evidence: '/e/dn.log' }] });
|
|
if (regC.cases[0].evidence_record.network_label !== ISLAND_LABEL) { console.log('self-test failed: a record naming the 2.0 devnet at record time did not take the island label'); fails = 1; }
|
|
// a lifted reason-only record beside a real cell: the row reads the cell's decision and the placeholder is gone
|
|
const regL = { cases: [{ id: 'L1', method: 'Automated', accept: 'a', run_status: 'NOT RUN', evidence_records: { record: { decision: 'NOT RUN', reason: 'no harness yet', at: 't' } } }] };
|
|
record(regL, { cells: { lc: { command: 'x', box_class: 'b', fixtures: [], cases: ['L1'] } }, not_run: {} }, { run_id: 'rl', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'lc', status: 'PASS', evidence: '/e/l.log' }] });
|
|
if (!(regL.cases[0].run_status === 'PASS' && !('record' in regL.cases[0].evidence_records))) { console.log(`self-test failed: a lifted reason-only record kept a PASS cell at NOT RUN or survived beside it: ${JSON.stringify(regL.cases[0].evidence_records)}`); fails = 1; }
|
|
record(reg, map, { run_id: 'r1p', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'PASS', evidence: '/e/pow.log' }] });
|
|
if (acceptSnapshot(reg) !== before) { console.log('self-test failed: a record changed an accept text'); fails = 1; }
|
|
if (!(touched.length === 1 && reg.cases[0].run_status === 'PASS' && reg.cases[0].run_id === 'r1p' && reg.cases[0].evidence_record.manifest_sha === 'abc' && reg.cases[0].evidence_path === '/e/pow.log' && reg.cases[0].updated)) { console.log(`self-test failed: the run was not written to the mapped case's live fields: ${JSON.stringify(reg.cases[0])}`); fails = 1; }
|
|
if (!(reg.cases[1].run_status === 'NOT RUN' && /corpus/.test(reg.cases[1].evidence_record.reason))) { console.log('self-test failed: an unmapped Automated case did not read NOT RUN with its reason'); fails = 1; }
|
|
if (reg.cases[0].run_status !== 'PASS') { console.log('self-test failed: the PASS after the RUNNING pass did not land'); fails = 1; }
|
|
const stamp1 = reg.cases[1].updated; record(reg, map, { run_id: 'r1b', manifest_sha: 'abc', evidence_dir: '/e', method: 'native', cells: [{ cell: 'pow', status: 'PASS', evidence: '/e/pow.log' }] });
|
|
if (reg.cases[1].updated !== stamp1) { console.log('self-test failed: an unchanged NOT RUN row was re-stamped on a later run'); fails = 1; }
|
|
if (reg.cases[2].run_status) { console.log('self-test failed: a manual case was given a run status'); fails = 1; }
|
|
const regS = { suites: [{ code: 'X', tests: [{ id: 'X-1', method: 'Automated', accept: 'a' }] }] }; if (casesOf(regS).length !== 1) { console.log('self-test failed: the suites/tests registry shape was not read'); fails = 1; }
|
|
const regN = { suites: [{ code: 'FIN', tests: [{ id: 'F-1', method: 'Automated', accept: 'keep' }] }] }; fs.writeFileSync(`${d}/regn.json`, JSON.stringify(regN));
|
|
const nr = child_process.spawnSync(process.execPath, [new URL(import.meta.url).pathname, '--note', 'FIN', 'the ruling'], { env: { ...process.env, TEST_REGISTRY: `${d}/regn.json`, TEST_MAP: `${d}/map.json` }, encoding: 'utf8' });
|
|
const regN2 = JSON.parse(fs.readFileSync(`${d}/regn.json`, 'utf8'));
|
|
if (!(nr.status === 0 && regN2.suites[0].notes?.length === 1 && regN2.suites[0].notes[0].text === 'the ruling' && regN2.suites[0].tests[0].accept === 'keep')) { console.log(`self-test failed: --note did not append a dated note to the suite and keep the accept text: ${nr.stdout} ${nr.stderr}`); fails = 1; }
|
|
record(reg, map, { run_id: 'r3', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'PASS', evidence: '/e/pow.log', prereqs: { oracle: 'present', pinned_keys: 'missing', real_proof_fixture: 'present' } }] });
|
|
if (!(reg.cases[0].run_status === 'BLOCKED' && reg.cases[0].evidence_record.blocked_on?.[0] === 'pinned_keys')) { console.log(`self-test failed: a PASS with a missing prerequisite was not BLOCKED (INT-17): ${JSON.stringify(reg.cases[0].run_status)}`); fails = 1; }
|
|
record(reg, map, { run_id: 'r4', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'pow', status: 'PASS', evidence: '/e/pow.log', prereqs: { oracle: 'present', pinned_keys: 'present', real_proof_fixture: 'present' } }] });
|
|
if (reg.cases[0].run_status !== 'PASS') { console.log('self-test failed: a PASS with every prerequisite present was not written'); fails = 1; }
|
|
const reg2 = { cases: [{ id: 'G3', method: 'Automated', accept: 'a' }] }; const mapG = { cells: { fleet: { command: 'x', box_class: 'b', fixtures: [], cases: ['G3'] }, amd: { command: 'y', box_class: 'b', fixtures: [], cases: ['G3'] } }, not_run: {} };
|
|
record(reg2, mapG, { run_id: 'f1', manifest_sha: 'abc', method: 'GPU', cells: [{ cell: 'fleet', status: 'RUNNING', evidence: '/e/fleet' }] });
|
|
record(reg2, mapG, { run_id: 'a1', manifest_sha: 'abc', method: 'GPU', cells: [{ cell: 'amd', status: 'PASS', evidence: '/e/amd' }] });
|
|
const g = reg2.cases[0];
|
|
if (!(Object.keys(g.evidence_records).length === 2 && g.evidence_records.fleet.run_id === 'f1' && g.run_status === 'NOT RUN' && g.in_progress_since && /\/e\/fleet; \/e\/amd|\/e\/amd; \/e\/fleet/.test(g.evidence_path))) { console.log(`self-test failed: two cells on one case did not keep both records with a combined decision: ${JSON.stringify(g)}`); fails = 1; }
|
|
record(reg2, mapG, { run_id: 'f2', manifest_sha: 'abc', method: 'GPU', cells: [{ cell: 'fleet', status: 'PASS', evidence: '/e/fleet' }] });
|
|
if (g.run_status !== 'PASS') { console.log('self-test failed: PASS on every cell did not combine to PASS'); fails = 1; }
|
|
record(reg2, mapG, { run_id: 'a2', manifest_sha: 'abc', method: 'GPU', cells: [{ cell: 'amd', status: 'FAIL', evidence: '/e/amd' }] });
|
|
if (g.run_status !== 'FAIL') { console.log('self-test failed: a FAIL on one cell did not combine to FAIL'); fails = 1; }
|
|
const regF = { cases: [{ id: 'M1', method: 'Automated', accept: 'a' }, { id: 'M2', method: 'Automated', accept: 'b' }] }; const mapF = { cells: { miner: { command: 'x', box_class: 'b', fixtures: [], cases: ['M1', 'M2'] } }, not_run: {} };
|
|
record(regF, mapF, { run_id: 'inc', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'miner', status: 'FAIL', evidence: 'e', cases: ['M2'] }] });
|
|
if (!(regF.cases[1].run_status === 'FAIL' && !regF.cases[0].run_status)) { console.log('self-test failed: a cell with a cases filter wrote beyond the named cases'); fails = 1; }
|
|
let filtThrew = false; try { record(regF, mapF, { run_id: 'inc2', manifest_sha: 'abc', method: 'native', cells: [{ cell: 'miner', status: 'FAIL', cases: ['Z9'] }] }); } catch { filtThrew = true; }
|
|
if (!filtThrew) { console.log('self-test failed: a cases filter naming a case the cell does not map was accepted'); fails = 1; }
|
|
let cutThrew = false; try { record(reg, map, { run_id: 'c1', manifest_sha: 'abc', method: 'native', cut: { binary: '/root/x', commit_string: 'abc', kit_isa: 'clean' }, cells: [] }); } catch (e) { cutThrew = /cut batch is refused/.test(e.message); }
|
|
if (!cutThrew) { console.log('self-test failed: a cut batch without a box path and the ISA clean line was accepted'); fails = 1; }
|
|
let cutOk = true; try { record(reg, map, { run_id: 'c2', manifest_sha: 'abc1234', method: 'native', cut: { binary: 'build-1:/srv/artefacts/x/igneumd', commit_string: 'abc1234', kit_isa: 'kit-isa: every binary is clean of AVX-512 (the x86-64-v3 baseline)' }, cells: [] }); } catch { cutOk = false; }
|
|
if (!cutOk) { console.log('self-test failed: a cut batch with the read-back and the ISA line was refused'); fails = 1; }
|
|
let threw = false; try { record(reg, map, { run_id: 'r2', manifest_sha: 'x', method: 'native', cells: [{ cell: 'ghost', status: 'PASS' }] }); } catch { threw = true; }
|
|
if (!threw) { console.log('self-test failed: a batch naming a cell not in the map was accepted'); fails = 1; }
|
|
fs.rmSync(d, { recursive: true, force: true });
|
|
if (!fails) console.log('self-test passed: a complete map checks; an unknown case id and an unmapped Automated case are refused; a run batch writes run_status, run_id, evidence_path, updated and the evidence record to the mapped cases only, leaves every accept text byte-identical, gives an unmapped Automated case NOT RUN with its reason and a manual case nothing; a batch naming an unknown cell is refused; --note appends a dated note to a suite and never touches an accept text; an unchanged NOT RUN row is not re-stamped; a cell with a missing prerequisite is BLOCKED, never PASS (INT-17); a cut batch needs the binary on a box, the commit string read back and the kit ISA clean line; a cell may narrow its write to named cases; the decision vocabulary is exactly NOT RUN, BLOCKED, FAIL, PASS with RUNNING read as in progress; every record carries the p.139 fields and the four approvals, never inferred; several cells on one case keep every record and combine the decision');
|
|
process.exit(fails);
|
|
}
|
|
const reg = load(REG); const map = load(MAP);
|
|
if (args.includes('--check')) { const r = check(reg, map); for (const l of r.lines) console.error(`test-record: ${l}`); console.log(`test-record: ${r.automated} Automated cases, ${r.mapped} mapped to cells, ${r.notRun} NOT RUN with a reason${r.bad ? `, ${r.bad} problems` : ''}`); process.exit(r.bad ? 1 : 0); }
|
|
if (args.includes('--label-islands')) { const n = labelIslands(reg); fs.writeFileSync(REG, JSON.stringify(reg, null, 2) + '\n'); console.log(`test-record: ${n} record(s) measured on the 2.0 devnet since ${ISLAND_SINCE} labelled "${ISLAND_LABEL}"`); process.exit(0); }
|
|
if (args.includes('--normalize')) { const n = normalize(reg); fs.writeFileSync(REG, JSON.stringify(reg, null, 2) + '\n'); console.log(`test-record: normalized ${n} rows to the decision vocabulary and the record schema`); process.exit(0); }
|
|
if (arg('--cases')) { console.log(((map.cells || {})[arg('--cases')]?.cases || []).join(',')); process.exit(0); }
|
|
if (arg('--note-file')) { const n = load(arg('--note-file')); args.push('--note', n.suite, n.text); }
|
|
if (arg('--note')) {
|
|
const code = arg('--note'); const text = args[args.indexOf('--note') + 2];
|
|
if (code === 'registry' && text) { const before = acceptSnapshot(reg); reg.notes = reg.notes || []; reg.notes.push({ at: new Date().toISOString(), text }); if (acceptSnapshot(reg) !== before) { console.error('test-record: REFUSED'); process.exit(1); } fs.writeFileSync(REG, JSON.stringify(reg, null, 2) + '\n'); console.log(`test-record: registry note ${reg.notes.length}: ${text.slice(0, 80)}`); process.exit(0); }
|
|
const suite = (reg.suites || []).find((s) => s.code === code);
|
|
if (!suite || !text) { console.error(`test-record: --note needs a suite code in the registry and a text (got ${code}, ${text ? 'text' : 'no text'})`); process.exit(2); }
|
|
const before = acceptSnapshot(reg); suite.notes = suite.notes || []; suite.notes.push({ at: new Date().toISOString(), text });
|
|
if (acceptSnapshot(reg) !== before) { console.error('test-record: REFUSED: the note would change an accept text'); process.exit(1); }
|
|
fs.writeFileSync(REG, JSON.stringify(reg, null, 2) + '\n'); console.log(`test-record: note ${suite.notes.length} on ${code}: ${text.slice(0, 80)}`); process.exit(0);
|
|
}
|
|
if (arg('--record')) {
|
|
const batch = load(arg('--record')); const before = acceptSnapshot(reg); const touched = record(reg, map, batch);
|
|
if (acceptSnapshot(reg) !== before) { console.error('test-record: REFUSED: the record would change an accept text'); process.exit(1); }
|
|
fs.writeFileSync(REG, JSON.stringify(reg, null, 2) + '\n'); console.log(`test-record: run ${batch.run_id} (manifest ${String(batch.manifest_sha).slice(0, 8)}) written to ${touched.length} cases: ${touched.join(', ')}`); process.exit(0);
|
|
}
|
|
console.error('usage: test-record.mjs --check | --record <batch.json> | --cases <cell> | --self-test'); process.exit(2);
|