RF Gauntlet
Every interferer in the chamber is 100% within its radio spec. Only the combination — and the duty cycle — is worst-case. An LLM conductor ramps the hostility per band until something breaks, and scores our devices as neighbors, not just survivors.
A hostile-but-legal RF environment for connectivity testing.
Field connectivity failures almost never come from a single broken device. They come from density: thirty APs in an apartment building, a parking lot full of cars running phone-as-key, a conference hall of BLE beacons. Every interferer in this rig is 100% within its radio spec. Only the combination — and the duty cycle — is worst-case.
The goal is two-sided:
- Survivability — put our device (wearable + paired phone) in the middle of that and prove the link stays up.
- Citizenship — prove our device isn't contributing to the hell. Passive
observers capture everything the DUT transmits and score it against
docs/dut-citizenship.md. A device that holds its link by shouting over everyone else fails.
Principle
- In-spec only. No jammers, no out-of-band tricks, no protocol violations. If a device can't legally do it, it doesn't go in the chamber.
- Worst-case duty cycle. Every node runs at the most aggressive behavior its spec allows: minimum advertising intervals, back-to-back inquiry trains, 100%-duty-cycle scanning, beacons at the lowest basic rate.
- Real things. Each interferer models something that actually exists in the field: the car doing phone-as-key in the garage, the AP farm in the apartment block, the Auracast broadcast at the airport.
- LLM-conducted. A conductor model composes scenarios from the interferer catalog, executes them, watches DUT link metrics, escalates hostility until something breaks, and writes up the breaking point with evidence.
Architecture
+------------------+
| LLM conductor | plans, executes, scores
+--------+---------+
| control plane (HTTP/JSON-RPC)
+------------------------+------------------------+
| RF chamber / quiet room |
| |
| [BR/EDR nodes] [BLE nodes] [LE Audio] [Wi-Fi] |
| inquiry looper adv spammers Auracast AP farm |
| page stormer active scan (BIS) slow |
| A2DP hog conn saturator client |
| phone-key sim [15.4] probe |
| ext-adv spam zigbee stormer |
| |
| DUT: wearable + paired phone |
| (behind programmable attenuator) |
+--------------------------------------------------+
The conductor never touches firmware. It drives node agents through the control plane: start/stop nodes, set parameters, set chamber path loss, sample DUT metrics, and render a verdict.
Repo map
docs/bom.md— parts and device listdocs/interferers.md— interferer catalog: spec basis, worst-case params, hardware, expected victim impactdocs/scenario-dsl.md— scenario YAML schemadocs/llm-driver.md— the conductor spec: role, tool interface, control loop, scoring, safety railsscenarios/— example scenarios (smoke.yaml,worst-case.yaml)driver/— control-plane agent contract + orchestrator skeleton
Quickstart
- Build the fleet per
docs/bom.mdand flash node firmware. - Place nodes in the chamber; DUT behind the programmable attenuator.
- Bring up the control plane: one HTTP agent per node +
driver/orchestrator.py. - Run the smoke scenario, then let the conductor escalate:
python driver/orchestrator.py --scenario scenarios/smoke.yaml
Safety
- Prefer a shielded chamber or shielded room. Open-air runs stay within ISM band rules; node TX power caps are enforced by the agent contract, not by asking nicely.
- The conductor MUST NOT exceed per-node TX caps or run longer than the
scenario's time box. See
docs/llm-driver.mdsafety rails. - DUT protection: abort criteria (excessive disconnect churn) exist so a bad scenario can't wedge the DUT in a reconnect loop indefinitely.