Files
pbakaus_impeccable/tests/oracle/run.mjs
T
Paul BakausandClaude Fable 5.1 9961848ce2 oracle: replay byte-for-byte on Linux too
The corpus was recorded on macOS and eight cases failed on ubuntu CI for
reasons that were all environment, not behavior:

- stageWorkspace returns the realpath of the staged dir. macOS's tmpdir is a
  symlink and two goldens (context-dir-override, live-accept-source-locked)
  had recorded that artifact; both re-recorded, reviewed in DELTAS.md. The
  source-locked case now actually exercises the lock it is named for.
- context-lowercase-product-name declares platforms: ['darwin', 'win32'];
  run.mjs skips such cases elsewhere and says so in the summary.
- The hook-project workspace's empty provider skill folders (.claude,
  .cursor) are now tracked with .gitkeep; git cannot track empty
  directories, so a fresh checkout had none and hooks on found nothing to
  repair.
- crates/live's read_dir_raw sorts entries by name: the goldens hold the
  order macOS returned, Linux returns hash order, and the source-candidate
  lists in live-commit output depended on it.

macOS: 795 pass, 0 fail. The Svelte accept cases additionally need the
public repo's node_modules on the machine that runs them (CI now installs
them).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vau2X53xGTjjTCXWMVBoNY
2026-09-01 16:24:13 -07:00

44 lines
2.0 KiB
JavaScript

#!/usr/bin/env node
/**
* Replay the corpus against an implementation and diff against goldens.
* IMPECCABLE_BIN=/path/to/impeccable node tests/oracle/run.mjs [prefix]
* node tests/oracle/run.mjs --js [prefix] # self-check: JS vs its own goldens
* Exit 1 on any difference. Cases whose id appears in DELTAS.md as accepted
* are reported but not counted as failures.
*/
import fs from 'node:fs';
import path from 'node:path';
import { allCases, runCase, readGolden, diffResults, caseRunsHere, ORACLE_DIR } from './lib.mjs';
const argv = process.argv.slice(2);
const impl = argv.includes('--js') ? 'js' : 'bin';
const prefix = argv.find(a => !a.startsWith('--')) || '';
const accepted = loadAcceptedDeltas();
const cases = (await allCases()).filter(c => c.id.startsWith(prefix));
let pass = 0, fail = 0, acceptedCount = 0, missing = 0, skipped = 0;
for (const c of cases) {
if (!caseRunsHere(c)) { skipped++; process.stdout.write(`-- ${c.id}: skipped (platforms: ${c.platforms.join(', ')})\n`); continue; }
const golden = readGolden(c.id);
if (!golden) { missing++; process.stdout.write(`?? ${c.id}: no golden (run record.mjs)\n`); continue; }
const actual = runCase(c, { impl });
const diffs = diffResults(golden, actual);
if (!diffs.length) { pass++; continue; }
if (accepted.has(c.id)) { acceptedCount++; process.stdout.write(`~~ ${c.id}: differs (accepted delta)\n`); continue; }
fail++;
process.stdout.write(`XX ${c.id}\n${diffs.map(d => ' ' + d.replace(/\n/g, '\n ')).join('\n')}\n`);
}
process.stdout.write(`\n${pass} pass, ${fail} fail, ${acceptedCount} accepted deltas, ${missing} missing goldens${skipped ? `, ${skipped} skipped on ${process.platform}` : ''} (${impl})\n`);
process.exit(fail || missing ? 1 : 0);
function loadAcceptedDeltas() {
const p = path.join(ORACLE_DIR, 'DELTAS.md');
if (!fs.existsSync(p)) return new Set();
const ids = new Set();
for (const line of fs.readFileSync(p, 'utf8').split('\n')) {
const m = /^- `([^`]+)`/.exec(line);
if (m) ids.add(m[1]);
}
return ids;
}