import { randomUUID } from "node:crypto"; import { mkdir, readFile, writeFile } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { M3_IO_CHAIN, M3_IO_CONTROL_CONTRACT_VERSION, M3_IO_CONTROL_ROUTE, describeM3IoControl } from "../../internal/cloud/m3-io-control.mjs"; export const M3_IO_E2E_CONTRACT_VERSION = "m3-io-control-e2e-v1"; export const defaultFrontendUrl = "http://74.48.78.17:16666/"; export const defaultApiUrl = "http://74.48.78.17:16667/v1/m3/io"; export const controlPathReachablePersistenceBlocked = "control_path_reachable_trusted_persistence_blocked"; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const labels = Object.freeze({ source: "SOURCE", local: "LOCAL", dryRun: "DRY-RUN", devLive: "DEV-LIVE", blocked: "BLOCKED" }); const forbiddenLiveFlags = Object.freeze([ "--prod", "--production", "--real-hardware", "--read-secret", "--read-token", "--deploy", "--apply", "--restart", "--restart-runtime", "--restart-unidesk", "--restart-code-queue", "--restart-backend-core" ]); const valueFlags = new Set(["--report", "--output", "--url", "--api-url", "--target", "--timeout-ms"]); const booleanFlags = new Set([ "--live", "--confirm-dev", "--confirmed-non-production", "--expect-non-prod", "--source", "--source-static", "--dry-run", "--pretty", ...forbiddenLiveFlags ]); export function parseM3IoControlE2eArgs(argv = []) { const flags = new Set(); const values = new Map(); for (let index = 0; index < argv.length; index += 1) { const arg = argv[index]; if (!arg.startsWith("--")) { throw new Error(`unexpected positional argument: ${arg}`); } if (valueFlags.has(arg)) { const value = argv[index + 1]; if (!value || value.startsWith("--")) { throw new Error(`${arg} requires a value`); } values.set(arg.slice(2), value); index += 1; continue; } if (!booleanFlags.has(arg)) { throw new Error(`unknown flag: ${arg}`); } flags.add(arg); } const target = values.get("target") ?? (values.has("api-url") ? "api" : "frontend"); if (!["frontend", "api"].includes(target)) { throw new Error("--target must be frontend or api"); } const timeoutMs = parsePositiveInteger(values.get("timeout-ms"), 8000); return { flags, values, live: flags.has("--live"), source: flags.has("--source") || flags.has("--source-static"), dryRun: flags.has("--dry-run"), confirmDev: flags.has("--confirm-dev"), confirmedNonProduction: flags.has("--confirmed-non-production") || flags.has("--expect-non-prod"), target, frontendUrl: values.get("url") ?? defaultFrontendUrl, apiUrl: values.get("api-url") ?? defaultApiUrl, reportPath: values.get("report") ?? values.get("output") ?? null, timeoutMs, pretty: flags.has("--pretty") }; } export function requireM3IoControlE2eGates(args) { for (const flag of forbiddenLiveFlags) { if (args.flags.has(flag)) { throw new Error(`${flag} is forbidden for the DEV M3 IO control harness`); } } if (!args.live) { return { mode: "source-static", liveWriteAllowed: false, mutationAllowed: false }; } if (args.dryRun || args.source) { throw new Error("--live cannot be combined with --dry-run, --source, or --source-static"); } if (!args.confirmDev || !args.confirmedNonProduction) { throw new Error("live mode requires --live --confirm-dev --confirmed-non-production"); } return { mode: "dev-live", liveWriteAllowed: true, mutationAllowed: true }; } export function expectedM3IoLiveSequence() { return [ { id: "write-do1-true", method: "POST", path: M3_IO_CONTROL_ROUTE, action: "do.write", expectedValue: true, mutatesDevState: true, request: doWriteRequest(true) }, { id: "read-di1-true", method: "POST", path: M3_IO_CONTROL_ROUTE, action: "di.read", expectedValue: true, mutatesDevState: false, request: diReadRequest() }, { id: "write-do1-false", method: "POST", path: M3_IO_CONTROL_ROUTE, action: "do.write", expectedValue: false, mutatesDevState: true, request: doWriteRequest(false) }, { id: "read-di1-false", method: "POST", path: M3_IO_CONTROL_ROUTE, action: "di.read", expectedValue: false, mutatesDevState: false, request: diReadRequest() } ]; } export async function buildM3IoControlSourceReport(options = {}) { const root = options.repoRoot ?? repoRoot; const checks = await runM3IoControlSourceChecks({ repoRoot: root }); const classification = checks.every((check) => check.status === "pass") ? "source_static_contract_checked" : "source_contract_failed"; const status = classification === "source_static_contract_checked" ? "pass" : "blocked"; return { tool: "m3-io-control-e2e", contractVersion: M3_IO_E2E_CONTRACT_VERSION, mode: "source-static", sourceKind: labels.source, evidenceLabels: evidenceLabelDescriptions(), liveMutation: { attempted: false, allowed: false, reason: "Default SOURCE/static mode never POSTs to DEV and never mutates simulator state." }, endpoints: { frontendSameOriginBase: defaultFrontendUrl, frontendSameOriginPath: M3_IO_CONTROL_ROUTE, cloudApiPath: M3_IO_CONTROL_ROUTE, directCloudApiEndpoint: defaultApiUrl, gatewayBoxPatchPanelDirectCallsAllowed: false }, dryRunPlan: { sourceKind: labels.dryRun, liveWriteWillRun: false, sequence: expectedM3IoLiveSequence().map((step) => ({ id: step.id, method: step.method, path: step.path, action: step.action, expectedValue: step.expectedValue, mutatesDevState: step.mutatesDevState })) }, checks, summary: { status, classification, trustedGreen: false, observedAt: isoNow(), result: status === "pass" ? "SOURCE/static M3 IO control contract passed; DEV-LIVE was not run." : "SOURCE/static M3 IO control contract failed; DEV-LIVE must not run until fixed." } }; } export async function runM3IoControlSourceChecks({ repoRoot: root = repoRoot } = {}) { const [serverSource, jsonRpcSource, m3Source, appSource, htmlSource, artifactPublisherSource] = await Promise.all([ readRepoText(root, "internal/cloud/server.mjs"), readRepoText(root, "internal/cloud/json-rpc.mjs"), readRepoText(root, "internal/cloud/m3-io-control.mjs"), readRepoText(root, "web/hwlab-cloud-web/app.mjs"), readRepoText(root, "web/hwlab-cloud-web/index.html"), readRepoText(root, "scripts/dev-artifact-publish.mjs") ]); const contract = describeM3IoControl({ env: { HWLAB_M3_IO_CONTROL_ENABLED: "true" } }); const frontendGuardrails = checkFrontendNoDirectRuntimeCalls({ appSource, htmlSource, artifactPublisherSource }); const requestSchema = validateExpectedRequestSchemas(expectedM3IoLiveSequence()); const responseSchema = validateM3IoSourceResponseContract(m3Source); return [ checkResult( "route-name-contract", contract.route === M3_IO_CONTROL_ROUTE && M3_IO_CONTROL_ROUTE === "/v1/m3/io" && contract.contractVersion === M3_IO_CONTROL_CONTRACT_VERSION, "cloud-api route is /v1/m3/io with the m3-io-control-v1 contract.", { route: contract.route, contractVersion: contract.contractVersion, evidenceLevel: labels.source } ), checkResult( "m3-chain-contract", routeChainMatches(contract.chain), "M3 chain is box-simu-1 DO1 -> hwlab-patch-panel -> box-simu-2 DI1.", { chain: contract.chain, evidenceLevel: labels.source } ), checkResult( "cloud-api-rest-route-contract", serverSource.includes("url.pathname === M3_IO_CONTROL_ROUTE") && serverSource.includes("handleM3IoControlHttp") && serverSource.includes("m3IoControl: describeM3IoControl"), "cloud-api exposes GET/POST /v1/m3/io and advertises it from /v1.", { route: M3_IO_CONTROL_ROUTE, evidenceLevel: labels.source } ), checkResult( "cloud-api-json-rpc-method-contract", jsonRpcSource.includes("M3_IO_RPC_METHODS.doWrite") && jsonRpcSource.includes("M3_IO_RPC_METHODS.diRead") && jsonRpcSource.includes('handleM3IoRpc("do.write"') && jsonRpcSource.includes('handleM3IoRpc("di.read"'), "cloud-api JSON-RPC exposes M3 do.write and di.read through the same controlled handler.", { methods: ["m3.io.do.write", "m3.io.di.read"], evidenceLevel: labels.source } ), checkResult( "request-schema-contract", requestSchema.status === "pass", "Expected DEV live sequence uses only do.write on DO1 and di.read on DI1.", { issues: requestSchema.issues, sequence: requestSchema.sequence, evidenceLevel: labels.dryRun } ), checkResult( "response-schema-contract", responseSchema.status === "pass", "M3 IO responses carry operationId, traceId, auditId, evidenceId, evidenceState, and frontendBypass=false.", { issues: responseSchema.issues, evidenceLevel: labels.source } ), checkResult( "frontend-same-origin-guardrail", frontendGuardrails.status === "pass", "Cloud Web only calls same-origin /v1/m3/io for the user control path and has no direct gateway/box/patch-panel fetches.", { fetchTargets: frontendGuardrails.fetchTargets, issues: frontendGuardrails.issues, evidenceLevel: labels.source } ) ]; } export function checkFrontendNoDirectRuntimeCalls({ appSource, htmlSource = "", artifactPublisherSource = "" }) { const source = `${appSource}\n${htmlSource}`; const fetchTargets = literalFetchTargets(appSource); const issues = []; const allowedSameOriginTargets = new Set([ "/help.md", "/health/live", "/v1", "/v1/agent/chat", "/v1/m3/io", "/json-rpc" ]); for (const target of fetchTargets) { if (!target.startsWith("/")) { issues.push(`frontend fetch target is not same-origin relative: ${target}`); } if (target.startsWith("/") && !allowedSameOriginTargets.has(target)) { issues.push(`frontend fetch target is not in the allowed same-origin set: ${target}`); } } const directRuntimePatterns = [ /\bfetch(?:Json)?\(\s*["'`][^"'`]*(?:gateway-simu|box-simu|patch-panel|:7101|:7201|:7301)/iu, /\bfetch(?:Json)?\(\s*["'`]https?:\/\//iu, /https?:\/\/[^"'`\s]*(?:gateway-simu|box-simu|patch-panel|:7101|:7201|:7301)/iu, /(?:\/invoke|\/sync\/tick)/iu ]; for (const pattern of directRuntimePatterns) { if (pattern.test(source)) { issues.push(`frontend source matches forbidden direct runtime pattern: ${pattern.source}`); } } const actionBody = functionBody(appSource, "runM3IoAction"); if (!/fetchJson\("\/v1\/m3\/io"/u.test(actionBody)) { issues.push("runM3IoAction must POST through same-origin /v1/m3/io"); } if (/fetchJson\(["'`](?!\/v1\/m3\/io)/u.test(actionBody) || /\bfetch\(/u.test(actionBody)) { issues.push("runM3IoAction must not call any path other than fetchJson(\"/v1/m3/io\")"); } if (!/if \(!m3ControlCanOperate\(\)\)/u.test(actionBody)) { issues.push("runM3IoAction must fail closed before POST when M3 readiness is blocked"); } const readinessBody = functionBody(appSource, "m3ControlCanOperate"); for (const [pattern, label] of [ [/readiness\?\.status === "ready"/u, "readiness.status=ready"], [/readiness\?\.controlReady === true/u, "readiness.controlReady=true"], [/readiness\?\.sourceKind === "DEV-LIVE"/u, "readiness.sourceKind=DEV-LIVE"], [/readiness\?\.evidenceLevel === "DEV-LIVE"/u, "readiness.evidenceLevel=DEV-LIVE"] ]) { if (!pattern.test(readinessBody)) { issues.push(`m3ControlCanOperate must require ${label}`); } } if (!/url\.pathname === "\/v1\/m3\/io"/u.test(artifactPublisherSource)) { issues.push("cloud-web artifact server must proxy same-origin /v1/m3/io to cloud-api"); } return { status: issues.length === 0 ? "pass" : "fail", fetchTargets, issues }; } export function validateExpectedRequestSchemas(sequence) { const issues = []; for (const step of sequence) { if (step.path !== M3_IO_CONTROL_ROUTE || step.method !== "POST") { issues.push(`${step.id} must POST ${M3_IO_CONTROL_ROUTE}`); } if (!["do.write", "di.read"].includes(step.request.action)) { issues.push(`${step.id} action is invalid`); } if (step.request.action === "do.write") { if ( step.request.gatewayId !== M3_IO_CHAIN.sourceGatewayId || step.request.resourceId !== M3_IO_CHAIN.sourceResourceId || step.request.boxId !== M3_IO_CHAIN.sourceBoxId || step.request.port !== M3_IO_CHAIN.sourcePort || typeof step.request.value !== "boolean" ) { issues.push(`${step.id} must write ${M3_IO_CHAIN.sourceResourceId}:${M3_IO_CHAIN.sourcePort} with a boolean value`); } } if (step.request.action === "di.read") { if ( step.request.gatewayId !== M3_IO_CHAIN.targetGatewayId || step.request.resourceId !== M3_IO_CHAIN.targetResourceId || step.request.boxId !== M3_IO_CHAIN.targetBoxId || step.request.port !== M3_IO_CHAIN.targetPort || Object.hasOwn(step.request, "value") ) { issues.push(`${step.id} must read ${M3_IO_CHAIN.targetResourceId}:${M3_IO_CHAIN.targetPort} without a value`); } } } return { status: issues.length === 0 ? "pass" : "fail", issues, sequence: sequence.map((step) => ({ id: step.id, action: step.request.action, gatewayId: step.request.gatewayId, resourceId: step.request.resourceId, boxId: step.request.boxId, port: step.request.port, value: Object.hasOwn(step.request, "value") ? step.request.value : undefined })) }; } export function validateM3IoSourceResponseContract(m3Source) { const requiredPatterns = [ /operationId:\s*input\.operation\.operationId/u, /traceId:\s*input\.meta\.traceId/u, /auditId:\s*records\.auditEvent\.auditId/u, /evidenceId:\s*records\.evidenceRecord\.evidenceId/u, /gatewaySessionId:\s*target\.gatewaySessionId/u, /resourceId:\s*target\.resourceId/u, /port:\s*target\.port/u, /value:\s*target\.value/u, /auditState:\s*auditState\(/u, /evidenceState:\s*evidenceState\(/u, /durableStatus:\s*durableStatus\(/u, /blockerClassification:\s*redactedBlockerClassification\(/u, /persistence:\s*persistenceSummary\(/u, /describeM3IoControlLive/u, /buildM3IoReadiness/u, /controlReady:\s*false/u, /frontendBypass:\s*false/u, /patchPanelOnlyPropagation:\s*true/u, /sourceKind:\s*"DEV-LIVE"/u, /sourceKind:\s*"BLOCKED"/u ]; const issues = requiredPatterns .filter((pattern) => !pattern.test(m3Source)) .map((pattern) => `missing response contract pattern: ${pattern.source}`); return { status: issues.length === 0 ? "pass" : "fail", issues }; } export function validateM3IoLiveResponse(payload, step) { const issues = []; if (!payload || typeof payload !== "object" || Array.isArray(payload)) { return { status: "fail", issues: ["response body must be a JSON object"] }; } for (const field of ["status", "accepted", "action", "chain", "controlPath", "traceId", "evidenceState"]) { if (!Object.hasOwn(payload, field)) { issues.push(`missing ${field}`); } } for (const field of ["operationId", "auditId", "evidenceId"]) { if (payload.status === "succeeded" && !stringValue(payload[field])) { issues.push(`missing ${field} on succeeded response`); } } if (payload.action !== step.action) { issues.push(`expected action ${step.action}, got ${payload.action}`); } if (payload.controlPath?.frontendBypass !== false) { issues.push("controlPath.frontendBypass must be false"); } if (payload.controlPath?.cloudApi !== true || payload.controlPath?.gatewaySimu !== true || payload.controlPath?.boxSimu !== true) { issues.push("controlPath must prove cloudApi, gatewaySimu, and boxSimu were used"); } if (step.action === "do.write" && payload.controlPath?.patchPanel !== true) { issues.push("do.write must prove patchPanel=true"); } if (payload.chain && !routeChainMatches(payload.chain)) { issues.push("response chain does not match the required M3 DO1->DI1 route"); } if (payload.status === "succeeded") { const actualValue = payload.result?.value; if (actualValue !== step.expectedValue) { issues.push(`expected result.value ${String(step.expectedValue)}, got ${String(actualValue)}`); } } return { status: issues.length === 0 ? "pass" : "fail", issues }; } export function classifyM3IoControlReport(report) { const sourceChecks = report.checks ?? []; if (sourceChecks.some((check) => check.status !== "pass")) { return { status: "blocked", classification: "source_contract_failed", trustedGreen: false }; } const operations = report.liveOperations ?? []; if (operations.length === 0) { return { status: "pass", classification: "source_static_contract_checked", trustedGreen: false }; } if (operations.some((operation) => operation.status === "unreachable" || operation.status === "http_error")) { return { status: "blocked", classification: "control_path_unreachable", trustedGreen: false }; } if (operations.some((operation) => operation.status !== "succeeded" || operation.schema?.status === "fail")) { return { status: "blocked", classification: "control_path_blocked", trustedGreen: false }; } const allTrusted = operations.every((operation) => operation.evidenceState?.status === "green" && operation.evidenceState?.sourceKind === labels.devLive && operation.evidenceState?.durable === true ); if (!allTrusted) { return { status: "blocked", classification: controlPathReachablePersistenceBlocked, trustedGreen: false }; } return { status: "pass", classification: "trusted_green", trustedGreen: true }; } export async function runM3IoControlLiveReport(args, sourceReport) { const endpoint = resolveM3IoEndpoint(args); const contractProbe = await requestJson(endpoint.href, { method: "GET", timeoutMs: args.timeoutMs }); const operations = []; const sourceChecks = sourceReport.checks ?? []; if (!contractProbe.ok) { operations.push({ id: "contract-probe", status: "unreachable", sourceKind: labels.devLive, endpoint: endpoint.href, httpStatus: contractProbe.status, error: contractProbe.error }); } else if (contractProbe.body?.route !== M3_IO_CONTROL_ROUTE || !routeChainMatches(contractProbe.body?.chain)) { operations.push({ id: "contract-probe", status: "blocked", sourceKind: labels.devLive, endpoint: endpoint.href, httpStatus: contractProbe.status, error: "live /v1/m3/io contract did not match the source M3 route" }); } else { for (const step of expectedM3IoLiveSequence()) { const operation = await postM3IoLiveStep(endpoint.href, step, args.timeoutMs); operations.push(operation); if (operation.status !== "succeeded") { break; } } } const report = { ...sourceReport, mode: "dev-live", sourceKind: labels.devLive, liveMutation: { attempted: true, allowed: true, reason: "DEV live mode was explicitly gated by --live --confirm-dev --confirmed-non-production." }, endpoints: { ...sourceReport.endpoints, selectedTarget: args.target, selectedEndpoint: endpoint.href, selectedEndpointKind: endpoint.kind }, contractProbe: { ok: contractProbe.ok, status: contractProbe.status, route: contractProbe.body?.route ?? null, chain: contractProbe.body?.chain ?? null, error: contractProbe.error ?? null }, liveOperations: operations, summary: { ...sourceReport.summary, observedAt: isoNow() } }; report.summary = { ...report.summary, ...classifyM3IoControlReport({ checks: sourceChecks, liveOperations: operations }) }; report.summary.result = resultTextForClassification(report.summary.classification); return report; } export function resolveM3IoEndpoint(args) { const endpoint = args.target === "api" ? new URL(args.apiUrl) : new URL(M3_IO_CONTROL_ROUTE, args.frontendUrl); const port = endpoint.port || (endpoint.protocol === "http:" ? "80" : "443"); const allowed = endpoint.protocol === "http:" && endpoint.hostname === "74.48.78.17" && endpoint.pathname === M3_IO_CONTROL_ROUTE && ((args.target === "frontend" && port === "16666") || (args.target === "api" && port === "16667")); if (!allowed) { throw new Error("live endpoint must match target: frontend uses DEV http://74.48.78.17:16666/v1/m3/io; api uses DEV http://74.48.78.17:16667/v1/m3/io"); } return { href: endpoint.href, kind: port === "16666" ? "cloud-web-same-origin" : "cloud-api-direct", port: Number(port) }; } export async function runM3IoControlE2eCli(argv = []) { const args = parseM3IoControlE2eArgs(argv); const gates = requireM3IoControlE2eGates(args); const sourceReport = await buildM3IoControlSourceReport(); const report = gates.mode === "dev-live" ? await runM3IoControlLiveReport(args, sourceReport) : sourceReport; if (args.reportPath) { await writeReport(args.reportPath, report); } process.stdout.write(`${JSON.stringify(report, null, args.pretty ? 2 : 0)}\n`); return report.summary.status === "pass" ? 0 : 1; } export function formatM3IoControlE2eFailure(error) { return { tool: "m3-io-control-e2e", contractVersion: M3_IO_E2E_CONTRACT_VERSION, status: "error", sourceKind: labels.blocked, error: { message: error instanceof Error ? error.message : String(error) } }; } async function postM3IoLiveStep(endpoint, step, timeoutMs) { const traceId = `trc_m3_io_e2e_${step.id.replaceAll("-", "_")}_${randomUUID()}`; const requestId = `req_m3_io_e2e_${step.id.replaceAll("-", "_")}_${randomUUID()}`; const body = { ...step.request, projectId: M3_IO_CHAIN.projectId, traceId, requestId, actorId: "usr_hwlab_m3_io_e2e" }; const response = await requestJson(endpoint, { method: "POST", body, timeoutMs, headers: { "x-trace-id": traceId, "x-request-id": requestId, "x-actor-id": "usr_hwlab_m3_io_e2e" } }); if (!response.ok) { return { id: step.id, action: step.action, status: response.status === 0 ? "unreachable" : "http_error", sourceKind: labels.devLive, endpoint, httpStatus: response.status, error: response.error, request: redactLiveRequest(body) }; } const schema = validateM3IoLiveResponse(response.body, step); return { id: step.id, action: step.action, status: response.body?.status === "succeeded" && schema.status === "pass" ? "succeeded" : "blocked", sourceKind: labels.devLive, endpoint, httpStatus: response.status, request: redactLiveRequest(body), schema, operationId: response.body?.operationId ?? null, traceId: response.body?.traceId ?? traceId, auditId: response.body?.auditId ?? null, evidenceId: response.body?.evidenceId ?? null, evidenceState: response.body?.evidenceState ?? null, accepted: response.body?.accepted ?? null, resultValue: response.body?.result?.value, blocker: response.body?.blocker ?? null, controlPath: response.body?.controlPath ?? null }; } async function requestJson(url, { method = "GET", body, timeoutMs = 8000, headers = {} } = {}) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); try { const response = await fetch(url, { method, headers: body === undefined ? { accept: "application/json", ...headers } : { accept: "application/json", "content-type": "application/json", ...headers }, body: body === undefined ? undefined : JSON.stringify(body), signal: controller.signal }); const text = await response.text(); let parsed = null; try { parsed = text ? JSON.parse(text) : null; } catch { parsed = null; } return { ok: response.ok, status: response.status, body: parsed, error: response.ok ? null : parsed?.error?.message ?? parsed?.blocker?.message ?? response.statusText }; } catch (error) { return { ok: false, status: 0, body: null, error: error.name === "AbortError" ? `request timed out after ${timeoutMs}ms` : error.message }; } finally { clearTimeout(timer); } } function doWriteRequest(value) { return { action: "do.write", gatewayId: M3_IO_CHAIN.sourceGatewayId, resourceId: M3_IO_CHAIN.sourceResourceId, boxId: M3_IO_CHAIN.sourceBoxId, port: M3_IO_CHAIN.sourcePort, value }; } function diReadRequest() { return { action: "di.read", gatewayId: M3_IO_CHAIN.targetGatewayId, resourceId: M3_IO_CHAIN.targetResourceId, boxId: M3_IO_CHAIN.targetBoxId, port: M3_IO_CHAIN.targetPort }; } function routeChainMatches(chain) { return chain?.sourceGatewayId === M3_IO_CHAIN.sourceGatewayId && chain?.sourceResourceId === M3_IO_CHAIN.sourceResourceId && chain?.sourceBoxId === M3_IO_CHAIN.sourceBoxId && chain?.sourcePort === M3_IO_CHAIN.sourcePort && chain?.targetGatewayId === M3_IO_CHAIN.targetGatewayId && chain?.targetResourceId === M3_IO_CHAIN.targetResourceId && chain?.targetBoxId === M3_IO_CHAIN.targetBoxId && chain?.targetPort === M3_IO_CHAIN.targetPort && chain?.patchPanelServiceId === M3_IO_CHAIN.patchPanelServiceId; } function checkResult(id, ok, summary, details = {}) { return { id, status: ok ? "pass" : "fail", sourceKind: details.evidenceLevel ?? labels.source, summary, ...details }; } function literalFetchTargets(source) { return [...source.matchAll(/\b(?:fetch|fetchJson)\(\s*(["'`])([^"'`]+)\1/gu)] .map((match) => match[2]) .filter((target) => !target.includes("${")); } function functionBody(source, functionName) { const match = source.match(new RegExp(`function\\s+${escapeRegExp(functionName)}\\s*\\([^)]*\\)\\s*\\{`, "u")); if (!match) return ""; let depth = 0; for (let index = match.index + match[0].length - 1; index < source.length; index += 1) { const char = source[index]; if (char === "{") depth += 1; if (char === "}") { depth -= 1; if (depth === 0) return source.slice(match.index, index + 1); } } return ""; } function resultTextForClassification(classification) { if (classification === "trusted_green") { return "DEV-LIVE M3 IO control path and durable trusted records are green."; } if (classification === controlPathReachablePersistenceBlocked) { return "DEV-LIVE control path was reachable, but runtime durable/trusted persistence was blocked; not trusted green."; } if (classification === "control_path_blocked") { return "DEV-LIVE M3 IO control path returned a blocked or schema-invalid operation."; } if (classification === "control_path_unreachable") { return "DEV-LIVE M3 IO control endpoint was unreachable or non-2xx."; } if (classification === "source_contract_failed") { return "SOURCE/static contract failed."; } return "SOURCE/static M3 IO control contract passed; DEV-LIVE was not run."; } function evidenceLabelDescriptions() { return [ { label: labels.source, meaning: "Checked-in source or static contract; no runtime mutation." }, { label: labels.local, meaning: "Local/in-process fixture evidence only; not a live DEV claim." }, { label: labels.dryRun, meaning: "Planned sequence or schema validation; no live DEV POST." }, { label: labels.devLive, meaning: "Explicitly gated DEV HTTP execution through cloud-web/cloud-api only." }, { label: labels.blocked, meaning: "Cannot promote to trusted green." } ]; } function redactLiveRequest(body) { return { action: body.action, gatewayId: body.gatewayId, resourceId: body.resourceId, boxId: body.boxId, port: body.port, value: Object.hasOwn(body, "value") ? body.value : undefined, projectId: body.projectId, traceId: body.traceId, requestId: body.requestId, actorId: body.actorId }; } function stringValue(value) { return typeof value === "string" && value.trim().length > 0; } function parsePositiveInteger(value, fallback) { if (value === undefined) return fallback; const parsed = Number.parseInt(value, 10); if (!Number.isInteger(parsed) || parsed <= 0) { throw new Error("numeric value must be a positive integer"); } return parsed; } async function readRepoText(root, relativePath) { return readFile(path.join(root, relativePath), "utf8"); } async function writeReport(reportPath, report) { const absolute = path.resolve(repoRoot, reportPath); if (!absolute.startsWith(`${repoRoot}${path.sep}`)) { throw new Error("report path must stay inside the repository"); } await mkdir(path.dirname(absolute), { recursive: true }); await writeFile(absolute, `${JSON.stringify(report, null, 2)}\n`); } function isoNow() { return new Date().toISOString(); } function escapeRegExp(value) { return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); }