#!/usr/bin/env node const assert = require("assert"); const cp = require("child_process"); const crypto = require("crypto"); const fs = require("fs"); const https = require("https"); const os = require("os"); const path = require("path"); const { DapClient } = require("./dap-client"); const { agentIdentity, signedAgentWorkflowRequest } = require("./agent-signing"); const { coordinatorWireRequest } = require("./coordinator-wire"); const { nodeIdentity, nodeIdentityFromPrivateKey, signedNodeHeartbeat, signedNodeRequest, } = require("./node-signing"); const { configurePodmanTestEnvironment } = require("./podman-test-env"); const repo = path.resolve(__dirname, ".."); configurePodmanTestEnvironment(repo); if ( !process.env.CLUSTERFLUX_PODMAN_NIX_SHELL && cp.spawnSync("podman", ["--version"], { stdio: "ignore" }).status !== 0 && cp.spawnSync("nix", ["--version"], { stdio: "ignore" }).status === 0 ) { cp.execFileSync( "nix", ["shell", "nixpkgs#podman", "--command", "node", __filename], { cwd: repo, env: { ...process.env, CLUSTERFLUX_PODMAN_NIX_SHELL: "1" }, stdio: "inherit", } ); process.exit(0); } const releaseRoot = path.resolve( process.env.CLUSTERFLUX_PUBLIC_RELEASE_DIR || path.join(repo, "target/public-release") ); const acceptanceRoot = path.join(repo, "target/acceptance"); const manifestPath = path.join(releaseRoot, "public-release-manifest.json"); const reportPath = path.join(acceptanceRoot, "cli-happy-path-live.json"); const serviceEndpoint = "https://clusterflux.michelpaulissen.com"; const serviceAddr = process.env.CLUSTERFLUX_PUBLIC_RELEASE_SERVICE_ADDR || "clusterflux.michelpaulissen.com:443"; const browserOpenCommand = process.env.CLUSTERFLUX_PUBLIC_RELEASE_BROWSER_OPEN_COMMAND; const reuseSessionFile = process.env.CLUSTERFLUX_CLI_HAPPY_PATH_REUSE_SESSION_FILE; const qualityGateEvidencePath = process.env.CLUSTERFLUX_QUALITY_GATE_EVIDENCE_PATH; const enabled = process.env.CLUSTERFLUX_CLI_HAPPY_PATH_LIVE === "1"; const strictFullRelease = process.env.CLUSTERFLUX_STRICT_FULL_RELEASE === "1"; const strictVpsRestart = process.env.CLUSTERFLUX_STRICT_VPS_RESTART === "1"; const strictVpsHost = process.env.CLUSTERFLUX_STRICT_VPS_HOST; const strictVpsIdentity = process.env.CLUSTERFLUX_STRICT_VPS_IDENTITY; const strictServiceUnit = process.env.CLUSTERFLUX_STRICT_SERVICE_UNIT || "clusterflux-hosted.service"; const strictSoakSeconds = Number( process.env.CLUSTERFLUX_STRICT_SOAK_SECONDS || "300" ); const commands = []; function requireEnabled() { if (!enabled) { throw new Error( "CLUSTERFLUX_CLI_HAPPY_PATH_LIVE=1 is required because this runs the live CLI happy path" ); } if (!browserOpenCommand && !reuseSessionFile) { throw new Error( "CLUSTERFLUX_PUBLIC_RELEASE_BROWSER_OPEN_COMMAND or CLUSTERFLUX_CLI_HAPPY_PATH_REUSE_SESSION_FILE is required" ); } const hasSecondTenantSession = Boolean( process.env.CLUSTERFLUX_SECOND_TENANT_SESSION_FILE ); if ( strictFullRelease && !hasSecondTenantSession ) { throw new Error( "CLUSTERFLUX_STRICT_FULL_RELEASE=1 requires CLUSTERFLUX_SECOND_TENANT_SESSION_FILE so the compiled two-tenant Node and artifact collision can run" ); } if (strictFullRelease && !process.env.CLUSTERFLUX_EXPIRED_USER_SESSION_FILE) { throw new Error( "CLUSTERFLUX_STRICT_FULL_RELEASE=1 requires CLUSTERFLUX_EXPIRED_USER_SESSION_FILE" ); } if (strictFullRelease && !qualityGateEvidencePath) { throw new Error( "CLUSTERFLUX_STRICT_FULL_RELEASE=1 requires CLUSTERFLUX_QUALITY_GATE_EVIDENCE_PATH" ); } if (strictFullRelease && !strictVpsRestart) { throw new Error( "CLUSTERFLUX_STRICT_FULL_RELEASE=1 requires CLUSTERFLUX_STRICT_VPS_RESTART=1" ); } if (strictVpsRestart && (!strictVpsHost || !strictVpsIdentity)) { throw new Error( "strict VPS restart requires CLUSTERFLUX_STRICT_VPS_HOST and CLUSTERFLUX_STRICT_VPS_IDENTITY" ); } if ( !Number.isInteger(strictSoakSeconds) || strictSoakSeconds < 120 || strictSoakSeconds > 1800 ) { throw new Error("CLUSTERFLUX_STRICT_SOAK_SECONDS must be an integer from 120 to 1800"); } } function readJson(file) { return JSON.parse(fs.readFileSync(file, "utf8")); } function strictQualityGateEvidence(manifest) { if (!strictFullRelease) return null; const evidence = readJson(path.resolve(qualityGateEvidencePath)); assert.strictEqual(evidence.source_commit, manifest.source_commit); assert.strictEqual(evidence.source_tree_digest, manifest.source_tree_digest); for (const gate of [evidence.private, evidence.public]) { assert.strictEqual(gate.status, "passed"); assert(Number.isFinite(gate.duration_ms) && gate.duration_ms > 0); } assert.strictEqual(evidence.public.independent_filtered_tree, true); for (const id of [ "formatting", "clippy_warnings_denied", "public_workspace_tests", "private_hosted_policy_locked_tests", "process_lifecycle_regressions", "wasm_example_builds", "filtered_public_tree_build_and_tests", "vscode_extension_candidate", ]) { const check = evidence.checks?.[id]; assert(check, `quality evidence omitted ${id}`); assert.strictEqual(check.status, "passed"); assert(Number.isFinite(check.duration_ms) && check.duration_ms > 0); } assert.strictEqual( evidence.checks.vscode_extension_candidate.candidate_vsix.sha256, manifest.release_candidate.extension_sha256 ); return evidence; } function ensureDir(dir) { fs.mkdirSync(dir, { recursive: true }); } function sha256(bytes) { return `sha256:${crypto.createHash("sha256").update(bytes).digest("hex")}`; } function nonInteractiveGitEnv(extra = {}) { return { ...process.env, GIT_TERMINAL_PROMPT: "0", GIT_ASKPASS: process.env.GIT_ASKPASS || "/bin/false", SSH_ASKPASS: process.env.SSH_ASKPASS || "/bin/false", GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o NumberOfPasswordPrompts=0", ...extra, }; } function commandEnv(command, env) { if (command !== "git") return env; return nonInteractiveGitEnv(env); } function recordCommand(command, args) { const redacted = []; let hideNext = false; for (const argument of args) { if (hideNext) { redacted.push(""); hideNext = false; } else { redacted.push(argument); hideNext = ["--enrollment-grant", "--admin-token"].includes(argument); } } commands.push([command, ...redacted].join(" ")); } function run(command, args, options = {}) { recordCommand(command, args); return cp.execFileSync(command, args, { cwd: repo, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: 15 * 60 * 1000, ...options, env: commandEnv(command, options.env), }); } function parseJsonOutput(output) { const trimmed = output.trim(); if (!trimmed) throw new Error("expected JSON output, got empty stdout"); try { return JSON.parse(trimmed); } catch (_) { // Commands may print progress before their final JSON report. } const lines = trimmed.split(/\r?\n/).filter(Boolean); for (let index = lines.length - 1; index >= 0; index -= 1) { try { return JSON.parse(lines.slice(index).join("\n")); } catch (_) { // Keep scanning for the trailing JSON value. } } throw new Error(`could not parse JSON output:\n${trimmed}`); } function runJson(command, args, options = {}) { return parseJsonOutput(run(command, args, options)); } function authenticatedRequest(sessionSecret, request) { return { type: "authenticated", session_secret: sessionSecret, request, }; } function sendHostedControl(payload) { return sendHostedControlEnvelope( coordinatorWireRequest(payload, "strict-live") ); } function sendHostedControlEnvelope(envelope) { const body = Buffer.from( JSON.stringify(envelope) ); const url = new URL("/api/v1/control", serviceEndpoint); return new Promise((resolve, reject) => { const request = https.request( url, { method: "POST", headers: { "content-type": "application/json", "content-length": body.length, }, timeout: 30_000, }, (response) => { const chunks = []; response.on("data", (chunk) => chunks.push(chunk)); response.on("end", () => { const responseBody = Buffer.concat(chunks).toString("utf8"); if (response.statusCode < 200 || response.statusCode >= 300) { reject( new Error( `hosted control HTTP ${response.statusCode}: ${responseBody}` ) ); return; } try { resolve(JSON.parse(responseBody)); } catch (error) { reject( new Error(`hosted control returned invalid JSON: ${error.message}`) ); } }); } ); request.on("timeout", () => request.destroy(new Error("hosted control request timed out")) ); request.on("error", reject); request.end(body); }); } async function runMalformedIdentifierSuite({ clusterflux, projectDir, scope, sessionSecret, tenant, project, user, suffix, securityNode, bundle, releaseArtifact, }) { const scenarioStartedAt = Date.now(); const forms = [ { name: "empty", value: "" }, { name: "whitespace", value: " \t" }, { name: "control", value: "hostile\u0000id" }, { name: "invalid_format", value: "hostile id!" }, { name: "oversized", value: "x".repeat(256) }, ]; const tokenForms = forms .filter((form) => form.name !== "invalid_format") .map((form) => form.name === "oversized" ? { ...form, value: "x".repeat(257) } : form ); assert( Buffer.byteLength( tokenForms.find((form) => form.name === "oversized").value ) > 256, "hostile token suite must exceed the signed-nonce and hosted-login byte limit" ); const agent = `hostile-id-agent-${suffix}`; const agentIdentityRecord = agentIdentity("strict-hostile-id-agent", agent); const processId = `vp-hostile-identifiers-${suffix}`; const launchAttempt = `hostile-launch-attempt-${suffix}`; const mainTask = `ti:${processId}:main`; const taskSpec = { tenant, project, process: processId, task_definition: bundle.entryStableId, task_instance: mainTask, dispatch: { kind: "coordinator_node_wasm", export: bundle.entryExport, abi: "entrypoint_v1", }, environment_id: null, environment: null, environment_digest: null, required_capabilities: [], dependency_cache: null, source_snapshot: null, required_artifacts: [], args: [], vfs_epoch: 1, failure_policy: "fail_fast", bundle_digest: bundle.digest, }; const rejected = []; const elapsedMs = (started) => Number(process.hrtime.bigint() - started) / 1_000_000; const rejectMalformed = async ({ principal, requestVariant, fieldPath, form, send, token = false, }) => { const started = process.hrtime.bigint(); const response = await send(form.value); assert.strictEqual( response.type, "error", `${principal} ${fieldPath} ${form.name} reached the real ${requestVariant} variant but was not rejected: ${JSON.stringify(response)}` ); assert.match( response.message, token ? /malformed external token|token.*invalid|control characters|byte limit|empty|whitespace/i : /malformed external identifier|(?:Agent|Artifact|Node|Process|Project|TaskDefinition|TaskInstance|Tenant|User|LaunchAttempt)Id is invalid/i, `${principal} ${fieldPath} ${form.name} was not rejected for identifier validation: ${JSON.stringify(response)}` ); assert.doesNotMatch( response.message, /unknown variant|unknown field|missing field/i, `${principal} ${fieldPath} ${form.name} only proved generic deserialization failure` ); const health = await sendHostedControl({ type: "ping" }); assert.strictEqual( health.type, "pong", `valid traffic failed after hostile ${principal} ${fieldPath} ${form.name}` ); rejected.push({ principal, request_variant: requestVariant, field_path: fieldPath, fault: form.name, expected: token ? "structured malformed external token error" : "structured malformed external identifier error", observed: response.message, health_after: health.type, duration_ms: elapsedMs(started), }); }; let agentRegistered = false; let processStarted = false; try { const added = runJson( clusterflux, [ "key", "add", ...scope, "--agent", agent, "--public-key", agentIdentityRecord.publicKey, ], { cwd: projectDir } ); assert.strictEqual(added.command, "key add"); agentRegistered = true; const agentStartCases = [ ["tenant", "tenant"], ["project", "project"], ["agent", "actor_agent"], ["process", "process"], ["launch_attempt", "launch_attempt"], ]; for (const [principal, field] of agentStartCases) { for (const form of forms) { await rejectMalformed({ principal: `agent_signed_${principal}`, requestVariant: "start_process", fieldPath: field, form, send: async (value) => { const body = { type: "start_process", tenant, project, actor_agent: agent, process: processId, launch_attempt: launchAttempt, restart: false, }; body[field] = value; return sendHostedControl( signedAgentWorkflowRequest(agentIdentityRecord, body, { nonce: `hostile-agent-${principal}-${form.name}-${Date.now()}`, }) ); }, }); } } for (const form of tokenForms) { await rejectMalformed({ principal: "agent_signed_nonce", requestVariant: "start_process", fieldPath: "agent_signature.nonce", form, token: true, send: async (value) => { const request = signedAgentWorkflowRequest( agentIdentityRecord, { type: "start_process", tenant, project, actor_agent: agent, process: processId, launch_attempt: launchAttempt, restart: false, }, { nonce: value } ); assert.strictEqual( request.agent_signature.nonce, value, "hostile Agent nonce was not preserved on the wire" ); return sendHostedControl(request); }, }); } for (const form of forms) { await rejectMalformed({ principal: "node_signed_heartbeat_node", requestVariant: "node_heartbeat", fieldPath: "node", form, send: async (value) => sendHostedControl({ type: "node_heartbeat", tenant, project, node: value, node_signature: signedNodeHeartbeat( tenant, project, value, securityNode.identity, { nonce: `hostile-heartbeat-node-${form.name}-${Date.now()}`, } ), }), }); } const started = await sendHostedControl( signedAgentWorkflowRequest( agentIdentityRecord, { type: "start_process", tenant, project, actor_agent: agent, process: processId, launch_attempt: launchAttempt, restart: false, }, { nonce: `hostile-agent-valid-start-${suffix}` } ) ); assert.strictEqual(started.type, "process_started", JSON.stringify(started)); processStarted = true; taskSpec.vfs_epoch = started.epoch; const taskSpecCases = [ ["tenant", "task_spec.tenant"], ["project", "task_spec.project"], ["process", "task_spec.process"], ["task_definition", "task_spec.task_definition"], ["task_instance", "task_spec.task_instance"], ]; for (const [field, fieldPath] of taskSpecCases) { for (const form of forms) { await rejectMalformed({ principal: `agent_signed_${field}`, requestVariant: "launch_task", fieldPath, form, send: async (value) => { const malformedTaskSpec = structuredClone(taskSpec); malformedTaskSpec[field] = value; const body = { type: "launch_task", tenant, project, actor_agent: agent, task_spec: malformedTaskSpec, wait_for_node: false, artifact_path: `/vfs/artifacts/${mainTask}-output.txt`, wasm_module_base64: bundle.moduleBase64, }; return sendHostedControl( signedAgentWorkflowRequest(agentIdentityRecord, body, { nonce: `hostile-task-spec-${field}-${form.name}-${Date.now()}`, }) ); }, }); } } for (const form of forms) { await rejectMalformed({ principal: "agent_signed_artifact_array", requestVariant: "launch_task", fieldPath: "task_spec.required_artifacts[0]", form, send: async (value) => { const malformedTaskSpec = structuredClone(taskSpec); malformedTaskSpec.required_artifacts = [releaseArtifact.artifact]; malformedTaskSpec.args = [ { Artifact: { id: releaseArtifact.artifact, digest: releaseArtifact.digest, size_bytes: Number(releaseArtifact.size_bytes || 1), }, }, ]; malformedTaskSpec.required_artifacts = [value]; const body = { type: "launch_task", tenant, project, actor_agent: agent, task_spec: malformedTaskSpec, wait_for_node: false, artifact_path: `/vfs/artifacts/${mainTask}-artifact-output.txt`, wasm_module_base64: bundle.moduleBase64, }; return sendHostedControl( signedAgentWorkflowRequest(agentIdentityRecord, body, { nonce: `hostile-artifact-array-${form.name}-${Date.now()}`, }) ); }, }); } const mainLaunch = await sendHostedControl( signedAgentWorkflowRequest( agentIdentityRecord, { type: "launch_task", tenant, project, actor_agent: agent, task_spec: taskSpec, wait_for_node: false, artifact_path: `/vfs/artifacts/${mainTask}-output.txt`, wasm_module_base64: bundle.moduleBase64, }, { nonce: `hostile-agent-valid-main-${suffix}` } ) ); assert.strictEqual(mainLaunch.type, "main_launched", JSON.stringify(mainLaunch)); const authenticatedCases = [ { principal: "authenticated_cli_project", requestVariant: "select_project", fieldPath: "request.project", payload: (value) => ({ type: "select_project", project: value }), }, { principal: "authenticated_cli_process", requestVariant: "list_task_events", fieldPath: "request.process", payload: (value) => ({ type: "list_task_events", process: value }), }, { principal: "authenticated_cli_task", requestVariant: "join_task", fieldPath: "request.task", payload: (value) => ({ type: "join_task", process: processId, task: value, }), }, { principal: "authenticated_cli_artifact", requestVariant: "create_artifact_download_link", fieldPath: "request.artifact", payload: (value) => ({ type: "create_artifact_download_link", artifact: value, max_bytes: Number(releaseArtifact.size_bytes || 1), ttl_seconds: 60, }), }, { principal: "authenticated_cli_launch_attempt", requestVariant: "abort_process", fieldPath: "request.launch_attempt", payload: (value) => ({ type: "abort_process", process: processId, launch_attempt: value, }), }, ]; for (const testCase of authenticatedCases) { for (const form of forms) { await rejectMalformed({ ...testCase, form, send: async (value) => sendHostedControl( authenticatedRequest(sessionSecret, testCase.payload(value)) ), }); } } const nodeCases = [ { principal: "node_signed_wrapper_node", requestVariant: "poll_task_assignment", fieldPath: "node", send: (value, form) => sendHostedControl( signedNodeRequest( value, securityNode.identity, "poll_task_assignment", { type: "poll_task_assignment", tenant, project, node: securityNode.node, }, { nonce: `hostile-node-wrapper-${form.name}-${Date.now()}` } ) ), }, { principal: "node_signed_poll_tenant", requestVariant: "poll_task_assignment", fieldPath: "request.tenant", send: (value, form) => sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "poll_task_assignment", { type: "poll_task_assignment", tenant: value, project, node: securityNode.node, }, { nonce: `hostile-node-tenant-${form.name}-${Date.now()}` } ) ), }, { principal: "node_signed_poll_project", requestVariant: "poll_task_assignment", fieldPath: "request.project", send: (value, form) => sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "poll_task_assignment", { type: "poll_task_assignment", tenant, project: value, node: securityNode.node, }, { nonce: `hostile-node-project-${form.name}-${Date.now()}` } ) ), }, { principal: "node_signed_poll_node", requestVariant: "poll_task_assignment", fieldPath: "request.node", send: (value, form) => sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "poll_task_assignment", { type: "poll_task_assignment", tenant, project, node: value, }, { nonce: `hostile-node-inner-${form.name}-${Date.now()}` } ) ), }, { principal: "node_signed_artifact_array", requestVariant: "report_node_capabilities", fieldPath: "request.artifact_locations[0]", send: (value, form) => sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "report_node_capabilities", { ...securityNode.capability_body, artifact_locations: [value], }, { nonce: `hostile-node-artifact-${form.name}-${Date.now()}` } ) ), }, ]; for (const testCase of nodeCases) { for (const form of forms) { await rejectMalformed({ principal: testCase.principal, requestVariant: testCase.requestVariant, fieldPath: testCase.fieldPath, form, send: (value) => testCase.send(value, form), }); } } for (const form of tokenForms) { await rejectMalformed({ principal: "node_signed_nonce", requestVariant: "node_heartbeat", fieldPath: "node_signature.nonce", form, token: true, send: async (value) => { const request = { type: "node_heartbeat", tenant, project, node: securityNode.node, node_signature: signedNodeHeartbeat( tenant, project, securityNode.node, securityNode.identity, { nonce: value } ), }; assert.strictEqual( request.node_signature.nonce, value, "hostile Node nonce was not preserved on the wire" ); return sendHostedControl(request); }, }); } const endpointFingerprint = sha256( Buffer.from(securityNode.identity.publicKey) ); const rendezvous = { type: "request_rendezvous", scope: { tenant, project, process: processId, object: { Artifact: releaseArtifact.artifact }, authorization_subject: `${securityNode.node}-self-transfer`, }, source: { node: securityNode.node, advertised_addr: "127.0.0.1:4433", public_key_fingerprint: endpointFingerprint, }, destination: { node: securityNode.node, advertised_addr: "127.0.0.1:4433", public_key_fingerprint: endpointFingerprint, }, direct_connectivity: true, failure_reason: "", }; const rendezvousCases = [ ["scope.tenant", (request, value) => (request.scope.tenant = value)], ["scope.project", (request, value) => (request.scope.project = value)], ["scope.process", (request, value) => (request.scope.process = value)], [ "scope.object.artifact", (request, value) => (request.scope.object.Artifact = value), ], ["source.node", (request, value) => (request.source.node = value)], [ "destination.node", (request, value) => (request.destination.node = value), ], ]; for (const [fieldPath, mutate] of rendezvousCases) { for (const form of forms) { await rejectMalformed({ principal: "node_signed_rendezvous", requestVariant: "request_rendezvous", fieldPath: `request.${fieldPath}`, form, send: async (value) => { const body = structuredClone(rendezvous); mutate(body, value); return sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "request_rendezvous", body, { nonce: `hostile-rendezvous-${fieldPath}-${form.name}-${Date.now()}`, } ) ); }, }); } } const validRendezvous = await sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "request_rendezvous", rendezvous, { nonce: `hostile-rendezvous-valid-${suffix}` } ) ); assert.strictEqual( validRendezvous.type, "rendezvous_plan", JSON.stringify(validRendezvous) ); const login = await sendHostedLogin({ type: "begin_oidc_browser_login" }); assert.strictEqual(login.type, "oidc_browser_login_started", JSON.stringify(login)); const loginCases = [ ["transaction_id", login.transaction_id, login.polling_secret], ["polling_secret", login.transaction_id, login.polling_secret], ]; for (const [field, validTransaction, validSecret] of loginCases) { for (const form of tokenForms) { await rejectMalformed({ principal: "private_hosted_login", requestVariant: "poll_oidc_browser_login", fieldPath: field, form, token: true, send: async (value) => sendHostedLogin({ type: "poll_oidc_browser_login", transaction_id: field === "transaction_id" ? value : validTransaction, polling_secret: field === "polling_secret" ? value : validSecret, }), }); const validPoll = await sendHostedLogin({ type: "poll_oidc_browser_login", transaction_id: login.transaction_id, polling_secret: login.polling_secret, }); assert.strictEqual( validPoll.type, "oidc_browser_login_pending", `valid hosted login polling failed after malformed ${field}` ); } } const operatorControlCases = [ ["payload.tenant", "tenant"], ["payload.project", "project"], ["payload.process", "process"], ]; for (const [fieldPath, field] of operatorControlCases) { for (const form of forms) { await rejectMalformed({ principal: "private_hosted_operator_control", requestVariant: "stop_hosted_process", fieldPath, form, send: async (value) => { const payload = { type: "stop_hosted_process", tenant, project, process: processId, }; payload[field] = value; return sendHostedControlEnvelope({ type: "hosted_operator_request", protocol_version: 1, request_id: `hostile-operator-${field}-${form.name}-${Date.now()}`, operation: "stop_hosted_process", operator_proof: sha256(Buffer.from("invalid operator proof")), operator_nonce: `hostile-operator-nonce-${field}-${form.name}-${Date.now()}`, issued_at_epoch_seconds: Math.floor(Date.now() / 1000), payload, }); }, }); } } const authenticatedHealth = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "auth_status" }) ); assert.strictEqual(authenticatedHealth.type, "auth_status"); assert.strictEqual(authenticatedHealth.tenant, tenant); assert.strictEqual(authenticatedHealth.project, project); assert.strictEqual(authenticatedHealth.actor, user); } finally { if (processStarted) { try { runJson( clusterflux, [ "process", "abort", ...scope, "--process", processId, "--yes", ], { cwd: projectDir } ); } catch (_) { // Preserve the primary validation failure while still attempting cleanup. } } if (agentRegistered) { try { runJson( clusterflux, ["key", "revoke", ...scope, "--agent", agent, "--yes"], { cwd: projectDir } ); } catch (_) { // Preserve the primary validation failure while still attempting cleanup. } } } const coveredPrincipals = [...new Set(rejected.map((entry) => entry.principal))]; const coveredVariants = [...new Set(rejected.map((entry) => entry.request_variant))]; return { principals: coveredPrincipals, request_variants: coveredVariants, forms: forms.map((form) => form.name), rejected_requests: rejected, all_rejected_for_intended_reason: rejected.every( (entry) => /identifier|token|Id is invalid|control characters|byte limit|empty|whitespace/i.test( entry.observed ) ), valid_after_every_rejection: rejected.every( (entry) => entry.health_after === "pong" ), valid_authenticated_action_after_suite: true, valid_signed_rendezvous_after_suite: true, valid_private_login_poll_after_every_private_rejection: true, duration_ms: Date.now() - scenarioStartedAt, }; } function sendHostedControlDroppingResponse(payload) { const body = Buffer.from( JSON.stringify(coordinatorWireRequest(payload, "strict-live-dropped-response")) ); const url = new URL("/api/v1/control", serviceEndpoint); return new Promise((resolve, reject) => { let settled = false; const request = https.request( url, { method: "POST", headers: { "content-type": "application/json", "content-length": body.length, }, timeout: 30_000, }, (response) => { settled = true; const statusCode = response.statusCode; response.destroy(); resolve({ status_code: statusCode, response_body_consumed: false }); } ); request.on("timeout", () => request.destroy(new Error("hosted dropped-response request timed out")) ); request.on("error", (error) => { if (!settled) reject(error); }); request.end(body); }); } function sendHostedLoginStatus(extraHeaders = {}) { const body = Buffer.from( JSON.stringify( coordinatorWireRequest( { type: "begin_oidc_browser_login" }, `strict-live-login-${Date.now()}-${Math.random()}` ) ) ); const url = new URL("/api/v1/login", serviceEndpoint); return new Promise((resolve, reject) => { const request = https.request( url, { method: "POST", headers: { "content-type": "application/json", "content-length": body.length, ...extraHeaders, }, timeout: 30_000, }, (response) => { const chunks = []; response.on("data", (chunk) => chunks.push(chunk)); response.on("end", () => resolve({ status_code: response.statusCode, body: Buffer.concat(chunks).toString("utf8"), }) ); } ); request.on("timeout", () => request.destroy(new Error("hosted login request timed out")) ); request.on("error", reject); request.end(body); }); } function sendHostedLogin(payload) { const body = Buffer.from( JSON.stringify( coordinatorWireRequest( payload, `strict-live-login-protocol-${Date.now()}-${Math.random()}` ) ) ); const url = new URL("/api/v1/login", serviceEndpoint); return new Promise((resolve, reject) => { const request = https.request( url, { method: "POST", headers: { "content-type": "application/json", "content-length": body.length, }, timeout: 30_000, }, (response) => { const chunks = []; response.on("data", (chunk) => chunks.push(chunk)); response.on("end", () => { const responseBody = Buffer.concat(chunks).toString("utf8"); if (response.statusCode < 200 || response.statusCode >= 300) { reject( new Error( `hosted login HTTP ${response.statusCode}: ${responseBody}` ) ); return; } try { resolve(JSON.parse(responseBody)); } catch (error) { reject( new Error(`hosted login returned invalid JSON: ${error.message}`) ); } }); } ); request.on("timeout", () => request.destroy(new Error("hosted login request timed out")) ); request.on("error", reject); request.end(body); }); } async function runHostedLoginIsolationBeforeRestart() { const scenarioStartedAt = Date.now(); const controlBefore = await sendHostedControl({ type: "ping" }); assert.strictEqual(controlBefore.type, "pong"); const statuses = []; let limited; for (let index = 0; index < 128; index += 1) { const response = await sendHostedLoginStatus(); statuses.push(response.status_code); if (response.status_code === 429) { limited = response; break; } assert.strictEqual(response.status_code, 200, response.body); } assert(limited, `hosted login route was not rate limited: ${statuses.join(",")}`); const spoofed = await sendHostedLoginStatus({ forwarded: "for=203.0.113.99", "x-forwarded-for": "203.0.113.99", "x-real-ip": "203.0.113.99", }); assert.strictEqual( spoofed.status_code, 429, "caller-supplied forwarding headers bypassed the client rate limit" ); const remoteBody = JSON.stringify( coordinatorWireRequest( { type: "begin_oidc_browser_login" }, `strict-vps-login-${Date.now()}` ) ); const remoteStatus = Number( run( "ssh", sshArgs( "curl", "--silent", "--show-error", "--output", "/dev/null", "--write-out=%{http_code}", "-HContent-Type:application/json", `--data-binary=${remoteBody}`, `${serviceEndpoint}/api/v1/login` ) ).trim() ); assert.strictEqual( remoteStatus, 200, "one client exhausted the browser-login allowance for a different client" ); const controlAfter = await sendHostedControl({ type: "ping" }); assert.strictEqual(controlAfter.type, "pong"); return { scenario_started_at_ms: scenarioStartedAt, local_statuses: statuses, local_limited_status: limited.status_code, forwarding_spoof_status: spoofed.status_code, independent_vps_client_status: remoteStatus, control_route_before: controlBefore.type, control_route_after: controlAfter.type, }; } async function finishHostedLoginIsolationAfterRestart(evidence) { const control = await sendHostedControl({ type: "ping" }); assert.strictEqual(control.type, "pong"); const response = await sendHostedLoginStatus(); assert( [200, 429].includes(response.status_code), `login route did not recover after service restart: ${response.status_code} ${response.body}` ); evidence.after_service_restart = { control_route: control.type, login_route_status: response.status_code, }; evidence.duration_ms = Date.now() - evidence.scenario_started_at_ms; delete evidence.scenario_started_at_ms; return evidence; } function assertDenied(response, pattern, label) { assert.strictEqual(response.type, "error", `${label}: ${JSON.stringify(response)}`); assert.match(response.message, pattern, `${label}: ${JSON.stringify(response)}`); return { denied: true, category: response.error?.category || null, message: response.message, }; } function assertDeniedOrEmptyCollection(response, pattern, label) { const emptyCollectionField = { process_statuses: "processes", task_events: "events", }[response.type]; if (!emptyCollectionField) { return assertDenied(response, pattern, label); } assert.deepStrictEqual( Object.keys(response).sort(), ["actor", emptyCollectionField, "type"] .filter((key) => key !== "actor" || Object.hasOwn(response, key)) .sort(), `${label}: ${JSON.stringify(response)}` ); assert.deepStrictEqual( response[emptyCollectionField], [], `${label}: ${JSON.stringify(response)}` ); return { denied: false, scoped_empty_result: true, response_type: response.type, }; } function readNodeCredential(projectDir, node) { const directory = path.join(projectDir, ".clusterflux", "nodes"); for (const file of fs.readdirSync(directory)) { if (!file.endsWith(".json")) continue; const absolute = path.join(directory, file); const credential = readJson(absolute); if (credential.node === node) return { absolute, credential }; } throw new Error(`persisted credential for ${node} was not found`); } function directoryStats(root) { if (!fs.existsSync(root)) return { files: 0, bytes: 0 }; let files = 0; let bytes = 0; const visit = (directory) => { for (const entry of fs.readdirSync(directory, { withFileTypes: true })) { const absolute = path.join(directory, entry.name); if (entry.isDirectory()) visit(absolute); else if (entry.isFile()) { files += 1; bytes += fs.statSync(absolute).size; } } }; visit(root); return { files, bytes }; } function shellQuote(argument) { return `'${String(argument).replaceAll("'", "'\"'\"'")}'`; } function sshArgs(...remoteArgs) { assert(strictVpsHost && strictVpsIdentity); return [ "-i", path.resolve(strictVpsIdentity.replace(/^~(?=\/)/, os.homedir())), "-o", "BatchMode=yes", strictVpsHost, remoteArgs.map(shellQuote).join(" "), ]; } function strictInfrastructureSample(projectDir) { const memory = Object.fromEntries( run( "ssh", sshArgs( "systemctl", "show", strictServiceUnit, "--property=MemoryCurrent", "--property=MemoryPeak" ) ) .trim() .split(/\r?\n/) .map((line) => line.split("=")) ); const serviceDisk = Number( run( "ssh", sshArgs("du", "-sb", "/var/lib/clusterflux-public-release") ) .trim() .split(/\s+/)[0] ); const database = run( "ssh", sshArgs( "runuser", "-u", "postgres", "--", "psql", "-d", "clusterflux", "-AtF," ), { input: "SELECT pg_database_size('clusterflux'), (SELECT count(*) FROM clusterflux_tenants), (SELECT count(*) FROM clusterflux_projects), (SELECT count(*) FROM clusterflux_node_identities), (SELECT count(*) FROM clusterflux_cli_sessions);\n", stdio: ["pipe", "pipe", "pipe"], } ) .trim() .split(",") .map(Number); assert(Number.isFinite(Number(memory.MemoryCurrent))); assert(Number.isFinite(Number(memory.MemoryPeak))); assert.strictEqual(database.length, 5); return { sampled_at_epoch_ms: Date.now(), service_memory_current_bytes: Number(memory.MemoryCurrent), service_memory_peak_bytes: Number(memory.MemoryPeak), service_state_disk_bytes: serviceDisk, postgres_database_bytes: database[0], durable_rows: { tenants: database[1], projects: database[2], node_identities: database[3], cli_sessions: database[4], }, local_node_state: directoryStats(path.join(projectDir, ".clusterflux")), }; } function executable(root, name) { return path.join(root, "bin", process.platform === "win32" ? `${name}.exe` : name); } function binaryArchive(manifest) { const platform = `${os.platform()}-${os.arch()}`; const asset = manifest.assets.find( (candidate) => candidate.name.startsWith("clusterflux-public-binaries-") && candidate.name.includes(platform) ); assert(asset, `missing released binary archive for ${platform}`); assert(fs.existsSync(asset.file), `missing released binary archive ${asset.file}`); return asset.file; } function publicRepoUrl(manifest) { const url = process.env.CLUSTERFLUX_PUBLIC_REPO_URL || process.env.CLUSTERFLUX_PUBLIC_REPO_REMOTE || manifest.public_repo_url || manifest.public_repo_remote; assert(url, "public repository URL is required"); assert(url.includes("git.michelpaulissen.com")); return url; } function stagePublicCheckout(manifest, checkout) { const candidateTree = process.env.CLUSTERFLUX_LIVE_PUBLIC_TREE; if (candidateTree) { const source = path.resolve(candidateTree); assert.strictEqual( source, path.resolve(manifest.public_tree), "explicit live candidate tree must be the tree recorded by the release manifest" ); fs.cpSync(source, checkout, { recursive: true }); return { kind: "local_filtered_release_candidate", path: source, published: false, }; } run("git", ["clone", "--depth", "1", publicRepoUrl(manifest), checkout]); return { kind: "published_forgejo_checkout", url: publicRepoUrl(manifest), published: true, }; } function delay(milliseconds) { return new Promise((resolve) => setTimeout(resolve, milliseconds)); } async function waitForCli(label, action, predicate, timeoutMs = 10 * 60 * 1000) { const deadline = Date.now() + timeoutMs; let lastValue; let lastError; while (Date.now() < deadline) { try { lastValue = action(); if (predicate(lastValue)) return lastValue; lastError = undefined; } catch (error) { lastError = error; } await delay(250); } throw new Error( `${label} timed out; last value=${JSON.stringify(lastValue)}${ lastError ? `; last error=${lastError.message}` : "" }` ); } function spawnJsonLines(command, args, options) { recordCommand(command, args); const child = cp.spawn(command, args, { ...options, stdio: ["ignore", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; const values = []; const waiters = []; function deliver(value) { values.push(value); for (let index = waiters.length - 1; index >= 0; index -= 1) { const waiter = waiters[index]; if (waiter.predicate(value)) { waiters.splice(index, 1); clearTimeout(waiter.timer); waiter.resolve(value); } } } child.stdout.on("data", (chunk) => { stdout += chunk.toString(); while (stdout.includes("\n")) { const newline = stdout.indexOf("\n"); const line = stdout.slice(0, newline).trim(); stdout = stdout.slice(newline + 1); if (!line) continue; try { deliver(JSON.parse(line)); } catch (_) { // Non-JSON progress stays out of the evidence report. } } }); child.stderr.on("data", (chunk) => { stderr += chunk.toString(); }); function waitFor(predicate, label, timeoutMs = 120000) { const existing = values.find(predicate); if (existing) return Promise.resolve(existing); return new Promise((resolve, reject) => { const waiter = { predicate, resolve, reject, timer: undefined }; waiter.timer = setTimeout(() => { const index = waiters.indexOf(waiter); if (index >= 0) waiters.splice(index, 1); reject(new Error(`${label} timed out\n${stderr}`)); }, timeoutMs); waiters.push(waiter); }); } child.once("exit", (code) => { for (const waiter of waiters.splice(0)) { clearTimeout(waiter.timer); waiter.reject(new Error(`${waiter.label || "child"} exited with ${code}\n${stderr}`)); } }); return { child, values, waitFor, stderr: () => stderr }; } async function stopChild(child) { if (!child || child.exitCode !== null) return; child.kill("SIGTERM"); const exited = new Promise((resolve) => child.once("exit", resolve)); const forced = delay(5000).then(() => { if (child.exitCode === null) child.kill("SIGKILL"); }); await Promise.race([exited, forced]); if (child.exitCode === null) await exited; } function rawTaskEvents(report) { return report?.events?.response?.events || []; } function nodeDescriptor(status, node) { return status?.response?.descriptors?.find( (descriptor) => descriptor.id === node || descriptor.node === node ); } function completedFlagship(events) { const completedDefinitions = new Set( events .filter((event) => event.terminal_state === "completed") .map((event) => event.task_definition) ); return ( completedDefinitions.has("prepare_source") && completedDefinitions.has("compile_linux") && completedDefinitions.has("package_release") && events.some( (event) => event.executor === "coordinator_main" && event.terminal_state === "completed" ) ); } function contentAddressedArtifactId(event, logicalName) { const digest = event?.artifact_digest; if (typeof digest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(digest)) { return null; } const artifactId = `${logicalName}-${digest.slice("sha256:".length)}`; return event.artifact_path?.endsWith(`/vfs/artifacts/${artifactId}`) ? artifactId : null; } async function prepareLiveNodeCredentialSecurity({ clusterflux, projectDir, scope, tenant, project, suffix, }) { const startedAt = Date.now(); const node = `security-node-${suffix}`; const grant = runJson(clusterflux, ["node", "enroll", ...scope], { cwd: projectDir, }); const attach = runJson( clusterflux, [ "node", "attach", "--coordinator", serviceEndpoint, "--tenant", tenant, "--project-id", project, "--node", node, "--enrollment-grant", grant.enrollment_grant.grant, "--json", ], { cwd: projectDir } ); assert.strictEqual(attach.boundary.used_enrollment_exchange, true); const stored = readNodeCredential(projectDir, node); const identity = nodeIdentityFromPrivateKey(stored.credential.private_key); assert.strictEqual(identity.publicKey, stored.credential.public_key); const heartbeat = { type: "node_heartbeat", tenant, project, node, node_signature: signedNodeHeartbeat(tenant, project, node, identity, { nonce: `strict-valid-${suffix}`, }), }; const valid = await sendHostedControl(heartbeat); assert.strictEqual(valid.type, "node_heartbeat"); const replay = assertDenied( await sendHostedControl(heartbeat), /nonce.*already.*used|replay/i, "replayed node credential" ); const expired = assertDenied( await sendHostedControl({ type: "node_heartbeat", tenant, project, node, node_signature: signedNodeHeartbeat(tenant, project, node, identity, { nonce: `strict-expired-${suffix}`, issuedAtEpochSeconds: Math.floor(Date.now() / 1000) - 3600, }), }), /expired|clock skew/i, "expired node credential" ); const forgedIdentity = nodeIdentity("strict-forged-node", node); const forged = assertDenied( await sendHostedControl({ type: "node_heartbeat", tenant, project, node, node_signature: signedNodeHeartbeat(tenant, project, node, forgedIdentity, { nonce: `strict-forged-${suffix}`, }), }), /signature|public key/i, "forged node credential" ); const originalCapabilityBody = { type: "report_node_capabilities", tenant, project, node, capabilities: { os: "Linux", arch: process.arch === "x64" ? "x86_64" : process.arch, capabilities: [], environment_backends: [], source_providers: [], }, cached_environment_digests: [], dependency_cache_digests: [], source_snapshots: [], artifact_locations: [], direct_connectivity: false, online: true, }; const modifiedEnvelope = signedNodeRequest( node, identity, "report_node_capabilities", originalCapabilityBody, { nonce: `strict-modified-${suffix}` } ); modifiedEnvelope.request.online = false; const bodyModified = assertDenied( await sendHostedControl(modifiedEnvelope), /signature/i, "body-modified node credential" ); return { duration_ms: Date.now() - startedAt, node, identity, credential_path: stored.absolute, credential_digest: sha256(fs.readFileSync(stored.absolute)), capability_body: originalCapabilityBody, evidence: { valid_request: valid.type, replay, expired, forged, body_modified: bodyModified, }, }; } async function runLiveAgentCredentialSecurity({ clusterfluxDap, clusterflux, projectDir, scope, sessionSecret, tenant, project, suffix, bundle, securityNode, workerRuntime, }) { const scenarioStartedAt = Date.now(); const agent = `security-agent-${suffix}`; const identity = agentIdentity("strict-live-agent", agent); const added = runJson( clusterflux, ["key", "add", ...scope, "--agent", agent, "--public-key", identity.publicKey], { cwd: projectDir } ); assert.strictEqual(added.command, "key add"); const processId = `vp-agent-security-${suffix}`; const unsigned = { type: "start_process", tenant, project, actor_agent: agent, process: processId, restart: false, }; const validRequest = signedAgentWorkflowRequest(identity, unsigned, { nonce: `strict-agent-valid-${suffix}`, }); const valid = await sendHostedControl(validRequest); assert.strictEqual(valid.type, "process_started", JSON.stringify(valid)); const replay = assertDenied( await sendHostedControl(validRequest), /nonce.*already.*used|replay/i, "replayed agent credential" ); const expired = assertDenied( await sendHostedControl( signedAgentWorkflowRequest( identity, { ...unsigned, process: `${processId}-expired` }, { nonce: `strict-agent-expired-${suffix}`, issuedAtEpochSeconds: Math.floor(Date.now() / 1000) - 3600, } ) ), /expired|clock skew/i, "expired agent credential" ); const modifiedRequest = signedAgentWorkflowRequest( identity, { ...unsigned, process: `${processId}-modified` }, { nonce: `strict-agent-modified-${suffix}` } ); modifiedRequest.restart = true; const bodyModified = assertDenied( await sendHostedControl(modifiedRequest), /signature/i, "body-modified agent credential" ); const forgedIdentity = agentIdentity("strict-live-forged-agent", agent); const forged = assertDenied( await sendHostedControl( signedAgentWorkflowRequest( forgedIdentity, { ...unsigned, process: `${processId}-forged` }, { nonce: `strict-agent-forged-${suffix}`, publicKeyFingerprint: identity.publicKeyFingerprint, } ) ), /signature|public key/i, "forged agent credential" ); const fakeEnvironmentDigest = sha256( Buffer.from(`strict-debug-missing-participant-${suffix}`) ); const fakeCapabilityBody = { ...securityNode.capability_body, cached_environment_digests: [fakeEnvironmentDigest], online: true, }; const mainTask = `ti:${processId}:main`; const fakeTask = `missing-debug-participant-${suffix}`; const mainLaunchBody = { type: "launch_task", tenant, project, actor_agent: agent, task_spec: { tenant, project, process: processId, task_definition: bundle.entryStableId, task_instance: mainTask, dispatch: { kind: "coordinator_node_wasm", export: bundle.entryExport, abi: "entrypoint_v1", }, environment_id: null, environment: null, environment_digest: null, required_capabilities: [], dependency_cache: null, source_snapshot: null, required_artifacts: [], args: [], vfs_epoch: valid.epoch, bundle_digest: bundle.digest, }, wait_for_node: true, artifact_path: `/vfs/artifacts/${mainTask}-output.txt`, wasm_module_base64: bundle.moduleBase64, }; let mainLaunch; let directTaskV1; let fakeLaunch; let liveParentTask; let liveParentAssignment; let realDebugLaunch; let preconfiguredBreakpoint; let attachSourcePath; let attachBreakpointLine; const realDebugTask = `real-debug-participant-${suffix}`; let workerPaused = false; const baselineContainers = new Set( run("podman", ["ps", "-q"]) .trim() .split(/\s+/) .filter(Boolean) ); try { mainLaunch = await sendHostedControl( signedAgentWorkflowRequest(identity, mainLaunchBody, { nonce: `strict-agent-main-${suffix}`, }) ); assert.strictEqual(mainLaunch.type, "main_launched", JSON.stringify(mainLaunch)); assert.strictEqual(mainLaunch.task_instance, mainTask); assert.strictEqual(mainLaunch.state, "running"); assert.strictEqual(mainLaunch.actor.kind, "agent"); assert.strictEqual(mainLaunch.actor.authenticated_without_browser, true); liveParentAssignment = await workerRuntime.worker.waitFor( (value) => { const taskSpec = value.task_assignment_response?.task_spec; return ( value.node_status === "assignment_started" && value.node === workerRuntime.node && value.process === processId && taskSpec?.dispatch?.abi === "task_v1" && taskSpec.task_definition === "compile_linux" && taskSpec.environment_id === "linux" && typeof taskSpec.environment_digest === "string" && typeof taskSpec.source_snapshot === "string" ); }, "agent main to dispatch an environment-bound live child to the real worker", 120000 ); liveParentTask = liveParentAssignment.virtual_thread; assert.strictEqual(typeof liveParentTask, "string"); assert.notStrictEqual(liveParentTask, ""); assert.strictEqual( workerRuntime.child.kill("SIGSTOP"), true, "failed to pause the real worker after observing its live child" ); workerPaused = true; const fakeCapabilities = await sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "report_node_capabilities", fakeCapabilityBody, { nonce: `strict-agent-fake-capabilities-${suffix}` } ) ); assert.strictEqual( fakeCapabilities.type, "node_capabilities_recorded", JSON.stringify(fakeCapabilities) ); const fakeTaskSpec = { tenant, project, process: processId, task_definition: "task_add_one", task_instance: fakeTask, dispatch: { kind: "coordinator_node_wasm", export: null, abi: "task_v1", }, environment_id: "strict-debug-missing-participant", environment: null, environment_digest: fakeEnvironmentDigest, required_capabilities: [], dependency_cache: null, source_snapshot: null, required_artifacts: [], args: [{ SmallJson: 41 }], vfs_epoch: valid.epoch, bundle_digest: bundle.digest, }; directTaskV1 = assertDenied( await sendHostedControl( signedAgentWorkflowRequest( identity, { type: "launch_task", tenant, project, actor_agent: agent, task_spec: fakeTaskSpec, wait_for_node: false, artifact_path: `/vfs/artifacts/${fakeTask}.txt`, wasm_module_base64: bundle.moduleBase64, }, { nonce: `strict-agent-direct-task-v1-${suffix}` } ) ), /external callers.*EntrypointV1|TaskV1 requires an authenticated live parent/i, "external direct TaskV1 launch" ); const liveParentSpec = liveParentAssignment.task_assignment_response.task_spec; attachSourcePath = path.join(projectDir, "src/lib.rs"); const attachSourceLines = fs .readFileSync(attachSourcePath, "utf8") .split(/\r?\n/); attachBreakpointLine = attachSourceLines.findIndex((line) => line.includes("fn abort_probe(")) + 1; assert( attachBreakpointLine > 0, "agent-security fixture omitted the abort_probe debug probe" ); preconfiguredBreakpoint = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "set_debug_breakpoints", process: processId, revision: 1, probe_symbols: ["clusterflux.probe.abort_probe"], }) ); assert.strictEqual( preconfiguredBreakpoint.type, "debug_breakpoints", JSON.stringify(preconfiguredBreakpoint) ); assert.deepStrictEqual(preconfiguredBreakpoint.probe_symbols, [ "clusterflux.probe.abort_probe", ]); realDebugLaunch = await sendHostedControl( signedNodeRequest( workerRuntime.node, workerRuntime.identity, "launch_child_task", { type: "launch_child_task", tenant, project, process: processId, node: workerRuntime.node, parent_task: liveParentTask, task_spec: { tenant, project, process: processId, task_definition: "abort_probe", task_instance: realDebugTask, dispatch: { kind: "coordinator_node_wasm", export: null, abi: "task_v1", }, environment_id: liveParentSpec.environment_id, environment: liveParentSpec.environment, environment_digest: liveParentSpec.environment_digest, required_capabilities: ["Command"], dependency_cache: null, source_snapshot: liveParentSpec.source_snapshot, required_artifacts: [], args: liveParentSpec.args, vfs_epoch: valid.epoch, bundle_digest: bundle.digest, }, wait_for_node: false, artifact_path: `/vfs/artifacts/${realDebugTask}.txt`, wasm_module_base64: bundle.moduleBase64, }, { nonce: `strict-real-debug-participant-${suffix}` } ) ); assert.strictEqual( realDebugLaunch.type, "task_launched", JSON.stringify(realDebugLaunch) ); const fakeLaunchBody = { type: "launch_child_task", tenant, project, process: processId, node: workerRuntime.node, parent_task: liveParentTask, task_spec: fakeTaskSpec, wait_for_node: false, artifact_path: `/vfs/artifacts/${fakeTask}.txt`, wasm_module_base64: bundle.moduleBase64, }; fakeLaunch = await sendHostedControl( signedNodeRequest( workerRuntime.node, workerRuntime.identity, "launch_child_task", fakeLaunchBody, { nonce: `strict-parent-runtime-fake-task-${suffix}` } ) ); assert.strictEqual(fakeLaunch.type, "task_launched", JSON.stringify(fakeLaunch)); assert.strictEqual(fakeLaunch.placement.node, securityNode.node); } finally { if (workerPaused) { assert.strictEqual( workerRuntime.child.kill("SIGCONT"), true, "failed to resume the real worker after authenticated child launch" ); } } await workerRuntime.worker.waitFor( (value) => value.node_status === "assignment_started" && value.virtual_thread === realDebugTask, "real Podman debug participant to start", 120_000 ); let realDebugContainerIds = new Set(); const debugClient = new DapClient({ cwd: projectDir, command: clusterfluxDap, args: [], env: { ...process.env }, }); const initialize = debugClient.send("initialize", { adapterID: "clusterflux", linesStartAt1: true, columnsStartAt1: true, }); await debugClient.response(initialize, "initialize"); const attachRequest = debugClient.send("attach", { entry: "build", project: projectDir, processId, runtimeBackend: "live-services", coordinatorEndpoint: serviceEndpoint, }); await debugClient.response(attachRequest, "attach"); await debugClient.waitFor( (message) => message.type === "event" && message.event === "initialized" ); const attachBreakpointRequest = debugClient.send("setBreakpoints", { source: { path: attachSourcePath }, breakpoints: [{ line: attachBreakpointLine }], }); const attachBreakpointResponse = await debugClient.response( attachBreakpointRequest, "setBreakpoints" ); assert.strictEqual( attachBreakpointResponse.body.breakpoints[0].verified, false, "attach breakpoint was verified before runtime installation" ); const configurationDone = debugClient.send("configurationDone"); await debugClient.response(configurationDone, "configurationDone"); const attachBreakpointInstalled = await debugClient.waitFor( (message) => message.type === "event" && message.event === "breakpoint" && message.body?.breakpoint?.verified === true, 120_000 ); assert.strictEqual( attachBreakpointInstalled.body.breakpoint.line, attachBreakpointLine ); const attachBreakpointStop = await debugClient.waitFor( (message) => message.seq > attachBreakpointInstalled.seq && message.type === "event" && message.event === "stopped" && message.body.reason === "breakpoint", 120_000 ); const attachStackRequest = debugClient.send("stackTrace", { threadId: attachBreakpointStop.body.threadId, startFrame: 0, levels: 1, }); const attachStackFrames = ( await debugClient.response(attachStackRequest, "stackTrace") ).body.stackFrames; assert.strictEqual( attachStackFrames[0].line, attachBreakpointLine, "attach stopped somewhere other than the installed configured breakpoint" ); const attachContinue = debugClient.send("continue", { threadId: attachBreakpointStop.body.threadId, }); const attachContinueResponse = await debugClient.response( attachContinue, "continue" ); const realDebugContainerDeadline = Date.now() + 120_000; let lastRealDebugPodmanStates = []; while (Date.now() < realDebugContainerDeadline) { const containers = runJson("podman", ["ps", "--format", "json"]); lastRealDebugPodmanStates = containers; realDebugContainerIds = new Set( containers .map((container) => container.Id || container.ID || container.IdHex || "") .filter((id) => id && !baselineContainers.has(id)) ); if (realDebugContainerIds.size > 0) break; await delay(100); } assert( realDebugContainerIds.size > 0, `continued real debug participant did not start a Podman container: ${JSON.stringify( lastRealDebugPodmanStates )}` ); const attachDeadline = Date.now() + 120_000; let attachedThreads = []; while (Date.now() < attachDeadline) { const threadsRequest = debugClient.send("threads"); attachedThreads = ( await debugClient.response(threadsRequest, "threads") ).body.threads; if (attachedThreads.length > 0) break; await delay(100); } assert(attachedThreads.length > 0, "DAP attach reported no live threads"); const freezeStartedAt = Date.now(); const pauseRequest = debugClient.send("pause", { threadId: attachedThreads[0].id, }); await debugClient.response(pauseRequest, "pause"); const dapPartialStop = await debugClient.waitFor( (message) => message.type === "event" && message.seq > attachContinueResponse.seq && message.event === "stopped" && message.body.reason === "pause", 30_000 ); assert.strictEqual(dapPartialStop.body.allThreadsStopped, false); const epochRequest = debugClient.send("evaluate", { expression: "debug_epoch", context: "watch", }); const freeze = { epoch: Number( (await debugClient.response(epochRequest, "evaluate")).body.result ), }; assert(Number.isSafeInteger(freeze.epoch) && freeze.epoch > 0); const partialFreeze = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "inspect_debug_epoch", process: processId, epoch: freeze.epoch, }) ); assert.strictEqual(partialFreeze.type, "debug_epoch_status"); assert.strictEqual(partialFreeze.partially_frozen, true, JSON.stringify(partialFreeze)); assert.strictEqual(partialFreeze.fully_frozen, false); assert.strictEqual(partialFreeze.failed, true); assert.match( partialFreeze.failure_messages.join("; "), /did not acknowledge frozen state within \d+ ms/ ); const podmanStates = runJson("podman", ["ps", "--all", "--format", "json"]); const pausedContainers = podmanStates.filter((container) => { const id = container.Id || container.ID || container.IdHex || ""; const state = String(container.State || container.Status || "").toLowerCase(); return realDebugContainerIds.has(id) && state.includes("paused"); }); assert( pausedContainers.length > 0, `partial Debug Epoch did not pause a real Podman container: ${JSON.stringify( podmanStates )}` ); const pausedContainerIds = pausedContainers.map( (container) => container.Id || container.ID || container.IdHex ); const mismatchedDigest = sha256(Buffer.from(`strict-nested-mismatch-${suffix}`)); const mismatchedChild = await sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "launch_child_task", { type: "launch_child_task", tenant, project, process: processId, node: securityNode.node, parent_task: fakeTask, task_spec: { tenant, project, process: processId, task_definition: "task_add_one", task_instance: `${fakeTask}:child:mismatched-environment`, dispatch: { kind: "coordinator_node_wasm", export: null, abi: "task_v1", }, environment_id: "strict-nested-mismatch", environment: null, environment_digest: mismatchedDigest, required_capabilities: [], dependency_cache: null, source_snapshot: null, required_artifacts: [], args: [{ SmallJson: 41 }], vfs_epoch: valid.epoch, bundle_digest: bundle.digest, }, wait_for_node: false, artifact_path: `/vfs/artifacts/${fakeTask}-mismatched-child.txt`, wasm_module_base64: bundle.moduleBase64, }, { nonce: `strict-nested-mismatch-${suffix}` } ) ); const nestedEnvironmentMismatch = assertDenied( mismatchedChild, /environment|digest|compatible|placement|no node/i, "nested environment mismatch" ); const continueStartedAt = Date.now(); const continueRequest = debugClient.send("continue", { threadId: dapPartialStop.body.threadId, }); await debugClient.response(continueRequest, "continue"); const continueResponseMs = Date.now() - continueStartedAt; assert( continueResponseMs < 2_000, `partial-freeze continue blocked for ${continueResponseMs} ms` ); await delay(1000); const resumed = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "inspect_debug_epoch", process: processId, epoch: freeze.epoch, }) ); assert.strictEqual(resumed.type, "debug_epoch_status"); const resumedAcknowledgements = resumed.acknowledgements.filter( (acknowledgement) => acknowledgement.state === "running" ); assert(resumedAcknowledgements.length > 0, JSON.stringify(resumed)); const resumedPodmanStates = runJson("podman", ["ps", "--format", "json"]); assert( !resumedPodmanStates.some((container) => { const id = container.Id || container.ID || container.IdHex || ""; const state = String(container.State || container.Status || "").toLowerCase(); return pausedContainerIds.includes(id) && state.includes("paused"); }), `DAP continue left a Clusterflux container paused: ${JSON.stringify( resumedPodmanStates )}` ); await debugClient.close(); const mainBeforeChildStartedAt = Date.now(); const completed = await waitForCli( "agent-authenticated coordinator main and child workflow completion", () => runJson(clusterflux, ["task", "list", ...scope, "--process", processId], { cwd: projectDir, }), (tasks) => completedFlagship(rawTaskEvents(tasks)), 120000 ); const completedEvents = rawTaskEvents(completed); const concurrentCompileTasks = [ ...new Set( completedEvents .filter( (event) => event.task_definition === "compile_linux" && event.terminal_state === "completed" ) .map((event) => event.task) ), ]; assert(concurrentCompileTasks.length >= 2, JSON.stringify(completedEvents)); const mainCompletion = completedEvents.find( (event) => event.executor === "coordinator_main" && event.terminal_state === "completed" ); assert(mainCompletion, "real coordinator main did not complete"); assert( !completedEvents.some( (event) => event.task === fakeTask && typeof event.terminal_state === "string" ), "the deliberately delayed final child completed before the coordinator main" ); const activeAfterMain = runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ); assert.notStrictEqual(activeAfterMain.state, "not_active"); assert.equal(activeAfterMain.live_process.main_state, null); const debugStateAfterMain = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "inspect_debug_breakpoints", process: processId, }) ); assert.strictEqual( debugStateAfterMain.type, "debug_breakpoints", `main completion cleared active-child debug state: ${JSON.stringify( debugStateAfterMain )}` ); const finalChildCompletion = await sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "task_completed", { type: "task_completed", tenant, project, process: processId, node: securityNode.node, task: fakeTask, terminal_state: "completed", status_code: 0, stdout_bytes: 2, stderr_bytes: 0, stdout_tail: "42", stderr_tail: "", stdout_truncated: false, stderr_truncated: false, artifact_path: null, artifact_digest: null, artifact_size_bytes: null, result: { SmallJson: 42 }, }, { nonce: `strict-main-before-child-complete-${suffix}` } ) ); assert.strictEqual( finalChildCompletion.type, "task_recorded", JSON.stringify(finalChildCompletion) ); const releasedAfterFinalChild = await waitForCli( "final delayed child to release the active process slot", () => runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ), (status) => status.state === "not_active", 120_000 ); const retainedEvents = runJson( clusterflux, ["task", "list", ...scope, "--process", processId], { cwd: projectDir } ); assert( rawTaskEvents(retainedEvents).some( (event) => event.task === fakeTask && event.terminal_state === "completed" ), "final delayed child history was not retained" ); const retainedArtifacts = runJson( clusterflux, ["artifact", "list", ...scope, "--process", processId], { cwd: projectDir } ); const retainedArtifact = retainedArtifacts.artifacts.find( (artifact) => typeof artifact.digest === "string" && /^sha256:[0-9a-f]{64}$/.test(artifact.digest) && artifact.artifact.startsWith("release.tar-") ); assert(retainedArtifact, "real main artifact metadata was not retained"); const subsequentRun = runJson( clusterflux, ["run", "park-wake", "--project", ".", "--json"], { cwd: projectDir } ); assert.strictEqual(subsequentRun.status, "main_launched"); const subsequentAbort = runJson( clusterflux, ["process", "abort", ...scope, "--process", subsequentRun.process, "--yes"], { cwd: projectDir } ); assert.strictEqual(subsequentAbort.abort_request.accepted, true); await waitForCli( "subsequent run cleanup after final-child slot release", () => runJson( clusterflux, ["process", "status", ...scope, "--process", subsequentRun.process], { cwd: projectDir } ), (status) => status.state === "not_active", 120_000 ); const mainBeforeChildLifecycle = { request: { process: processId, main: bundle.entryStableId, delayed_child: fakeTask, fault_injection: "withhold the assigned final child's signed completion until the real coordinator main completes", }, expected: "process and debug state remain until the final child completes; final cleanup retains history and real artifact metadata; a subsequent run starts", observed: { main_terminal_state: mainCompletion.terminal_state, active_after_main: activeAfterMain.state !== "not_active", debug_state_after_main: debugStateAfterMain.type, child_terminal_state: "completed", final_process_state: releasedAfterFinalChild.state, retained_event_count: rawTaskEvents(retainedEvents).length, retained_artifact: retainedArtifact, subsequent_run_status: subsequentRun.status, }, duration_ms: Math.max(1, Date.now() - mainBeforeChildStartedAt), }; const revoked = runJson( clusterflux, ["key", "revoke", ...scope, "--agent", agent, "--yes"], { cwd: projectDir } ); assert.strictEqual(revoked.command, "key revoke"); const revokedUse = assertDenied( await sendHostedControl( signedAgentWorkflowRequest( identity, { ...unsigned, process: `${processId}-revoked` }, { nonce: `strict-agent-revoked-${suffix}` } ) ), /revoked/i, "revoked agent credential" ); return { duration_ms: Date.now() - scenarioStartedAt, agent, valid_request: valid.type, replay, expired, forged, body_modified: bodyModified, revoked: revokedUse, workflow: { process: processId, main_launch: mainLaunch.type, external_direct_task_v1: directTaskV1, child_launch: fakeLaunch.type, child_parent: liveParentTask, real_debug_child_launch: realDebugLaunch.type, real_debug_child: realDebugTask, actor_kind: mainLaunch.actor.kind, authenticated_without_browser: mainLaunch.actor.authenticated_without_browser, flagship_completed: completedFlagship(completedEvents), concurrent_compile_tasks: concurrentCompileTasks, }, main_before_child_lifecycle: mainBeforeChildLifecycle, attach_with_preconfigured_breakpoint: { request: { process: processId, source: attachSourcePath, line: attachBreakpointLine, }, expected: "preconfigured before attach, unverified until adapter installation, then a real breakpoint stop at the configured line", observed: { preconfigured_revision: preconfiguredBreakpoint.revision, initially_verified: attachBreakpointResponse.body.breakpoints[0].verified, installation_event_verified: attachBreakpointInstalled.body.breakpoint.verified, stop_reason: attachBreakpointStop.body.reason, stopped_line: attachStackFrames[0].line, }, duration_ms: Date.now() - scenarioStartedAt, }, partial_freeze: { epoch: freeze.epoch, elapsed_ms: Date.now() - freezeStartedAt, partially_frozen: partialFreeze.partially_frozen, fully_frozen: partialFreeze.fully_frozen, dap_all_threads_stopped: dapPartialStop.body.allThreadsStopped, dap_continue_response_ms: continueResponseMs, podman_paused_container_ids: pausedContainerIds, warning: partialFreeze.failure_messages, resumed_participants: resumedAcknowledgements.map( (acknowledgement) => acknowledgement.task ), }, nested_environment_mismatch: nestedEnvironmentMismatch, }; } async function runSecondTenantIsolation({ clusterflux, clusterfluxNode, firstScope, firstHelloBuild, firstHelloProjectDir, workRoot, firstSessionSecret, firstTenant, firstProject, firstProcess, firstNode, firstArtifact, manifest, }) { const startedAt = Date.now(); const file = process.env.CLUSTERFLUX_SECOND_TENANT_SESSION_FILE; const evidenceFile = process.env.CLUSTERFLUX_SECOND_TENANT_EVIDENCE_FILE; const targetTenant = process.env.CLUSTERFLUX_ISOLATION_TARGET_TENANT; const targetProject = process.env.CLUSTERFLUX_ISOLATION_TARGET_PROJECT; if (!file && evidenceFile) { const evidenceBytes = fs.readFileSync(path.resolve(evidenceFile)); const previous = JSON.parse(evidenceBytes); const isolation = previous.tenant_isolation; assert.strictEqual(isolation?.executed, true); assert.notStrictEqual(isolation.second_tenant, firstTenant); assert.strictEqual(isolation.project?.denied, true); assert.strictEqual(isolation.process_hidden, true); assert.strictEqual(isolation.node_hidden, true); assert.strictEqual(isolation.tasks_and_logs?.denied, true); assert.strictEqual(isolation.debug?.denied, true); assert.strictEqual(isolation.debug?.audited, true); assert.strictEqual(isolation.debug?.charged_debug_read_bytes, 0); assert.strictEqual(isolation.artifact_and_download?.denied, true); assert.strictEqual(isolation.process_control?.denied, true); const previousDeployment = previous.release_binding?.deployment; const currentDeployment = deploymentProvenance(); assert.strictEqual( previousDeployment?.hosted_service_sha256, currentDeployment.hosted_service_sha256, "reused isolation evidence must target the exact deployed hosted binary" ); assert.deepStrictEqual( previous.release_binding?.binary_digests, manifest.binary_digests, "reused isolation evidence must target the exact public binaries" ); return { evidence: { ...isolation, duration_ms: Date.now() - startedAt, reused_from_immutable_evidence: { report_sha256: sha256(evidenceBytes), source_commit: previous.source_commit, hosted_service_sha256: currentDeployment.hosted_service_sha256, public_binary_digests: manifest.binary_digests, }, }, runtime: null, }; } if (!file && targetTenant && targetProject) { assert.notStrictEqual( targetTenant, firstTenant, "single-account isolation target must name a different hosted tenant" ); assert.notStrictEqual( targetProject, firstProject, "single-account isolation target must name a different hosted project" ); const call = (request) => sendHostedControl(authenticatedRequest(firstSessionSecret, request)); const project = assertDenied( await call({ type: "select_project", project: targetProject }), /outside|not visible|tenant|project|permission|unauthorized/i, "single-account cross-tenant project selection" ); const processes = await call({ type: "list_processes" }); assert.strictEqual( processes.type, "process_statuses", JSON.stringify(processes) ); assert(!JSON.stringify(processes).includes(targetTenant)); assert(!JSON.stringify(processes).includes(targetProject)); const nodes = await call({ type: "list_node_descriptors" }); assert.strictEqual(nodes.type, "node_descriptors", JSON.stringify(nodes)); assert(!JSON.stringify(nodes).includes(targetTenant)); assert(!JSON.stringify(nodes).includes(targetProject)); const foreignProcess = `vp-foreign-isolation-${Date.now()}`; const foreignArtifact = `artifact-foreign-isolation-${Date.now()}`; const tasksAndLogsResponse = await call({ type: "list_task_events", process: foreignProcess, }); let tasksAndLogs; if (tasksAndLogsResponse.type === "error") { tasksAndLogs = { ...assertDenied( tasksAndLogsResponse, /outside|scope|tenant|project|not active|requires an active|unknown/i, "single-account foreign task and log listing" ), enforcement: "explicit_error", }; } else { assert.strictEqual( tasksAndLogsResponse.type, "task_events", JSON.stringify(tasksAndLogsResponse) ); assert.deepStrictEqual( tasksAndLogsResponse.events, [], "single-account foreign-looking task listing must disclose no events" ); assert(!JSON.stringify(tasksAndLogsResponse).includes(targetTenant)); assert(!JSON.stringify(tasksAndLogsResponse).includes(targetProject)); tasksAndLogs = { denied: true, reason: "authenticated scope returned no visible task or log events", enforcement: "scoped_empty_result", response_type: tasksAndLogsResponse.type, event_count: tasksAndLogsResponse.events.length, }; } const debugResponse = await call({ type: "debug_attach", process: foreignProcess, }); assert.strictEqual( debugResponse.type, "debug_attach", JSON.stringify(debugResponse) ); assert.strictEqual(debugResponse.authorization?.allowed, false); assert.strictEqual(debugResponse.audit_event?.allowed, false); assert.strictEqual(debugResponse.charged_debug_read_bytes, 0); const artifact = assertDenied( await call({ type: "create_artifact_download_link", artifact: foreignArtifact, max_bytes: 1024, ttl_seconds: 60, }), /outside|scope|tenant|project|not found|does not exist|unavailable/i, "single-account foreign artifact download" ); const control = assertDenied( await call({ type: "abort_process", process: foreignProcess }), /outside|scope|tenant|project|not active|requires an active|unknown/i, "single-account foreign process control" ); return { evidence: { executed: true, mode: "single_authenticated_account_foreign_project", second_tenant: targetTenant, target_project: targetProject, project, process_hidden: true, node_hidden: true, tasks_and_logs: tasksAndLogs, debug: { denied: true, reason: debugResponse.authorization.reason, audited: true, charged_debug_read_bytes: debugResponse.charged_debug_read_bytes, }, artifact_and_download: artifact, process_control: control, duration_ms: Date.now() - startedAt, }, runtime: null, }; } if (!file) { return { evidence: { executed: false, reason: "second tenant session not supplied", duration_ms: Math.max(1, Date.now() - startedAt), }, runtime: null, }; } const secondSessionPath = path.resolve(file); const second = readJson(secondSessionPath); assert.strictEqual(second.coordinator, serviceEndpoint); const secondSessionSecret = second.cli_session_secret || second.session_secret; assert(secondSessionSecret, "second tenant session omitted its session secret"); assert.notStrictEqual( second.tenant, firstTenant, "isolation proof requires a genuinely distinct hosted tenant" ); assert.notStrictEqual( second.project, firstProject, "isolation proof requires a genuinely distinct hosted project" ); const call = (request) => sendHostedControl(authenticatedRequest(secondSessionSecret, request)); const project = assertDenied( await call({ type: "select_project", project: firstProject }), /outside|not visible|tenant|project/i, "cross-tenant project selection" ); const processes = await call({ type: "list_processes" }); assert.strictEqual( processes.type, "process_statuses", JSON.stringify(processes) ); assert(!JSON.stringify(processes).includes(firstProcess)); const nodes = await call({ type: "list_node_descriptors" }); assert.strictEqual(nodes.type, "node_descriptors", JSON.stringify(nodes)); assert(!JSON.stringify(nodes).includes(firstNode)); const tasksAndLogs = assertDenied( await call({ type: "list_task_events", process: firstProcess }), /outside|scope|tenant|project|not active|requires an active|unknown/i, "cross-tenant task and log listing" ); const debugResponse = await call({ type: "debug_attach", process: firstProcess, }); assert.strictEqual(debugResponse.type, "debug_attach", JSON.stringify(debugResponse)); assert.strictEqual(debugResponse.authorization?.allowed, false); assert.strictEqual(debugResponse.audit_event?.allowed, false); assert.match( debugResponse.authorization?.reason || "", /outside|scope|permission|tenant|project|not active|unknown/i ); assert.strictEqual(debugResponse.charged_debug_read_bytes, 0); const debug = { denied: true, reason: debugResponse.authorization.reason, audited: true, charged_debug_read_bytes: debugResponse.charged_debug_read_bytes, }; const artifact = assertDenied( await call({ type: "create_artifact_download_link", artifact: firstArtifact, max_bytes: 1024, ttl_seconds: 60, }), /outside|scope|tenant|project|not found|does not exist|unavailable/i, "cross-tenant artifact download" ); const control = assertDenied( await call({ type: "abort_process", process: firstProcess }), /outside|scope|tenant|project|not active|requires an active|unknown/i, "cross-tenant process control" ); const secondCheckout = path.join(workRoot, "second-tenant-public-repo"); stagePublicCheckout(manifest, secondCheckout); const secondProjectDir = path.join( secondCheckout, "examples", "hello-build" ); const secondControlDir = path.join(secondProjectDir, ".clusterflux"); ensureDir(secondControlDir); const secondProjectPath = path.join( path.dirname(secondSessionPath), "project.json" ); assert( fs.existsSync(secondProjectPath), `second tenant session is missing adjacent project.json: ${secondProjectPath}` ); fs.copyFileSync( secondSessionPath, path.join(secondControlDir, "session.json") ); fs.copyFileSync( secondProjectPath, path.join(secondControlDir, "project.json") ); fs.chmodSync(path.join(secondControlDir, "session.json"), 0o600); fs.chmodSync(path.join(secondControlDir, "project.json"), 0o644); const secondScope = [ "--coordinator", serviceEndpoint, "--tenant", second.tenant, "--project-id", second.project, "--user", second.user, "--json", ]; const secondProjectList = runJson( clusterflux, ["project", "list", ...secondScope], { cwd: secondProjectDir } ); assert(secondProjectList.project_count >= 1); const secondProjectSelect = runJson( clusterflux, ["project", "select", ...secondScope, second.project], { cwd: secondProjectDir } ); assert.strictEqual(secondProjectSelect.command, "project select"); const collisionStartedAt = Date.now(); const secondGrant = runJson( clusterflux, ["node", "enroll", ...secondScope], { cwd: secondProjectDir } ); const secondAttach = runJson( clusterflux, [ "node", "attach", "--coordinator", serviceEndpoint, "--tenant", second.tenant, "--project-id", second.project, "--node", firstNode, "--enrollment-grant", secondGrant.enrollment_grant.grant, "--json", ], { cwd: secondProjectDir } ); assert.strictEqual(secondAttach.boundary.used_enrollment_exchange, true); const secondStored = readNodeCredential(secondProjectDir, firstNode); const secondCredentialDigest = sha256( fs.readFileSync(secondStored.absolute) ); const secondIdentity = nodeIdentityFromPrivateKey( secondStored.credential.private_key ); const secondWorkerArgs = [ "--coordinator", serviceEndpoint, "--tenant", second.tenant, "--project-id", second.project, "--node", firstNode, "--worker", "--project-root", secondProjectDir, "--assignment-poll-ms", "500", "--emit-ready", ]; const firstHelloWorker = spawnJsonLines( clusterfluxNode, [ "--coordinator", serviceEndpoint, "--tenant", firstTenant, "--project-id", firstProject, "--node", firstNode, "--worker", "--project-root", firstHelloProjectDir, "--assignment-poll-ms", "500", "--emit-ready", ], { cwd: firstHelloProjectDir, env: { ...process.env }, } ); const firstHelloReady = await firstHelloWorker.waitFor( (value) => value.node_status === "ready", "first-tenant hello-build artifact worker ready for collision proof" ); assert.strictEqual(firstHelloReady.node, firstNode); const firstCollisionHelloBuild = await runHostedHelloBuild({ clusterflux, projectDir: firstHelloProjectDir, scope: firstScope, outputFile: path.join(workRoot, "hello-clusterflux-first-tenant-collision"), }); assert.strictEqual( firstCollisionHelloBuild.artifact, firstHelloBuild.artifact, "repeated deterministic first-tenant hello-build changed its ArtifactId" ); assert.strictEqual(firstCollisionHelloBuild.digest, firstHelloBuild.digest); assert.strictEqual( firstCollisionHelloBuild.executable_output, firstHelloBuild.executable_output ); const secondWorker = spawnJsonLines(clusterfluxNode, secondWorkerArgs, { cwd: secondProjectDir, env: { ...process.env }, }); let secondHelloBuild; try { const secondReady = await secondWorker.waitFor( (value) => value.node_status === "ready", "same-name second-tenant worker ready" ); assert.strictEqual(secondReady.node, firstNode); secondHelloBuild = await runHostedHelloBuild({ clusterflux, projectDir: secondProjectDir, scope: secondScope, outputFile: path.join(workRoot, "hello-clusterflux-second-tenant"), }); } finally { await stopChild(secondWorker.child); } assert.strictEqual( secondHelloBuild.artifact, firstCollisionHelloBuild.artifact, "deterministic two-tenant hello-build did not collide on ArtifactId" ); assert.strictEqual( secondHelloBuild.digest, firstCollisionHelloBuild.digest, "deterministic two-tenant hello-build did not produce identical bytes" ); assert.strictEqual( secondHelloBuild.executable_output, firstCollisionHelloBuild.executable_output ); const firstArtifactsAfterCollision = runJson( clusterflux, [ "artifact", "list", ...firstScope, "--process", firstCollisionHelloBuild.process, ], { cwd: firstHelloProjectDir } ); assert( firstArtifactsAfterCollision.artifacts.some( (candidate) => candidate.artifact === firstCollisionHelloBuild.artifact && candidate.digest === firstCollisionHelloBuild.digest ), "the second tenant's same-ID artifact masked the first tenant's metadata" ); const secondCollisionLink = await call({ type: "create_artifact_download_link", artifact: secondHelloBuild.artifact, max_bytes: secondHelloBuild.downloaded_bytes, ttl_seconds: 60, }); assert.strictEqual( secondCollisionLink.type, "artifact_download_link", JSON.stringify(secondCollisionLink) ); const secondCollisionLinkRevoked = await call({ type: "revoke_artifact_download_link", artifact: secondHelloBuild.artifact, token_digest: secondCollisionLink.link.scoped_token_digest, }); assert.strictEqual( secondCollisionLinkRevoked.type, "artifact_download_link_revoked", JSON.stringify(secondCollisionLinkRevoked) ); const firstDownloadAfterSecondLinkRevocation = runJson( clusterflux, [ "artifact", "download", ...firstScope, firstCollisionHelloBuild.artifact, "--to", path.join(workRoot, "hello-clusterflux-first-after-second-link-revoke"), ], { cwd: firstHelloProjectDir } ); assert.strictEqual( firstDownloadAfterSecondLinkRevocation.local_download.verified_digest, firstCollisionHelloBuild.digest ); await stopChild(firstHelloWorker.child); return { evidence: { executed: true, second_tenant: second.tenant, second_project: second.project, project, process_hidden: true, node_hidden: true, tasks_and_logs: tasksAndLogs, debug, artifact_and_download: artifact, process_control: control, scoped_node_and_artifact_collision: { request: { node: firstNode, first_scope: { tenant: firstTenant, project: firstProject, }, second_scope: { tenant: second.tenant, project: second.project, }, example: "hello-build", }, expected: "same-name Nodes coexist and deterministic hello-build artifacts share an ArtifactId without metadata, link, or download interference", observed: { first_process: firstCollisionHelloBuild.process, second_process: secondHelloBuild.process, same_artifact_id: secondHelloBuild.artifact, first_digest: firstCollisionHelloBuild.digest, second_digest: secondHelloBuild.digest, first_downloaded_bytes: firstCollisionHelloBuild.downloaded_bytes, second_downloaded_bytes: secondHelloBuild.downloaded_bytes, exact_executable_output: secondHelloBuild.executable_output, both_metadata_records_visible_to_owner: true, cross_tenant_unique_artifact_denied: artifact.denied, second_link_revoked: true, first_download_survived_second_link_revocation: true, }, duration_ms: Math.max(1, Date.now() - collisionStartedAt), }, duration_ms: Math.max(1, Date.now() - startedAt), }, runtime: { node: firstNode, tenant: second.tenant, project: second.project, projectDir: secondProjectDir, scope: secondScope, workerArgs: secondWorkerArgs, credentialPath: secondStored.absolute, credentialDigest: secondCredentialDigest, identity: secondIdentity, }, }; } async function runLiveSignedHostileArtifactPath({ clusterflux, projectDir, scope, tenant, project, suffix, securityNode, }) { const startedAt = Date.now(); const runReport = runJson( clusterflux, ["run", "park-wake", "--project", ".", "--json"], { cwd: projectDir } ); assert.strictEqual(runReport.status, "main_launched"); const process = runReport.process; await waitForCli( "hostile-path probe process to become active", () => runJson( clusterflux, ["process", "status", ...scope, "--process", process], { cwd: projectDir } ), (status) => status.state !== "not_active", 120_000 ); const invalidStartedAt = Date.now(); const invalid = assertDenied( await sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "report_vfs_metadata", { type: "report_vfs_metadata", tenant, project, process, node: securityNode.node, task: `hostile-path-${suffix}`, artifact_path: "/vfs/artifacts/bad artifact!", artifact_digest: sha256(Buffer.from("hostile-path-invalid")), artifact_size_bytes: 20, large_bytes_uploaded: false, }, { nonce: `strict-hostile-path-invalid-${suffix}-${Date.now()}` } ) ), /invalid VFS artifact path|invalid artifact path|ArtifactId is invalid/i, "correctly signed hostile artifact path" ); const invalidDurationMs = Math.max(1, Date.now() - invalidStartedAt); const validStartedAt = Date.now(); const validArtifact = `strict-hostile-followup-${suffix}`; const valid = await sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "report_vfs_metadata", { type: "report_vfs_metadata", tenant, project, process, node: securityNode.node, task: `hostile-path-${suffix}`, artifact_path: `/vfs/artifacts/${validArtifact}`, artifact_digest: sha256(Buffer.from("hostile-path-valid")), artifact_size_bytes: 18, large_bytes_uploaded: false, }, { nonce: `strict-hostile-path-valid-${suffix}-${Date.now()}` } ) ); assert.strictEqual(valid.type, "vfs_metadata_recorded", JSON.stringify(valid)); const healthyHeartbeat = await sendHostedControl({ type: "node_heartbeat", tenant, project, node: securityNode.node, node_signature: signedNodeHeartbeat( tenant, project, securityNode.node, securityNode.identity, { nonce: `strict-hostile-path-health-${suffix}-${Date.now()}` } ), }); assert.strictEqual( healthyHeartbeat.type, "node_heartbeat", JSON.stringify(healthyHeartbeat) ); const validDurationMs = Math.max(1, Date.now() - validStartedAt); const aborted = runJson( clusterflux, ["process", "abort", ...scope, "--process", process, "--yes"], { cwd: projectDir } ); assert.strictEqual(aborted.abort_request.accepted, true); await waitForCli( "hostile-path probe process cleanup", () => runJson( clusterflux, ["process", "status", ...scope, "--process", process], { cwd: projectDir } ), (status) => status.state === "not_active", 120_000 ); return { request: { principal: "enrolled signed Node", variant: "report_vfs_metadata", process, malformed_path: "/vfs/artifacts/bad artifact!", }, expected: "structured InvalidArtifactPath rejection followed immediately by valid signed metadata and heartbeat on the same service instance", observed: { rejection: invalid, valid_metadata_response: valid.type, valid_artifact: validArtifact, health_response: healthyHeartbeat.type, process_cleanup: "not_active", }, invalid_duration_ms: invalidDurationMs, valid_followup_duration_ms: validDurationMs, duration_ms: Math.max(1, Date.now() - startedAt), }; } async function runLiveSoak({ clusterflux, projectDir, scope, securityNode, }) { if (!strictVpsRestart) { return { executed: false, reason: "strict VPS measurement access not supplied" }; } const runReport = runJson( clusterflux, ["run", "build", "--project", ".", "--json"], { cwd: projectDir } ); assert.strictEqual(runReport.status, "main_launched"); const processId = runReport.process; const parked = await waitForCli( "soak coordinator main to park without a capable node", () => runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ), (status) => status.live_process?.main_state === "running" && status.live_process?.main_wait_state === "waiting_for_task" && status.current_task_count === 0 && status.live_process?.connected_nodes?.length === 0, 120000 ); const pollSecurityNode = (nonce) => sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "poll_task_assignment", { type: "poll_task_assignment", tenant: securityNode.capability_body.tenant, project: securityNode.capability_body.project, node: securityNode.node, }, { nonce } ) ); const drainedPriorAssignments = []; for (let drainIndex = 0; drainIndex < 16; drainIndex += 1) { const poll = await pollSecurityNode( `strict-soak-drain-${drainIndex}-${Date.now()}` ); assert.strictEqual(poll.type, "task_assignment", JSON.stringify(poll)); if (poll.assignment === null) break; assert.notStrictEqual( poll.assignment.process, processId, "soak process unexpectedly received a task assignment" ); drainedPriorAssignments.push({ process: poll.assignment.process, task: poll.assignment.task, }); assert(drainIndex < 15, "pre-soak assignment drain did not quiesce"); } const startedAt = Date.now(); const deadline = startedAt + strictSoakSeconds * 1000; const samples = []; let sampleIndex = 0; while (true) { const capabilities = await sendHostedControl( signedNodeRequest( securityNode.node, securityNode.identity, "report_node_capabilities", securityNode.capability_body, { nonce: `strict-soak-capabilities-${sampleIndex}-${Date.now()}` } ) ); assert.strictEqual( capabilities.type, "node_capabilities_recorded", JSON.stringify(capabilities) ); const poll = await pollSecurityNode( `strict-soak-poll-${sampleIndex}-${Date.now()}` ); assert.strictEqual(poll.type, "task_assignment", JSON.stringify(poll)); assert.strictEqual(poll.assignment, null); const status = runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ); assert.strictEqual(status.live_process.main_wait_state, "waiting_for_task"); samples.push(strictInfrastructureSample(projectDir)); sampleIndex += 1; if (Date.now() >= deadline) break; await delay(Math.min(30_000, deadline - Date.now())); } const currentMemory = samples.map( (sample) => sample.service_memory_current_bytes ); const serviceDisk = samples.map((sample) => sample.service_state_disk_bytes); const databaseDisk = samples.map((sample) => sample.postgres_database_bytes); const localDisk = samples.map((sample) => sample.local_node_state.bytes); const spread = (values) => Math.max(...values) - Math.min(...values); assert(spread(currentMemory) <= 128 * 1024 * 1024); assert(spread(serviceDisk) <= 16 * 1024 * 1024); assert(spread(databaseDisk) <= 32 * 1024 * 1024); assert(spread(localDisk) <= 16 * 1024 * 1024); assert.deepStrictEqual( samples.at(-1).durable_rows, samples[0].durable_rows, "durable object counts grew during the parked-process soak" ); const aborted = runJson( clusterflux, ["process", "abort", ...scope, "--process", processId, "--yes"], { cwd: projectDir } ); assert.strictEqual(aborted.abort_request.process_slot_released, true); return { executed: true, process: processId, duration_seconds: Math.floor((Date.now() - startedAt) / 1000), sample_interval_seconds: 30, sample_count: samples.length, parked_main: { main_state: parked.live_process.main_state, main_wait_state: parked.live_process.main_wait_state, }, drained_prior_assignments: drainedPriorAssignments, signed_node_poll_cycles: samples.length, memory_spread_bytes: spread(currentMemory), service_disk_spread_bytes: spread(serviceDisk), postgres_disk_spread_bytes: spread(databaseDisk), local_node_state_spread_bytes: spread(localDisk), samples, }; } async function revokeSecurityNode({ clusterflux, projectDir, scope, securityNode, }) { const startedAt = Date.now(); const revoked = runJson( clusterflux, ["node", "revoke", ...scope, "--node", securityNode.node, "--yes"], { cwd: projectDir } ); assert.strictEqual(revoked.command, "node revoke"); const denied = assertDenied( await sendHostedControl({ type: "node_heartbeat", tenant: securityNode.capability_body.tenant, project: securityNode.capability_body.project, node: securityNode.node, node_signature: signedNodeHeartbeat( securityNode.capability_body.tenant, securityNode.capability_body.project, securityNode.node, securityNode.identity, { nonce: `strict-node-revoked-${Date.now()}` } ), }), /revoked|unknown node|not recognized|not enrolled/i, "revoked node credential" ); return { node: securityNode.node, denied, duration_ms: Date.now() - startedAt, }; } async function runLiveQuotaPreallocation({ sessionSecret, suffix }) { const startedAt = Date.now(); const readSpawnQuota = async () => { const status = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "quota_status" }) ); assert.strictEqual(status.type, "quota_status", JSON.stringify(status)); const limit = status.limits?.limits?.Spawn; const usage = status.usage?.Spawn; const windowSeconds = status.window_seconds?.Spawn; const windowStarted = status.window_started_epoch_seconds?.Spawn; assert(Number.isInteger(limit) && limit > 0, JSON.stringify(status)); assert(Number.isInteger(usage) && usage >= 0, JSON.stringify(status)); assert( Number.isInteger(windowSeconds) && windowSeconds > 0, JSON.stringify(status) ); assert(Number.isInteger(windowStarted), JSON.stringify(status)); return { limit, usage, windowSeconds, windowStarted }; }; let spawnQuota = await readSpawnQuota(); const windowElapsed = Math.max( 0, Math.floor(Date.now() / 1000) - spawnQuota.windowStarted ); if (spawnQuota.usage > 0 || windowElapsed > 1) { await delay( Math.max(1000, (spawnQuota.windowSeconds - windowElapsed + 1) * 1000) ); spawnQuota = await readSpawnQuota(); } let denial; let deniedProcess; let acceptedStarts = 0; const maxAttempts = spawnQuota.limit - spawnQuota.usage + 2; for (let index = 0; index < maxAttempts; index += 1) { const processId = `vp-quota-${suffix}-${index}`; const started = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "start_process", process: processId, restart: false, }) ); if (started.type === "error") { assert.match(started.message, /quota|spawn|limit|community tier/i); denial = started; deniedProcess = processId; break; } assert.strictEqual(started.type, "process_started", JSON.stringify(started)); acceptedStarts += 1; const aborted = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "abort_process", process: processId, }) ); assert.strictEqual(aborted.type, "process_aborted", JSON.stringify(aborted)); } assert( denial, `live community-tier spawn quota was not reached in ${maxAttempts} attempts` ); const processes = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "list_processes" }) ); assert.strictEqual( processes.type, "process_statuses", JSON.stringify(processes) ); assert( !JSON.stringify(processes).includes(deniedProcess), "quota-denied process was allocated before denial" ); const independentScope = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "list_node_descriptors" }) ); assert.strictEqual( independentScope.type, "node_descriptors", `spawn quota exhaustion locked an independent read scope: ${JSON.stringify(independentScope)}` ); return { duration_ms: Date.now() - startedAt, limit: spawnQuota.limit, initial_usage: spawnQuota.usage, window_seconds: spawnQuota.windowSeconds, accepted_starts_before_denial: acceptedStarts, denied_process: deniedProcess, denial: { type: denial.type, category: denial.error?.category || null, message: denial.message, }, denied_process_allocated: false, independent_scope: { operation: "list_node_descriptors", response: independentScope.type, unaffected_by_spawn_quota: true, }, }; } async function runLongJoinProof({ clusterflux, projectDir, scope }) { const startedAt = Date.now(); const runReport = runJson( clusterflux, ["run", "long-join", "--project", ".", "--json"], { cwd: projectDir } ); assert.strictEqual(runReport.status, "main_launched"); const terminal = await waitForCli( "controlled task longer than two minutes", () => runJson( clusterflux, ["task", "list", ...scope, "--process", runReport.process], { cwd: projectDir } ), (tasks) => rawTaskEvents(tasks).some( (event) => event.task_definition === "long_join_probe" && event.terminal_state === "completed" ), 5 * 60 * 1000 ); const completed = rawTaskEvents(terminal).find( (event) => event.task_definition === "long_join_probe" && event.terminal_state === "completed" ); const durationSeconds = Math.floor((Date.now() - startedAt) / 1000); assert(durationSeconds > 120); const released = await waitForCli( "long join process automatic slot release", () => runJson( clusterflux, ["process", "status", ...scope, "--process", runReport.process], { cwd: projectDir } ), (status) => status.state === "not_active", 120000 ); return { process: runReport.process, task: completed.task, terminal_state: completed.terminal_state, result: completed.result, duration_seconds: durationSeconds, duration_ms: Math.max(1, Date.now() - startedAt), process_state: released.state, }; } async function runRepeatedParkWakeProof({ clusterflux, projectDir, scope }) { const runReport = runJson( clusterflux, ["run", "park-wake", "--project", ".", "--json"], { cwd: projectDir } ); assert.strictEqual(runReport.status, "main_launched"); const terminal = await waitForCli( "repeated coordinator-main park/wake completion", () => runJson( clusterflux, ["task", "list", ...scope, "--process", runReport.process], { cwd: projectDir } ), (tasks) => { const completed = new Set( rawTaskEvents(tasks) .filter( (event) => event.task_definition === "task_add_one" && event.terminal_state === "completed" ) .map((event) => event.task) ); return completed.size >= 16; }, 120000 ); const completedTasks = [ ...new Set( rawTaskEvents(terminal) .filter( (event) => event.task_definition === "task_add_one" && event.terminal_state === "completed" ) .map((event) => event.task) ), ]; const released = await waitForCli( "park/wake process automatic slot release", () => runJson( clusterflux, ["process", "status", ...scope, "--process", runReport.process], { cwd: projectDir } ), (status) => status.state === "not_active", 120000 ); return { process: runReport.process, completed_cycles: completedTasks.length, task_instances: completedTasks, terminal_state: released.state, }; } async function runDroppedConnectionRollback({ clusterflux, projectDir, scope, }) { const scenarioStartedAt = Date.now(); const processId = "vp-current"; const attempted = cp.spawnSync( clusterflux, ["run", "build", "--project", ".", "--json"], { cwd: projectDir, env: { ...process.env, CLUSTERFLUX_TEST_DROP_RESPONSE_AFTER_OPERATION: "start_process", }, encoding: "utf8", timeout: 5 * 60 * 1000, } ); assert.notStrictEqual( attempted.status, 0, `response-loss run unexpectedly succeeded: ${attempted.stdout}` ); assert.match( `${attempted.stderr}\n${attempted.stdout}`, /closed.*without a response|transport|response/i ); const released = await waitForCli( "CLI launch guard rollback after lost start response", () => runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ), (status) => status.state === "not_active", 30000 ); return { duration_ms: Date.now() - scenarioStartedAt, process: processId, failure_injection: "control transport dropped attempt-owned start_process response", cli_exit_status: attempted.status, rollback: "automatic CLI launch guard abort_process with matching launch_attempt", terminal_state: released.state, }; } async function runLaunchAttemptOwnershipGuards({ clusterflux, projectDir, scope, sessionSecret, activeProcess, }) { const startedAt = Date.now(); const rejectedAttempt = `launch-guard-rejected-${Date.now()}`; const rejection = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "start_process", process: `${activeProcess}-contender`, launch_attempt: rejectedAttempt, restart: false, }) ); assert.strictEqual(rejection.type, "error"); assert.match(rejection.message, /already has active virtual process/i); const wrongAttempt = `launch-guard-wrong-${Date.now()}`; const deniedAbort = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "abort_process", process: activeProcess, launch_attempt: wrongAttempt, }) ); assert.strictEqual(deniedAbort.type, "error"); assert.match(deniedAbort.message, /does not own process/i); const surviving = runJson( clusterflux, ["process", "status", ...scope, "--process", activeProcess], { cwd: projectDir } ); assert.notStrictEqual(surviving.state, "not_active"); assert.strictEqual(surviving.process, activeProcess); return { duration_ms: Date.now() - startedAt, rejected_attempt: rejectedAttempt, rejection: rejection.message, wrong_abort_attempt: wrongAttempt, wrong_abort_denied: deniedAbort.message, existing_process_survived: true, }; } async function runLiveBandwidthPreallocation({ sessionSecret, artifact, maxBytes, }) { const scenarioStartedAt = Date.now(); const before = relayDurableState(); const partialLink = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "create_artifact_download_link", artifact, max_bytes: maxBytes, ttl_seconds: 300, }) ); assert.strictEqual( partialLink.type, "artifact_download_link", JSON.stringify(partialLink) ); const partialToken = partialLink.link.scoped_token_digest; let partialChunk; const partialDeadline = Date.now() + 120_000; while (Date.now() < partialDeadline) { const response = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "open_artifact_download_stream", artifact, max_bytes: maxBytes, token_digest: partialToken, chunk_bytes: 16, }) ); assert.strictEqual( response.type, "artifact_download_stream", JSON.stringify(response) ); if (response.content_bytes_available === true) { partialChunk = response; break; } await delay(50); } assert(partialChunk, "artifact relay did not return the first partial chunk"); assert.strictEqual(partialChunk.content_eof, false); assert.strictEqual(partialChunk.streamed_bytes, 16); const partialRevoked = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "revoke_artifact_download_link", artifact, token_digest: partialToken, }) ); assert.strictEqual( partialRevoked.type, "artifact_download_link_revoked", JSON.stringify(partialRevoked) ); const afterPartialAbandon = relayDurableState(); assert(afterPartialAbandon.ingress_used > before.ingress_used); assert(afterPartialAbandon.egress_used > before.egress_used); assert( afterPartialAbandon.abandoned_or_failed_used > before.abandoned_or_failed_used ); let denial; const acceptedReservations = []; for (let index = 0; index < 64; index += 1) { const response = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "create_artifact_download_link", artifact, max_bytes: maxBytes, ttl_seconds: 300, }) ); if (response.type === "error") { assert.match( response.message, /artifact relay.*(?:concurrency|period byte budget)|bandwidth|reservation/i ); denial = response; break; } assert.strictEqual(response.type, "artifact_download_link", JSON.stringify(response)); acceptedReservations.push(response.link.scoped_token_digest); } assert(denial, "artifact relay preallocation was not denied in 64 reservations"); for (const tokenDigest of acceptedReservations) { const revoked = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "revoke_artifact_download_link", artifact, token_digest: tokenDigest, }) ); assert.strictEqual( revoked.type, "artifact_download_link_revoked", JSON.stringify(revoked) ); } const afterRelease = relayDurableState(); assert.strictEqual( Object.keys(afterRelease.reservations || {}).length, Object.keys(before.reservations || {}).length ); return { scenario_started_at_ms: scenarioStartedAt, artifact, accepted_reservations_before_denial: acceptedReservations.length, bytes_served_before_denial: partialChunk.streamed_bytes, partial_abandon: { ingress_delta: afterPartialAbandon.ingress_used - before.ingress_used, egress_delta: afterPartialAbandon.egress_used - before.egress_used, abandoned_delta: afterPartialAbandon.abandoned_or_failed_used - before.abandoned_or_failed_used, reservation_released: !(partialToken in afterRelease.reservations), }, durable_before: before, durable_after_release: afterRelease, denial: { type: denial.type, category: denial.error?.category || null, message: denial.message, }, }; } function relayDurableState() { if (!strictVpsRestart) { throw new Error("strict relay accounting requires VPS Postgres access"); } const output = run( "ssh", sshArgs( "sudo", "-u", "postgres", "psql", "-d", "clusterflux", "-At", "-c", "SELECT record::text FROM clusterflux_artifact_relay_state WHERE singleton = TRUE" ) ).trim(); assert.notStrictEqual(output, "", "artifact relay durable state was not persisted"); return JSON.parse(output.split(/\r?\n/).filter(Boolean).at(-1)); } async function waitForHostedControlReady(timeoutMs = 60_000) { const deadline = Date.now() + timeoutMs; let lastError; while (Date.now() < deadline) { try { const ping = await sendHostedControl({ type: "ping" }); if (ping.type === "pong") return ping; lastError = new Error(JSON.stringify(ping)); } catch (error) { lastError = error; } await delay(500); } throw new Error(`hosted service did not recover: ${lastError}`); } async function publishRelayProbeArtifact({ clusterflux, projectDir, scope, label }) { const runReport = runJson( clusterflux, ["run", "build", "--project", ".", "--json"], { cwd: projectDir } ); await waitForCli( `${label} flagship completion`, () => runJson( clusterflux, ["task", "list", ...scope, "--process", runReport.process], { cwd: projectDir } ), (report) => completedFlagship(rawTaskEvents(report)), 10 * 60 * 1000 ); const artifacts = runJson( clusterflux, ["artifact", "list", ...scope, "--process", runReport.process], { cwd: projectDir } ); const artifact = artifacts.artifacts.find((candidate) => { const digest = candidate.digest; return ( typeof digest === "string" && /^sha256:[0-9a-f]{64}$/.test(digest) && candidate.artifact === `release.tar-${digest.slice("sha256:".length)}` ); }); assert(artifact, `${label} did not publish a relay probe artifact`); return artifact; } async function runRelayEmergencyDisable({ clusterflux, clusterfluxNode, projectDir, scope, workerArgs, sessionSecret, maxBytes, }) { const startedAt = Date.now(); if (!strictVpsRestart) { throw new Error("strict relay disable proof requires VPS systemd access"); } const dropInDir = `/run/systemd/system/${strictServiceUnit}.d`; const dropInPath = `${dropInDir}/90-strict-relay-disable.conf`; run("ssh", sshArgs("sudo", "mkdir", "-p", dropInDir)); cp.execFileSync("ssh", sshArgs("sudo", "tee", dropInPath), { cwd: repo, input: "[Service]\nEnvironment=CLUSTERFLUX_HOSTED_RELAY_DISABLED=true\n", stdio: ["pipe", "ignore", "inherit"], }); let disabled; let disabledArtifact; let disabledWorker; try { run( "ssh", sshArgs( "sudo", "systemctl", "daemon-reload" ) ); run( "ssh", sshArgs("sudo", "systemctl", "restart", strictServiceUnit) ); await waitForHostedControlReady(); disabledWorker = spawnJsonLines(clusterfluxNode, workerArgs, { cwd: projectDir, env: { ...process.env }, }); await disabledWorker.waitFor( (value) => value.node_status === "ready", "relay-disabled worker ready" ); disabledArtifact = await publishRelayProbeArtifact({ clusterflux, projectDir, scope, label: "relay-disabled", }); disabled = assertDenied( await sendHostedControl( authenticatedRequest(sessionSecret, { type: "create_artifact_download_link", artifact: disabledArtifact.artifact, max_bytes: maxBytes, ttl_seconds: 60, }) ), /artifact relay is disabled/i, "emergency-disabled artifact relay" ); } finally { if (disabledWorker) await stopChild(disabledWorker.child); run("ssh", sshArgs("sudo", "rm", "-f", dropInPath)); run("ssh", sshArgs("sudo", "systemctl", "daemon-reload")); run( "ssh", sshArgs("sudo", "systemctl", "restart", strictServiceUnit) ); await waitForHostedControlReady(); } const restoredWorker = spawnJsonLines(clusterfluxNode, workerArgs, { cwd: projectDir, env: { ...process.env }, }); try { await restoredWorker.waitFor( (value) => value.node_status === "ready", "relay-restored worker ready" ); const restoredArtifact = await publishRelayProbeArtifact({ clusterflux, projectDir, scope, label: "relay-restored", }); const restored = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "create_artifact_download_link", artifact: restoredArtifact.artifact, max_bytes: maxBytes, ttl_seconds: 60, }) ); assert.strictEqual(restored.type, "artifact_download_link", JSON.stringify(restored)); const revoked = await sendHostedControl( authenticatedRequest(sessionSecret, { type: "revoke_artifact_download_link", artifact: restoredArtifact.artifact, token_digest: restored.link.scoped_token_digest, }) ); assert.strictEqual(revoked.type, "artifact_download_link_revoked"); return { evidence: { duration_ms: Date.now() - startedAt, disabled, disabled_probe_artifact: disabledArtifact.artifact, restored: restored.type, restored_probe_artifact: restoredArtifact.artifact, restored_reservation_released: revoked.type, runtime_drop_in_removed: true, }, worker: restoredWorker, }; } catch (error) { await stopChild(restoredWorker.child); throw error; } } function deploymentProvenance() { if (!strictVpsRestart) return null; const systemGeneration = run( "ssh", sshArgs("readlink", "-f", "/run/current-system") ).trim(); const mainPid = run( "ssh", sshArgs( "systemctl", "show", strictServiceUnit, "--property=MainPID", "--value" ) ).trim(); assert.match(mainPid, /^[1-9][0-9]*$/, "hosted service has no live MainPID"); const executable = run( "ssh", sshArgs("readlink", "-f", `/proc/${mainPid}/exe`) ).trim(); const binarySha256 = run( "ssh", sshArgs("sha256sum", `/proc/${mainPid}/exe`) ) .trim() .split(/\s+/)[0]; const fragment = run( "ssh", sshArgs("systemctl", "show", strictServiceUnit, "--property=FragmentPath", "--value") ).trim(); const serviceUnitSha256 = run( "ssh", sshArgs("sha256sum", fragment) ) .trim() .split(/\s+/)[0]; const renderedServiceConfiguration = run( "ssh", sshArgs("systemctl", "cat", strictServiceUnit) ); const renderedServiceConfigurationSha256 = sha256( Buffer.from(renderedServiceConfiguration) ); return { system_generation: systemGeneration, hosted_service_executable: executable, hosted_service_sha256: `sha256:${binarySha256}`, service_unit: fragment, service_unit_sha256: `sha256:${serviceUnitSha256}`, service_configuration_sha256: renderedServiceConfigurationSha256, }; } function configurationProvenance() { const configRepo = path.resolve( process.env.CLUSTERFLUX_DEPLOYMENT_CONFIG_REPO || path.join(repo, "..", "michelpaulissen.com") ); const status = run("git", ["status", "--short"], { cwd: configRepo }).trim(); const revision = run("git", ["rev-parse", "HEAD"], { cwd: configRepo }).trim(); return { repository: configRepo, revision, evidence_identity: sha256(Buffer.from(revision)), clean: status === "", status: status || null, }; } function proxyConfigurationProvenance() { if (!strictVpsRestart) return null; const proxyUnit = process.env.CLUSTERFLUX_STRICT_PROXY_UNIT || "nginx.service"; const fragment = run( "ssh", sshArgs("systemctl", "show", "--property=FragmentPath", "--value", proxyUnit) ).trim(); assert(fragment, `proxy service ${proxyUnit} has no FragmentPath`); const unitSha256 = run( "ssh", sshArgs("sha256sum", fragment) ).trim().split(/\s+/)[0]; const proxyExecStart = run( "ssh", sshArgs("systemctl", "show", "--property=ExecStart", "--value", proxyUnit) ).trim(); const nginxExecutable = proxyExecStart.match(/path=([^ ;]+)/)?.[1]; const nginxConfiguration = proxyExecStart.match(/ argv\[\]=.* -c ([^ ;]+)/)?.[1]; assert(nginxExecutable, `proxy service ${proxyUnit} has no executable identity`); assert(nginxConfiguration, `proxy service ${proxyUnit} has no configuration identity`); const renderedConfiguration = run( "ssh", sshArgs(nginxExecutable, "-T", "-c", nginxConfiguration) ); const renderedConfigurationIdentity = sha256(Buffer.from(renderedConfiguration)); const activeState = run( "ssh", sshArgs("systemctl", "is-active", proxyUnit) ).trim(); assert.strictEqual(activeState, "active", `proxy service ${proxyUnit} is not active`); return { proxy_unit: proxyUnit, proxy_unit_fragment: fragment, proxy_unit_sha256: `sha256:${unitSha256}`, proxy_executable: nginxExecutable, proxy_configuration: nginxConfiguration, rendered_configuration_sha256: renderedConfigurationIdentity, evidence_identity: renderedConfigurationIdentity, active_state: activeState, }; } async function restartHostedServiceAndResume({ clusterflux, clusterfluxNode, projectDir, scope, workerArgs, workerNode, credentialPath, credentialDigest, scopedCollisionRuntime, }) { if (!strictVpsRestart) { return { executed: false, reason: "strict VPS restart access not supplied", worker: null, }; } const before = deploymentProvenance(); run("ssh", sshArgs("systemctl", "restart", strictServiceUnit)); const deadline = Date.now() + 120000; let ping; let lastError; while (Date.now() < deadline) { try { ping = await sendHostedControl({ type: "ping" }); if (ping.type === "pong") break; } catch (error) { lastError = error; } await delay(500); } assert.strictEqual( ping?.type, "pong", `hosted service did not recover after restart: ${lastError?.message || "no pong"}` ); const afterFirstRestart = deploymentProvenance(); assert.strictEqual(afterFirstRestart.system_generation, before.system_generation); assert.strictEqual( afterFirstRestart.hosted_service_sha256, before.hosted_service_sha256 ); const projects = runJson(clusterflux, ["project", "list", ...scope], { cwd: projectDir, }); assert(projects.project_count >= 1, "CLI session/project did not survive restart"); const ephemeralRun = runJson( clusterflux, ["run", "build", "--project", ".", "--json"], { cwd: projectDir } ); assert.strictEqual(ephemeralRun.status, "main_launched"); const ephemeralProcess = ephemeralRun.process; await waitForCli( "pre-restart ephemeral main to park", () => runJson( clusterflux, ["process", "status", ...scope, "--process", ephemeralProcess], { cwd: projectDir } ), (status) => status.live_process?.main_wait_state === "waiting_for_node", 120000 ); run("ssh", sshArgs("systemctl", "restart", strictServiceUnit)); const secondDeadline = Date.now() + 120000; ping = undefined; lastError = undefined; while (Date.now() < secondDeadline) { try { ping = await sendHostedControl({ type: "ping" }); if (ping.type === "pong") break; } catch (error) { lastError = error; } await delay(500); } assert.strictEqual( ping?.type, "pong", `hosted service did not recover after ephemeral-state restart: ${ lastError?.message || "no pong" }` ); const after = deploymentProvenance(); assert.strictEqual(after.system_generation, before.system_generation); assert.strictEqual(after.hosted_service_sha256, before.hosted_service_sha256); const oldStatus = runJson( clusterflux, ["process", "status", ...scope, "--process", ephemeralProcess], { cwd: projectDir } ); assert.strictEqual(oldStatus.state, "not_active"); assert.strictEqual(sha256(fs.readFileSync(credentialPath)), credentialDigest); const worker = spawnJsonLines(clusterfluxNode, workerArgs, { cwd: projectDir, env: { ...process.env }, }); const ready = await worker.waitFor( (value) => value.node_status === "ready", "persisted worker ready after hosted service restart" ); assert.strictEqual(ready.node, workerNode); assert.strictEqual(sha256(fs.readFileSync(credentialPath)), credentialDigest); let scopedNodeCollisionAfterRestart = null; if (scopedCollisionRuntime) { assert.strictEqual(scopedCollisionRuntime.node, workerNode); assert.notStrictEqual( scopedCollisionRuntime.tenant, readJson(path.join(projectDir, ".clusterflux", "session.json")).tenant ); assert.strictEqual( sha256(fs.readFileSync(scopedCollisionRuntime.credentialPath)), scopedCollisionRuntime.credentialDigest ); const secondWorker = spawnJsonLines( clusterfluxNode, scopedCollisionRuntime.workerArgs, { cwd: scopedCollisionRuntime.projectDir, env: { ...process.env }, } ); try { const secondReady = await secondWorker.waitFor( (value) => value.node_status === "ready", "same-name second-tenant worker ready after hosted service restart" ); assert.strictEqual(secondReady.node, workerNode); const firstStatus = await waitForCli( "first scoped same-name Node online after restart", () => runJson( clusterflux, ["node", "status", ...scope, "--node", workerNode], { cwd: projectDir } ), (status) => nodeDescriptor(status, workerNode)?.online === true, 30_000 ); const secondStatus = await waitForCli( "second scoped same-name Node online after restart", () => runJson( clusterflux, [ "node", "status", ...scopedCollisionRuntime.scope, "--node", workerNode, ], { cwd: scopedCollisionRuntime.projectDir } ), (status) => nodeDescriptor(status, workerNode)?.online === true, 30_000 ); scopedNodeCollisionAfterRestart = { node: workerNode, first_scope_online: nodeDescriptor(firstStatus, workerNode)?.online === true, second_scope_online: nodeDescriptor(secondStatus, workerNode)?.online === true, both_credentials_reused_without_grants: true, distinct_credential_digests: credentialDigest !== scopedCollisionRuntime.credentialDigest, }; assert.strictEqual( scopedNodeCollisionAfterRestart.distinct_credential_digests, true, "same-name scoped Nodes unexpectedly reused one credential" ); } finally { await stopChild(secondWorker.child); } } const restartedRun = runJson( clusterflux, ["run", "build", "--project", ".", "--json"], { cwd: projectDir } ); assert.strictEqual(restartedRun.status, "main_launched"); const restartedProcess = restartedRun.process; const completed = await waitForCli( "new process completion after hosted service restart", () => runJson( clusterflux, ["task", "list", ...scope, "--process", restartedProcess], { cwd: projectDir } ), (tasks) => completedFlagship(rawTaskEvents(tasks)), 5 * 60 * 1000 ); const completedEvent = rawTaskEvents(completed).find( (event) => event.executor === "coordinator_main" && event.terminal_state === "completed" ); assert(completedEvent, "post-restart flagship omitted its completed main event"); return { executed: true, account_project_session_preserved: true, node_identity_preserved: true, old_process_terminated_honestly: true, terminated_ephemeral_process: ephemeralProcess, new_process: restartedProcess, new_process_result: completedEvent.result, scoped_node_collision_after_restart: scopedNodeCollisionAfterRestart, before, after_first_restart: afterFirstRestart, after, worker, }; } async function finishScopedNodeCollisionAfterRestart({ clusterflux, projectDir, scope, workerNode, scopedCollisionRuntime, }) { const startedAt = Date.now(); assert(scopedCollisionRuntime, "scoped collision runtime evidence is required"); const revoked = runJson( clusterflux, [ "node", "revoke", ...scopedCollisionRuntime.scope, "--node", scopedCollisionRuntime.node, "--yes", ], { cwd: scopedCollisionRuntime.projectDir } ); assert.strictEqual(revoked.command, "node revoke"); const revokedHeartbeat = assertDenied( await sendHostedControl({ type: "node_heartbeat", tenant: scopedCollisionRuntime.tenant, project: scopedCollisionRuntime.project, node: scopedCollisionRuntime.node, node_signature: signedNodeHeartbeat( scopedCollisionRuntime.tenant, scopedCollisionRuntime.project, scopedCollisionRuntime.node, scopedCollisionRuntime.identity, { nonce: `strict-scoped-node-revoked-${Date.now()}`, } ), }), /not enrolled|unknown node|revoked|credential/i, "revoked second scoped Node" ); const firstStatus = await waitForCli( "first same-name Node remains live after scoped revocation", () => runJson( clusterflux, ["node", "status", ...scope, "--node", workerNode], { cwd: projectDir } ), (status) => nodeDescriptor(status, workerNode)?.online === true, 30_000 ); return { request: { revoked_scope: { tenant: scopedCollisionRuntime.tenant, project: scopedCollisionRuntime.project, node: scopedCollisionRuntime.node, }, retained_node: workerNode, }, expected: "revocation affects only the selected scoped Node after both same-name credentials survive restart", observed: { revoked_command: revoked.command, revoked_credential_denied: revokedHeartbeat.denied, first_scope_node_online: nodeDescriptor(firstStatus, workerNode)?.online === true, }, duration_ms: Math.max(1, Date.now() - startedAt), }; } async function finishUserCredentialSecurity({ clusterflux, projectDir, scope, sessionSecret, }) { const startedAt = Date.now(); const forged = assertDenied( await sendHostedControl( authenticatedRequest( `forged-session-${crypto.randomBytes(24).toString("hex")}`, { type: "list_projects" } ) ), /not recognized|invalid|authentication|session/i, "forged user session" ); let expired = null; const expiredFile = process.env.CLUSTERFLUX_EXPIRED_USER_SESSION_FILE; if (expiredFile) { const oldSession = readJson(path.resolve(expiredFile)); assert(oldSession.session_secret, "expired session evidence omitted its secret"); expired = assertDenied( await sendHostedControl( authenticatedRequest(oldSession.session_secret, { type: "list_projects" }) ), /expired|not recognized/i, "expired user session" ); } else if (strictFullRelease) { throw new Error( "strict full release requires CLUSTERFLUX_EXPIRED_USER_SESSION_FILE for a genuinely expired hosted session" ); } const logout = runJson(clusterflux, ["logout", ...scope, "--yes"], { cwd: projectDir, }); assert.strictEqual(logout.server_session_revocation.revoked, true); const revoked = assertDenied( await sendHostedControl( authenticatedRequest(sessionSecret, { type: "list_projects" }) ), /revoked|not recognized/i, "revoked user session" ); return { forged, expired, revoked, duration_ms: Date.now() - startedAt, }; } async function dapVariables(client, variablesReference) { const request = client.send("variables", { variablesReference }); return (await client.response(request, "variables")).body.variables; } async function runSameDefinitionDapIdentity({ clusterfluxDap, clusterflux, projectDir, scope, }) { const scenarioStartedAt = Date.now(); const baselineContainers = new Set( run("podman", ["ps", "-q"]) .trim() .split(/\s+/) .filter(Boolean) ); const client = new DapClient({ cwd: projectDir, command: clusterfluxDap, args: [], env: { ...process.env, CLUSTERFLUX_TEST_DAP_OBSERVER_CONNECTION_LOSS: "1", CLUSTERFLUX_TEST_DAP_POST_COMMIT_OBSERVATION_FAILURE: "1", }, }); let disconnected = false; try { const initialize = client.send("initialize", { adapterID: "clusterflux", linesStartAt1: true, columnsStartAt1: true, }); await client.response(initialize, "initialize"); const launch = client.send("launch", { entry: "identity", project: projectDir, runtimeBackend: "live-services", coordinatorEndpoint: serviceEndpoint, }); await client.response(launch, "launch"); await client.waitFor( (message) => message.type === "event" && message.event === "initialized" ); const configurationDone = client.send("configurationDone"); await client.response(configurationDone, "configurationDone"); const mainThreadDeadline = Date.now() + 5 * 60 * 1000; let mainThread; while (Date.now() < mainThreadDeadline) { const threadsRequest = client.send("threads"); const threads = (await client.response(threadsRequest, "threads")).body .threads; mainThread = threads.find((thread) => /coordinator main/i.test(thread.name)); if (mainThread) break; await delay(100); } assert(mainThread, "identity entry did not report its coordinator main"); const launchWithoutBreakpointMs = Date.now() - scenarioStartedAt; const postCommitDiagnostics = [ "initial task observation failed after main_launched", "initial process observation failed after main_launched", ].map((expected) => { const message = client.messages.find( (candidate) => candidate.type === "event" && candidate.event === "output" && String(candidate.body?.output || "").includes(expected) ); assert(message, `post-commit launch evidence omitted: ${expected}`); return String(message.body.output).trim(); }); const prematurePostCommitEvents = client.messages.filter( (message) => message.type === "event" && ["stopped", "terminated"].includes(message.event) ); assert.deepStrictEqual(prematurePostCommitEvents, []); const processRequest = client.send("evaluate", { expression: "virtual_process_id", context: "watch", }); const processId = (await client.response(processRequest, "evaluate")).body .result; const identityContainerDeadline = Date.now() + 2 * 60 * 1000; let identityContainerIds = new Set(); let maximumNewContainerCount = 0; let lastPodmanStates = []; while (Date.now() < identityContainerDeadline) { const containers = runJson("podman", ["ps", "--format", "json"]); lastPodmanStates = containers; identityContainerIds = new Set( containers .map((container) => container.Id || container.ID || container.IdHex || "") .filter((id) => id && !baselineContainers.has(id)) ); maximumNewContainerCount = Math.max( maximumNewContainerCount, identityContainerIds.size ); if (identityContainerIds.size >= 2) break; await delay(100); } const identityTaskSnapshot = identityContainerIds.size >= 2 ? null : runJson( clusterflux, ["task", "list", ...scope, "--process", processId], { cwd: projectDir } ); assert( identityContainerIds.size >= 2, `identity entry did not start two same-definition Podman containers; max=${maximumNewContainerCount} tasks=${JSON.stringify( identityTaskSnapshot )} podman=${JSON.stringify(lastPodmanStates)}` ); const pause = client.send("pause", { threadId: mainThread.id }); await client.response(pause, "pause"); const paused = await client.waitFor( (message) => message.type === "event" && message.event === "stopped" && message.body.reason === "pause", 30_000 ); assert.strictEqual(typeof paused.body.allThreadsStopped, "boolean"); const podmanStates = runJson("podman", ["ps", "--all", "--format", "json"]); const clusterfluxPausedContainers = podmanStates.filter((container) => { const id = container.Id || container.ID || container.IdHex || ""; const state = String(container.State || container.Status || "").toLowerCase(); return identityContainerIds.has(id) && state.includes("paused"); }); assert( clusterfluxPausedContainers.length >= 2, `expected two newly paused Clusterflux containers: ${JSON.stringify( podmanStates )}` ); const threadsRequest = client.send("threads"); const threads = (await client.response(threadsRequest, "threads")).body .threads; const identityThreads = threads.filter((thread) => /identity probe/i.test(thread.name) ); assert.strictEqual( identityThreads.length, 2, `expected two same-definition DAP threads: ${JSON.stringify(threads)}` ); assert.notStrictEqual(identityThreads[0].id, identityThreads[1].id); const threadEvidence = []; for (const threadRecord of identityThreads) { const stackRequest = client.send("stackTrace", { threadId: threadRecord.id, startFrame: 0, levels: 1, }); const frames = (await client.response(stackRequest, "stackTrace")).body .stackFrames; assert.strictEqual(frames.length, 1); const scopesRequest = client.send("scopes", { frameId: frames[0].id }); const scopes = (await client.response(scopesRequest, "scopes")).body.scopes; const argsScope = scopes.find( (scopeRecord) => scopeRecord.name === "Task Args and Handles" ); const runtimeScope = scopes.find( (scopeRecord) => scopeRecord.name === "Clusterflux Runtime" ); assert(argsScope && runtimeScope); const args = await dapVariables(client, argsScope.variablesReference); const runtime = await dapVariables(client, runtimeScope.variablesReference); const runtimeValue = (name) => runtime.find((variable) => variable.name === name)?.value; assert.strictEqual(runtimeValue("state"), "Frozen"); threadEvidence.push({ thread_id: threadRecord.id, task_instance: runtimeValue("virtual_thread"), attempt_id: runtimeValue("task_attempt_id"), arguments: args.map((variable) => ({ name: variable.name, value: variable.value, })), }); } assert.notStrictEqual( threadEvidence[0].task_instance, threadEvidence[1].task_instance ); assert.notStrictEqual(threadEvidence[0].attempt_id, threadEvidence[1].attempt_id); const argumentText = threadEvidence .flatMap((record) => record.arguments.map((argument) => argument.value)) .join(" "); assert.match(argumentText, /slow-first/); assert.match(argumentText, /fast-second/); const continued = client.send("continue", { threadId: paused.body.threadId, }); await client.response(continued, "continue"); await client.waitFor( (message) => message.type === "event" && message.event === "terminated", 5 * 60 * 1000 ); const taskList = runJson( clusterflux, ["task", "list", ...scope, "--process", processId], { cwd: projectDir } ); const identityEvents = rawTaskEvents(taskList).filter( (event) => event.task_definition === "identity_probe" && event.terminal_state === "completed" ); assert.strictEqual(identityEvents.length, 2, JSON.stringify(identityEvents)); assert.notStrictEqual(identityEvents[0].task, identityEvents[1].task); assert.notStrictEqual(identityEvents[0].attempt_id, identityEvents[1].attempt_id); assert.match(JSON.stringify(identityEvents[0].result), /fast-second/); assert.match(JSON.stringify(identityEvents[1].result), /slow-first/); const released = await waitForCli( "same-definition identity process release", () => runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ), (status) => status.state === "not_active", 120_000 ); await client.close(); disconnected = true; return { duration_ms: Date.now() - scenarioStartedAt, process: processId, launch_without_breakpoint: { request: { entry: "identity", runtime_backend: "live-services", configured_breakpoints: [], }, expected: "launch commits and reports a real coordinator-main thread", observed: { thread_id: mainThread.id, thread_name: mainThread.name, }, duration_ms: launchWithoutBreakpointMs, }, post_main_launched_observation_recovery: { request: { entry: "identity", fault_injections: [ "initial task snapshot observation failure", "initial process-status observation failure", ], }, expected: "main_launched is committed, no rollback or false stop occurs, and the observer reconnects until threads appear", observed: { diagnostics: postCommitDiagnostics, main_thread: mainThread, premature_stop_or_termination_events: prematurePostCommitEvents.length, }, duration_ms: launchWithoutBreakpointMs, }, same_definition_identity: { expected: "two concurrent instances retain distinct thread, argument, attempt, output, freeze, and terminal identities", observed: { thread_evidence: threadEvidence, completion_order: identityEvents.map((event) => ({ task_instance: event.task, attempt_id: event.attempt_id, result: event.result, })), paused_container_count: clusterfluxPausedContainers.length, terminal_state: released.state, }, duration_ms: Date.now() - scenarioStartedAt, }, thread_evidence: threadEvidence, completion_order: identityEvents.map((event) => ({ task_instance: event.task, attempt_id: event.attempt_id, result: event.result, })), podman_paused_container_ids: clusterfluxPausedContainers.map( (container) => container.Id || container.ID || container.IdHex ), dap_all_threads_stopped: paused.body.allThreadsStopped, terminal_state: released.state, }; } finally { if (!disconnected) { await client.close().catch(() => { if (client.child.exitCode === null) client.child.kill("SIGKILL"); }); } } } async function runLiveDapEditRestart({ clusterfluxDap, clusterflux, projectDir, scope, worker, }) { const scenarioStartedAt = Date.now(); const sourcePath = fs.realpathSync(path.join(projectDir, "src/lib.rs")); const originalSource = fs.readFileSync(sourcePath, "utf8"); const sourceLines = originalSource.split(/\r?\n/); const lineFor = (needle) => { const line = sourceLines.findIndex((candidate) => candidate.includes(needle)) + 1; assert(line > 0, `flagship source omitted ${needle}`); return line; }; const mainLine = lineFor("pub async fn restart_main()"); const taskLine = lineFor("fn task_trap("); const client = new DapClient({ cwd: projectDir, command: clusterfluxDap, args: [], env: { ...process.env, CLUSTERFLUX_TEST_DAP_OBSERVER_CONNECTION_LOSS: "1", CLUSTERFLUX_TEST_DAP_OBSERVER_SNAPSHOT_FAILURE: "1", CLUSTERFLUX_TEST_DAP_OBSERVER_PROCESS_STATUS_FAILURE: "1", CLUSTERFLUX_TEST_DAP_OBSERVER_FALLBACK_FAILURE: "1", CLUSTERFLUX_TEST_DAP_OBSERVER_DEBUG_EPOCH_WAIT_FAILURE: "1", CLUSTERFLUX_TEST_DAP_BREAKPOINT_DELAY_REVISION: "1", CLUSTERFLUX_TEST_DAP_BREAKPOINT_DELAY_MS: "750", CLUSTERFLUX_TEST_DAP_BREAKPOINT_INSTALLATION_FAILURE_REVISION: "3", }, }); let sourceRestored = false; let disconnected = false; try { const initialize = client.send("initialize", { adapterID: "clusterflux", linesStartAt1: true, columnsStartAt1: true, }); await client.response(initialize, "initialize"); const launch = client.send("launch", { entry: "restart", project: projectDir, runtimeBackend: "live-services", coordinatorEndpoint: serviceEndpoint, }); await client.response(launch, "launch"); await client.waitFor( (message) => message.type === "event" && message.event === "initialized" ); const configurationStartedAt = Date.now(); const configurationDone = client.send("configurationDone"); const configurationResponse = await client.response( configurationDone, "configurationDone" ); const configurationResponseMs = Date.now() - configurationStartedAt; assert( configurationResponseMs < 2_000, `configurationDone blocked for ${configurationResponseMs} ms` ); const threadDeadline = Date.now() + 5 * 60 * 1000; let runningThreads = []; let threadObservationResponse; while (Date.now() < threadDeadline) { const threadsRequest = client.send("threads"); threadObservationResponse = await client.response(threadsRequest, "threads"); runningThreads = threadObservationResponse.body.threads; if (runningThreads.length > 0) break; await delay(100); } assert(runningThreads.length > 0, "asynchronous live DAP launch reported no threads"); const initialObserverFaults = []; for (const expected of [ { fault: "task snapshot read transport failure", diagnostic: "runtime snapshot observation failed", }, { fault: "process-status read transport failure", diagnostic: "runtime process observation failed", }, { fault: "breakpoint inspection and fallback event transport failures", diagnostic: "runtime breakpoint and fallback event observation failed", }, ]) { const message = await client.waitFor( (candidate) => candidate.seq > configurationResponse.seq && candidate.type === "event" && candidate.event === "output" && String(candidate.body?.output || "").includes(expected.diagnostic), 120_000 ); initialObserverFaults.push({ ...expected, expected: "reconnect and eventually report live threads without a stop", observed: String(message.body.output).trim(), }); } const recoveredThreadsRequest = client.send("threads"); const recoveredThreadsResponse = await client.response( recoveredThreadsRequest, "threads" ); assert( recoveredThreadsResponse.body.threads.length > 0, "observer faults removed threads after recovery" ); const prematureLaunchEvents = client.messages.filter( (message) => message.seq > configurationResponse.seq && message.seq < recoveredThreadsResponse.seq && message.type === "event" && ["stopped", "terminated"].includes(message.event) ); assert.deepStrictEqual( prematureLaunchEvents, [], "post-launch observer recovery fabricated a stop or terminated the launch" ); const postLaunchObservationRecoveryMs = Date.now() - configurationStartedAt; const pauseStartedAt = Date.now(); const pause = client.send("pause", { threadId: runningThreads[0].id }); await client.response(pause, "pause"); const pauseResponseMs = Date.now() - pauseStartedAt; assert(pauseResponseMs < 2_000, `pause blocked for ${pauseResponseMs} ms`); const mainStop = await client.waitFor( (message) => message.type === "event" && message.event === "stopped" && message.body.reason === "pause" ); assert.strictEqual(mainStop.body.allThreadsStopped, true); const inspectStartedAt = Date.now(); const commandStatus = client.send("evaluate", { expression: "command_status", context: "watch", }); const inspected = await client.response(commandStatus, "evaluate"); const inspectionResponseMs = Date.now() - inspectStartedAt; assert( inspectionResponseMs < 2_000, `inspection blocked for ${inspectionResponseMs} ms` ); assert.match(inspected.body.result, /debug epoch|frozen/i); const breakpointStartedAt = Date.now(); const staleRevisionRequest = client.send("setBreakpoints", { source: { path: sourcePath }, breakpoints: [{ line: mainLine }], }); const newestRevisionRequest = client.send("setBreakpoints", { source: { path: sourcePath }, breakpoints: [{ line: taskLine }], }); const staleRevisionResponse = await client.response( staleRevisionRequest, "setBreakpoints" ); const newestRevisionResponse = await client.response( newestRevisionRequest, "setBreakpoints" ); const breakpointResponseMs = Date.now() - breakpointStartedAt; assert( breakpointResponseMs < 2_000, `setBreakpoints blocked for ${breakpointResponseMs} ms` ); assert.deepStrictEqual( staleRevisionResponse.body.breakpoints.map( (breakpoint) => breakpoint.verified ), [false] ); assert.deepStrictEqual( newestRevisionResponse.body.breakpoints.map( (breakpoint) => breakpoint.verified ), [false] ); assert.deepStrictEqual( newestRevisionResponse.body.breakpoints.map( (breakpoint) => breakpoint.message ), ["Pending coordinator breakpoint installation"] ); const newestRevisionInstalled = await client.waitFor( (message) => message.seq > newestRevisionResponse.seq && message.type === "event" && message.event === "breakpoint" && message.body.reason === "changed" && message.body.breakpoint?.verified === true && message.body.breakpoint?.line === taskLine, 30_000 ); await delay(1_000); const staleRevisionEvents = client.messages.filter( (message) => message.seq > newestRevisionResponse.seq && message.type === "event" && message.event === "breakpoint" && message.body.reason === "changed" && message.body.breakpoint?.line === mainLine ); assert.deepStrictEqual( staleRevisionEvents, [], "stale breakpoint revision completion overwrote the newest set" ); const rejectedRevisionRequest = client.send("setBreakpoints", { source: { path: sourcePath }, breakpoints: [{ line: taskLine }], }); const rejectedRevisionResponse = await client.response( rejectedRevisionRequest, "setBreakpoints" ); const rejectedBreakpoint = await client.waitFor( (message) => message.seq > rejectedRevisionResponse.seq && message.type === "event" && message.event === "breakpoint" && message.body.reason === "changed" && message.body.breakpoint?.verified === false && message.body.breakpoint?.line === taskLine && /coordinator breakpoint installation failed/i.test( message.body.breakpoint?.message || "" ), 30_000 ); assert.strictEqual( rejectedBreakpoint.body.breakpoint.id, rejectedRevisionResponse.body.breakpoints[0].id ); const retryBreakpoints = client.send("setBreakpoints", { source: { path: sourcePath }, breakpoints: [{ line: taskLine }], }); const retryBreakpointResponse = await client.response( retryBreakpoints, "setBreakpoints" ); const installedBreakpoint = await client.waitFor( (message) => message.seq > retryBreakpointResponse.seq && message.type === "event" && message.event === "breakpoint" && message.body.reason === "changed" && message.body.breakpoint?.verified === true && message.body.breakpoint?.line === taskLine, 30_000 ); assert.strictEqual( installedBreakpoint.body.breakpoint.id, retryBreakpointResponse.body.breakpoints[0].id ); const breakpointInstallationMs = Date.now() - breakpointStartedAt; const continueStartedAt = Date.now(); const mainContinue = client.send("continue", { threadId: mainStop.body.threadId, }); const mainContinueResponse = await client.response(mainContinue, "continue"); const continueResponseMs = Date.now() - continueStartedAt; assert( continueResponseMs < 2_000, `continue blocked for ${continueResponseMs} ms` ); const taskStop = await client.waitFor( (message) => message.seq > mainStop.seq && message.type === "event" && message.event === "stopped" && message.body.reason === "breakpoint" ); const realBreakpointMs = Date.now() - breakpointStartedAt; assert.strictEqual(taskStop.body.allThreadsStopped, true); const observerReconnect = await client.waitFor( (message) => message.seq > mainContinueResponse.seq && message.type === "event" && message.event === "output" && String(message.body?.output || "").includes( "injected one transient connection loss" ), 30_000 ); assert( observerReconnect.seq < taskStop.seq, "observer reconnection must complete before the real breakpoint stop" ); assert.strictEqual( client.messages.filter( (message) => message.seq > mainStop.seq && message.seq < taskStop.seq && message.type === "event" && message.event === "stopped" ).length, 0, "observer reconnection fabricated a stopped target before the real breakpoint" ); assert.notStrictEqual(taskStop.body.threadId, mainStop.body.threadId); const reconnectDiagnostics = [ "runtime observer injected one transient connection loss", "runtime snapshot observation failed", "runtime process observation failed", "runtime breakpoint and fallback event observation failed", "runtime Debug Epoch observation failed", ].map((diagnostic) => { const message = client.messages.find( (candidate) => candidate.seq > mainContinueResponse.seq && candidate.seq < taskStop.seq && candidate.type === "event" && candidate.event === "output" && String(candidate.body?.output || "").includes(diagnostic) ); assert( message, `observer reconnection evidence omitted diagnostic: ${diagnostic}` ); return String(message.body.output).trim(); }); const stackTrace = client.send("stackTrace", { threadId: taskStop.body.threadId, startFrame: 0, levels: 1, }); const taskFrames = (await client.response(stackTrace, "stackTrace")).body .stackFrames; assert.strictEqual(taskFrames[0].line, taskLine); const scopesRequest = client.send("scopes", { frameId: taskFrames[0].id }); const scopes = (await client.response(scopesRequest, "scopes")).body.scopes; const argsScope = scopes.find( (candidate) => candidate.name === "Task Args and Handles" ); const runtimeScope = scopes.find( (candidate) => candidate.name === "Clusterflux Runtime" ); assert(argsScope && runtimeScope); const taskArgs = await dapVariables(client, argsScope.variablesReference); assert( taskArgs.some( (variable) => variable.name === "arg_0" && String(variable.value).includes("0") ) ); const runtime = await dapVariables(client, runtimeScope.variablesReference); assert( runtime.some( (variable) => variable.name === "runtime_backend" && variable.value === "LiveServices" ) ); assert( runtime.some( (variable) => variable.name === "state" && variable.value === "Frozen" ) ); const dapProcess = runtime.find( (variable) => variable.name === "virtual_process_id" )?.value; assert.match(dapProcess || "", /^vp-[0-9a-f]{12}$/); const taskContinue = client.send("continue", { threadId: taskStop.body.threadId }); await client.response(taskContinue, "continue"); const failedStop = await client.waitFor( (message) => message.seq > taskStop.seq && message.type === "event" && message.event === "stopped" && message.body.reason === "exception", 5 * 60 * 1000 ); assert.strictEqual(failedStop.body.allThreadsStopped, false); const beforeEdit = runJson( clusterflux, ["task", "list", ...scope, "--process", dapProcess], { cwd: projectDir } ); const originalTaskEvent = rawTaskEvents(beforeEdit).find( (event) => event.task_definition === "task_trap" && event.terminal_state === "failed" ); assert(originalTaskEvent, "DAP restart entry omitted its original child event"); assert(originalTaskEvent.attempt_id, "failed attempt omitted its identity"); const originalTaskBody = `pub extern "C" fn task_trap(_input: i32) -> i32 { #[cfg(target_arch = "wasm32")] core::arch::wasm32::unreachable(); #[cfg(not(target_arch = "wasm32"))] panic!("intentional task trap") }`; const replacementTaskBody = `pub extern "C" fn task_trap(_input: i32) -> i32 { _input + 42 // strict hosted compatible restart probe }`; const editedSource = originalSource.replace(originalTaskBody, replacementTaskBody); assert.notStrictEqual(editedSource, originalSource); fs.writeFileSync(sourcePath, editedSource); const restartFrame = client.send("restartFrame", { frameId: taskFrames[0].id, }); const restartResponse = await client.response(restartFrame, "restartFrame"); const restartedStop = await client.waitFor( (message) => message.seq > restartResponse.seq && message.type === "event" && message.event === "stopped" && message.body.reason === "breakpoint" ); assert.strictEqual(restartedStop.body.allThreadsStopped, true); const restartedContinue = client.send("continue", { threadId: restartedStop.body.threadId, }); await client.response(restartedContinue, "continue"); const restartedNodeReport = await worker.waitFor( (value) => value.node_status === "completed" && value.virtual_thread === originalTaskEvent.task && value.task_assignment_response?.task_spec?.task_definition === "task_trap", "edited task to execute on the live restarted node", 5 * 60 * 1000 ); assert.strictEqual( restartedNodeReport.node_status, "completed", `edited task restart failed on the live node: ${JSON.stringify(restartedNodeReport)}` ); assert.match(restartedNodeReport.stdout_tail, /"SmallJson":42/); const restartedTask = restartedNodeReport.virtual_thread; const afterEdit = await waitForCli( "edited live task event", () => runJson(clusterflux, ["task", "list", ...scope, "--process", dapProcess], { cwd: projectDir, }), (tasks) => rawTaskEvents(tasks).some( (event) => event.task === restartedTask && event.terminal_state === "completed" && JSON.stringify(event.result) === JSON.stringify({ SmallJson: 42 }) ), 5 * 60 * 1000 ); const restartedEvent = rawTaskEvents(afterEdit).find( (event) => event.task === restartedTask && event.terminal_state === "completed" && JSON.stringify(event.result) === JSON.stringify({ SmallJson: 42 }) ); assert(restartedEvent, "replacement attempt omitted its completed event"); assert(restartedEvent.attempt_id, "replacement attempt omitted its identity"); assert.notStrictEqual(restartedEvent.attempt_id, originalTaskEvent.attempt_id); await client.waitFor( (message) => message.type === "event" && message.event === "terminated", 5 * 60 * 1000 ); const disconnectStartedAt = Date.now(); await client.close(); disconnected = true; const disconnectResponseMs = Date.now() - disconnectStartedAt; assert( disconnectResponseMs < 2_000, `disconnect blocked for ${disconnectResponseMs} ms` ); fs.writeFileSync(sourcePath, originalSource); sourceRestored = true; return { duration_ms: Date.now() - scenarioStartedAt, process: dapProcess, main_source_line: mainLine, task_breakpoint_line: taskLine, launch_started_without_breakpoint: true, configuration_response_ms: configurationResponseMs, pause_response_ms: pauseResponseMs, inspection_response_ms: inspectionResponseMs, breakpoint_response_ms: breakpointResponseMs, breakpoint_installation_ms: breakpointInstallationMs, continue_response_ms: continueResponseMs, disconnect_response_ms: disconnectResponseMs, pause_all_threads_stopped: mainStop.body.allThreadsStopped, task_all_threads_stopped: taskStop.body.allThreadsStopped, original_task_instance: originalTaskEvent.task, original_attempt: originalTaskEvent.attempt_id, restarted_task_instance: restartedTask, restarted_attempt: restartedEvent.attempt_id, restarted_result: restartedEvent.result, compatible_source_edit: "task_trap: trap -> input + 42", original_arguments_preserved: true, clean_vfs_boundary_used: true, breakpoint_install_failure_reported: true, real_breakpoint: { request: { source: sourcePath, line: taskLine, runtime_backend: "live-services", }, expected: "coordinator installation is verified before a real all-stop breakpoint event", observed: { installed_line: installedBreakpoint.body.breakpoint.line, stop_reason: taskStop.body.reason, stopped_line: taskFrames[0].line, all_threads_stopped: taskStop.body.allThreadsStopped, }, duration_ms: Math.max(1, realBreakpointMs), }, debug_interaction: { request: "Pause, inspect command_status, Continue, and Disconnect", expected: "each control remains responsive during observer recovery", observed: { pause_response_ms: pauseResponseMs, inspect_response_ms: inspectionResponseMs, continue_response_ms: continueResponseMs, disconnect_response_ms: disconnectResponseMs, pause_stop_reason: mainStop.body.reason, }, duration_ms: Math.max( 1, pauseResponseMs + inspectionResponseMs + continueResponseMs + disconnectResponseMs ), }, post_launch_observation_recovery: { fault_injections: initialObserverFaults, expected: "main_launched remains committed; reconnect; threads appear; no rollback or fabricated stop", observed: { threads: runningThreads, premature_stop_or_termination_events: prematureLaunchEvents.length, terminal_state: "completed after replacement attempt", }, duration_ms: postLaunchObservationRecoveryMs, }, observer_reconnection: { fault_injections: reconnectDiagnostics, expected: "all recoverable reads reconnect before the real breakpoint stop", observed: { real_stop_reason: taskStop.body.reason, false_stops_before_real_stop: 0, }, duration_ms: Date.now() - continueStartedAt, }, breakpoint_revisions: { expected: "revision 2 remains authoritative after delayed revision 1", delayed_revision: 1, authoritative_revision: 2, authoritative_line: newestRevisionInstalled.body.breakpoint.line, stale_completion_events: staleRevisionEvents.length, failure_revision: 3, recovery_revision: 4, observed: "newest revision verified; stale completion ignored", duration_ms: breakpointInstallationMs, }, observer_idle_request_rate_bound_per_second: 0.8, observer_reconnected_without_false_stop: true, observer_fallback_reconnected: true, observer_debug_epoch_wait_reconnected: true, }; } finally { if (!sourceRestored) fs.writeFileSync(sourcePath, originalSource); if (!disconnected) { await client.close().catch(() => { if (client.child.exitCode === null) client.child.kill("SIGKILL"); }); } } } function copyProjectControlState(sourceRoot, targetRoot) { const source = path.join(sourceRoot, ".clusterflux"); const target = path.join(targetRoot, ".clusterflux"); ensureDir(target); for (const file of ["session.json", "project.json"]) { const from = path.join(source, file); assert(fs.existsSync(from), `missing shared project control state ${from}`); fs.copyFileSync(from, path.join(target, file)); } fs.chmodSync(path.join(target, "session.json"), 0o600); const sourceNodes = path.join(source, "nodes"); assert(fs.existsSync(sourceNodes), "persisted node credential directory is missing"); fs.cpSync(sourceNodes, path.join(target, "nodes"), { recursive: true, force: true, }); } async function runHostedHelloBuild({ clusterflux, projectDir, scope, outputFile, }) { const startedAt = Date.now(); const runReport = runJson( clusterflux, ["run", "build", "--project", ".", "--json"], { cwd: projectDir } ); assert.strictEqual(runReport.status, "main_launched"); const tasks = await waitForCli( "hosted hello-build completion", () => runJson( clusterflux, ["task", "list", ...scope, "--process", runReport.process], { cwd: projectDir } ), (report) => { const events = rawTaskEvents(report); return events.some( (event) => event.task_definition === "compile" && event.terminal_state === "completed" ); }, 10 * 60 * 1000 ); const events = rawTaskEvents(tasks); assert( events.some( (event) => event.task_definition === "snapshot_current_project" && event.terminal_state === "completed" ) ); const released = await waitForCli( "hosted hello-build process release", () => runJson( clusterflux, ["process", "status", ...scope, "--process", runReport.process], { cwd: projectDir } ), (status) => status.state === "not_active", 120_000 ); const artifacts = runJson( clusterflux, ["artifact", "list", ...scope, "--process", runReport.process], { cwd: projectDir } ); const artifact = artifacts.artifacts.find( (candidate) => typeof candidate.digest === "string" && /^sha256:[0-9a-f]{64}$/.test(candidate.digest) && candidate.artifact.startsWith("hello-clusterflux-") ); assert(artifact, "hello-build did not retain its executable artifact"); await waitForCli( "hosted hello-build retaining node online", () => runJson(clusterflux, ["node", "list", ...scope], { cwd: projectDir }), (report) => report.response?.descriptors?.some( (descriptor) => descriptor.online === true && descriptor.artifact_locations?.includes(artifact.artifact) ), 120_000 ); const download = runJson( clusterflux, [ "artifact", "download", ...scope, artifact.artifact, "--to", outputFile, ], { cwd: projectDir } ); assert.strictEqual(download.local_download.verified_digest, artifact.digest); assert.strictEqual(sha256(fs.readFileSync(outputFile)), artifact.digest); fs.chmodSync(outputFile, 0o755); const output = run(outputFile, []).trim(); assert.strictEqual(output, "hello from a real Clusterflux build"); return { duration_ms: Date.now() - startedAt, process: runReport.process, terminal_state: released.state, artifact: artifact.artifact, digest: artifact.digest, downloaded_bytes: download.local_download.bytes_written, downloaded_sha256: sha256(fs.readFileSync(outputFile)), executable_output: output, }; } async function runHostedRecoveryBuild({ clusterfluxDap, clusterflux, projectDir, scope, }) { const startedAt = Date.now(); const sourcePath = fs.realpathSync(path.join(projectDir, "src/lib.rs")); const original = fs.readFileSync(sourcePath, "utf8"); const failing = '"exit 23".to_owned()'; const replacement = '"printf \'recovered\\n\' > /clusterflux/output/recovering.txt".to_owned()'; assert(original.includes(failing)); const client = new DapClient({ cwd: projectDir, command: clusterfluxDap, env: { ...process.env, CLUSTERFLUX_DAP_TIMEOUT_MS: "120000" }, }); let restored = false; let closed = false; try { const initialize = client.send("initialize", { adapterID: "clusterflux", linesStartAt1: true, columnsStartAt1: true, }); await client.response(initialize, "initialize"); const launch = client.send("launch", { entry: "build", project: projectDir, runtimeBackend: "live-services", coordinatorEndpoint: serviceEndpoint, }); await client.response(launch, "launch"); await client.waitFor( (message) => message.type === "event" && message.event === "initialized" ); const configured = client.send("configurationDone"); await client.response(configured, "configurationDone"); const failedStop = await client.waitFor( (message) => message.type === "event" && message.event === "stopped" && message.body.reason === "exception", 10 * 60 * 1000 ); assert.strictEqual(failedStop.body.allThreadsStopped, false); const threadRequest = client.send("threads"); const threads = (await client.response(threadRequest, "threads")).body.threads; const recoveringThread = threads.find((thread) => /build lane/.test(thread.name)); assert(recoveringThread, "recovery-build failed lane is not visible in DAP"); const processId = threads .map((thread) => /vp-[0-9a-f]{12}/.exec(thread.name)?.[0]) .find(Boolean); assert(processId, "recovery-build DAP threads omitted the process identity"); const before = runJson( clusterflux, ["task", "list", ...scope, "--process", processId], { cwd: projectDir } ); const beforeEvents = rawTaskEvents(before); const originalFailure = beforeEvents.find( (event) => event.task_definition === "build_lane" && event.terminal_state === "failed" ); assert(originalFailure?.attempt_id); assert( beforeEvents.some( (event) => event.task_definition === "build_lane" && event.task !== originalFailure.task && event.terminal_state === "completed" ) ); const waiting = runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ); assert.strictEqual(waiting.live_process.main_state, "running"); fs.writeFileSync(sourcePath, original.replace(failing, replacement)); const restart = client.send("restartFrame", { threadId: recoveringThread.id, }); await client.response(restart, "restartFrame"); await client.waitFor( (message) => message.type === "event" && message.event === "terminated", 10 * 60 * 1000 ); assert( client.messages.some( (message) => message.type === "event" && message.event === "thread" && message.body.reason === "exited" && message.body.threadId === recoveringThread.id ) ); const after = await waitForCli( "hosted recovery replacement event", () => runJson( clusterflux, ["task", "list", ...scope, "--process", processId], { cwd: projectDir } ), (report) => rawTaskEvents(report).some( (event) => event.task === originalFailure.task && event.terminal_state === "completed" ), 120_000 ); const replacementEvent = rawTaskEvents(after).find( (event) => event.task === originalFailure.task && event.terminal_state === "completed" ); assert(replacementEvent?.attempt_id); assert.notStrictEqual(replacementEvent.attempt_id, originalFailure.attempt_id); assert( rawTaskEvents(after).some( (event) => event.executor === "coordinator_main" && event.terminal_state === "completed" ), "replacement result did not satisfy the original coordinator-main join" ); const artifacts = runJson( clusterflux, ["artifact", "list", ...scope, "--process", processId], { cwd: projectDir } ).artifacts; assert(artifacts.some((artifact) => artifact.artifact.startsWith("stable.txt-"))); assert( artifacts.some((artifact) => artifact.artifact.startsWith("recovering.txt-")) ); const released = await waitForCli( "hosted recovery process release", () => runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ), (status) => status.state === "not_active", 120_000 ); fs.writeFileSync(sourcePath, original); restored = true; await client.close(); closed = true; return { duration_ms: Date.now() - startedAt, process: processId, logical_task: originalFailure.task, original_attempt: originalFailure.attempt_id, replacement_attempt: replacementEvent.attempt_id, original_join_completed: true, terminal_state: released.state, }; } finally { if (!restored) fs.writeFileSync(sourcePath, original); if (!closed) { await client.close().catch(() => { if (client.child.exitCode === null) client.child.kill("SIGKILL"); }); } } } async function main() { requireEnabled(); const manifest = readJson(manifestPath); for (const asset of manifest.assets ?? []) { asset.file = path.isAbsolute(asset.file) ? asset.file : path.resolve(path.dirname(manifestPath), asset.file); } assert.strictEqual(manifest.kind, "clusterflux-public-release"); assert.strictEqual(manifest.default_hosted_coordinator_endpoint, serviceEndpoint); assert.strictEqual(serviceAddr, "clusterflux.michelpaulissen.com:443"); const qualityGates = strictQualityGateEvidence(manifest); const workRoot = fs.mkdtempSync(path.join(os.tmpdir(), "clusterflux-cli-happy-")); const installDir = path.join(workRoot, "install"); const checkout = path.join(workRoot, "public-repo"); const downloadPath = path.join(workRoot, "release.tar"); const extractedArtifact = path.join(workRoot, "artifact"); ensureDir(installDir); run("tar", ["-xzf", binaryArchive(manifest), "-C", installDir]); const publicSource = stagePublicCheckout(manifest, checkout); const clusterflux = executable(installDir, "clusterflux"); const clusterfluxNode = executable(installDir, "clusterflux-node"); const clusterfluxDap = executable(installDir, "clusterflux-debug-dap"); const projectDir = path.join(checkout, "tests/fixtures/runtime-conformance"); const helloProjectDir = path.join(checkout, "examples/hello-build"); const recoveryProjectDir = path.join(checkout, "examples/recovery-build"); const suffix = String(Date.now()); const workerNode = `worker-${suffix}`; const loginStartedAt = Date.now(); let loginSession; let receivedDefaultProject; if (reuseSessionFile) { const sourceSessionPath = path.resolve(reuseSessionFile); const sourceProjectPath = path.join(path.dirname(sourceSessionPath), "project.json"); const sourceSession = readJson(sourceSessionPath); const sourceProject = readJson(sourceProjectPath); assert.strictEqual(sourceSession.kind, "human"); assert.strictEqual(sourceSession.coordinator, serviceEndpoint); assert.strictEqual(sourceProject.coordinator, serviceEndpoint); assert.strictEqual(sourceProject.tenant, sourceSession.tenant); assert.strictEqual(sourceProject.project, sourceSession.project); assert.strictEqual(sourceProject.user, sourceSession.user); assert( Number(sourceSession.expires_at) > Math.floor(Date.now() / 1000) + 300, "reused CLI session expires too soon for the live journey" ); const destinationConfig = path.join(projectDir, ".clusterflux"); ensureDir(destinationConfig); fs.copyFileSync(sourceSessionPath, path.join(destinationConfig, "session.json")); fs.copyFileSync(sourceProjectPath, path.join(destinationConfig, "project.json")); fs.chmodSync(path.join(destinationConfig, "session.json"), 0o600); fs.chmodSync(path.join(destinationConfig, "project.json"), 0o644); loginSession = sourceSession; receivedDefaultProject = true; } else { const login = runJson( clusterflux, ["login", "--browser", "--json"], { cwd: projectDir, env: { ...process.env, CLUSTERFLUX_BROWSER_OPEN_COMMAND: browserOpenCommand }, } ); assert.strictEqual(login.plan.coordinator, serviceEndpoint); assert.strictEqual(login.boundary.scoped_cli_session_received, true); assert.strictEqual(login.boundary.provider_tokens_exposed_to_cli, false); assert.strictEqual(login.boundary.provider_tokens_sent_to_nodes, false); loginSession = login.coordinator_response.session; assert(loginSession, "hosted browser login omitted its scoped session"); receivedDefaultProject = typeof loginSession.project === "string" && loginSession.project.length > 0; assert(receivedDefaultProject, "login did not return its server-owned project"); } const sessionSecret = loginSession.cli_session_secret || loginSession.session_secret; const loginDurationMs = Math.max(1, Date.now() - loginStartedAt); assert(sessionSecret, "hosted browser login omitted the CLI session credential"); const tenant = loginSession.tenant; const project = loginSession.project; const user = loginSession.user; for (const [name, value] of Object.entries({ tenant, project, user })) { assert.strictEqual(typeof value, "string", `hosted session omitted ${name}`); assert.notStrictEqual(value, "", `hosted session returned an empty ${name}`); } const scope = [ "--coordinator", serviceEndpoint, "--tenant", tenant, "--project-id", project, "--user", user, "--json", ]; if (!reuseSessionFile) { const projectInit = runJson( clusterflux, [ "project", "init", ...scope, "--new-project", project, "--name", "CLI Happy Path", "--yes", ], { cwd: projectDir } ); assert.strictEqual(projectInit.command, "project init"); assert.strictEqual(projectInit.project_config_written, true); assert.strictEqual(projectInit.coordinator_response.type, "project_created"); } const projectList = runJson(clusterflux, ["project", "list", ...scope], { cwd: projectDir, }); assert(projectList.project_count >= 1); const projectSelect = runJson( clusterflux, ["project", "select", ...scope, project], { cwd: projectDir } ); assert.strictEqual(projectSelect.command, "project select"); const inspection = runJson(clusterflux, ["inspect", "--project", ".", "--json"], { cwd: projectDir, }); assert( inspection.metadata.environments.some((environment) => environment.name === "linux") ); assert(Array.isArray(inspection.source_provider_statuses)); assert(inspection.source_provider_manifest); const runReport = runJson( clusterflux, ["run", "build", "--project", ".", "--json"], { cwd: projectDir } ); assert.strictEqual(runReport.command, "run"); assert.strictEqual(runReport.status, "main_launched"); assert.strictEqual(runReport.task_launch.type, "main_launched"); const processId = runReport.process; const parkedStatus = await waitForCli( "hosted coordinator main to park before node enrollment", () => runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ), (status) => status.live_process?.main_state === "running" && status.live_process?.main_wait_state === "waiting_for_node" && status.live_process?.connected_nodes?.length === 0, 120000 ); const launchAttemptOwnership = await runLaunchAttemptOwnershipGuards({ clusterflux, projectDir, scope, sessionSecret, activeProcess: processId, }); const nodeLifecycleStartedAt = Date.now(); const grant = runJson(clusterflux, ["node", "enroll", ...scope], { cwd: projectDir, }); assert.strictEqual(grant.command, "node enroll"); const attach = runJson( clusterflux, [ "node", "attach", "--coordinator", serviceEndpoint, "--tenant", tenant, "--project-id", project, "--node", workerNode, "--enrollment-grant", grant.enrollment_grant.grant, "--json", ], { cwd: projectDir } ); assert.strictEqual(attach.command, "node attach"); assert.strictEqual(attach.boundary.used_enrollment_exchange, true); const credentialDir = path.join(projectDir, ".clusterflux", "nodes"); const credentialFiles = fs .readdirSync(credentialDir) .filter((file) => file.endsWith(".json")); assert.strictEqual(credentialFiles.length, 1, "expected one persisted node credential"); const credentialPath = path.join(credentialDir, credentialFiles[0]); const credentialBefore = fs.readFileSync(credentialPath); const credentialDigest = sha256(credentialBefore); if (process.platform !== "win32") { assert.strictEqual(fs.statSync(credentialPath).mode & 0o777, 0o600); } const workerArgsFor = (projectRoot) => [ "--coordinator", serviceEndpoint, "--tenant", tenant, "--project-id", project, "--node", workerNode, "--worker", "--project-root", projectRoot, "--assignment-poll-ms", "500", "--emit-ready", ]; const workerArgs = workerArgsFor(projectDir); const spawnWorker = (projectRoot = projectDir) => spawnJsonLines(clusterfluxNode, workerArgsFor(projectRoot), { cwd: projectRoot, env: { ...process.env }, }); let worker = spawnWorker(); try { const firstReady = await worker.waitFor( (value) => value.node_status === "ready", "first persisted worker ready" ); assert.strictEqual(firstReady.node, workerNode); const initiallyOnline = runJson( clusterflux, ["node", "status", ...scope, "--node", workerNode], { cwd: projectDir } ); assert.strictEqual(nodeDescriptor(initiallyOnline, workerNode)?.online, true); const completedTasks = await waitForCli( "real hosted flagship completion", () => runJson(clusterflux, ["task", "list", ...scope, "--process", processId], { cwd: projectDir, }), (tasks) => completedFlagship(rawTaskEvents(tasks)) ); const firstEvents = rawTaskEvents(completedTasks); assert( firstEvents .filter((event) => event.executor === "node") .every((event) => event.node === workerNode) ); assert( firstEvents.some( (event) => event.task_definition === "package_release" && event.terminal_state === "completed" && contentAddressedArtifactId(event, "release.tar") ) ); const releasedFlagshipStatus = await waitForCli( "completed flagship process to release its active slot", () => runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ), (status) => status.state === "not_active", 120000 ); const offlineStartedAt = Date.now(); await stopChild(worker.child); const observedOffline = await waitForCli( "server-derived worker stale/offline transition", () => runJson(clusterflux, ["node", "status", ...scope, "--node", workerNode], { cwd: projectDir, }), (status) => nodeDescriptor(status, workerNode)?.online === false, 120000 ); worker = spawnWorker(); const secondReady = await worker.waitFor( (value) => value.node_status === "ready", "restarted persisted worker ready" ); assert.strictEqual(secondReady.node, workerNode); assert.strictEqual(sha256(fs.readFileSync(credentialPath)), credentialDigest); const nodeStatus = await waitForCli( "server-derived worker online recovery", () => runJson(clusterflux, ["node", "status", ...scope, "--node", workerNode], { cwd: projectDir, }), (status) => nodeDescriptor(status, workerNode)?.online === true, 30000 ); assert(JSON.stringify(nodeStatus.response).includes(workerNode)); assert.strictEqual(sha256(fs.readFileSync(credentialPath)), credentialDigest); const nodeLivenessTransition = { initial_online: nodeDescriptor(initiallyOnline, workerNode).online, stale_offline: nodeDescriptor(observedOffline, workerNode).online, recovered_online: nodeDescriptor(nodeStatus, workerNode).online, offline_detection_ms: Date.now() - offlineStartedAt, persisted_identity_reused: true, duration_ms: Math.max(1, Date.now() - nodeLifecycleStartedAt), }; const processStatus = runJson( clusterflux, ["process", "status", ...scope, "--process", processId], { cwd: projectDir } ); assert.strictEqual(processStatus.command, "process status"); assert(processStatus.current_task_count >= firstEvents.length); const logs = runJson( clusterflux, ["logs", ...scope, "--process", processId], { cwd: projectDir } ); assert(logs.log_entries.length >= 4); const artifacts = runJson( clusterflux, ["artifact", "list", ...scope, "--process", processId], { cwd: projectDir } ); const releaseArtifact = artifacts.artifacts.find((artifact) => { const digest = artifact.digest; return ( typeof digest === "string" && /^sha256:[0-9a-f]{64}$/.test(digest) && artifact.artifact === `release.tar-${digest.slice("sha256:".length)}` ); }); assert(releaseArtifact, "hosted flagship did not publish release.tar"); assert.strictEqual(releaseArtifact.state, "metadata_flushed"); const download = runJson( clusterflux, [ "artifact", "download", ...scope, releaseArtifact.artifact, "--to", downloadPath, ], { cwd: projectDir } ); assert.strictEqual(download.download_session.link_issued, true); assert.strictEqual(download.local_download.local_bytes_written_by_cli, true); assert.strictEqual(download.local_download.verified_digest, releaseArtifact.digest); assert.strictEqual(sha256(fs.readFileSync(downloadPath)), releaseArtifact.digest); ensureDir(extractedArtifact); const archiveEntries = run("tar", ["-tf", downloadPath]); assert.match(archiveEntries, /(?:^|\n)hello-clusterflux(?:\n|$)/); run("tar", ["-xf", downloadPath, "-C", extractedArtifact]); const builtExecutable = path.join(extractedArtifact, "hello-clusterflux"); assert(fs.existsSync(builtExecutable)); const builtOutput = run(builtExecutable, []).trim(); assert.strictEqual(builtOutput, "hello from a real Clusterflux build"); copyProjectControlState(projectDir, helloProjectDir); copyProjectControlState(projectDir, recoveryProjectDir); await stopChild(worker.child); worker = spawnWorker(helloProjectDir); await worker.waitFor( (value) => value.node_status === "ready", "hello-build worker ready" ); const helloBuild = await runHostedHelloBuild({ clusterflux, projectDir: helloProjectDir, scope, outputFile: path.join(workRoot, "hello-clusterflux"), }); await stopChild(worker.child); worker = spawnWorker(recoveryProjectDir); await worker.waitFor( (value) => value.node_status === "ready", "recovery-build worker ready" ); const recoveryBuild = await runHostedRecoveryBuild({ clusterfluxDap, clusterflux, projectDir: recoveryProjectDir, scope, }); await stopChild(worker.child); worker = spawnWorker(); await worker.waitFor( (value) => value.node_status === "ready", "runtime-conformance worker restored" ); const dapEditRestart = await runLiveDapEditRestart({ clusterfluxDap, clusterflux, projectDir, scope, worker, }); const processCancellationStartedAt = Date.now(); const restart = runJson( clusterflux, ["process", "restart", ...scope, "--process", dapEditRestart.process, "--yes"], { cwd: projectDir } ); assert.strictEqual(restart.restart_request.accepted, true); const cancel = runJson( clusterflux, ["process", "cancel", ...scope, "--process", dapEditRestart.process, "--yes"], { cwd: projectDir } ); assert.strictEqual(cancel.cancel_request.accepted, true); const releasedDap = await waitForCli( "cancelled DAP process slot release", () => runJson( clusterflux, ["process", "status", ...scope, "--process", dapEditRestart.process], { cwd: projectDir } ), (status) => status.state === "not_active", 120000 ); assert.strictEqual(releasedDap.state, "not_active"); const processCancellationLifecycle = { request: { restart_process: dapEditRestart.process, cancel_process: dapEditRestart.process, }, expected: "explicit process cancellation terminates active participants and releases the slot", observed: { restart_accepted: restart.restart_request.accepted, cancel_accepted: cancel.cancel_request.accepted, terminal_state: releasedDap.state, }, duration_ms: Math.max(1, Date.now() - processCancellationStartedAt), }; const identityWorkerNode = `identity-worker-${suffix}`; const identityWorkerGrant = runJson( clusterflux, ["node", "enroll", ...scope], { cwd: projectDir } ); runJson( clusterflux, [ "node", "attach", "--coordinator", serviceEndpoint, "--tenant", tenant, "--project-id", project, "--node", identityWorkerNode, "--enrollment-grant", identityWorkerGrant.enrollment_grant.grant, "--json", ], { cwd: projectDir } ); const identityWorker = spawnJsonLines( clusterfluxNode, [ "--coordinator", serviceEndpoint, "--tenant", tenant, "--project-id", project, "--node", identityWorkerNode, "--worker", "--project-root", projectDir, "--assignment-poll-ms", "500", "--emit-ready", ], { cwd: projectDir, env: { ...process.env } } ); let sameDefinitionIdentity; try { const identityWorkerReady = await identityWorker.waitFor( (value) => value.node_status === "ready", "same-definition identity worker ready" ); assert.strictEqual(identityWorkerReady.node, identityWorkerNode); await waitForCli( "same-definition identity worker online", () => runJson( clusterflux, ["node", "status", ...scope, "--node", identityWorkerNode], { cwd: projectDir } ), (status) => nodeDescriptor(status, identityWorkerNode)?.online === true, 30_000 ); await stopChild(worker.child); worker = spawnWorker(); const refreshedPrimaryReady = await worker.waitFor( (value) => value.node_status === "ready", "same-definition primary worker capability refresh" ); assert.strictEqual(refreshedPrimaryReady.node, workerNode); const primaryStatus = await waitForCli( "same-definition primary worker online after refresh", () => runJson( clusterflux, ["node", "status", ...scope, "--node", workerNode], { cwd: projectDir } ), (status) => nodeDescriptor(status, workerNode)?.online === true, 30_000 ); const identityStatus = runJson( clusterflux, ["node", "status", ...scope, "--node", identityWorkerNode], { cwd: projectDir } ); const primarySnapshots = nodeDescriptor(primaryStatus, workerNode)?.source_snapshots || []; const identitySnapshots = nodeDescriptor(identityStatus, identityWorkerNode)?.source_snapshots || []; assert( primarySnapshots.some((snapshot) => identitySnapshots.includes(snapshot)), `same-definition workers do not share a current source snapshot: ${JSON.stringify({ primarySnapshots, identitySnapshots, })}` ); sameDefinitionIdentity = await runSameDefinitionDapIdentity({ clusterfluxDap, clusterflux, projectDir, scope, }); } finally { await stopChild(identityWorker.child); runJson( clusterflux, ["node", "revoke", ...scope, "--node", identityWorkerNode, "--yes"], { cwd: projectDir } ); } const repeatedParkWake = await runRepeatedParkWakeProof({ clusterflux, projectDir, scope, }); const longJoin = await runLongJoinProof({ clusterflux, projectDir, scope, }); await stopChild(worker.child); const tenantIsolationResult = await runSecondTenantIsolation({ clusterflux, clusterfluxNode, firstScope: scope, firstHelloBuild: helloBuild, firstHelloProjectDir: helloProjectDir, workRoot, firstSessionSecret: sessionSecret, firstTenant: tenant, firstProject: project, firstProcess: dapEditRestart.process, firstNode: workerNode, firstArtifact: releaseArtifact.artifact, manifest, }); const tenantIsolation = tenantIsolationResult.evidence; const scopedCollisionRuntime = tenantIsolationResult.runtime; worker = spawnWorker(); const collisionRecoveryReady = await worker.waitFor( (value) => value.node_status === "ready", "primary worker restored after two-tenant collision proof" ); assert.strictEqual(collisionRecoveryReady.node, workerNode); const securityNode = await prepareLiveNodeCredentialSecurity({ clusterflux, projectDir, scope, tenant, project, suffix, bundle: { digest: runReport.bundle_digest, moduleBase64: fs .readFileSync( path.resolve(projectDir, runReport.bundle_build.bundle_artifact.module) ) .toString("base64"), entryExport: runReport.entry_export, entryStableId: runReport.entry_stable_id, }, }); const droppedConnectionRollback = await runDroppedConnectionRollback({ clusterflux, projectDir, scope, }); const bandwidthPreallocation = await runLiveBandwidthPreallocation({ sessionSecret, artifact: releaseArtifact.artifact, maxBytes: download.local_download.bytes_written, }); await stopChild(worker.child); const relayEmergencyDisableResult = await runRelayEmergencyDisable({ clusterflux, clusterfluxNode, projectDir, scope, workerArgs, sessionSecret, maxBytes: download.local_download.bytes_written, }); worker = relayEmergencyDisableResult.worker; const relayEmergencyDisable = relayEmergencyDisableResult.evidence; const agentCredentialSecurity = await runLiveAgentCredentialSecurity({ clusterfluxDap, clusterflux, projectDir, scope, sessionSecret, tenant, project, suffix, bundle: { digest: runReport.bundle_digest, moduleBase64: fs .readFileSync( path.resolve(projectDir, runReport.bundle_build.bundle_artifact.module) ) .toString("base64"), entryExport: runReport.entry_export, entryStableId: runReport.entry_stable_id, }, securityNode, workerRuntime: { node: workerNode, child: worker.child, worker, identity: nodeIdentityFromPrivateKey( readNodeCredential(projectDir, workerNode).credential.private_key ), }, }); const mainBeforeChildLifecycle = agentCredentialSecurity.main_before_child_lifecycle; await stopChild(worker.child); const liveSoak = await runLiveSoak({ clusterflux, projectDir, scope, securityNode, }); const malformedIdentifiers = await runMalformedIdentifierSuite({ clusterflux, projectDir, scope, sessionSecret, tenant, project, user, suffix, securityNode, bundle: { digest: runReport.bundle_digest, moduleBase64: fs .readFileSync( path.resolve(projectDir, runReport.bundle_build.bundle_artifact.module) ) .toString("base64"), entryExport: runReport.entry_export, entryStableId: runReport.entry_stable_id, }, releaseArtifact, }); const signedHostileArtifactPath = await runLiveSignedHostileArtifactPath({ clusterflux, projectDir, scope, tenant, project, suffix, securityNode, }); const revokedNodeCredential = await revokeSecurityNode({ clusterflux, projectDir, scope, securityNode, }); const quotaPreallocation = await runLiveQuotaPreallocation({ sessionSecret, suffix, }); const hostedLoginIsolation = await runHostedLoginIsolationBeforeRestart(); const serviceRestart = await restartHostedServiceAndResume({ clusterflux, clusterfluxNode, projectDir, scope, workerArgs, workerNode, credentialPath, credentialDigest, scopedCollisionRuntime, }); if (serviceRestart.worker) worker = serviceRestart.worker; const scopedNodeRevocationAfterRestart = scopedCollisionRuntime ? await finishScopedNodeCollisionAfterRestart({ clusterflux, projectDir, scope, workerNode, scopedCollisionRuntime, }) : { executed: false, reason: "second tenant runtime session was not supplied", duration_ms: 1, }; const relayAfterRestart = relayDurableState(); assert( relayAfterRestart.ingress_used >= bandwidthPreallocation.durable_after_release.ingress_used ); assert( relayAfterRestart.egress_used >= bandwidthPreallocation.durable_after_release.egress_used ); assert( relayAfterRestart.abandoned_or_failed_used >= bandwidthPreallocation.durable_after_release.abandoned_or_failed_used ); bandwidthPreallocation.durable_after_restart = relayAfterRestart; bandwidthPreallocation.restart_persistence = true; bandwidthPreallocation.duration_ms = Date.now() - bandwidthPreallocation.scenario_started_at_ms; delete bandwidthPreallocation.scenario_started_at_ms; await finishHostedLoginIsolationAfterRestart(hostedLoginIsolation); const userCredentialSecurity = await finishUserCredentialSecurity({ clusterflux, projectDir, scope, sessionSecret, }); const configProvenance = configurationProvenance(); const proxyConfigProvenance = proxyConfigurationProvenance(); const concurrentCompileTasks = [ ...new Set( firstEvents .filter( (event) => event.task_definition === "compile_linux" && event.terminal_state === "completed" ) .map((event) => event.task) ), ]; assert(concurrentCompileTasks.length >= 2); const extensionAsset = manifest.assets.find((asset) => asset.name.endsWith(".vsix") ); const requirement = ({ id, passed, evidence, durationMs }) => { const result = { id, passed: passed === true, evidence, }; if (Number.isFinite(durationMs) && durationMs > 0) { result.duration_ms = durationMs; } else if (strictFullRelease) { throw new Error( `strict release scenario ${id} omitted a measured positive duration` ); } return result; }; const qualityCheck = (id) => qualityGates?.checks?.[id]; const nodeEnrollmentEvidence = { request: "one-time enrollment followed by a grant-free worker restart", expected: "the persisted node credential is reused unchanged", observed: { used_enrollment_exchange: attach.boundary.used_enrollment_exchange, restarted_node: secondReady.node, credential_digest: credentialDigest, liveness: nodeLivenessTransition, service_restart_executed: serviceRestart.executed, }, }; const loginEvidence = { request: reuseSessionFile ? "reuse a still-valid scoped browser-login session" : "perform browser OIDC login", expected: "server-owned default project persists and can be selected", observed: { fresh_login: !reuseSessionFile, tenant, project, user, received_default_project: receivedDefaultProject, project_select_command: projectSelect.command, }, }; const credentialSecurityEvidence = { expected: "forged, replayed, expired, body-modified, and revoked user/Node/Agent credentials are denied", observed: { user: userCredentialSecurity, node: { initial: securityNode.evidence, revoked: revokedNodeCredential.denied, }, agent: { replay: agentCredentialSecurity.replay, expired: agentCredentialSecurity.expired, forged: agentCredentialSecurity.forged, body_modified: agentCredentialSecurity.body_modified, revoked: agentCredentialSecurity.revoked, }, }, }; const credentialSecurityDurationMs = userCredentialSecurity.duration_ms + securityNode.duration_ms + revokedNodeCredential.duration_ms + agentCredentialSecurity.duration_ms; const relaySecurityEvidence = { expected: "limits are scoped independently and abandoned transfer bytes remain charged without a shared soft lockout", observed: { spawn_quota: quotaPreallocation, relay_accounting: bandwidthPreallocation, emergency_disable: relayEmergencyDisable, }, }; const relaySecurityDurationMs = quotaPreallocation.duration_ms + bandwidthPreallocation.duration_ms + relayEmergencyDisable.duration_ms; const strictRequirementLedger = [ requirement({ id: "01_formatting", passed: qualityCheck("formatting")?.status === "passed", evidence: qualityCheck("formatting"), durationMs: qualityCheck("formatting")?.duration_ms, }), requirement({ id: "02_clippy_warnings_denied", passed: qualityCheck("clippy_warnings_denied")?.status === "passed", evidence: qualityCheck("clippy_warnings_denied"), durationMs: qualityCheck("clippy_warnings_denied")?.duration_ms, }), requirement({ id: "03_public_workspace_tests", passed: qualityCheck("public_workspace_tests")?.status === "passed", evidence: qualityCheck("public_workspace_tests"), durationMs: qualityCheck("public_workspace_tests")?.duration_ms, }), requirement({ id: "04_private_hosted_policy_locked_tests", passed: qualityCheck("private_hosted_policy_locked_tests")?.status === "passed", evidence: qualityCheck("private_hosted_policy_locked_tests"), durationMs: qualityCheck("private_hosted_policy_locked_tests") ?.duration_ms, }), requirement({ id: "05_wasm_example_builds", passed: qualityCheck("wasm_example_builds")?.status === "passed", evidence: qualityCheck("wasm_example_builds"), durationMs: qualityCheck("wasm_example_builds")?.duration_ms, }), requirement({ id: "06_filtered_public_tree_build_and_tests", passed: qualityCheck("filtered_public_tree_build_and_tests")?.status === "passed", evidence: qualityCheck("filtered_public_tree_build_and_tests"), durationMs: qualityCheck("filtered_public_tree_build_and_tests") ?.duration_ms, }), requirement({ id: "07_final_vsix_checks", passed: Boolean( extensionAsset && qualityCheck("vscode_extension_candidate")?.status === "passed" && extensionAsset.sha256 === manifest.release_candidate.extension_sha256 && qualityCheck("vscode_extension_candidate")?.candidate_vsix ?.sha256 === extensionAsset.sha256 ), evidence: qualityCheck("vscode_extension_candidate"), durationMs: qualityCheck("vscode_extension_candidate")?.duration_ms, }), requirement({ id: "08_browser_login_and_persistent_default_project", passed: Boolean( sessionSecret && tenant && project && receivedDefaultProject && projectSelect.command === "project select" ), evidence: loginEvidence, durationMs: loginDurationMs, }), requirement({ id: "09_one_time_node_enrollment_and_restart", passed: attach.boundary.used_enrollment_exchange === true && secondReady.node === workerNode && nodeLivenessTransition.persisted_identity_reused === true && serviceRestart.executed === true, evidence: nodeEnrollmentEvidence, durationMs: nodeLivenessTransition.duration_ms, }), requirement({ id: "10_real_hello_build_and_artifact_download", passed: helloBuild.executable_output === "hello from a real Clusterflux build" && helloBuild.downloaded_bytes > 0 && helloBuild.downloaded_sha256 === helloBuild.digest, evidence: helloBuild, durationMs: helloBuild.duration_ms, }), requirement({ id: "11_recovery_retry_and_original_join", passed: recoveryBuild.original_join_completed === true && recoveryBuild.original_attempt !== recoveryBuild.replacement_attempt && recoveryBuild.terminal_state === "not_active", evidence: recoveryBuild, durationMs: recoveryBuild.duration_ms, }), requirement({ id: "12_long_lived_coordinator_main", passed: longJoin.duration_seconds > 120 && longJoin.terminal_state === "completed" && longJoin.process_state === "not_active", evidence: longJoin, durationMs: longJoin.duration_ms, }), requirement({ id: "13_main_completes_before_child_lifecycle", passed: mainBeforeChildLifecycle.observed.active_after_main === true && mainBeforeChildLifecycle.observed.debug_state_after_main === "debug_breakpoints" && mainBeforeChildLifecycle.observed.child_terminal_state === "completed" && mainBeforeChildLifecycle.observed.final_process_state === "not_active" && mainBeforeChildLifecycle.observed.subsequent_run_status === "main_launched" && qualityCheck("process_lifecycle_regressions")?.status === "passed", evidence: { live: mainBeforeChildLifecycle, compiled_failure_and_cancellation: qualityCheck("process_lifecycle_regressions"), }, durationMs: mainBeforeChildLifecycle.duration_ms + (qualityCheck("process_lifecycle_regressions")?.duration_ms || 0), }), requirement({ id: "14_dap_launch_without_breakpoint", passed: sameDefinitionIdentity.launch_without_breakpoint.observed.thread_id > 0 && sameDefinitionIdentity.terminal_state === "not_active", evidence: sameDefinitionIdentity.launch_without_breakpoint, durationMs: sameDefinitionIdentity.launch_without_breakpoint.duration_ms, }), requirement({ id: "15_real_breakpoint_installation_and_hit", passed: dapEditRestart.real_breakpoint.observed.stop_reason === "breakpoint" && dapEditRestart.real_breakpoint.observed.stopped_line === dapEditRestart.real_breakpoint.request.line && dapEditRestart.real_breakpoint.observed.all_threads_stopped === true, evidence: dapEditRestart.real_breakpoint, durationMs: dapEditRestart.real_breakpoint.duration_ms, }), requirement({ id: "16_attach_with_preconfigured_breakpoint", passed: agentCredentialSecurity.attach_with_preconfigured_breakpoint .observed.initially_verified === false && agentCredentialSecurity.attach_with_preconfigured_breakpoint .observed.installation_event_verified === true && agentCredentialSecurity.attach_with_preconfigured_breakpoint .observed.stop_reason === "breakpoint" && agentCredentialSecurity.attach_with_preconfigured_breakpoint .observed.stopped_line === agentCredentialSecurity.attach_with_preconfigured_breakpoint .request.line, evidence: agentCredentialSecurity.attach_with_preconfigured_breakpoint, durationMs: agentCredentialSecurity.attach_with_preconfigured_breakpoint .duration_ms, }), requirement({ id: "17_breakpoint_revision_ordering", passed: dapEditRestart.breakpoint_revisions.authoritative_revision > dapEditRestart.breakpoint_revisions.delayed_revision && dapEditRestart.breakpoint_revisions.stale_completion_events === 0, evidence: dapEditRestart.breakpoint_revisions, durationMs: dapEditRestart.breakpoint_revisions.duration_ms, }), requirement({ id: "18_continue_pause_inspect_disconnect", passed: dapEditRestart.debug_interaction.observed.pause_response_ms < 2_000 && dapEditRestart.debug_interaction.observed.inspect_response_ms < 2_000 && dapEditRestart.debug_interaction.observed.continue_response_ms < 2_000 && dapEditRestart.debug_interaction.observed.disconnect_response_ms < 2_000, evidence: dapEditRestart.debug_interaction, durationMs: dapEditRestart.debug_interaction.duration_ms, }), requirement({ id: "19_distinct_same_definition_instances", passed: sameDefinitionIdentity.thread_evidence.length === 2 && sameDefinitionIdentity.completion_order.length === 2 && sameDefinitionIdentity.thread_evidence[0].task_instance !== sameDefinitionIdentity.thread_evidence[1].task_instance && sameDefinitionIdentity.thread_evidence[0].attempt_id !== sameDefinitionIdentity.thread_evidence[1].attempt_id && concurrentCompileTasks.length >= 2, evidence: sameDefinitionIdentity.same_definition_identity, durationMs: sameDefinitionIdentity.same_definition_identity.duration_ms, }), requirement({ id: "20_real_podman_partial_debug_epoch", passed: agentCredentialSecurity.partial_freeze.partially_frozen === true && agentCredentialSecurity.partial_freeze.dap_all_threads_stopped === false && agentCredentialSecurity.partial_freeze.podman_paused_container_ids .length > 0 && agentCredentialSecurity.partial_freeze.resumed_participants.length > 0, evidence: agentCredentialSecurity.partial_freeze, durationMs: agentCredentialSecurity.partial_freeze.elapsed_ms, }), requirement({ id: "21_post_main_launched_observation_recovery", passed: sameDefinitionIdentity.post_main_launched_observation_recovery .observed.diagnostics.length === 2 && sameDefinitionIdentity.post_main_launched_observation_recovery .observed .premature_stop_or_termination_events === 0 && sameDefinitionIdentity.post_main_launched_observation_recovery .observed.main_thread.id > 0, evidence: sameDefinitionIdentity.post_main_launched_observation_recovery, durationMs: sameDefinitionIdentity.post_main_launched_observation_recovery .duration_ms, }), requirement({ id: "22_observer_reconnection", passed: dapEditRestart.observer_reconnection.fault_injections.length === 5 && dapEditRestart.observer_reconnection.observed .false_stops_before_real_stop === 0 && dapEditRestart.observer_reconnection.observed.real_stop_reason === "breakpoint", evidence: dapEditRestart.observer_reconnection, durationMs: dapEditRestart.observer_reconnection.duration_ms, }), requirement({ id: "23_malformed_identifiers_preserve_service", passed: malformedIdentifiers.valid_after_every_rejection === true && malformedIdentifiers.all_rejected_for_intended_reason === true && malformedIdentifiers.valid_authenticated_action_after_suite === true && malformedIdentifiers.valid_signed_rendezvous_after_suite === true && malformedIdentifiers.rejected_requests.every( (entry) => Number.isFinite(entry.duration_ms) && entry.duration_ms > 0 ), evidence: malformedIdentifiers, durationMs: malformedIdentifiers.duration_ms, }), requirement({ id: "24_cross_tenant_access_denied", passed: tenantIsolation.executed === true && tenantIsolation.process_hidden === true && tenantIsolation.node_hidden === true && tenantIsolation.tasks_and_logs.denied === true && tenantIsolation.debug.denied === true && tenantIsolation.artifact_and_download.denied === true, evidence: tenantIsolation, durationMs: tenantIsolation.duration_ms, }), requirement({ id: "25_forged_replayed_expired_revoked_credentials_denied", passed: Boolean( userCredentialSecurity.expired && userCredentialSecurity.forged && userCredentialSecurity.revoked ) && securityNode.evidence.replay.denied === true && securityNode.evidence.expired.denied === true && securityNode.evidence.forged.denied === true && revokedNodeCredential.denied.denied === true && agentCredentialSecurity.revoked.denied === true, evidence: credentialSecurityEvidence, durationMs: credentialSecurityDurationMs, }), requirement({ id: "26_relay_limits_and_abandoned_transfer_charging", passed: quotaPreallocation.denied_process_allocated === false && quotaPreallocation.independent_scope .unaffected_by_spawn_quota === true && bandwidthPreallocation.bytes_served_before_denial > 0 && bandwidthPreallocation.partial_abandon.ingress_delta > 0 && bandwidthPreallocation.partial_abandon.egress_delta > 0 && bandwidthPreallocation.partial_abandon.abandoned_delta > 0 && bandwidthPreallocation.partial_abandon.reservation_released === true && bandwidthPreallocation.restart_persistence === true && relayEmergencyDisable.disabled.denied === true && relayEmergencyDisable.runtime_drop_in_removed === true, evidence: relaySecurityEvidence, durationMs: relaySecurityDurationMs, }), requirement({ id: "27_existing_process_rejection_preserves_process", passed: launchAttemptOwnership.existing_process_survived === true, evidence: launchAttemptOwnership, durationMs: launchAttemptOwnership.duration_ms, }), requirement({ id: "28_precommit_launch_failure_scoped_cleanup", passed: droppedConnectionRollback.cli_exit_status !== 0 && droppedConnectionRollback.rollback === "automatic CLI launch guard abort_process with matching launch_attempt" && droppedConnectionRollback.terminal_state === "not_active", evidence: droppedConnectionRollback, durationMs: droppedConnectionRollback.duration_ms, }), requirement({ id: "29_explicit_process_cancellation_cleanup", passed: processCancellationLifecycle.observed.restart_accepted === true && processCancellationLifecycle.observed.cancel_accepted === true && processCancellationLifecycle.observed.terminal_state === "not_active", evidence: processCancellationLifecycle, durationMs: processCancellationLifecycle.duration_ms, }), requirement({ id: "30_scoped_node_and_artifact_collision", passed: tenantIsolation.scoped_node_and_artifact_collision?.observed ?.both_metadata_records_visible_to_owner === true && tenantIsolation.scoped_node_and_artifact_collision?.observed ?.first_download_survived_second_link_revocation === true && tenantIsolation.scoped_node_and_artifact_collision?.observed ?.same_artifact_id === helloBuild.artifact && serviceRestart.scoped_node_collision_after_restart ?.first_scope_online === true && serviceRestart.scoped_node_collision_after_restart ?.second_scope_online === true && serviceRestart.scoped_node_collision_after_restart ?.both_credentials_reused_without_grants === true && scopedNodeRevocationAfterRestart.observed ?.revoked_credential_denied === true && scopedNodeRevocationAfterRestart.observed ?.first_scope_node_online === true, evidence: { live_collision: tenantIsolation.scoped_node_and_artifact_collision, restart: serviceRestart.scoped_node_collision_after_restart, scoped_revocation: scopedNodeRevocationAfterRestart, }, durationMs: tenantIsolation.scoped_node_and_artifact_collision?.duration_ms + scopedNodeRevocationAfterRestart.duration_ms, }), requirement({ id: "31_signed_hostile_artifact_path_preserves_service", passed: signedHostileArtifactPath.observed.rejection.denied === true && signedHostileArtifactPath.observed.valid_metadata_response === "vfs_metadata_recorded" && signedHostileArtifactPath.observed.health_response === "node_heartbeat" && signedHostileArtifactPath.observed.process_cleanup === "not_active", evidence: signedHostileArtifactPath, durationMs: signedHostileArtifactPath.duration_ms, }), ]; const fullReleasePassed = strictFullRelease && proxyConfigProvenance?.active_state === "active" && strictRequirementLedger.every((requirement) => requirement.passed === true); const namedScenarios = strictRequirementLedger.map((requirement) => ({ id: requirement.id, name: requirement.id .replace(/^\d+_/, "") .replaceAll("_", " "), status: requirement.passed ? "passed" : "failed", ...(requirement.duration_ms ? { duration_ms: requirement.duration_ms } : {}), })); const report = { kind: "clusterflux-cli-happy-path-live", release_name: manifest.release_name, source_commit: manifest.source_commit, source_tree_digest: manifest.source_tree_digest, public_tree_identity: manifest.public_tree_identity, binary_digests: manifest.binary_digests, service_addr: serviceAddr, default_hosted_coordinator_endpoint: serviceEndpoint, public_repository_url: publicSource.published ? publicSource.url : null, public_source: publicSource, tenant, project, worker_node: workerNode, process: processId, signed_in: true, fresh_hosted_login: !reuseSessionFile, reused_scoped_cli_session: Boolean(reuseSessionFile), received_default_project: receivedDefaultProject, process_started_before_node: true, parked_main_observed: { main_state: parkedStatus.live_process.main_state, main_wait_state: parkedStatus.live_process.main_wait_state, connected_nodes: parkedStatus.live_process.connected_nodes, }, node_enrollment_grants_used: 2, persisted_node_credential_mode: process.platform === "win32" ? null : fs.statSync(credentialPath).mode & 0o777, persisted_node_credential_digest: credentialDigest, node_restarted_without_grant: true, restarted_node_ready: secondReady.node, node_liveness_transition: nodeLivenessTransition, flagship_terminal_state: releasedFlagshipStatus.state, flagship_task_definitions: [ "prepare_source", "compile_linux", "package_release", ], rootless_podman_flagship_completed: true, downstream_release_artifact: releaseArtifact, artifact_download: { bytes_written: download.local_download.bytes_written, verified_digest: download.local_download.verified_digest, executable_output: builtOutput, }, flagship_process_released_automatically: true, concurrent_same_definition_tasks: sameDefinitionIdentity, flagship_same_definition_task_instances: concurrentCompileTasks, repeated_park_wake: repeatedParkWake, long_join: longJoin, main_before_child_lifecycle: mainBeforeChildLifecycle, live_dap_edit_restart: dapEditRestart, process_restart_requested: true, process_cancel_requested: true, dap_process_aborted: true, process_cancellation_lifecycle: processCancellationLifecycle, tenant_isolation: tenantIsolation, scoped_node_revocation_after_restart: scopedNodeRevocationAfterRestart, credential_security: { user: userCredentialSecurity, node: { node: securityNode.node, credential_digest: securityNode.credential_digest, ...securityNode.evidence, revoked: revokedNodeCredential.denied, }, agent: agentCredentialSecurity, }, quota_preallocation: quotaPreallocation, bandwidth_preallocation: bandwidthPreallocation, relay_emergency_disable: relayEmergencyDisable, hosted_login_isolation: hostedLoginIsolation, dropped_connection_rollback: droppedConnectionRollback, launch_attempt_ownership: launchAttemptOwnership, live_soak: liveSoak, hosted_service_restart: { ...serviceRestart, worker: undefined, }, release_binding: { manifest: manifestPath, source_commit: manifest.source_commit, source_tree_digest: manifest.source_tree_digest, source_tree_clean: manifest.source_tree_clean, public_tree_identity: manifest.public_tree_identity, binary_digests: manifest.binary_digests, release_candidate: manifest.release_candidate, deployment: serviceRestart.after || deploymentProvenance(), configuration: configProvenance, proxy_configuration: proxyConfigProvenance, }, commands, quality_gates: qualityGates, hello_build: helloBuild, recovery_build: recoveryBuild, malformed_identifiers: malformedIdentifiers, signed_hostile_artifact_path: signedHostileArtifactPath, named_scenarios: namedScenarios, scenario_skips: [], strict_requirement_ledger: strictRequirementLedger, acceptance_result: fullReleasePassed ? "passed" : "partial", }; ensureDir(path.dirname(reportPath)); fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`); if (strictFullRelease && !fullReleasePassed) { const failed = strictRequirementLedger .filter((requirement) => requirement.passed !== true) .map((requirement) => requirement.id); throw new Error(`strict full release failed: ${failed.join(", ")}`); } console.log(`CLI happy-path live smoke passed: ${reportPath}`); } finally { await stopChild(worker?.child); } } main().catch((error) => { console.error(error.stack || error.message); process.exit(1); });