component Orchestration { goal { Define and execute automated RF capture campaigns: sweep transmitters and channels, record, QA, and label the results. Own the campaign configuration schema, the executor, and the QA checks. } interface { CampaignConfig(name, recorder, transmitters, qa, output, mode, loops) with loaders from_dict, from_yaml, and from_device_profile; it requires a recorder and at least one transmitter. Supporting dataclasses: RecorderConfig, TransmitterConfig (type and control_method external_script/sdr/sdr_remote/sdr_agent), CaptureStep, QAConfig, and OutputConfig. CampaignExecutor(config, progress_cb=None).run() returns a CampaignResult of StepResults; check_recording(recording, config) returns a QAResult; label_recording writes ria: SigMF metadata. } } expand Orchestration { logic { The executor opens the SDR and remote TX controllers once, then for each loop, transmitter, and step it starts the transmitter, records IQ, stops the transmitter, then labels, QA-checks, and saves it as SigMF. QA estimates SNR from the PSD and checks duration and SNR; in flag-for-review mode a recording always passes but may be flagged. Cancellation is cooperative at step boundaries via the progress callback. } constraints { Frequencies, gains, durations, and bandwidths are parsed from human units (for example 2.45GHz, auto, 1.5m). Device names are aliased onto SDR drivers, including mock and sim for hardware-free runs. The controller's Conductor and the RT-OSS server are parallel HTTP wrappers that both reuse this package's CampaignConfig and CampaignExecutor in-process. } }