gizmoduck: row 307 (#1814, Vikunja 598) new tests, red first: row 270's ledgers per reason read the same count and the next collection goes through the harness module, core refuses an answer out of contract, pi answers what base scanPi read, claude-code answers harness-unsupported, a module without compactions refuses missing-export; capture.mjs checks the literals against base 1e629c892

This commit is contained in:
jason.woltje committed 2026-10-23 08:26:29 -05:00
1 parent cb048b93ce
commit 1f6db15899
3 files changed
+337

No files matched your search

@@ -0,0 +1,78 @@
// Row 307 (#1814): checks the new tests' literals against row 270's code at base 1e629c892.
//
// node capture.mjs <base checkout at 1e629c892> <candidate checkout>
//
// 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 <base checkout> <candidate checkout>");
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)) {
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);
@@ -0,0 +1,75 @@
// Row 307 (#1814, Vikunja 598): the harness kind's `compactions`. pi's answers what row 270's
// scanPi read at 1e629c892, with its reason order and version; claude-code reads nothing and
// answers harness-unsupported; a module without the export doesn't load.
//
// CASES: each case's streams and cursors, scanned at 1e629c892 with its budget and cap, give its
// answer (agents/gizmoduck/work/queue-307/capture.mjs checks that).
import test from "node:test";
import assert from "node:assert/strict";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { KINDS } from "../src/kinds.mjs";
import * as pi from "../harness/pi/index.mjs";
import * as claude from "../harness/claude-code/index.mjs";
import { tree } from "./helpers.mjs";
// capture:begin
const CASES = {
"plain": {"streams": {"a.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\n{\"type\":\"compaction\",\"id\":\"c1\",\"parentId\":null,\"timestamp\":\"2026-10-22T11:01:00.000Z\",\"summary\":\"s\",\"firstKeptEntryId\":\"k\",\"tokensBefore\":100}\n"}, "cursors": {}, "budget": 67108864, "cap": 1024, "answer": {"found": [{"entry": "c1", "completedAt": "2026-10-22T11:01:00.000Z", "stream": "a.jsonl"}], "cursors": {"a.jsonl": {"bytes": 233, "tail": "39650b0c01a938998403d9dec3f8c224a01509ccde607711e962bf68bcbff54a"}}, "known": true, "reason": null, "version": "0.85.1"}},
"budget": {"streams": {"a.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\n{\"type\":\"compaction\",\"id\":\"c1\",\"parentId\":null,\"timestamp\":\"2026-10-22T11:01:00.000Z\",\"summary\":\"s\",\"firstKeptEntryId\":\"k\",\"tokensBefore\":100}\n"}, "cursors": {}, "budget": 100, "cap": 1024, "answer": {"found": [], "cursors": {"a.jsonl": {"bytes": 90, "tail": "2dff60ffd3bc96efa6dd8d740044255d75a1f71d82e7e99a39158d18cf211fc5"}}, "known": false, "reason": "not-collected", "version": "0.85.1"}},
"cap": {"streams": {"a.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\n{\"type\":\"compaction\",\"id\":\"c1\",\"parentId\":null,\"timestamp\":\"2026-10-22T11:01:00.000Z\",\"summary\":\"s\",\"firstKeptEntryId\":\"k\",\"tokensBefore\":100}\n", "b.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\n"}, "cursors": {}, "budget": 67108864, "cap": 1, "answer": {"found": [{"entry": "c1", "completedAt": "2026-10-22T11:01:00.000Z", "stream": "a.jsonl"}], "cursors": {"a.jsonl": {"bytes": 233, "tail": "39650b0c01a938998403d9dec3f8c224a01509ccde607711e962bf68bcbff54a"}}, "known": false, "reason": "not-collected", "version": "0.85.1"}},
"shrank": {"streams": {"a.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\n"}, "cursors": {"a.jsonl": {"bytes": 233, "tail": "39650b0c01a938998403d9dec3f8c224a01509ccde607711e962bf68bcbff54a"}}, "budget": 67108864, "cap": 1024, "answer": {"found": [], "cursors": {"a.jsonl": {"bytes": 90, "tail": "2dff60ffd3bc96efa6dd8d740044255d75a1f71d82e7e99a39158d18cf211fc5"}}, "known": false, "reason": "store-incomplete", "version": "0.85.1"}},
"header": {"streams": {"a.jsonl": "{\"type\":\"message\",\"id\":\"m1\"}\n"}, "cursors": {}, "budget": 67108864, "cap": 1024, "answer": {"found": [], "cursors": {"a.jsonl": {"bytes": 29, "tail": "91f8cd26da181eddfdbefaef87896493bf488791937a099f5899467b04fc68df"}}, "known": false, "reason": "store-unreadable", "version": "0.85.1"}}
};
// capture:end
function stores(t, streams = {}, projects = {}) {
const root = mkdtempSync(join(tmpdir(), "mosaic-harness-compactions-"));
t.after(() => rmSync(root, { recursive: true, force: true }));
const store = { session: join(root, "session"), projects: join(root, "claude-projects") };
for (const [dir, files] of [[store.session, streams], [store.projects, projects]]) {
mkdirSync(dir);
for (const [name, text] of Object.entries(files)) writeFileSync(join(dir, name), text);
}
return store;
}
for (const [name, c] of Object.entries(CASES)) {
test(`row 307 pi answers what row 270 read: ${name}`, (t) => {
const store = stores(t, c.streams);
assert.deepEqual(pi.compactions({ store, cursors: c.cursors, budget: c.budget, streams: c.cap, first: false }), c.answer);
});
}
test("row 307 pi's first collection over Claude history answers harness-unsupported without a scan, and a later one scans", (t) => {
const { streams, budget, cap, answer } = CASES.plain;
const store = stores(t, streams, { "p.jsonl": "{}\n" });
const args = { store, cursors: {}, budget, streams: cap };
assert.deepEqual(pi.compactions({ ...args, first: true }), { found: [], cursors: {}, known: false, reason: "harness-unsupported", version: "0.85.1" });
assert.deepEqual(pi.compactions({ ...args, first: false }), answer);
// With no Claude history, the first collection scans too.
assert.deepEqual(pi.compactions({ ...args, store: stores(t, streams), first: true }), answer);
});
test("row 307 claude-code reads nothing and answers harness-unsupported with no version", () => {
const store = { session: "/nonexistent/session", projects: "/nonexistent/claude-projects" };
for (const first of [true, false]) {
assert.deepEqual(claude.compactions({ store, cursors: {}, budget: 1 << 20, streams: 32, first }),
{ found: [], cursors: {}, known: false, reason: "harness-unsupported", version: null });
}
});
test("row 307 a harness module without compactions doesn't load: missing-export", async (t) => {
const s = tree(t);
const url = pathToFileURL(resolve(fileURLToPath(new URL("../harness/pi/index.mjs", import.meta.url)))).href;
const names = ["interfaceVersion", ...KINDS.harness.exports.filter((k) => k !== "compactions")];
s.write("harness", "no-compactions", `export { ${names.join(", ")} } from ${JSON.stringify(url)};\n`);
const l = await s.loader();
const result = await l.load({ harness: ["no-compactions"] });
assert.deepEqual(result.refused.map((e) => [e.kind, e.name, e.code]), [["harness", "no-compactions", "missing-export"]]);
assert.match(result.refused[0].message, /^harness no-compactions doesn't export compactions$/);
assert.deepEqual(l.loaded().harness, []);
});
@@ -0,0 +1,184 @@
// Row 307 (#1814, Vikunja 598): core keeps the ledger and asks the harness module for the
// compactions. A ledger row 270 wrote reads the same count after the move, the next collection
// goes through the module's `compactions`, and core refuses an answer outside the contract before
// it writes anything.
//
// FIXTURES are what row 270's collectCompactions wrote at 1e629c892, one ledger per reason it
// writes plus a torn one: each fixture's streams, Claude projects and steps, replayed there with
// the clock at 12:00:00 and one second a step, give its ledger byte for byte
// (agents/gizmoduck/work/queue-307/capture.mjs checks that). `count` is compactionCount over it,
// and `next` is the count after one more pi collection at the next second.
import { test } from "node:test";
import assert from "node:assert/strict";
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { collectCompactions, compactionCount, LEDGER } from "../src/compactions.mjs";
import { sessionStore } from "../src/session.mjs";
import * as pi from "../../plugins/harness/pi/index.mjs";
// capture:begin
const FIXTURES = {
"known": {
"streams": {"a.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\n{\"type\":\"compaction\",\"id\":\"c1\",\"parentId\":null,\"timestamp\":\"2026-10-22T11:01:00.000Z\",\"summary\":\"s\",\"firstKeptEntryId\":\"k\",\"tokensBefore\":100}\n"},
"steps": [{"collect": "pi"}],
"ledger": [
"{\"v\":1,\"kind\":\"compaction\",\"entry\":\"c1\",\"completedAt\":\"2026-10-22T11:01:00.000Z\",\"stream\":\"a.jsonl\",\"at\":\"2026-10-22T12:00:00.000Z\"}",
"{\"v\":1,\"kind\":\"cursor\",\"stream\":\"a.jsonl\",\"bytes\":233,\"tail\":\"39650b0c01a938998403d9dec3f8c224a01509ccde607711e962bf68bcbff54a\",\"at\":\"2026-10-22T12:00:00.000Z\"}",
"{\"v\":1,\"kind\":\"collected\",\"at\":\"2026-10-22T12:00:00.000Z\",\"known\":true,\"reason\":null,\"harness\":\"pi\",\"version\":\"0.85.1\"}"
],
"count": {"count": 1, "known": true, "reason": null, "at": "2026-10-22T12:00:00.000Z"},
"next": {"count": 1, "known": true, "reason": null, "at": "2026-10-22T12:00:01.000Z"}
},
"store-incomplete": {
"streams": {"a.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\nnot json\n"},
"steps": [{"collect": "pi"}],
"ledger": [
"{\"v\":1,\"kind\":\"cursor\",\"stream\":\"a.jsonl\",\"bytes\":99,\"tail\":\"14607eb2c2f70f460e1a420da1b4ead7f00f2a81cc4105e9e55e6c5c828d6626\",\"at\":\"2026-10-22T12:00:00.000Z\"}",
"{\"v\":1,\"kind\":\"collected\",\"at\":\"2026-10-22T12:00:00.000Z\",\"known\":false,\"reason\":\"store-incomplete\",\"harness\":\"pi\",\"version\":\"0.85.1\"}"
],
"count": {"count": null, "known": false, "reason": "store-incomplete", "at": "2026-10-22T12:00:00.000Z"},
"next": {"count": null, "known": false, "reason": "store-incomplete", "at": "2026-10-22T12:00:01.000Z"}
},
"store-unreadable": {
"streams": {"a.jsonl": "{\"type\":\"message\",\"id\":\"m1\"}\n"},
"steps": [{"collect": "pi"}],
"ledger": [
"{\"v\":1,\"kind\":\"cursor\",\"stream\":\"a.jsonl\",\"bytes\":29,\"tail\":\"91f8cd26da181eddfdbefaef87896493bf488791937a099f5899467b04fc68df\",\"at\":\"2026-10-22T12:00:00.000Z\"}",
"{\"v\":1,\"kind\":\"collected\",\"at\":\"2026-10-22T12:00:00.000Z\",\"known\":false,\"reason\":\"store-unreadable\",\"harness\":\"pi\",\"version\":\"0.85.1\"}"
],
"count": {"count": null, "known": false, "reason": "store-unreadable", "at": "2026-10-22T12:00:00.000Z"},
"next": {"count": 0, "known": true, "reason": null, "at": "2026-10-22T12:00:01.000Z"}
},
"not-collected": {
"streams": {"a.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\n{\"type\":\"compaction\",\"id\":\"c1\",\"parentId\":null,\"timestamp\":\"2026-10-22T11:01:00.000Z\",\"summary\":\"s\",\"firstKeptEntryId\":\"k\",\"tokensBefore\":100}\n"},
"steps": [{"collect": "pi", "budget": 100}],
"ledger": [
"{\"v\":1,\"kind\":\"cursor\",\"stream\":\"a.jsonl\",\"bytes\":90,\"tail\":\"2dff60ffd3bc96efa6dd8d740044255d75a1f71d82e7e99a39158d18cf211fc5\",\"at\":\"2026-10-22T12:00:00.000Z\"}",
"{\"v\":1,\"kind\":\"collected\",\"at\":\"2026-10-22T12:00:00.000Z\",\"known\":false,\"reason\":\"not-collected\",\"harness\":\"pi\",\"version\":\"0.85.1\"}"
],
"count": {"count": null, "known": false, "reason": "not-collected", "at": "2026-10-22T12:00:00.000Z"},
"next": {"count": 1, "known": true, "reason": null, "at": "2026-10-22T12:00:01.000Z"}
},
"claude-code": {
"streams": {},
"steps": [{"collect": "claude-code"}],
"ledger": [
"{\"v\":1,\"kind\":\"collected\",\"at\":\"2026-10-22T12:00:00.000Z\",\"known\":false,\"reason\":\"harness-unsupported\",\"harness\":\"claude-code\",\"version\":null}"
],
"count": {"count": null, "known": false, "reason": "harness-unsupported", "at": "2026-10-22T12:00:00.000Z"},
"next": {"count": null, "known": false, "reason": "harness-unsupported", "at": "2026-10-22T12:00:01.000Z"}
},
"claude-history": {
"streams": {"a.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\n{\"type\":\"compaction\",\"id\":\"c1\",\"parentId\":null,\"timestamp\":\"2026-10-22T11:01:00.000Z\",\"summary\":\"s\",\"firstKeptEntryId\":\"k\",\"tokensBefore\":100}\n"},
"projects": {"p.jsonl": "{}\n"},
"steps": [{"collect": "pi"}],
"ledger": [
"{\"v\":1,\"kind\":\"collected\",\"at\":\"2026-10-22T12:00:00.000Z\",\"known\":false,\"reason\":\"harness-unsupported\",\"harness\":\"pi\",\"version\":\"0.85.1\"}"
],
"count": {"count": null, "known": false, "reason": "harness-unsupported", "at": "2026-10-22T12:00:00.000Z"},
"next": {"count": 1, "known": false, "reason": "harness-unsupported", "at": "2026-10-22T12:00:01.000Z"}
},
"torn": {
"streams": {"a.jsonl": "{\"type\":\"session\",\"version\":3,\"id\":\"a\",\"timestamp\":\"2026-10-22T11:00:00.000Z\",\"cwd\":\"/w\"}\n{\"type\":\"compaction\",\"id\":\"c1\",\"parentId\":null,\"timestamp\":\"2026-10-22T11:01:00.000Z\",\"summary\":\"s\",\"firstKeptEntryId\":\"k\",\"tokensBefore\":100}\n"},
"steps": [{"collect": "pi"}, {"tear": "{\"v\":1,\"kind\":\"coll"}, {"collect": "pi"}],
"ledger": [
"{\"v\":1,\"kind\":\"compaction\",\"entry\":\"c1\",\"completedAt\":\"2026-10-22T11:01:00.000Z\",\"stream\":\"a.jsonl\",\"at\":\"2026-10-22T12:00:00.000Z\"}",
"{\"v\":1,\"kind\":\"cursor\",\"stream\":\"a.jsonl\",\"bytes\":233,\"tail\":\"39650b0c01a938998403d9dec3f8c224a01509ccde607711e962bf68bcbff54a\",\"at\":\"2026-10-22T12:00:00.000Z\"}",
"{\"v\":1,\"kind\":\"collected\",\"at\":\"2026-10-22T12:00:00.000Z\",\"known\":true,\"reason\":null,\"harness\":\"pi\",\"version\":\"0.85.1\"}",
"{\"v\":1,\"kind\":\"coll",
"{\"v\":1,\"kind\":\"collected\",\"at\":\"2026-10-22T12:00:01.000Z\",\"known\":true,\"reason\":null,\"harness\":\"pi\",\"version\":\"0.85.1\"}"
],
"count": {"count": 1, "known": false, "reason": "store-incomplete", "at": "2026-10-22T12:00:01.000Z"},
"next": {"count": 1, "known": false, "reason": "store-incomplete", "at": "2026-10-22T12:00:02.000Z"}
}
};
// capture:end
function setup(t, fx = { streams: {}, ledger: null }) {
const root = mkdtempSync(join(tmpdir(), "seat-compactions-ledger-"));
t.after(() => rmSync(root, { recursive: true, force: true }));
const store = sessionStore(root, "acme", "th1", "s1");
for (const [name, text] of Object.entries(fx.streams)) writeFileSync(join(store.session, name), text);
for (const [name, text] of Object.entries(fx.projects ?? {})) writeFileSync(join(store.projects, name), text);
if (fx.ledger) writeFileSync(join(store.dir, LEDGER), fx.ledger.join("\n") + "\n", { mode: 0o600 });
const ledger = () => {
try {
return readFileSync(join(store.dir, LEDGER), "utf8");
} catch (e) {
if (e.code === "ENOENT") return null;
throw e;
}
};
return { root, store, ledger };
}
for (const [name, fx] of Object.entries(FIXTURES)) {
test(`row 307 the ${name} ledger row 270 wrote reads the same count`, (t) => {
const f = setup(t, fx);
assert.deepEqual(compactionCount(f.store.dir), fx.count);
});
test(`row 307 after the ${name} ledger, one collection through pi's module answers the next count`, (t) => {
const f = setup(t, fx);
assert.deepEqual(collectCompactions(f.store, { name: "pi", compactions: pi.compactions }, { now: () => fx.next.at }), fx.next);
});
}
const ok = { found: [], cursors: {}, known: true, reason: null, version: null };
const HEX = "0".repeat(64);
const BAD = [
[null, "not an object"],
[[], "not an object"],
[{ ...ok, found: {} }, "found isn't a list"],
[{ ...ok, found: [{ entry: "", completedAt: null, stream: "a.jsonl" }] }, "a found entry has no entry id"],
[{ ...ok, found: ["c1"] }, "a found entry has no entry id"],
[{ ...ok, found: [{ entry: "c1", completedAt: 5, stream: "a.jsonl" }] }, "found c1 has a completedAt that isn't a string or null"],
[{ ...ok, found: [{ entry: "c1", completedAt: null, stream: "" }] }, "found c1 has no stream"],
[{ ...ok, cursors: [] }, "cursors isn't an object"],
[{ ...ok, cursors: { "a.jsonl": { bytes: -1, tail: HEX } } }, 'cursor "a.jsonl" isn\'t { bytes, tail }'],
[{ ...ok, cursors: { "a.jsonl": { bytes: 1.5, tail: HEX } } }, 'cursor "a.jsonl" isn\'t { bytes, tail }'],
[{ ...ok, cursors: { "a.jsonl": { bytes: 1, tail: HEX.toUpperCase().replace(/0/g, "A") } } }, 'cursor "a.jsonl" isn\'t { bytes, tail }'],
[{ ...ok, cursors: { "a.jsonl": { bytes: 1, tail: "0".repeat(63) } } }, 'cursor "a.jsonl" isn\'t { bytes, tail }'],
[{ ...ok, reason: "lost", known: false }, 'reason "lost" isn\'t one of store-incomplete, store-unreadable, not-collected, harness-unsupported'],
[{ ...ok, reason: "not-collected" }, "known must be true exactly when reason is null"],
[{ ...ok, known: false }, "known must be true exactly when reason is null"],
[{ ...ok, known: 1 }, "known must be true exactly when reason is null"],
[{ ...ok, version: 1 }, "version isn't a string or null"],
];
test("row 307 core refuses an answer outside the contract and appends nothing", (t) => {
for (const fx of [undefined, FIXTURES.known]) {
const f = setup(t, fx);
const before = f.ledger();
for (const [answer, what] of BAD) {
const message = `harness odd compactions: bad answer: ${what}`;
assert.throws(() => collectCompactions(f.store, { name: "odd", compactions: () => answer }), { message }, JSON.stringify(answer));
assert.equal(f.ledger(), before, JSON.stringify(answer));
}
// The module's own throw reaches the caller as it is, and nothing is written either.
const boom = new Error("boom");
assert.throws(() => collectCompactions(f.store, { name: "odd", compactions: () => { throw boom; } }), (e) => e === boom);
assert.equal(f.ledger(), before);
// A good answer is written: the check refuses only what's out of contract.
assert.equal(collectCompactions(f.store, { name: "odd", compactions: () => ok }, { now: () => "2026-10-22T12:00:09.000Z" }).at, "2026-10-22T12:00:09.000Z");
}
});
test("row 307 the module gets the store's two native directories, a copy of the cursors, the budget, the cap and first", (t) => {
const seen = [];
// The module writes into the cursors it got and answers the same cursor: core's ledger copy
// doesn't have it, so core writes it.
const harness = { name: "odd", compactions: (args) => (seen.push(structuredClone(args)), args.cursors.x = { bytes: 0, tail: HEX }, { ...ok, cursors: { x: { bytes: 0, tail: HEX } } }) };
const fresh = setup(t);
collectCompactions(fresh.store, harness, { budget: 123, streams: 45 });
const known = setup(t, FIXTURES.known);
collectCompactions(known.store, harness);
const store = (f) => ({ session: f.store.session, projects: f.store.projects });
assert.deepEqual(seen, [
{ store: store(fresh), cursors: {}, budget: 123, streams: 45, first: true },
{ store: store(known), cursors: { "a.jsonl": { bytes: 233, tail: "39650b0c01a938998403d9dec3f8c224a01509ccde607711e962bf68bcbff54a" } }, budget: 64 << 20, streams: 1024, first: false },
]);
assert.equal(readFileSync(join(known.store.dir, LEDGER), "utf8").split("\n").filter((l) => l.includes('"stream":"x"')).length, 1);
});