Source commit: 20b59dc46b72103c2f8a516c692b5cc3d54fab19 Public tree identity: sha256:aaa5ac7b58b2a0d23c6b11e5f76324bf3839ca1f62653a83deb736932adcfbd9
262 lines
18 KiB
JavaScript
Executable file
262 lines
18 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
|
|
|
const assert = require("assert");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const repo = path.resolve(__dirname, "..");
|
|
|
|
function read(relativePath) {
|
|
return fs.readFileSync(path.join(repo, relativePath), "utf8");
|
|
}
|
|
|
|
function maybeRead(relativePath) {
|
|
const absolute = path.join(repo, relativePath);
|
|
if (!fs.existsSync(absolute)) return null;
|
|
return fs.readFileSync(absolute, "utf8");
|
|
}
|
|
|
|
function expect(source, name, pattern) {
|
|
assert.match(source, pattern, `missing acceptance environment evidence: ${name}`);
|
|
}
|
|
|
|
function expectIncludes(source, name, text) {
|
|
assert(source.includes(text), `missing acceptance environment evidence: ${name}`);
|
|
}
|
|
|
|
const publicAcceptance = read("scripts/acceptance-public.sh");
|
|
const privateAcceptance = read("scripts/acceptance-private.sh");
|
|
const publicSplit = read("scripts/verify-public-split.sh");
|
|
const acceptanceReport = read("scripts/acceptance-report.js");
|
|
const acceptanceReportSmoke = read("scripts/acceptance-report-smoke.js");
|
|
const readme = read("README.md");
|
|
const windowsWorkflow = read(".forgejo/workflows/windows-validation.yml");
|
|
const publicDryrunServiceSmoke = maybeRead("private/hosted-policy/scripts/public-release-dryrun-service-smoke.js");
|
|
const publicDryrunDeployPrep = maybeRead("private/hosted-policy/scripts/prepare-public-release-dryrun-deployment.js");
|
|
const publicDryrunSystemd = maybeRead("private/hosted-policy/deploy/disasmer-public-release-dryrun.service");
|
|
const publicDryrunRunbook = maybeRead("private/hosted-policy/deploy/README.md");
|
|
const hostedClientCompatSmoke = maybeRead("private/hosted-policy/scripts/hosted-client-compat-smoke.js");
|
|
const hostedService = maybeRead("private/hosted-policy/src/bin/disasmer-hosted-service.rs");
|
|
const hostedStartup = maybeRead(
|
|
"private/hosted-policy/src/bin/disasmer-hosted-service/startup.rs"
|
|
);
|
|
const hostedOperatorAuth = maybeRead(
|
|
"private/hosted-policy/src/bin/disasmer-hosted-service/operator_auth.rs"
|
|
);
|
|
const publicDryrunE2e = read("scripts/public-release-dryrun-e2e.js");
|
|
const finalDryrunEvidence = read("scripts/public-release-dryrun-final-evidence.js");
|
|
|
|
for (const [name, script] of [
|
|
["public acceptance", publicAcceptance],
|
|
["private acceptance", privateAcceptance],
|
|
]) {
|
|
expect(script, `${name} writes acceptance environment report first`, /node scripts\/acceptance-report\.js (public|private)[\s\S]*node scripts\/acceptance-report-smoke\.js/);
|
|
expectIncludes(
|
|
script,
|
|
`${name} runs acceptance environment contract`,
|
|
"node scripts/acceptance-environment-contract-smoke.js"
|
|
);
|
|
}
|
|
|
|
for (const [name, script] of [
|
|
["public acceptance", publicAcceptance],
|
|
["public split", publicSplit],
|
|
]) {
|
|
for (const smoke of [
|
|
"scripts/wasmtime-assignment-smoke.js",
|
|
"scripts/node-attach-smoke.js",
|
|
"scripts/cli-local-run-smoke.js",
|
|
"scripts/vscode-f5-smoke.js",
|
|
"scripts/dap-smoke.js",
|
|
"scripts/artifact-download-smoke.js",
|
|
"scripts/artifact-export-smoke.js",
|
|
"scripts/public-local-demo-matrix-smoke.js",
|
|
]) {
|
|
assert(script.includes(`node ${smoke}`), `${name} must run ${smoke}`);
|
|
}
|
|
}
|
|
|
|
expectIncludes(publicAcceptance, "public gate runs rootless Podman backend smoke", "node scripts/podman-backend-smoke.js");
|
|
expectIncludes(publicAcceptance, "public gate runs Wasmtime node smoke", "node scripts/wasmtime-node-smoke.js");
|
|
expectIncludes(privateAcceptance, "private gate runs hosted deployment smoke", "node private/hosted-policy/scripts/hosted-deployment-smoke.js");
|
|
expectIncludes(privateAcceptance, "private gate prepares public dry-run deployment bundle", "node private/hosted-policy/scripts/prepare-public-release-dryrun-deployment.js");
|
|
expectIncludes(privateAcceptance, "private gate runs hosted Client compatibility smoke", "node private/hosted-policy/scripts/hosted-client-compat-smoke.js");
|
|
expectIncludes(privateAcceptance, "private gate runs standalone Core coordinator smoke", "node scripts/self-hosted-coordinator-smoke.js");
|
|
expectIncludes(privateAcceptance, "private gate runs Postgres durable smoke", "node private/hosted-policy/scripts/postgres-durable-smoke.js");
|
|
expectIncludes(privateAcceptance, "private gate can run public release dry-run service smoke", "node private/hosted-policy/scripts/public-release-dryrun-service-smoke.js");
|
|
expectIncludes(privateAcceptance, "public release dry-run service smoke is env gated", "DISASMER_PUBLIC_RELEASE_DRYRUN_SERVICE_ADDR");
|
|
expectIncludes(privateAcceptance, "private gate runs hosted policy cargo tests", "cargo test --manifest-path private/hosted-policy/Cargo.toml");
|
|
expectIncludes(publicAcceptance, "public gate can run final dry-run evidence verifier", "node scripts/public-release-dryrun-final-evidence.js");
|
|
expectIncludes(publicAcceptance, "public gate can run public release dry-run e2e", "node scripts/public-release-dryrun-e2e.js");
|
|
expectIncludes(publicAcceptance, "public release dry-run e2e is env gated", "DISASMER_PUBLIC_RELEASE_DRYRUN_E2E");
|
|
expectIncludes(privateAcceptance, "private gate can run final dry-run evidence verifier", "node scripts/public-release-dryrun-final-evidence.js");
|
|
expectIncludes(publicAcceptance, "public final dry-run verifier is env gated", "DISASMER_PUBLIC_RELEASE_DRYRUN_FINAL");
|
|
expectIncludes(privateAcceptance, "private final dry-run verifier is env gated", "DISASMER_PUBLIC_RELEASE_DRYRUN_FINAL");
|
|
|
|
expect(publicSplit, "public split excludes private modules", /--exclude='\.\/private'/);
|
|
expect(publicSplit, "public split excludes experiments", /--exclude='\.\/experiments'/);
|
|
expect(publicSplit, "public split tests copied workspace", /cargo test --workspace --manifest-path "\$tmp_dir\/Cargo\.toml"/);
|
|
expect(publicSplit, "public split builds copied workspace binaries", /cargo build --workspace --bins --manifest-path "\$tmp_dir\/Cargo\.toml"/);
|
|
expectIncludes(
|
|
publicSplit,
|
|
"public split runs acceptance environment contract from copied tree",
|
|
'(cd "$tmp_dir" && node scripts/acceptance-environment-contract-smoke.js)'
|
|
);
|
|
|
|
for (const [name, pattern] of [
|
|
["commit SHA fallback", /process\.env\.DISASMER_ACCEPTANCE_COMMIT \|\| commandOutput\("git", \["rev-parse", "HEAD"\]\)/],
|
|
["tree status", /tree_status: \(commandOutput\("git", \["status", "--short"\]\) \|\| ""\)[\s\S]*\.filter\(Boolean\)/],
|
|
["OS report", /platform: os\.platform\(\)[\s\S]*kernel: os\.release\(\)/],
|
|
["Rust report", /rustc: commandOutput\("rustc", \["--version"\]\)/],
|
|
["Node report", /version: process\.version/],
|
|
["Podman report", /function podmanReport\(\)/],
|
|
["Postgres report", /postgres: \{[\s\S]*commandOutput\("postgres", \["--version"\]\) \|\|[\s\S]*commandOutput\("psql", \["--version"\]\)/],
|
|
["browser harness report", /browser_harness:/],
|
|
["VS Code harness report", /vscode_harness:/],
|
|
["Windows validation report", /windows_validation: process\.env\.DISASMER_WINDOWS_VALIDATION \|\| "not-run"/],
|
|
]) {
|
|
expect(acceptanceReport, name, pattern);
|
|
}
|
|
|
|
for (const [name, pattern] of [
|
|
["acceptance report validates Podman incomplete state", /assertPodmanReport/],
|
|
["acceptance report validates Windows not-run", /assertReport\(runReport\(mode\), mode, "not-run"\)/],
|
|
["acceptance report validates Windows runner mode", /DISASMER_WINDOWS_VALIDATION: "forgejo-windows-runner"/],
|
|
]) {
|
|
expect(acceptanceReportSmoke, name, pattern);
|
|
}
|
|
|
|
expect(readme, "README documents public acceptance script", /scripts\/acceptance-public\.sh/);
|
|
expect(readme, "README documents private acceptance script", /scripts\/acceptance-private\.sh/);
|
|
expect(readme, "README documents rootless Podman incomplete handling", /Podman backend behavior is marked `incomplete`/);
|
|
expect(readme, "README documents Postgres discovery in environment report", /Podman\/Postgres discovery/);
|
|
expect(readme, "README documents manual Windows validation", /manual `Windows validation`\s+workflow/);
|
|
|
|
expect(windowsWorkflow, "Windows workflow is manual", /workflow_dispatch/);
|
|
expect(windowsWorkflow, "Windows workflow uses intermittent Windows runner", /runs-on:\s*windows/);
|
|
expect(windowsWorkflow, "Windows workflow writes acceptance report", /node scripts\/acceptance-report\.js windows/);
|
|
|
|
if (publicDryrunServiceSmoke && publicDryrunDeployPrep && publicDryrunSystemd && publicDryrunRunbook) {
|
|
for (const [name, pattern] of [
|
|
["service smoke requires external service address", /DISASMER_PUBLIC_RELEASE_DRYRUN_SERVICE_ADDR is required/],
|
|
["service smoke requires browser test driver", /DISASMER_PUBLIC_RELEASE_DRYRUN_BROWSER_OPEN_COMMAND/],
|
|
["service smoke loads release manifest", /public-release-manifest\.json/],
|
|
["service smoke rejects stale release manifest", /manifest\.source_commit[\s\S]*expectedCommit/],
|
|
["service smoke records source commit", /source_commit: release\.sourceCommit/],
|
|
["service smoke records release name", /release_name: release\.releaseName/],
|
|
["service smoke connects through public domain", /addr\.host[\s\S]*serviceHost/],
|
|
["service smoke verifies DNS state", /\["not-published", "published"\]\.includes\(dnsPublicationState\)/],
|
|
["service smoke begins a server-owned OIDC login", /type: "begin_oidc_browser_login"/],
|
|
["service smoke polls with opaque credentials", /type: "poll_oidc_browser_login"[\s\S]*transaction_id[\s\S]*polling_secret/],
|
|
["service smoke rejects missing hosted callback completion", /timed out waiting for the hosted OIDC callback/],
|
|
["service smoke reads server-created project", /type: "list_projects"/],
|
|
["service smoke enrolls signed node", /type: "create_node_enrollment_grant"[\s\S]*exchange_node_enrollment_grant/],
|
|
["service smoke starts session-authorized process", /type: "start_process"/],
|
|
["service smoke reports signed node capabilities", /signedNodeRequest[\s\S]*report_node_capabilities/],
|
|
["service smoke reads authorized debug state", /type: "debug_attach"/],
|
|
["service smoke aborts its probe process", /type: "abort_process"/],
|
|
["service smoke records private hosted coordinator", /coordinator_implementation:[\s\S]*"hosted-policy-coordinator"/],
|
|
["service smoke writes evidence report", /public-release-dryrun-service\.json/],
|
|
]) {
|
|
expect(publicDryrunServiceSmoke, name, pattern);
|
|
}
|
|
|
|
for (const [name, source, pattern] of [
|
|
["deployment prep builds hosted service release", publicDryrunDeployPrep, /cargo"[\s\S]*"build"[\s\S]*"--release"[\s\S]*"private\/hosted-policy\/Cargo\.toml"[\s\S]*"disasmer-hosted-service"/],
|
|
["deployment prep stages systemd unit", publicDryrunDeployPrep, /disasmer-public-release-dryrun\.service/],
|
|
["deployment prep writes manifest", publicDryrunDeployPrep, /deployment-manifest\.json/],
|
|
["deployment prep records private hosted coordinator", publicDryrunDeployPrep, /coordinator_implementation:[\s\S]*"hosted-policy-coordinator"/],
|
|
["deployment prep records service address", publicDryrunDeployPrep, /service_addr:[\s\S]*`\$\{serviceHost\}:\$\{servicePort\}`/],
|
|
["deployment prep records DNS state", publicDryrunDeployPrep, /dns_publication_state: dnsPublicationState/],
|
|
["deployment prep records service smoke command", publicDryrunDeployPrep, /public-release-dryrun-service-smoke\.js/],
|
|
["systemd keeps hosted HTTP upstream on loopback", publicDryrunSystemd, /--listen 127\.0\.0\.1:9080/],
|
|
["systemd loads root-owned operator credentials", publicDryrunSystemd, /EnvironmentFile=\/etc\/disasmer-public-release-dryrun\/operator\.env/],
|
|
["systemd avoids privileged port capability", publicDryrunSystemd, /NoNewPrivileges=true/],
|
|
["systemd uses dedicated user", publicDryrunSystemd, /User=disasmer[\s\S]*Group=disasmer/],
|
|
["runbook says externally reachable", publicDryrunRunbook, /externally reachable host/],
|
|
["runbook documents DNS pending fallback", publicDryrunRunbook, /Until the `disasmer\.michelpaulissen\.com` DNS record is deployed/],
|
|
["runbook gives hosts entry", publicDryrunRunbook, /<deployment-ip> disasmer\.michelpaulissen\.com/],
|
|
["runbook separates authority vocabulary", publicDryrunRunbook, /Client and signed Node protocols[\s\S]*Identity boundary[\s\S]*Operator boundary/],
|
|
["runbook documents operator credential", publicDryrunRunbook, /DISASMER_HOSTED_OPERATOR_TOKEN/],
|
|
]) {
|
|
expect(source, name, pattern);
|
|
}
|
|
}
|
|
|
|
if (hostedClientCompatSmoke && hostedService && hostedStartup && hostedOperatorAuth) {
|
|
const hostedServiceSecurity = `${hostedService}\n${hostedStartup}\n${hostedOperatorAuth}`;
|
|
for (const [name, pattern] of [
|
|
["hosted service embeds core coordinator runtime", /core_coordinator: CoordinatorService/],
|
|
["hosted service parses the unified identity, operator, and client protocol", /decode_incoming_request/],
|
|
["hosted service delegates client requests", /handle_client_request/],
|
|
["hosted service routes decoded client requests to Core", /IncomingRequest::Client\(request\)/],
|
|
["hosted service requires replay-resistant operator envelope proofs", /hosted_operator_request[\s\S]*HostedOperatorAuth[\s\S]*replay_nonces[\s\S]*verify_request[\s\S]*hosted_operator_request_proof_from_token_digest/],
|
|
["hosted service issues the authenticated Core CLI session", /core_coordinator[\s\S]*\.issue_cli_session/],
|
|
["hosted service creates the authenticated default project through Core", /AuthenticatedCoordinatorRequest::CreateProject/],
|
|
]) {
|
|
expect(hostedServiceSecurity, name, pattern);
|
|
}
|
|
|
|
for (const [name, pattern] of [
|
|
["compat smoke starts hosted service", /disasmer-hosted-service/],
|
|
["compat smoke creates hosted project", /type: "create_project"/],
|
|
["compat smoke creates session-authorized enrollment grant", /type: "create_node_enrollment_grant"/],
|
|
["compat smoke runs public CLI attach", /"disasmer-cli"[\s\S]*"node"[\s\S]*"attach"/],
|
|
["compat smoke verifies public enrollment exchange", /node_enrollment_exchanged/],
|
|
["compat smoke runs public CLI browser login", /"login"[\s\S]*"--browser"[\s\S]*DISASMER_BROWSER_OPEN_COMMAND/],
|
|
["compat smoke derives hosted scope", /const session = login\.coordinator_response\.session/],
|
|
["compat smoke rejects forged identity", /forged_unsigned_project/],
|
|
["compat smoke rejects an actually expired hosted session", /DISASMER_HOSTED_CLI_SESSION_TTL_SECONDS[\s\S]*expired; run disasmer login --browser again/],
|
|
["compat smoke denies cross-tenant task-event reads", /crossTenantTaskEventsDenied[\s\S]*type: "list_task_events"[\s\S]*vp-victim/],
|
|
["compat smoke writes evidence report", /hosted-client-compat\.json/],
|
|
]) {
|
|
expect(hostedClientCompatSmoke, name, pattern);
|
|
}
|
|
}
|
|
|
|
for (const [name, pattern] of [
|
|
["e2e runner requires explicit opt-in", /DISASMER_PUBLIC_RELEASE_DRYRUN_E2E/],
|
|
["e2e runner requires the honestly reset pre-final ledger", /assertPreFinalLedger\(readPhase3Ledger\(repo\)\)/],
|
|
["e2e runner requires public domain service address", /serviceAddr[\s\S]*serviceHost/],
|
|
["e2e runner downloads release assets", /downloadReleaseAssets/],
|
|
["e2e runner verifies release checksums", /verifyChecksums/],
|
|
["e2e runner clones public repo", /git"[\s\S]*"clone"[\s\S]*publicRepositoryUrl/],
|
|
["e2e runner uses default hosted coordinator", /defaultLoginPlan\.coordinator[\s\S]*serviceEndpoint/],
|
|
["e2e runner uses server-owned browser login", /DISASMER_PUBLIC_RELEASE_DRYRUN_BROWSER_OPEN_COMMAND[\s\S]*DISASMER_BROWSER_OPEN_COMMAND/],
|
|
["e2e runner attaches user node", /node"[\s\S]*"attach"/],
|
|
["e2e runner starts public worker runtime", /workerArgs[\s\S]*"--worker"[\s\S]*cp\.spawn\(disasmerNode/],
|
|
["e2e runner launches released product through CLI", /"run"[\s\S]*"build"[\s\S]*runReport\.status[\s\S]*main_launched/],
|
|
["standalone Core proof launches a real Wasm TaskSpec", /type: "launch_task"[\s\S]*task_spec:[\s\S]*kind: "coordinator_node_wasm"[\s\S]*bundle_digest: manifest\.bundle_digest/],
|
|
["e2e runner verifies public assignment polling", /worker_assignment_poll_protocol/],
|
|
["e2e runner validates standalone Core coordinator", /validateStandaloneCoreCoordinator/],
|
|
["e2e runner records standalone Core coordinator", /core_coordinator_implementation/],
|
|
["e2e runner verifies task events", /list_task_events/],
|
|
["e2e runner creates artifact download link", /create_artifact_download_link/],
|
|
["e2e runner verifies VS Code debugger", /vscode-f5-smoke\.js/],
|
|
["e2e runner writes e2e report", /public-release-dryrun-e2e\.json/],
|
|
]) {
|
|
expect(publicDryrunE2e, name, pattern);
|
|
}
|
|
|
|
for (const [name, pattern] of [
|
|
["final verifier requires public release manifest", /public-release-manifest\.json/],
|
|
["final verifier requires Forgejo release evidence", /public-release-dryrun-forgejo-release\.json/],
|
|
["final verifier requires deployment manifest", /deployment-manifest\.json/],
|
|
["final verifier requires service smoke evidence", /public-release-dryrun-service\.json/],
|
|
["final verifier requires all 191 Phase 3 criteria passed", /assertFinalLedger\(readPhase3Ledger\(repo\)\)/],
|
|
["final verifier requires current service smoke source", /service\.source_commit[\s\S]*manifest\.source_commit/],
|
|
["final verifier requires current service smoke release", /service\.release_name[\s\S]*manifest\.release_name/],
|
|
["final verifier requires hosted Client compatibility evidence", /hosted-client-compat\.json/],
|
|
["final verifier requires current Client compatibility source", /compat\.source_commit[\s\S]*manifest\.source_commit/],
|
|
["final verifier requires current Client compatibility release", /compat\.release_name[\s\S]*manifest\.release_name/],
|
|
["final verifier requires Core coordinator compatibility evidence", /core-coordinator-compat\.json/],
|
|
["final verifier requires current public coordinator source", /coreCoordinator\.source_commit[\s\S]*manifest\.source_commit/],
|
|
["final verifier requires current public coordinator release", /coreCoordinator\.release_name[\s\S]*manifest\.release_name/],
|
|
["final verifier requires public e2e evidence", /public-release-dryrun-e2e\.json/],
|
|
["final verifier records both coordinator validations", /coordinator_validation/],
|
|
["final verifier writes final evidence", /public-release-dryrun-final\.json/],
|
|
]) {
|
|
expect(finalDryrunEvidence, name, pattern);
|
|
}
|
|
|
|
console.log("Acceptance environment contract smoke passed");
|