Canonical design record for the headless FT8/FT4 server — architecture, interfaces, operational model, and runtime evolution.
IBM TeamSD aligned, 15 chapters, implementation-grounded content.
| Attribute | Value |
|---|---|
| Document ID | SDD-MRRC-FT8-2026-001 |
| Version | V1.2 |
| Baseline Date | 2026-08-04 |
| Phase | Live on radio.vlsc.net:9988 (FT-710) |
| Runtime | WSJT-X 3.0.2 Improved DSP + FastAPI + Uvicorn + NumPy |
| Frontend | HTML5, CSS3, vanilla JavaScript, Canvas PWA |
| Core Interfaces | FastAPI REST/WS + supervised DSP Worker IPC + rigctld loopback |
ATT / PREAMP / AGC / RF gain now switch through raw \send_raw CAT frames instead of hamlib's L/l level path, which the FT-710 never answers (verified live 2026-08-04 against the station rigctld). Codes: RA01;=6 dB, PA01;=10 dB, GT06;=AUTO — hamlib 4.7.2 sends the wrong GT04; — and RG0<NNN>;=0..1. The drawer reads the rig's real state and drops the stale snapshot after every write.
Hamlib 4.6.2 mis-framed the width command (SH0NN; instead of SH00NN;) so M <mode> <width> never changed the rig. The width now goes through raw \send_raw with the true SH-register readback (1.8 / 2.4 / 3.0 kHz), compatible with the hamlib 4.7.2 upgrade. TX power (PC0…;) is rejected by the FT-710 and is deliberately not exposed.
The live cockpit: 20 m FT8 band activity and decodes on 14.074 MHz.
Physical ring positions were keyed to (absolute − base) % capacity, so once eviction advanced base, reads addressed samples with the new base while data never moved — a shift growing 1:1 with wall clock, wrapping at capacity. Positions now key to the absolute sample index alone (X % capacity): eviction never moves data, base is purely a bounds check.
The reply path was missing the UC-003 "opposite TX slot": TxDriver gated on a hard-coded even parity that never changed, so replies to partners on the same phase always collided. The sequencer now carries tx_phase = 1 − slot_id % 2 and the QSO alternates to completion.
Replies always missed the slot right after the message they answer. The TX decision is now provisional: the window stays open until decision_cutoff with polling instead of sleeping, and a fit guard defers past-fit-deadline replies to the next eligible slot.
Spectrum frames now emit only the 3 kHz FT8 passband — no blank half-canvas, half the payload. A band selector in the cockpit top bar tunes 7/14/21/28 MHz FT8 dial frequencies via the lease-gated /radio/band mutation.