Files
playbook/antigravity-awesome-skills/verification/aas-v1/verifier/bin/verify-product.mjs
T
2026-07-18 00:02:59 +00:00

130 lines
8.6 KiB
JavaScript

#!/usr/bin/env node
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { digestJson, sha256 } from "../lib/canonical.mjs";
import { snapshotZones } from "../lib/fs-evidence.mjs";
import { selfTestObserver } from "../lib/observer.mjs";
import { executableDigest, loadReceiptValidator, SUITE_IDS, writeCanonicalReceipt } from "../lib/receipt.mjs";
import { installCandidate, isolatedZones, systemIdentity } from "../lib/runtime.mjs";
import {
packageSuite, prepareRuntimeCache, suite, verifyAdapters, verifyEntrypoints,
verifyFuzz, verifyHostile, verifyLegacy, verifyMcp, verifyProperty,
} from "../lib/suites.mjs";
import { inspectPackageTarball } from "../lib/tarball.mjs";
const here = path.dirname(fileURLToPath(import.meta.url));
const verifierRoot = path.resolve(here, "..");
const verificationRoot = path.resolve(verifierRoot, "..");
const baselineRoot = path.join(verificationRoot, "baseline", "v1");
function args(values) {
const out = {};
for (let i = 2; i < values.length; i += 2) {
if (!values[i].startsWith("--") || values[i + 1] === undefined) throw new Error(`Invalid argument: ${values[i]}`);
out[values[i].slice(2)] = values[i + 1];
}
return out;
}
function required(value, name, pattern = /./) {
if (!value || !pattern.test(value)) throw new Error(`--${name} is required or invalid`);
return value;
}
function readJson(file) { return JSON.parse(fs.readFileSync(file, "utf8")); }
function failedSuite(id, error) {
const evidence = { code: error.code || "AAS_VERIFIER_INTERNAL", detailDigest: digestJson({ name: error.name, message: error.message }) };
return { id, status: "failed", executions: 0, failures: 1, evidenceSha256: digestJson(evidence), evidence };
}
function transactionSuite(file, manifest, validator) {
if (!file || !fs.existsSync(file)) throw Object.assign(new Error("OS-level transaction evidence is required"), { code: "AAS_VERIFIER_TRANSACTION_EVIDENCE_MISSING" });
const value = readJson(file);
if (!validator(value)) throw Object.assign(new Error("Transaction evidence schema failed"), { code: "AAS_VERIFIER_TRANSACTION_EVIDENCE_SCHEMA" });
const fault = new Set(value.faultBoundaryClasses || []);
const race = new Set(value.raceClasses || []);
for (const item of manifest.faultBoundaryClasses) if (!fault.has(item)) throw Object.assign(new Error(`Fault boundary not covered: ${item}`), { code: "AAS_VERIFIER_FAULT_BOUNDARY_MISSING" });
for (const item of manifest.raceClasses) if (!race.has(item)) throw Object.assign(new Error(`Race class not covered: ${item}`), { code: "AAS_VERIFIER_RACE_CLASS_MISSING" });
if (value.testMode === true || value.mocked === true || value.productionBinary !== true) throw Object.assign(new Error("Transaction evidence is not production black-box evidence"), { code: "AAS_VERIFIER_TRANSACTION_NOT_BLACK_BOX" });
if (value.partialStates !== 0 || value.unmanagedMutations !== 0 || value.hardPolicyViolations !== 0) throw Object.assign(new Error("Transaction safety invariant failed"), { code: "AAS_VERIFIER_TRANSACTION_INVARIANT" });
return suite("transaction", value, value.executions || 0);
}
const options = args(process.argv);
const tarball = path.resolve(required(options.tarball, "tarball"));
const candidateCommit = required(options["candidate-commit"], "candidate-commit", /^[a-f0-9]{40}$/);
const verifierCommit = required(options["verifier-commit"], "verifier-commit", /^[a-f0-9]{40}$/);
const jobId = required(options["job-id"], "job-id");
const output = path.resolve(required(options.out, "out"));
const workRoot = path.resolve(required(options["work-root"], "work-root"));
const runtimeMatrix = readJson(path.join(baselineRoot, "runtime-matrix.json"));
const job = runtimeMatrix.jobs.find((entry) => entry.id === jobId);
if (!job) throw new Error(`Unknown job: ${jobId}`);
if (process.platform !== job.os.replace("macos", "darwin").replace("windows", "win32")) throw new Error(`Job/platform mismatch: ${jobId}/${process.platform}`);
if (process.arch !== job.architecture || process.version !== `v${job.nodePatch}`) throw new Error(`Frozen runtime identity mismatch: ${process.arch}/${process.version}`);
fs.mkdirSync(workRoot, { recursive: true, mode: 0o700 });
const evidenceDir = path.join(workRoot, "observer-evidence");
const zones = isolatedZones(path.join(workRoot, "zones"));
const zoneBefore = snapshotZones(zones);
const manifest = readJson(path.join(baselineRoot, "verifier-manifest.json"));
const freeze = readJson(path.join(baselineRoot, "freeze-manifest.json"));
const budgets = readJson(path.join(baselineRoot, "budgets.json"));
const hostileManifest = readJson(path.join(baselineRoot, "hostile", "manifest.json"));
const transactionValidator = loadReceiptValidator(path.join(verificationRoot, "schemas", "product-transaction-evidence.schema.json"));
const inspection = inspectPackageTarball(tarball);
const runtime = await installCandidate(tarball, path.join(workRoot, "candidate-install"));
const tarballBytes = fs.readFileSync(tarball);
const observer = await selfTestObserver({ cwd: zones.tmp, env: process.env, zones, evidenceDir });
const runtimePromotion = await prepareRuntimeCache(runtime, tarballBytes, inspection.sha512, zones.cache);
const suites = [];
const failures = [];
const run = async (id, action) => {
try { suites.push(await action()); }
catch (error) {
suites.push(failedSuite(id, error));
failures.push({ code: /^AAS_VERIFIER_/.test(error.code || "") ? error.code : "AAS_VERIFIER_INTERNAL", suite: id, detailDigest: digestJson({ name: error.name, message: error.message }) });
}
};
await run("package", () => packageSuite(inspection, runtime));
await run("entrypoints", () => verifyEntrypoints(runtime, zones));
await run("mcp", () => verifyMcp(runtime, zones, evidenceDir));
await run("property", () => verifyProperty(runtime, budgets, runtimeMatrix.jobs.indexOf(job), verifierRoot));
await run("fuzz", () => verifyFuzz(runtime, budgets, runtimeMatrix.jobs.indexOf(job), verifierRoot));
await run("hostile", () => verifyHostile(runtime, zones, evidenceDir, hostileManifest, path.join(baselineRoot, "hostile"), verifierRoot));
await run("legacy", () => verifyLegacy(runtime, zones, verifierRoot, path.join(baselineRoot, "legacy", "14.6.0")));
await run("transaction", () => transactionSuite(options["transaction-evidence"], manifest, transactionValidator));
await run("adapters", () => verifyAdapters(runtime, zones, path.join(baselineRoot, "host-adapters"), inspection.sha512, runtimePromotion.identity.closureDigest));
for (const id of SUITE_IDS) if (!suites.some((entry) => entry.id === id)) suites.push(failedSuite(id, Object.assign(new Error("Suite did not execute"), { code: "AAS_VERIFIER_SUITE_MISSING" })));
const mcp = suites.find((entry) => entry.id === "mcp");
const canonicalSha = mcp?.evidence?.canonicalResponseDigest || digestJson(null);
const { jobId: _jobId, ...identity } = systemIdentity(job);
const mcpBefore = mcp?.evidence?.before || Object.fromEntries(Object.keys(zones).map((name) => [name, zoneBefore[name].digest]));
const mcpAfter = mcp?.evidence?.after || mcpBefore;
const receipt = {
schemaVersion: 1,
receiptVersion: "1.0.0",
status: failures.length ? "failed" : "passed",
job: { id: job.id, workflowRunId: process.env.GITHUB_RUN_ID || "1", workflowRunAttempt: process.env.GITHUB_RUN_ATTEMPT || "1" },
candidate: {
commit: candidateCommit, package: runtime.manifest.name, version: runtime.manifest.version,
tarballBytes: inspection.bytes, tarballSha256: inspection.sha256, tarballSha512: inspection.sha512,
packManifestSha256: digestJson(inspection.entries), installTreeSha256: runtime.treeDigest,
},
verifier: { version: "1.0.0", commit: verifierCommit, rootDigest: freeze.rootDigest, contractDigest: digestJson(manifest), owner: "aas-v1-independent-verifier" },
environment: { ...identity, nodeExecutableSha256: executableDigest() },
observer: { contractVersion: observer.contractVersion, backend: observer.backend, selfTestDigest: observer.selfTestDigest, networkSentinels: observer.observedNetworkSentinels, writeSentinels: observer.observedWriteSentinels, overflow: false, ambiguousLineage: false },
zones: Object.fromEntries(Object.keys(zones).map((name) => [name, { beforeSha256: mcpBefore[name], afterSha256: mcpAfter[name], persistentWriteCount: 0 }])),
suites: suites.sort((a, b) => SUITE_IDS.indexOf(a.id) - SUITE_IDS.indexOf(b.id)),
canonicalPayload: { sha256: canonicalSha, excludedFields: ["timestamp", "correlationId", "localizedMessage", "diagnostics"], sampleCount: 60 },
failures,
};
writeCanonicalReceipt(output, receipt);
process.stdout.write(`${JSON.stringify({ ok: failures.length === 0, output, failures })}\n`);
if (failures.length) process.exit(1);