perf(web): measure and reuse batch verification stages
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

This commit is contained in:
mes123456
2026-09-03 15:20:57 +08:00
parent b1376b46af
commit b29d4c88a7
3 changed files with 26 additions and 6 deletions

View File

@@ -24,10 +24,11 @@ function waitMs(milliseconds) {
}
function command(command, logPath) {
const started = Date.now();
const result = spawnSync("bash", ["-lc", command], { cwd: root, encoding: "utf8", maxBuffer: 16 * 1024 * 1024 });
const output = `${result.stdout ?? ""}${result.stderr ?? ""}`;
if (logPath) fs.writeFileSync(abs(logPath), output);
return { code: result.status ?? 1, output };
return { code: result.status ?? 1, durationMs: Date.now() - started, output };
}
function currentTask() {
@@ -62,6 +63,20 @@ function assertContext() {
if (result.code !== 0) throw new Error(`context gate failed (exit ${result.code})`);
}
function typecheckProven(task) {
try {
const manifest = JSON.parse(read(`tests/golden/${task}/manifest.json`));
const receiptPath = manifest.artifacts?.moduleReceipt?.path;
if (!receiptPath) return false;
const receipt = JSON.parse(read(receiptPath));
return receipt.status === "PASS" && receipt.source?.unchanged === true
&& receipt.commands?.some((entry) => entry.exitCode === 0 && entry.command.trim() === "npm --prefix web run typecheck");
}
catch {
return false;
}
}
let iterations = 0;
const summary = [];
while (maxIterations === 0 || iterations < maxIterations) {
@@ -82,7 +97,10 @@ while (maxIterations === 0 || iterations < maxIterations) {
const after = currentTask();
const terminal = after.task === before.task && terminalTask(before.task);
if (after.task === before.task && !terminal) throw new Error(`${before.task} focused command exited 0 without advancing queue; log=${logPath}`);
const gates = command("node tools/web/check-context-governance.mjs && node tools/web/check-execution-control-plane.mjs --allow-unrunnable && node tools/web/check-v2-task-index.mjs && node tools/web/check-v2-handoff.mjs && npm --prefix web run typecheck && npm --prefix web run lint && git diff --check", `tests/golden/${before.task}/continuous-gates.log`);
const typecheckCommand = typecheckProven(before.task)
? "printf 'typecheck reused from hash-bound module receipt\\n'"
: "npm --prefix web run typecheck";
const gates = command(`node tools/web/check-context-governance.mjs && node tools/web/check-execution-control-plane.mjs --allow-unrunnable && node tools/web/check-v2-task-index.mjs && node tools/web/check-v2-handoff.mjs && ${typecheckCommand} && npm --prefix web run lint && git diff --check`, `tests/golden/${before.task}/continuous-gates.log`);
if (gates.code !== 0) throw new Error(`${before.task} post-handoff gate failed (exit ${gates.code}); log=tests/golden/${before.task}/continuous-gates.log`);
iterations += 1;
summary.push({ task: before.task, command: focused, nextTask: terminal ? null : after.task, terminal, log: logPath });