// Row 307 (#1814): checks the new tests' literals against row 270's code at base 1e629c892.
//
// node capture.mjs
//
// Reads the FIXTURES and CASES blocks (between `// capture:begin` and `// capture:end`) from the
// candidate's two new test files. Replays each fixture's steps with the base's collectCompactions,
// harness named by string as row 270 takes it, with the clock at 12:00:00 and one second a step,
// and compares the ledger byte for byte. Prints the base's compactionCount for each. Runs the
// base's scanPi over each case and compares the answer the base's reason order gives (:301) with
// version PI_VERSION. Exit 0 only when every one matches. Writes only under TMPDIR.
import assert from "node:assert/strict";
import { appendFileSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import { pathToFileURL } from "node:url";
const [base, cand] = process.argv.slice(2).map((p) => p && resolve(p));
if (!base || !cand) {
console.error("usage: node capture.mjs ");
process.exit(2);
}
function block(file) {
const text = readFileSync(join(cand, file), "utf8");
const m = /\n\/\/ capture:begin\nconst [A-Z]+ = (\{[\s\S]*?\});\n\/\/ capture:end\n/.exec(text);
if (!m) throw new Error(`${file}: no capture block`);
return JSON.parse(m[1]);
}
const FIXTURES = block("packages/seat/tests/compactions-ledger.test.mjs");
const CASES = block("packages/plugins/tests/harness-compactions.test.mjs");
const seat = await import(pathToFileURL(join(base, "packages/seat/src/compactions.mjs")).href);
const { sessionStore } = await import(pathToFileURL(join(base, "packages/seat/src/session.mjs")).href);
const root = mkdtempSync(join(tmpdir(), "g307-capture-"));
let failed = 0;
const report = (what, same, detail) => {
console.log(`${same ? "MATCH" : "DIFF "} ${what}${detail ? ` ${detail}` : ""}`);
if (!same) failed++;
};
try {
for (const [name, fx] of Object.entries(FIXTURES)) {
mkdirSync(join(root, `f-${name}`));
const store = sessionStore(join(root, `f-${name}`), "acme", "th1", "s1");
for (const [file, text] of Object.entries(fx.streams)) writeFileSync(join(store.session, file), text);
for (const [file, text] of Object.entries(fx.projects ?? {})) writeFileSync(join(store.projects, file), text);
let tick = 0;
const now = () => new Date(Date.UTC(2026, 9, 22, 12, 0, tick++)).toISOString();
for (const step of fx.steps) {
if (step.tear !== undefined) appendFileSync(join(store.dir, seat.LEDGER), step.tear);
else seat.collectCompactions(store, step.collect, { now, ...(step.budget === undefined ? {} : { budget: step.budget }) });
}
const got = readFileSync(join(store.dir, seat.LEDGER), "utf8");
const want = fx.ledger.join("\n") + "\n";
report(`ledger ${name}`, got === want, got === want ? `(${Buffer.byteLength(got)} bytes)` : `\n--- base wrote\n${got}--- test has\n${want}`);
const count = seat.compactionCount(store.dir);
report(`base count ${name}`, JSON.stringify(count) === JSON.stringify(fx.count), JSON.stringify(count));
}
for (const [name, c] of Object.entries(CASES)) {
const dir = join(root, `c-${name}`);
mkdirSync(dir);
for (const [file, text] of Object.entries(c.streams)) writeFileSync(join(dir, file), text);
const scan = seat.scanPi(dir, c.cursors, c.budget, c.cap);
const reason = ["store-incomplete", "store-unreadable", "not-collected"].find((p) => scan.problems.includes(p)) ?? null;
const answer = { found: scan.found, cursors: scan.cursors, known: reason === null, reason, version: seat.PI_VERSION };
let same = true;
try {
assert.deepStrictEqual(answer, c.answer);
} catch {
same = false;
}
report(`scan ${name}`, same, JSON.stringify(scan));
}
} finally {
rmSync(root, { recursive: true, force: true });
}
console.log(failed ? `${failed} differ` : "all match");
process.exit(failed ? 1 : 0);