Reorganize Blender Web execution around capabilities
Some checks are pending
M6 deployable RC / quick (push) Waiting to run
M6 deployable RC / chromium (push) Blocked by required conditions
M6 deployable RC / release (push) Blocked by required conditions

This commit is contained in:
mes123456
2026-08-24 18:37:46 -04:00
parent 0b2c3ba0dd
commit a081c68c87
2530 changed files with 763976 additions and 79 deletions

View File

@@ -0,0 +1,89 @@
import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { execFileSync } from "node:child_process";
import { fileURLToPath } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
const arg = (name) => { const index = process.argv.indexOf(name); return index >= 0 ? process.argv[index + 1] : undefined; };
const staged = path.resolve(root, arg("--staged-root") ?? "tests/golden/corrective/C0-002/staged");
const reportPath = path.resolve(root, arg("--report") ?? "tests/golden/corrective/C0-002/resign-check.json");
const read = (file) => fs.readFileSync(file, "utf8");
const json = (file) => JSON.parse(read(file));
const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex");
const relative = (file) => path.relative(root, file).replaceAll(path.sep, "/");
const check = [];
const ok = (name, value, detail = {}) => { assert.ok(value, name); check.push({ name, status: "PASS", ...detail }); };
const registryPath = path.join(staged, "completed-gap-tasks.candidate.json");
const planPath = path.join(staged, "next-task-plan.candidate.json");
const indexPath = path.join(staged, "task-index", "task-index.json");
const catalogPath = path.join(staged, "task-index", "task-catalog.jsonl");
const snapshotPath = path.join(staged, "source-snapshot", "snapshot-manifest.json");
const registry = json(registryPath);
const plan = json(planPath);
const index = json(indexPath);
const snapshot = json(snapshotPath);
ok("registry-count", registry.length === 273, { value: registry.length });
ok("registry-unique", new Set(registry).size === registry.length);
ok("plan-shape", plan.tasks.length === 6900 && plan.summary.completed === 273 && plan.summary.active === 1 && plan.firstTask === "M16-GAP-00274");
ok("plan-source-hash", plan.sources.completions.sha256 === sha256(registryPath));
ok("index-plan-hash", index.source.sha256 === sha256(planPath));
ok("index-catalog-hash", index.catalog.sha256 === sha256(catalogPath));
ok("index-active", index.activeTask === plan.firstTask);
ok("snapshot-nonempty", snapshot.files.length > 0, { value: snapshot.files.length });
const snapshotByPath = new Map();
for (const file of snapshot.files) {
const source = path.join(root, file.path);
const copy = path.join(root, file.snapshotPath);
assert.equal(sha256(source), file.sha256, file.path);
assert.equal(sha256(copy), file.sha256, file.snapshotPath);
snapshotByPath.set(file.path, file.sha256);
}
check.push({ name: "snapshot-hashes", status: "PASS", files: snapshot.files.length, bytes: snapshot.files.reduce((sum, file) => sum + file.bytes, 0) });
const manifestRoot = path.join(staged, "resigned-manifests");
const manifestTasks = fs.readdirSync(manifestRoot).filter((entry) => /^M(?:15|16)-/u.test(entry)).sort();
const m16Tasks = manifestTasks.filter((entry) => /^M16-GAP-\d{5}$/u.test(entry));
ok("resigned-manifest-count", m16Tasks.length === 274, { value: m16Tasks.length });
let doneCount = 0;
for (const task of m16Tasks) {
const manifest = json(path.join(manifestRoot, task, "manifest.json"));
if (manifest.status === "done") doneCount += 1;
for (const artifact of Object.values(manifest.artifacts ?? {})) {
if (!artifact?.path || !artifact?.sha256) continue;
assert.equal(snapshotByPath.get(artifact.path), artifact.sha256, `${task}:${artifact.path}`);
}
}
ok("resigned-manifest-done-count", doneCount === 273, { value: doneCount });
const rootParent = json(path.join(manifestRoot, "M15-03E", "manifest.json"));
ok("root-parent-repaired", rootParent.nextTask === "M16-GAP-00001");
const contextRoot = path.join(staged, "resigned-context");
const contexts = fs.readdirSync(contextRoot).filter((entry) => /^M16-GAP-\d{5}$/u.test(entry)).sort();
ok("repaired-context-count", contexts.length === 24, { value: contexts.length });
for (const task of contexts) {
const context = json(path.join(contextRoot, task, "task-context.json"));
assert.equal(context.task, task);
assert.equal(context.parentTask, json(path.join(manifestRoot, task, "manifest.json")).parentTask);
const parent = json(path.join(manifestRoot, context.parentTask, "manifest.json"));
assert.equal(parent.nextTask, task, `${task}:parent-nextTask`);
}
check.push({ name: "repaired-context-links", status: "PASS", files: contexts.length });
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "corrective-resign-check-"));
const regenerated = path.join(tempRoot, "plan.json");
try {
execFileSync(process.execPath, [path.join(root, "tools/web/generate-blender-next-task-plan.mjs"), regenerated, "--completion-path", registryPath], { cwd: root, stdio: "ignore" });
ok("candidate-plan-deterministic", fs.readFileSync(regenerated).equals(fs.readFileSync(planPath)));
} finally {
fs.rmSync(tempRoot, { recursive: true, force: true });
}
const result = { schemaVersion: 1, operation: "CORRECTIVE_STATE_RECONCILIATION_RESIGN_CHECK", status: "PASS", queueMutation: false, stagedRoot: relative(staged), checks: check, artifactCount: snapshot.files.length, planTaskCount: plan.tasks.length, completedCount: doneCount, activeTask: plan.firstTask };
fs.mkdirSync(path.dirname(reportPath), { recursive: true });
fs.writeFileSync(reportPath, `${JSON.stringify(result, null, 2)}\n`);
process.stdout.write(`corrective-resign-check-ok files=${snapshot.files.length} manifests=${m16Tasks.length} contexts=${contexts.length} active=${plan.firstTask}\n`);