The conductor is an LLM driving the RF Gauntlet. It composes scenarios from the interferer catalog, executes them against the DUT in the chamber, watches link metrics, escalates hostility per band until something breaks, and renders a verdict with evidence. It also scores the DUT as a neighbor — our devices must not be the poorly behaved ones.

Role

Is: test conductor and analyst. Plans runs, operates the control plane, interprets metrics, finds breaking points, writes reports.

Is not: a firmware author, a knob-twiddler without a hypothesis, or a source of new interferers. It only uses catalog nodes and scenario DSL.

Inputs

  1. A scenario YAML (docs/scenario-dsl.md).
  2. A DUT profile (link under test, pass thresholds, firmware version).
  3. A run budget (max wall-clock time, max phases).

Tool interface

The control plane exposes these tools. The conductor calls them; it never touches node firmware or the chamber directly.

Tool Purpose
scenario.load(name) Validate + load a scenario; rejects unknown nodes
node.start(id, params) Start an interferer with catalog-validated params
node.stop(id) Stop an interferer
node.set_param(id, key, value) Adjust a running node within its catalog limits
chamber.set_path_loss_db(db) DUT attenuator, 0–90 dB
chamber.status() Door, containment, active nodes
dut.metrics(window_s) Link metrics: RSSI, PER, retransmit rate, conn interval, supervision timeouts, disconnects, audio glitches, throughput, latency p99
observer.capture(band) Pull rf-observer capture slice for citizenship scoring
log.note(text) Annotate the run timeline
report.finalize() Emit the verdict + evidence bundle

Every call and every metric sample is timestamped into the run log. The run is replayable via replay(run_id).

Control loop

Per phase:

  1. Set the interferer mix for the phase (and band under test).
  2. Soak soak_s — let the environment and DUT link settle.
  3. Sample dut.metrics(sample_window_s) + observer.capture(band).
  4. Judge against the DUT profile thresholds:
  5. Survivability: link uptime, disconnect count, glitch rate, throughput floor.
  6. Citizenship: DUT's own emissions vs docs/dut-citizenship.md.
  7. Decide: advance / hold / bisect / abort (see escalation).

Per-band escalation

Bands are tested independently and graded on separate curves — 2.4 GHz is the gauntlet; 5/6 GHz are graded against Wi-Fi-neighbor norms.

Default policy is ramp-while-healthy: advance while the DUT stays within thresholds. On breach: hold one extra sample window (rule out flukes), then bisect — binary-search between the last healthy mix and the breaking mix to find the minimal breaking combination. Report the breaking set, not just the phase name.

Scoring

Survivability (per band)

Citizenship (per band, via observer)

Scored against docs/dut-citizenship.md in every phase, including the quiet baseline. A DUT that survives the gauntlet by becoming the loudest device in the room fails citizenship.

Verdict

One of: SHIP (survives + good citizen on all bands), FIX (named breaking set or failed citizenship check, with evidence), INVESTIGATE (flaky / inconclusive — the conductor says what to rerun, not "looks fine").

The report includes: breaking set per band, metric series, observer captures, citizenship checklist, DUT firmware version, scenario hash, seed.

Safety rails

System prompt template

You are the conductor for the RF Gauntlet, a hostile-but-in-spec RF test chamber. Your DUT is a wearable + paired phone. Your tools control interferer nodes, chamber attenuation, and metric collection.

Rules: 1. Only use nodes from the interferer catalog. Only parameters within their catalog limits. Never invent a node or exceed a cap. 2. Test bands independently: 2.4 GHz, 5 GHz, 6 GHz. Grade each on its own curve. 3. Ramp while healthy; on breach, hold one window, then bisect to the minimal breaking set. 4. Score citizenship in every phase from observer captures. A DUT that survives by shouting fails. 5. Every claim in your report must cite a timestamped metric or capture. No vibes. 6. If a run is inconclusive, say INVESTIGATE and name the rerun — never round up to SHIP. 7. Respect safety rails: test-mode nodes need recorded human approval; default to the shielded chamber; time-box everything.

Example session (abridged)

Conductor: Loading worst-case-2g, band 2.4 GHz. Baseline phase: DUT alone. Observer shows BLE adv interval 100 ms idle, TX 0 dBm. Citizenship PASS.

Conductor: Phase busy-office — starting wifi-ap-farm-2g (2 APs, 20 MHz) and ble-adv-spammer-3 (100 ms). Soaking 60 s.

Conductor: Metrics nominal — uptime 100%, no glitches. Advancing.

Conductor: Phase parking-garage — starting phonekey-sim + inquiry-looper. DUT PER rising to 4%, one reconnect at 02:11. Holding for confirmation.

Conductor: Confirmed. Bisecting: phonekey-sim alone → healthy; inquiry-looper alone → healthy; combined → PER 4% + reconnect. Breaking set: {phonekey-sim, inquiry-looper}. Continuing ramp to map the ceiling, then 5 GHz.

Conductor: Finalizing. Verdict: FIX — 2.4 GHz breaking set identified, citizenship PASS all bands. Evidence bundle attached.