import assert from "node:assert/strict"; import { execFileSync } from "node:child_process"; import test from "node:test"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { checkFrontendNoDirectRuntimeCalls, classifyM3IoControlReport, controlPathReachablePersistenceBlocked, expectedM3IoLiveSequence, parseM3IoControlE2eArgs, requireM3IoControlE2eGates, resolveM3IoEndpoint, validateExpectedRequestSchemas, validateM3IoLiveResponse } from "./src/m3-io-control-e2e.mjs"; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); test("M3 IO E2E default mode is SOURCE/static and never permits mutation", () => { const args = parseM3IoControlE2eArgs([]); assert.equal(args.live, false); assert.equal(args.target, "frontend"); assert.equal(args.frontendUrl, "http://74.48.78.17:16666/"); assert.deepEqual(requireM3IoControlE2eGates(args), { mode: "source-static", liveWriteAllowed: false, mutationAllowed: false }); }); test("M3 IO E2E live mode requires explicit DEV and non-production confirmations", () => { assert.throws( () => requireM3IoControlE2eGates(parseM3IoControlE2eArgs(["--live", "--confirm-dev"])), /requires --live --confirm-dev --confirmed-non-production/u ); assert.throws( () => requireM3IoControlE2eGates(parseM3IoControlE2eArgs(["--live", "--confirm-dev", "--confirmed-non-production", "--dry-run"])), /cannot be combined/u ); assert.deepEqual( requireM3IoControlE2eGates(parseM3IoControlE2eArgs(["--live", "--confirm-dev", "--confirmed-non-production"])), { mode: "dev-live", liveWriteAllowed: true, mutationAllowed: true } ); assert.deepEqual( requireM3IoControlE2eGates(parseM3IoControlE2eArgs(["--live", "--confirm-dev", "--expect-non-prod"])), { mode: "dev-live", liveWriteAllowed: true, mutationAllowed: true } ); }); test("M3 IO E2E rejects dangerous flags and non-DEV live endpoints", () => { assert.throws( () => requireM3IoControlE2eGates(parseM3IoControlE2eArgs(["--prod"])), /forbidden/u ); assert.throws( () => resolveM3IoEndpoint(parseM3IoControlE2eArgs([ "--live", "--confirm-dev", "--confirmed-non-production", "--url", "http://127.0.0.1:16666/" ])), /live endpoint must match target/u ); assert.equal( resolveM3IoEndpoint(parseM3IoControlE2eArgs(["--live", "--confirm-dev", "--confirmed-non-production"])).href, "http://74.48.78.17:16666/v1/m3/io" ); assert.throws( () => resolveM3IoEndpoint(parseM3IoControlE2eArgs([ "--live", "--confirm-dev", "--confirmed-non-production", "--url", "http://74.48.78.17:16667/" ])), /frontend uses DEV/u ); assert.equal( resolveM3IoEndpoint(parseM3IoControlE2eArgs([ "--live", "--confirm-dev", "--confirmed-non-production", "--target", "api" ])).href, "http://74.48.78.17:16667/v1/m3/io" ); }); test("M3 IO E2E source mode CLI prints non-mutating SOURCE/DRY-RUN report", () => { const stdout = execFileSync("node", ["scripts/m3-io-control-e2e.mjs"], { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }); const report = JSON.parse(stdout); assert.equal(report.mode, "source-static"); assert.equal(report.sourceKind, "SOURCE"); assert.equal(report.liveMutation.attempted, false); assert.equal(report.liveMutation.allowed, false); assert.equal(report.dryRunPlan.sourceKind, "DRY-RUN"); assert.equal(report.dryRunPlan.liveWriteWillRun, false); assert.equal(report.summary.classification, "source_static_contract_checked"); assert.equal(report.summary.trustedGreen, false); }); test("M3 IO E2E request schemas are fixed to DO1 write and DI1 read", () => { const result = validateExpectedRequestSchemas(expectedM3IoLiveSequence()); assert.equal(result.status, "pass"); assert.deepEqual( result.sequence.map((step) => [step.action, step.gatewayId, step.resourceId, step.boxId, step.port, step.value]), [ ["do.write", "gwsimu_1", "res_boxsimu_1", "boxsimu_1", "DO1", true], ["di.read", "gwsimu_2", "res_boxsimu_2", "boxsimu_2", "DI1", undefined], ["do.write", "gwsimu_1", "res_boxsimu_1", "boxsimu_1", "DO1", false], ["di.read", "gwsimu_2", "res_boxsimu_2", "boxsimu_2", "DI1", undefined] ] ); const invalid = expectedM3IoLiveSequence().map((step) => step.id === "write-do1-true" ? { ...step, request: { ...step.request, port: "DI1" } } : step ); assert.equal(validateExpectedRequestSchemas(invalid).status, "fail"); }); test("M3 IO E2E classifies reachable control with blocked durable persistence correctly", () => { const operations = expectedM3IoLiveSequence().map((step) => ({ id: step.id, action: step.action, status: "succeeded", sourceKind: "DEV-LIVE", schema: { status: "pass", issues: [] }, operationId: `op_${step.id}`, traceId: `trc_${step.id}`, auditId: `aud_${step.id}`, evidenceId: `ev_${step.id}`, resultValue: step.expectedValue, evidenceState: { status: "blocked", sourceKind: "BLOCKED", durable: false, writeStatus: "not_written" } })); const classification = classifyM3IoControlReport({ checks: [{ id: "source", status: "pass" }], liveOperations: operations }); assert.deepEqual(classification, { status: "blocked", classification: controlPathReachablePersistenceBlocked, trustedGreen: false }); }); test("M3 IO E2E classifies trusted green only with durable DEV-LIVE evidence", () => { const operations = expectedM3IoLiveSequence().map((step) => ({ id: step.id, action: step.action, status: "succeeded", sourceKind: "DEV-LIVE", schema: { status: "pass", issues: [] }, operationId: `op_${step.id}`, traceId: `trc_${step.id}`, auditId: `aud_${step.id}`, evidenceId: `ev_${step.id}`, resultValue: step.expectedValue, evidenceState: { status: "green", sourceKind: "DEV-LIVE", durable: true, writeStatus: "persisted" } })); assert.deepEqual( classifyM3IoControlReport({ checks: [{ id: "source", status: "pass" }], liveOperations: operations }), { status: "pass", classification: "trusted_green", trustedGreen: true } ); }); test("M3 IO E2E live durable green evidence overrides stale source check failure", () => { const operations = expectedM3IoLiveSequence().map((step) => ({ id: step.id, action: step.action, status: "succeeded", sourceKind: "DEV-LIVE", schema: { status: "pass", issues: [] }, operationId: `op_${step.id}`, traceId: `trc_${step.id}`, auditId: `aud_${step.id}`, evidenceId: `ev_${step.id}`, resultValue: step.expectedValue, evidenceState: { status: "green", sourceKind: "DEV-LIVE", durable: true, writeStatus: "persisted" } })); assert.deepEqual( classifyM3IoControlReport({ checks: [{ id: "source", status: "fail", summary: "stale source check" }], liveOperations: operations }), { status: "pass", classification: "trusted_green", trustedGreen: true } ); }); test("M3 IO E2E does not claim trusted green for SOURCE, DRY-RUN, LOCAL, fixture, or BLOCKED backend evidence", () => { for (const sourceKind of ["SOURCE", "DRY-RUN", "LOCAL", "fixture", "BLOCKED"]) { const operations = expectedM3IoLiveSequence().map((step) => ({ id: step.id, action: step.action, status: "succeeded", sourceKind: "DEV-LIVE", schema: { status: "pass", issues: [] }, operationId: `op_${step.id}`, traceId: `trc_${step.id}`, auditId: `aud_${step.id}`, evidenceId: `ev_${step.id}`, resultValue: step.expectedValue, evidenceState: { status: "green", sourceKind, durable: true, writeStatus: "persisted" } })); assert.deepEqual( classifyM3IoControlReport({ checks: [{ id: "source", status: "pass" }], liveOperations: operations }), { status: "blocked", classification: controlPathReachablePersistenceBlocked, trustedGreen: false } ); } }); test("M3 IO E2E frontend guardrail requires readiness before controls unlock", () => { const appSource = ` function m3ControlCanOperate(contract) { return contract?.status === "available" && contract?.readiness?.status === "ready" && contract?.readiness?.controlReady === true && contract?.readiness?.sourceKind === "DEV-LIVE" && contract?.readiness?.evidenceLevel === "DEV-LIVE"; } async function runM3IoAction() { if (!m3ControlCanOperate()) return; return fetchJson("/v1/m3/io", { method: "POST" }); } `; const pass = checkFrontendNoDirectRuntimeCalls({ appSource, artifactPublisherSource: 'if (url.pathname === "/v1/m3/io" || url.pathname === "/v1/m3/status") proxyCloudApi();' }); assert.equal(pass.status, "pass"); const fail = checkFrontendNoDirectRuntimeCalls({ appSource: ` function m3ControlCanOperate(contract) { return contract?.status === "available"; } async function runM3IoAction() { return fetchJson("/v1/m3/io", { method: "POST" }); } `, artifactPublisherSource: 'if (url.pathname === "/v1/m3/io" || url.pathname === "/v1/m3/status") proxyCloudApi();' }); assert.equal(fail.status, "fail"); assert.ok(fail.issues.some((issue) => /readiness/u.test(issue))); }); test("M3 IO E2E frontend guardrail catches direct gateway or patch-panel calls", () => { const appSource = ` function m3ControlCanOperate(contract) { return contract?.status === "available" && contract?.readiness?.status === "ready" && contract?.readiness?.controlReady === true && contract?.readiness?.sourceKind === "DEV-LIVE" && contract?.readiness?.evidenceLevel === "DEV-LIVE"; } async function runM3IoAction() { if (!m3ControlCanOperate()) return; return fetchJson("/v1/m3/io", { method: "POST" }); } async function other() { return fetch("/v1"); } `; const pass = checkFrontendNoDirectRuntimeCalls({ appSource, artifactPublisherSource: 'if (url.pathname === "/v1/m3/io" || url.pathname === "/v1/m3/status") proxyCloudApi();' }); assert.equal(pass.status, "pass"); const fail = checkFrontendNoDirectRuntimeCalls({ appSource: ` async function runM3IoAction() { await fetch("http://hwlab-gateway-simu-1.hwlab-dev.svc.cluster.local:7101/invoke"); } `, artifactPublisherSource: "" }); assert.equal(fail.status, "fail"); assert.ok(fail.issues.some((issue) => /direct runtime|same-origin|runM3IoAction/u.test(issue))); }); test("M3 IO E2E live response schema requires identifiers and frontendBypass=false", () => { const [step] = expectedM3IoLiveSequence(); const valid = validateM3IoLiveResponse({ status: "succeeded", accepted: true, action: step.action, chain: { projectId: "prj_m3_hardware_loop", sourceGatewayId: "gwsimu_1", sourceGatewaySessionId: "gws_gwsimu_1", sourceResourceId: "res_boxsimu_1", sourceBoxId: "boxsimu_1", sourcePort: "DO1", targetGatewayId: "gwsimu_2", targetGatewaySessionId: "gws_gwsimu_2", targetResourceId: "res_boxsimu_2", targetBoxId: "boxsimu_2", targetPort: "DI1", patchPanelServiceId: "hwlab-patch-panel" }, controlPath: { cloudApi: true, gatewaySimu: true, boxSimu: true, patchPanel: true, frontendBypass: false }, operationId: "op_m3_test", traceId: "trc_m3_test", auditId: "aud_m3_test", evidenceId: "evd_m3_test", evidenceState: { status: "blocked", sourceKind: "BLOCKED" }, result: { value: true } }, step); assert.equal(valid.status, "pass"); const invalid = validateM3IoLiveResponse({ status: "succeeded", accepted: true, action: step.action, chain: {}, controlPath: { frontendBypass: true }, traceId: "trc_m3_test", evidenceState: { status: "blocked" }, result: { value: false } }, step); assert.equal(invalid.status, "fail"); assert.ok(invalid.issues.some((issue) => /operationId|frontendBypass|chain|result\.value/u.test(issue))); });