Files
pikasTech-HWLAB/docs/m3-hardware-loop.md
T
2026-05-22 18:06:24 +00:00

5.5 KiB

M3 Hardware Trusted Loop Local Contract

This contract smoke proves the local M3 wiring path for:

box-simu-1 DO1 -> box-simu-2 DI1

The fixture is fixtures/mvp/m3-hardware-loop/topology.json. It contains two hwlab-box-simu resources, two hwlab-gateway-simu sessions, and one hwlab-patch-panel status object. The active wiring config has one exclusive connection from res_boxsimu_1:DO1 to res_boxsimu_2:DI1.

Run the smoke locally:

node scripts/m3-hardware-loop-smoke.mjs

What It Checks

  • DEV-only topology with two boxes, two gateways, and one active patch panel.
  • Patch-panel-only propagation; box local loopback is not accepted as a cross-device substitute.
  • Direct local call into the existing patch-panel model routes box-simu-1 DO1 to box-simu-2 DI1.
  • An unwired local signal does not cross devices.
  • The expected audit event includes the L0 audit fields: auditId, traceId, actorType, actorId, action, targetType, targetId, serviceId, environment, and occurredAt, plus project, gateway session, operation, outcome, and metadata fields.

Boundary

This is a local contract smoke only. It does not deploy DEV or PROD services, does not connect to real hardware, does not read secrets or tokens, and does not write audit_events rows to a database. The audit event in the fixture is an expected record shape for the future real flow.

The later real DEV M3 path must replace the in-process direct call with live service boundaries: cloud request validation, gateway session ownership, patch-panel state application, real or simulator box observation, persisted audit events, and evidence records. That future work must preserve the same wiring contract and must keep routing decisions under hwlab-patch-panel ownership instead of mutating another box directly.

L2 Local Runtime Smoke

Issue 53 adds a runnable localhost-only L2 simulator contract:

npm run l2:smoke

The smoke starts two hwlab-box-simu instances (box-a, box-b) and two hwlab-gateway-simu instances (gateway-a, gateway-b) on ephemeral localhost ports. It verifies:

  • box ports for AI1, AO1, DI1, DO1, and FREQ1;
  • internal port API writes for patch-panel-owned delivery;
  • gateway register, heartbeat, capability report, and invoke forwarding;
  • multi-instance identity separation for box-a/box-b and gateway-a/gateway-b;
  • HWLAB JSON-RPC error codes for missing gateway registration and unavailable capabilities;
  • returned audit and evidence object shapes.

This smoke is still not a DEV deploy or PROD deploy. It proves the minimum runtime surface that later M3/M5 live checks can call. Cross-device propagation is not implemented as box-simu loopback; the only accepted cross-device owner remains hwlab-patch-panel, which calls the box internal port API.

DEV Runtime Smoke

Use the no-write plan first:

node scripts/dev-m3-hardware-loop-smoke.mjs --dry-run

The dry-run plan writes reports/dev-gate/dev-m3-hardware-loop.json by default, records dryRunPlan.evidenceLevel: "DRY-RUN", lists the live write preconditions, enumerates the endpoints that a later live run would call, and keeps liveOperation.status: "not_run". It does not call DEV endpoints, does not send /ports/write or /signals/route, and cannot be promoted to DEV-LIVE.

Use this command only for the approved DEV simulator runtime window:

node scripts/dev-m3-hardware-loop-smoke.mjs --live --confirm-dev --expect-non-prod

The legacy --confirmed-non-production flag is accepted as compatibility, but new handoffs should use --expect-non-prod. The script refuses the default mode and refuses --dry-run combined with --live.

The live smoke writes reports/dev-gate/dev-m3-hardware-loop.json. It first checks the frozen DEV endpoint, http://74.48.78.17:16667, and stops at the first critical blocker from docs/dev-acceptance-matrix.md. When DEV ingress is not observable, the report is blocked and the script does not run the live do.write true -> di.read true operation.

If DEV ingress is reachable, the script requires explicit direct DEV simulator targets through these environment variables:

HWLAB_DEV_BOX_SIMU_1_URL
HWLAB_DEV_BOX_SIMU_2_URL
HWLAB_DEV_GATEWAY_SIMU_1_URL
HWLAB_DEV_GATEWAY_SIMU_2_URL
HWLAB_DEV_PATCH_PANEL_URL

Those targets must be two distinct HWLAB DEV simulator services for each simulator kind, plus one HWLAB DEV patch panel, not UniDesk substitutes. The script then checks two box simulators, two gateway simulators, active patch-panel wiring for res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1, a live direct call that reads DI1=true, and returned operation, trace, audit, and evidence identifiers. Fixture-backed local M3 output is never accepted as live DEV evidence.

Read-Only Continuation Evidence

When DEV ingress is blocked, continuation work may still record read-only evidence. The smoke report includes a static comparison of deploy/k8s/base/workloads.yaml against the M3 requirement for two hwlab-box-simu instances and two hwlab-gateway-simu instances. This is not live runtime proof. The checked-in DEV manifests are source-ready only when node scripts/validate-dev-m3-cardinality.mjs passes: two hwlab-box-simu replicas with boxsimu_1,boxsimu_2, two hwlab-gateway-simu replicas with res_boxsimu_1,res_boxsimu_2, and one hwlab-patch-panel. If the live runtime still lacks the required simulator cardinality, the fix is a separate authorized DEV deploy or runtime task, not a mutation inside the M3 evidence collection task.