Skip to content

Managed Runtime Packaging Requirements

This document captures the public-core packaging requirements for the Pro-managed station runtime. Product packaging, signing, installers, licensing, and desktop supervision remain in rigplane-pro; protocol, discovery, audio backend, and runtime dependency contracts stay here in rigplane-core.

Runtime Dependency Matrix

Area Python package Native/runtime dependency Notes
Serial control pyserial, pyserial-asyncio OS USB serial driver and device permissions Required for USB CI-V and CAT backends.
LAN audio codec opuslib libopus discoverable by the dynamic loader Required for Opus encode/decode paths used by LAN audio and bridge transcoding.
Local audio bridge sounddevice, numpy PortAudio Required for BlackHole, VB-Cable, PipeWire, PulseAudio, and other local loopback devices.
macOS USB audio lookup stdlib ctypes CoreAudio framework Used to map PortAudio/sounddevice devices to stable CoreAudio UIDs where available.
Optional DSP scipy when enabled platform wheels/native libraries Not required for the minimum managed-runtime startup contract.

Platform Topology

Platform Serial/USB control Local audio topology Current support posture
macOS /dev/cu.* USB serial devices via pyserial; user may need device permissions CoreAudio through PortAudio/sounddevice; BlackHole or Loopback for virtual bridge; direct radio USB audio appears as CoreAudio input/output devices Best-covered development path. Minimum paid-v1 support should include direct LAN audio, USB serial control, and documented BlackHole/Loopback setup.
Windows COM ports via pyserial; radio/vendor driver may be required PortAudio/sounddevice over WASAPI/MME/DirectSound; VB-Cable is the expected virtual bridge path Supported target, but USB audio device naming and VB-Cable routing need release smoke before paid-v1.
Linux /dev/ttyUSB*//dev/ttyACM*; user may need dialout/udev access PortAudio/sounddevice over ALSA/PulseAudio/PipeWire; PipeWire loopback, PulseAudio null sink, or ALSA snd-aloop Supported target for technical users; paid-v1 should document PipeWire/PulseAudio topology and package native dependencies explicitly.

Minimum Viable Paid-v1 Support

This section defines the minimum viable paid-v1 support bar for each platform.

For paid-v1, the managed runtime should be considered supportable when these paths are green:

Platform Minimum viable paid-v1 support
macOS Pro bundle starts managed runtime, discovers LAN and USB serial candidates, reports structured startup/runtime status, and can route WSJT-X audio through LAN direct or a documented BlackHole/Loopback bridge.
Windows Pro bundle starts managed runtime, discovers LAN and COM-port candidates, includes/loads libopus and PortAudio/sounddevice successfully, and documents VB-Cable/manual device selection for WSJT-X.
Linux Pro package starts managed runtime, discovers LAN and USB serial candidates when permissions allow, includes/loads libopus and PortAudio/sounddevice successfully, and documents PipeWire/PulseAudio loopback setup.

The core rigplane --json discover payload uses schema: rigplane.discovery.v1 and includes platform limitation hints for setup wizards. Discovery output must not include credentials. When USB audio topology resolution is available, serial connections may include a usbAudio object with PortAudio device indices, the resolved serial port, and platform location metadata. This is descriptive setup metadata only; it must not include account, radio, or service credentials.

Validation Commands

Core validation that does not require real hardware:

uv run pytest tests/test_discovery.py tests/test_cli_coverage.py tests/test_audio_pipeline_os_smoke.py -q --tb=short

Hardware or OS-assisted validation remains opt-in:

RIGPLANE_OS_AUDIO_SMOKE=1 uv run pytest tests/test_audio_pipeline_os_smoke.py -q --tb=short
RIGPLANE_HARDWARE_AUDIO=1 uv run pytest tests/hardware/test_ic7610_audio_pipeline.py -q --tb=short

For Windows local validation, install the managed-runtime bridge dependencies and run mocked core coverage first:

uv run pytest tests/test_discovery.py tests/test_cli_coverage.py tests/test_audio_pipeline_os_smoke.py -q --tb=short

Then run the opt-in PortAudio smoke with explicit device selectors. Typical Windows names include Microphone (USB Audio CODEC), Speakers (USB Audio CODEC), and CABLE Output (VB-Audio Virtual Cable); use an integer device id when a substring matches more than one device:

$env:RIGPLANE_OS_AUDIO_SMOKE="1"
$env:RIGPLANE_OS_AUDIO_TX_DEVICE="Microphone (USB Audio CODEC)"
$env:RIGPLANE_OS_AUDIO_RX_DEVICE="Speakers (USB Audio CODEC)"
uv run pytest tests/test_audio_pipeline_os_smoke.py -q --tb=short

For Linux local validation, run the same mocked core coverage, then select ALSA/PipeWire/PulseAudio device names reported by PortAudio. Common names include USB Audio CODEC: Audio (hw:2,0), pipewire, and pulse; use integer ids for ambiguous loopback devices:

RIGPLANE_OS_AUDIO_SMOKE=1 \
RIGPLANE_OS_AUDIO_TX_DEVICE='USB Audio CODEC: Audio (hw:2,0)' \
RIGPLANE_OS_AUDIO_RX_DEVICE='pipewire' \
uv run pytest tests/test_audio_pipeline_os_smoke.py -q --tb=short

Follow-up issues

  • rigplane-core#1464: validate Windows/Linux USB audio discovery smoke coverage.
  • rigplane-pro#700: package managed runtime native audio dependencies by platform.
  • rigplane-pro#671: harden cross-platform packaging and lifecycle for station runtime.
  • rigplane-pro#521 and rigplane-pro#522: validate Windows and Linux release artifacts with virtual audio devices.