# M5 MVP E2E Dry-Run Orchestration M5 is the static orchestration gate before the first real DEV MVP e2e run. It does not deploy, does not call DEV, does not run browser e2e, and does not read secrets. The source contract gate is: ```sh node scripts/m5-mvp-e2e-dry-run.mjs ``` The script reads the frozen protocol contracts, the DEV acceptance checklist, `fixtures/mvp/runtime.json`, and `fixtures/mvp/m5-e2e/dry-run-plan.json`. It validates the dependency graph and checks that each step has resolvable inputs and outputs. The L6 external acceptance CLI wraps the same report and dry-run plan: ```sh node tools/hwlab-cli/bin/hwlab-cli.mjs test e2e --env dev --mvp ``` Cloud Web #59 adds a separate read-only diagnostics contract: ```sh node web/hwlab-cloud-web/scripts/m3-readonly-contract.mjs ``` This contract is source-only. It verifies the public frontend/API endpoint split, the read-only JSON-RPC calls used by Cloud Web, the visible topology, route, health, and M3 evidence summary, and the rule that edge-only observations cannot be displayed as M3 `DEV-LIVE`. This command defaults to a JSON dry-run plan. `--dry-run` is accepted for backward compatibility, but it is no longer required for safety. The output must identify the M0-M5 report source, artifact and DEV health contract counts, two gateway sessions, two box resources, patch-panel status, agent and worker session IDs, evidence records, open blockers, and the statement that no DEV/PROD changes were made. ## Dry-Run Flow | Order | Step | Purpose | Required Inputs | Required Outputs | | --- | --- | --- | --- | --- | | 1 | DEV health | Confirm the frozen DEV endpoint and recorded edge/frp/D601/cloud health contracts. | DEV endpoint, ingress, edge route, frp, router, cloud API/web health records | Route, tunnel, namespace, cloud service identities | | 2 | Gateway/box status | Confirm gateway, simulator, resources, and capabilities are present. | Gateway sessions, box resources, capabilities | Gateway session, resource IDs, capability IDs | | 3 | Wiring | Confirm the active wiring config is patch-panel owned. | Wiring config, patch-panel status | Wiring config ID, patch-panel status ID | | 4 | Direct hardware call | Validate the direct JSON-RPC hardware operation envelope and field flow. | RPC request/response, resource, capability, patch-panel status | Operation ID, trace ID | | 5 | Audit | Confirm mutating setup and direct operation audit records exist. | Project, gateway, wiring, operation audit records | Direct operation audit ID | | 6 | Agent session | Confirm agent manager, worker, and skills contracts are linked. | Agent/worker sessions, agent health records | Agent session ID, worker session ID | | 7 | Agent hardware call | Validate the agent worker JSON-RPC hardware operation envelope and field flow. | RPC request/response, agent, worker, resource, capability, patch-panel status | Operation ID, trace ID | | 8 | Evidence | Confirm both hardware operations emit trace and evidence records. | Trace events, evidence records | Evidence IDs | | 9 | Cleanup | Confirm worker and gateway transient cleanup are recorded. | Cleanup records, cleanup audit | Cleanup IDs | ## M0-M4 Dependency Graph M5 closes over the earlier MVP contracts as contract-only prerequisites: | Source | Provides | Consumed By M5 | | --- | --- | --- | | M0 contract audit | Frozen service IDs, protocol schemas, MVP e2e sequence contract | DEV health, hardware operation envelopes, evidence contract | | M1 local smoke | Static parse boundary and dry-run safety posture | DEV health and cleanup safety checks | | M2 cloud core | Project record, JSON-RPC envelope, audit surface | Audit, direct hardware call, agent hardware call | | M3 hardware loop | Gateway session, box resources/capabilities, wiring config, patch-panel status | Gateway/box status, wiring, direct hardware call, agent hardware call | | M4 agent runtime | Agent session, worker session, trace events, evidence, cleanup | Agent session, agent hardware call, evidence, cleanup | The graph must remain acyclic. Each M5 step may only depend on earlier steps except the agent hardware call, which also depends on the already-established wiring step. ## Blocker Classes M5 keeps the blocker classes from the DEV acceptance matrix: | Class | Meaning | | --- | --- | | `contract_blocker` | Static contract, schema, checklist, or documentation cannot be parsed or contradicts frozen names. | | `environment_blocker` | DEV endpoint, environment, namespace, or PROD boundary is wrong. | | `network_blocker` | Master edge, frp, D601 route, or public DEV ingress cannot be observed or routes incorrectly. | | `runtime_blocker` | HWLAB cloud, router, gateway, simulator, box simulator, or patch-panel runtime contract fails. | | `agent_blocker` | Agent manager, worker, skills, trace, audit, or cleanup contract fails. | | `observability_blocker` | Artifact identity, commit, image/tag/digest, build source, deploy env, or health timestamp is missing. | | `safety_blocker` | Any prohibited action was attempted: real deployment, PROD target, browser/heavyweight e2e, secret read, force push, or UniDesk runtime substitution. | ## Real DEV E2E Gate Do not switch to the real command until all of these are true: 1. `node scripts/m5-mvp-e2e-dry-run.mjs` passes on `origin/main`. 2. `docs/dev-acceptance-checklist.json` and `docs/dev-acceptance-matrix.md` still freeze DEV at `http://74.48.78.17:16667`. 3. Every accepted artifact has `serviceId`, `commitId`, `image`, `tag`, `digest` or `not_applicable` reason, `buildSource`, `deployEnv`, and `healthTimestamp`. 4. DEV ingress, master edge proxy, frp, and D601 `hwlab-dev/hwlab-router` have current route observations. 5. Cloud API/web, gateway, gateway simulator, box simulator, patch panel, agent manager, worker, and skills are all observed in DEV with HWLAB service identities. 6. Gateway and box control remain patch-panel owned; no direct box bypass path is accepted. 7. Agent worker scope, trace, audit, evidence, and cleanup are observable and tied to one DEV project. 8. No blocker class is open and a human has explicitly approved a real DEV smoke. Only after those gates are satisfied should the runner switch from dry-run to the explicit live DEV command: ```sh hwlab-cli test e2e --env dev --mvp --live --confirm-dev --confirmed-non-production ``` That command is intentionally not executed by M5. While `reports/dev-gate/dev-mvp-gate-report.json` contains open blockers, the CLI must return `code: "BLOCKED"` with blocker evidence instead of substituting fixture output as live DEV evidence.