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 DO1tobox-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, andoccurredAt, 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, andFREQ1; - 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-bandgateway-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.