# Topology Constraint Validator `scripts/validate-topology-constraints.mjs` is a local contract validator for the MVP topology rules that were prose-only after M0. It reads fixtures from `fixtures/mvp/topology-constraints/` and does not call DEV, PROD, real hardware, databases, secrets, or service endpoints. Run it locally: ```sh node scripts/validate-topology-constraints.mjs ``` ## Contract - The fixture must describe a DEV topology with `hwlab-box-simu`, `hwlab-gateway-simu`, and one active `hwlab-patch-panel` status object. - Cross-device propagation must remain `patch-panel-only`. Box simulator local loopback is not a valid substitute for cross-device sync. - Wiring endpoints must reference known box resources and declared ports. - Active wiring configs must not contain resource-level directed cycles. - Active config exclusivity is enforced per project and resource group. The resource group is `wiringConfig.constraints.resourceGroupId` when present; otherwise it is the sorted set of resources touched by the config. - A resource group may have only one active wiring config unless the active patch panel reports `metadata.activeConfigOverride`. - A patch-panel override is valid only when it is reported by an active `hwlab-patch-panel`, preserves `patch-panel-only`, lists exactly the active config ids for the resource group, gives a non-empty reason, and selects the same `wiringConfigId` as the patch panel status object. - The patch panel's `activeConnections` must match the selected wiring config. ## Fixtures | Fixture | Expected result | Purpose | | --- | --- | --- | | `valid-topology.json` | valid | One active acyclic config routed by `hwlab-patch-panel`. | | `invalid-cycle.json` | `wiring_cycle` | Detects a directed resource cycle in active wiring. | | `invalid-multiple-active-configs.json` | `active_config_exclusivity` | Rejects multiple active configs in the same resource group without an override. | | `invalid-patch-panel-override.json` | `patch_panel_override_invalid` | Rejects a patch-panel override whose selected config disagrees with patch panel state. | Each fixture stores `expectedValidation` beside the topology. The validator passes only when valid fixtures produce no violations and invalid fixtures produce the expected violation code set. This makes the validator a pre-DEV contract for the future real M3 flow while keeping the current M3 hardware loop smoke focused on local patch-panel behavior.