13. Feasibility Assessment (ART 0530)

13.1 Feasibility Summary

Dimension Assessment Explanation
CAT/CI-V control feasibility High FT-710 CAT is field-tested; IC-7300/MK2 CI-V frame construction/parsing is conformance-tested against Icom manuals, with physical-radio ACK/timing acceptance pending
Spectrum feasibility High FT-710 FT4222 is field-tested; IC-7300/MK2 CI-V 0x27 activation, parsing, and queue behavior are software-tested, with physical waveform cadence pending
RX audio feasibility High PyAudio capture → Opus encode → WS broadcast → browser playback (per-backend sample rate)
TX audio feasibility High Browser mic → Opus encode → WS → decode → PyAudio → radio (per-backend sample rate)
Mobile feasibility Medium-High Responsive UI adapts to backend capabilities; iOS requires HTTPS for mic (reverse proxy)
Operational feasibility High Single-process server, backend selection via env var, start/stop scripts, PID file management
Product completeness High All core features (control, audio, spectrum, meters, memories) implemented for both supported backends

13.2 Risks

ID Risk Probability Impact Mitigation
R1 Serial port not found or wrong port Medium High Log available ports; env var configuration; clear error messages
R2 Real scope not available Medium Medium Automatic S-meter fallback; scope_pipe/CI-V 0x27 exits gracefully
R3 PyAudio device not matching selected radio Low-Medium Medium Per-backend name-based auto-detection; device list logging; fallback to system default
R4 TX release command lost Low Critical TX-status poll (500ms) + browser watchdog, dead-man switch, unload beacon
R5 Opus library not available Low Medium Graceful PCM fallback on server and browser
R6 Audio device contention Low Medium PyAudio opens/closes streams on demand; only one TX stream at a time
R7 scope_pipe subprocess crash Low-Medium Low Server continues; falls back to S-meter spectrum; pipe exit handled in finally block
R8 Stale frontend assets Low Medium Service worker bypasses JS/HTML; version query strings

13.3 Assumptions

ID Assumption Confidence Validation
A1 Selected radio connected via USB with correct serial parameters (FT-710 Enhanced COM Port at 38400 baud; IC-7300 CI-V at explicit 115200 8N1 with USB port unlinked from [REMOTE]) High Backend ID response; physical-radio acceptance checklist
A2 Selected radio USB audio device recognized by OS High PyAudio device enumeration
A3 libopus available on server (Homebrew opus package) Medium-High ctypes find_library(“opus”)
A4 FTDI libraries in lib/ match OS architecture (FT-710 backend only) Medium scope_pipe startup log
A5 Browser supports WebSocket, Web Audio, Canvas High Modern browsers
A6 libft4222.dylib from wfview app bundle for correct version (FT-710 backend only) Medium scope_pipe SPI read success

13.4 Current Issues

ID Issue Priority Status Resolution Path
I1 iOS Safari requires HTTPS for getUserMedia (mic access) Medium Open Use TLS reverse proxy (nginx) or connect via HTTPS
I2 PyAudio device index not configurable via env var Low Resolved (V2.6) Implemented as MRRC_AUDIO_RX_DEVICE / MRRC_AUDIO_TX_DEVICE (index or name substring); Windows package pre-locks USB Audio
I3 No per-band TX power control (FT-710 uses hardware power setting) Low N/A FT-710 has hardware RF POWER knob; CAT PC; command sets power globally
I4 No ATR-1000 / external tuner support Low Future Could add via second serial port
I5 No digital mode support (CW decoder, FT8, RTTY) Low Future Specialized DSP/packet decode needed
I6 No multi-client control arbitration — concurrent browsers can issue conflicting PTT/frequency commands (last-writer-wins) Medium Open Define arbitration rules (e.g., single-controller lock or role-based gating)
I7 mem_channels.json POST has no schema validation or backup Low Open Server-side payload validation; keep .bak copy before overwrite
I8 serve_static path traversal — STATIC_DIR / path (server.py) builds the response path from the request URL without resolve() + containment check, so an authenticated non-browser client can read arbitrary server-readable files (e.g. GET /../server.py, cert keys). Browsers normalize .., so exposure is raw-HTTP clients. High Resolved 2026-08-26 (_resolve_static_path resolves the join and rejects unless contained inside STATIC_DIR; traversal and absolute request paths now 404 instead of falling through to the SPA fallback; regression tests in tests/test_server_security.py) Resolve the joined path and reject unless is_relative_to(STATIC_DIR) before FileResponse; add a regression test Done
I9 Login password compared with != (non-constant-time, timing side channel) and a weak default password only logs a warning — a fresh install that skips the warning is effectively open. Medium Partially resolved 2026-08-26 (hmac.compare_digest via _password_matches; _warn_if_default_password() fires a loud startup WARNING when the well-known default is active; login-time <12-char warning kept). Still open: first-login forced password change, shorter cookie TTL. Switch to hmac.compare_digest Done; forced first-login change remains future work
I10 Web client audio/spectrum subchannels (/WSaudioRX, /WSaudioTX, /WSspectrum) have no independent reconnect — only /WSradio auto-reconnects, so a transient drop yields “controls alive but audio dead” until the control channel also cycles. Medium Resolved 2026-08-26 (subchannelReconnect gives each subchannel its own exponential backoff 1s→30s with on-open reset, CONNECTING-state guards against socket stacking, auth-expiry 4001 stays with the control flow, and _webClientOff suppresses self-heal while the power button has the client OFF; contract test in tests/test_server_ws_protocol.py) Give each subchannel its own exponential-backoff reconnect Done
I11 iOS app PTT release race (P0 in docs/IOS_APP_ANALYSIS.md): DragGesture.onEnded sends ptt:false only when the server echo already shows tx_status > 0, and there is no client watchdog/scenePhase guard — fast taps over WAN can leave the radio keyed up. Approved PTTManager fix design not yet implemented (0/N tasks). High Partially resolved 2026-08-26 (release race fixed: PTT gesture now tracks local pttHeld like TUNE’s tuneHeld, releases unconditionally on gesture end with optimistic local txStatus update in RadioViewModel.setPTT; requires device verification). Still open: 500 ms×3 watchdog, scenePhase force-release. Server side gained an opt-in stuck-keyup layer: MRRC_PTT_MAX_TX_SECONDS watchdog forces RX after continuous TX beyond the limit, covering zombie-but-connected sockets that neither client watchdogs nor the dead-man switch see. Unconditional release on gesture end Done; watchdog + scenePhase remain
I12 Stuck-keyup gap for connected-but-hung clients: every existing TX-release layer assumes either a working client or a disconnect. A zombie socket mid-TX keys the radio forever. High Resolved 2026-08-26 (server-side _max_tx_watchdog, opt-in via MRRC_PTT_MAX_TX_SECONDS, default off so operator QSO patterns are never interrupted; fire-and-forget unkey + zeroed TX meters + error toast, no verify loop per ch15) Opt-in max-continuous-TX force-RX implemented as a new outermost safety layer

13.5 Dependencies

ID Dependency Type Status
D1 Python 3.12+ Runtime Required
D2 FastAPI + Uvicorn Runtime Required (pip)
D3 pyserial Runtime Required (pip)
D4 PyAudio Runtime audio Required for audio (pip + portaudio)
D5 NumPy Runtime/DSP Required (pip)
D6 libopus Optional codec Optional (brew install opus / apt install libopus0)
D7 libft4222 + libftd2xx Optional scope Required for real FT4222 spectrum
D8 Supported radio + USB cable Hardware Required
D9 Browser WebSocket/Web Audio/Canvas Client Required

13.6 Feasibility Conclusion

MRRC Modern is fully feasible for remote operation of supported radios. Core software paths — backend-specific control, bidirectional Opus audio, spectrum waterfall, meter telemetry, memories, authentication, and PTT safety — are implemented. FT-710 has field-test history; the IC-7300/MK2 CI-V byte formats and asynchronous behavior are conformance-tested without hardware, so physical USB enumeration, command ACK timing, scope cadence, RF/tuner/power behavior, and RX/TX audio quality remain acceptance items rather than verified claims. iOS still requires HTTPS for microphone access. FT-710 FT4222 scope requires its libraries and degrades to S-meter fallback; IC-7300/MK2 scope requires the CI-V USB port unlinked from [REMOTE] at an explicitly selected 115200 baud.