76 lines
6.3 KiB
JavaScript
76 lines
6.3 KiB
JavaScript
// 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, []);
|
|
});
|