32e6f72eee
Run compaction fallback, kept inject, and mid-turn steer tests; document lost-reinject.jsonl auto→null source signature from the original bug. Co-authored-by: Cursor <cursoragent@cursor.com>
83 lines
2.7 KiB
JavaScript
Executable File
83 lines
2.7 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/**
|
|
* Phase 15 regression gate for B-003 (mid-turn / missed reinject).
|
|
*
|
|
* 1. Runs focused unit tests for source fallback, kept inject entries, mid-turn steer.
|
|
* 2. Audits lost-reinject.jsonl (if present) for the pre-fix failure signature.
|
|
*
|
|
* Full two-compact RPC E2E needs a long session; use manual checklist in TODO.md §15.
|
|
*/
|
|
import { spawnSync } from "node:child_process";
|
|
import { existsSync, readFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import { resolve, dirname } from "node:path";
|
|
|
|
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
const artifactPath = resolve(repoRoot, "lost-reinject.jsonl");
|
|
|
|
const unitPatterns = [
|
|
"test/compaction-source-fallback.test.ts",
|
|
"test/kept-window.test.ts",
|
|
"test/reinject-mid-turn.test.ts",
|
|
"test/reinject-double-compact.test.ts",
|
|
];
|
|
|
|
function runUnitGate() {
|
|
const result = spawnSync("npm", ["test", "--", ...unitPatterns], {
|
|
cwd: repoRoot,
|
|
stdio: "inherit",
|
|
});
|
|
if (result.status !== 0) {
|
|
process.exit(result.status ?? 1);
|
|
}
|
|
}
|
|
|
|
function auditLostReinjectArtifact() {
|
|
if (!existsSync(artifactPath)) {
|
|
console.log("b003-repro: lost-reinject.jsonl not found — skip artifact audit");
|
|
return;
|
|
}
|
|
const lines = readFileSync(artifactPath, "utf8").split("\n").filter(Boolean);
|
|
const stateEntries = [];
|
|
const injectEntries = [];
|
|
for (const line of lines) {
|
|
try {
|
|
const entry = JSON.parse(line);
|
|
if (entry.customType === "skill-reinject:state" && entry.data) {
|
|
stateEntries.push({
|
|
id: entry.id,
|
|
ts: entry.timestamp,
|
|
lastCompactionSource: entry.data.lastCompactionSource,
|
|
pendingReinject: entry.data.pendingReinject ?? [],
|
|
});
|
|
}
|
|
if (entry.type === "custom_message" && entry.customType === "skill-reinject:inject") {
|
|
injectEntries.push({ id: entry.id, ts: entry.timestamp });
|
|
}
|
|
} catch {
|
|
// skip malformed lines
|
|
}
|
|
}
|
|
const nullSourceAfterAuto = stateEntries.filter(
|
|
(entry, index) =>
|
|
index > 0 &&
|
|
entry.lastCompactionSource === null &&
|
|
stateEntries[index - 1]?.lastCompactionSource === "auto",
|
|
);
|
|
console.log("b003-repro artifact audit:");
|
|
console.log(` state snapshots: ${stateEntries.length}`);
|
|
console.log(` skill-reinject:inject messages: ${injectEntries.length}`);
|
|
console.log(` auto→null source transitions (pre-fix bug): ${nullSourceAfterAuto.length}`);
|
|
if (nullSourceAfterAuto.length > 0) {
|
|
console.log(" sample null-source entry:", JSON.stringify(nullSourceAfterAuto[0]));
|
|
console.log(
|
|
" post-fix expectation: ensureCompactionSourceMarked on session_compact → lastCompactionSource: auto",
|
|
);
|
|
}
|
|
}
|
|
|
|
console.log("b003-repro: running unit regression gate…");
|
|
runUnitGate();
|
|
auditLostReinjectArtifact();
|
|
console.log("b003-repro: PASS (unit gate)");
|