perf(web): add idempotent batch verification fast paths
This commit is contained in:
@@ -16,19 +16,44 @@ const task = process.argv.includes("--task")
|
||||
if (!task) throw new Error("unable to resolve current WBV2 task");
|
||||
const parentManifest = queue.match(/\| parent manifest \| `([^`]+)` \|/u)?.[1];
|
||||
if (!parentManifest) throw new Error("queue parent manifest is missing");
|
||||
const inputPaths = [
|
||||
const baseInputPaths = [
|
||||
"docs/EXECUTION_QUEUE.md",
|
||||
`docs/tasks/${task}.md`,
|
||||
parentManifest,
|
||||
`tests/golden/${task}/task-context.json`,
|
||||
];
|
||||
const inputHashFor = () => digest(inputPaths.map((file) => `${file}\0${fs.existsSync(abs(file)) ? digest(read(file)) : "MISSING"}\n`).join(""));
|
||||
const inputHash = inputHashFor();
|
||||
const statInput = (file) => {
|
||||
try {
|
||||
const stat = fs.statSync(abs(file), { bigint: true });
|
||||
return { bytes: Number(stat.size), mtime_ns: stat.mtimeNs.toString(), exists: true };
|
||||
}
|
||||
catch (error) {
|
||||
return { bytes: null, mtime_ns: null, exists: false, error: error?.code ?? "STAT_FAILED" };
|
||||
}
|
||||
};
|
||||
const metadataComparable = (value) => value && value.exists === true
|
||||
&& Number.isSafeInteger(value.bytes) && typeof value.mtime_ns === "string";
|
||||
let cached = null;
|
||||
try { cached = JSON.parse(fs.readFileSync(cachePath, "utf8")); }
|
||||
catch { /* First use or an interrupted write. */ }
|
||||
if (!process.argv.includes("--force") && cached?.status === "PASS" && cached.task === task && cached.inputHash === inputHash) {
|
||||
process.stdout.write(`wbv2-context-cache-hit task=${task} inputHash=${inputHash}\n`);
|
||||
const inputPaths = [...new Set([
|
||||
...baseInputPaths,
|
||||
...Object.keys(cached?.inputs ?? {}),
|
||||
])];
|
||||
const inputMetadata = Object.fromEntries(inputPaths.map((file) => [file, statInput(file)]));
|
||||
const metadataUnchanged = (cachedInputs) => inputPaths.every((file) => {
|
||||
const current = inputMetadata[file];
|
||||
const cached = cachedInputs?.[file];
|
||||
return metadataComparable(current) && metadataComparable(cached)
|
||||
&& current.bytes === cached.bytes && current.mtime_ns === cached.mtime_ns;
|
||||
});
|
||||
const digestPath = (file) => {
|
||||
try { return digest(read(file)); }
|
||||
catch { return "MISSING"; }
|
||||
};
|
||||
const inputHashFor = (paths = inputPaths) => digest(paths.map((file) => `${file}\0${digestPath(file)}\n`).join(""));
|
||||
if (!process.argv.includes("--force") && cached?.status === "PASS" && cached.task === task && metadataUnchanged(cached.inputs)) {
|
||||
process.stdout.write(`CONTEXT_PACKET_REUSED task=${task} inputHash=${cached.inputHash ?? "UNKNOWN"}\n`);
|
||||
process.exit(0);
|
||||
}
|
||||
const result = spawnSync(process.execPath, [abs("tools/web/print-task-context.mjs"), "--task", task], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
|
||||
@@ -38,8 +63,21 @@ if ((result.status ?? 1) !== 0 || (check.status ?? 1) !== 0) {
|
||||
process.exit(Math.max(result.status ?? 1, check.status ?? 1));
|
||||
}
|
||||
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
||||
const refreshedInputHash = inputHashFor();
|
||||
const payload = { schemaVersion: 1, status: "PASS", task, inputHash: refreshedInputHash, refreshedAt: new Date().toISOString() };
|
||||
let contextMetadata = {};
|
||||
try {
|
||||
const context = JSON.parse(read(`tests/golden/${task}/task-context.json`));
|
||||
contextMetadata = context.inputMetadata && typeof context.inputMetadata === "object" ? context.inputMetadata : {};
|
||||
} catch { /* The task-context checker already reported the precise failure. */ }
|
||||
const refreshedPaths = [...new Set([...inputPaths, ...Object.keys(contextMetadata)])];
|
||||
const refreshedInputHash = inputHashFor(refreshedPaths);
|
||||
const payload = {
|
||||
schemaVersion: 2,
|
||||
status: "PASS",
|
||||
task,
|
||||
inputHash: refreshedInputHash,
|
||||
inputs: Object.fromEntries(refreshedPaths.map((file) => [file, { ...statInput(file), sha256: contextMetadata[file]?.sha256 ?? digestPath(file) }])),
|
||||
refreshedAt: new Date().toISOString(),
|
||||
};
|
||||
const temporary = `${cachePath}.tmp-${process.pid}`;
|
||||
fs.writeFileSync(temporary, `${JSON.stringify(payload, null, 2)}\n`);
|
||||
fs.renameSync(temporary, cachePath);
|
||||
|
||||
Reference in New Issue
Block a user