Twenty rules. Eight categories.
Every one earned by a failure.
This is the complete corpus StandGuard runs against a bench configuration. Each rule is listed with the failure mode it exists because of — the catalog is scar tissue, written down. The machine-readable version is open and MIT-licensed in the standguard-spec repo.
1 · SCHEMAIs this a bench config at all?
Config must define a non-empty channel list.
FAILURE MODEAn empty or malformed export linting "clean" and gating a campaign on nothing.
Every channel requires a unique name field.
FAILURE MODETwo channels silently sharing identity in downstream tooling.
2 · UNIQUEUnambiguous signal identity
Duplicate channel names are rejected.
FAILURE MODEA renamed channel colliding with an existing one; sequences now drive the wrong line.
3 · PINOne physical pin, one owner
Two channels may not allocate the same physical pin.
FAILURE MODEA stimulus shorted into a measurement line. Destroys hardware. This is the canonical bench-killer — two engineers, one spreadsheet, one pin.
4 · LIMITSInside the ratings, always
A channel's drive voltage must stay under its own rating (voltage_v ≤ max_voltage_v).
FAILURE MODENominal drive configured above the rail the hardware can take.
Voltage and current limits must be positive numbers.
FAILURE MODEA negative limit from a units slip (mA entered as A) disabling the very check meant to protect the channel.
5 · INTERLOCKHazardous means cuttable
Channels rated ≥ 24 V (power or drive) must reference an interlock loop.
FAILURE MODEA 28 V bus with nothing that cuts it when a run goes wrong. Destroys hardware — and this is the one safety officers ask about first.
Lower-voltage drive channels without an interlock are flagged advisory.
FAILURE MODEThe "harmless" 12 V actuator line that wasn't.
An interlock reference must resolve to a defined loop.
FAILURE MODEA channel pointing at estop_loop_2 when only estop_loop_1 exists — protection that looks present in the config and is absent on the bench.
An interlock's cut-list must reference defined channels.
FAILURE MODEThe e-stop cuts bus_pwr — a typo for bus_power — and therefore cuts nothing. Read the autopsy →
6 · TIMINGData that means something
Sample rate must be ≥ 2× the channel's fastest signal frequency.
FAILURE MODESampling a 400 Hz signal at 700 Hz. The data looks fine. It is aliased. Weeks of campaign — void. The worst failures invalidate data without touching hardware.
Less than 5× oversampling is flagged for review.
FAILURE MODENyquist-compliant data that still can't reconstruct the waveform anyone needed.
Sample rates must be positive.
Step durations must be positive.
Total sequence time must fit inside campaign_window_s.
FAILURE MODEDiscovering the overrun when the bench times out at hour eleven of a twelve-hour window.
7 · STIMULUSNever overdrive
A step's amplitude_v must stay under the target channel's max_voltage_v.
FAILURE MODE14 V into a 12 V-rated channel. One keystroke over the rail. Destroys hardware.
Stimulating an input-only channel is flagged advisory.
FAILURE MODEA stimulus step aimed at a measurement channel — at best a no-op, at worst a fight between two drivers.
8 · SEQUENCESteps that point at real things
Every step must reference a defined channel.
FAILURE MODEA step pointing at a channel renamed last revision. The bench halts mid-campaign — or worse, doesn't.
Sequences with no steps are flagged for review.
FAILURE MODEThe "ran fine" campaign that ran nothing.
Step structure must validate against the schema (known action, required fields present).
FAILURE MODEA misspelled action silently skipped by a lenient runner.
$ standguard.py lint bench_rigA.json --strict [ERROR ] limits.voltage channels['aux_drive']: voltage_v 28 exceeds max_voltage_v 12 [ERROR ] interlock.cuts interlocks['estop_loop_1']: cuts references undefined channel 'bus_pwr' (did you mean 'bus_power'?) [WARN ] timing.oversampling channels['vibe_x']: 2.5× oversampling — below 5× review floor 20 checks · 2 errors · 1 warning · verdict: BENCH UNSAFE TO POWER (exit 1)
// The catalog grows by contribution, not by roadmap. Burned a bench in a way not listed here? Encode the failure mode — that is rule twenty-one.
Run all twenty on your bench config tonight.
One auditable file, zero dependencies, fully offline. Early access for verification teams — air-gapped tier available.