5. Non-Functional Requirements (ART 0507)

5.1 Performance and Timing

ID Requirement Target / Verification
NFR-001 Safe FT8 decode deadline Profile 3 result available before its TX decision cutoff; late result cannot trigger late TX
NFR-002 Decode latency visibility Per-profile/thread latency histogram and deadline-miss counter
NFR-003 Decode capacity Typical busy-band batch is returned without truncation; overflow is explicit
NFR-004 Waterfall cadence Target ~3.5 lines/s; old frames drop under backpressure
NFR-005 State latency Safety/state event reaches a healthy client within 500 ms on LAN
NFR-006 Slot identity Always floor(epoch/TRperiod); epoch-injected tests
NFR-007 Audio domains Decoder 12 kHz int16 mono; TX 48 kHz mono; binding asserts
NFR-008 Clock safety Clock step/unsafe offset inhibits TX until stable and manually re-armed
NFR-009 Late action safety Missed slot/deadline is skipped, never shifted into an unsafe late transmit

5.2 Availability and Isolation

ID Requirement Target / Verification
NFR-020 Long-running RX 24 h target; 1 h real-radio release gate without crash/leak symptom
NFR-021 DSP isolation Worker crash does not crash main; active TX is stopped and worker is restartable
NFR-022 Fault recovery CAT/audio/DSP recovery never restores armed TX automatically
NFR-023 Browser reconnect Exponential backoff; state snapshot on reconnect; no command replay
NFR-024 Restart invariant PTT off, TX disarmed, lease empty, monitor-only

5.3 Security

ID Requirement Target / Verification
NFR-030 TLS edge Caddy owns public 80/443; automatic TLS
NFR-031 Loopback services FastAPI, worker IPC and rigctld are not publicly bound
NFR-032 Strong password Argon2id with per-hash salt; no committed/plaintext secret
NFR-033 Session cookie Random opaque Secure, HttpOnly, SameSite=Strict; 30 min idle / 12 h absolute
NFR-034 No URL credential REST/WS never authenticate through query tokens
NFR-035 Request validation Mutations and WS upgrades validate configured Host and expected Origin
NFR-036 Login abuse resistance Bounded rate limit and progressive delay
NFR-037 Control arbitration Multiple sessions, exactly one renewable control lease
NFR-038 Emergency stop Any authenticated session can STOP TX without the lease
NFR-039 Diagnostic re-auth Password re-entry, five-minute sensitive-operation window and warning

5.4 Safety

ID Requirement Target / Verification
NFR-050 Sequencer-only TX No direct Web/DSP-to-PTT path
NFR-051 Lease heartbeat 5 s heartbeat, 15 s TTL; loss during TX stops immediately
NFR-052 STOP priority Idempotent, cancels audio/queued TX and requests PTT off immediately
NFR-053 Non-blocking PTT release No blocking confirmation loop in safety path
NFR-054 Health interlocks CAT/audio/DSP/clock fault prevents TX
NFR-055 Retry bound One initial send plus at most three retransmissions, then disarm
NFR-056 Completion behavior RR73/73 logs and disarms; no automatic next target
NFR-057 Watchdog Per-transmission and aggregate TX deadline enforced server-side
NFR-058 Startup/shutdown Best-effort PTT off on both paths; abnormal prior QSO marked aborted

5.5 Compatibility and UX

ID Requirement Target / Verification
NFR-060 Landscape operation Full cockpit at representative phone/tablet landscape sizes
NFR-061 Portrait degradation Observer, health, recent decodes and STOP remain; QSO start requires rotation
NFR-062 Touch semantics Explicit RX/TX/Both; selection separated from Reply
NFR-063 UI safety visibility CAT/audio/DSP, lease TTL, slot, TX/PTT and watchdog never hidden in menus
NFR-064 Supported browsers Current iOS Safari plus current desktop Safari/Chrome/Firefox
NFR-065 No fake controls Unsupported modes/features are hidden

5.6 Operability and Data

ID Requirement Target / Verification
NFR-070 Runtime logging Startup, health transition, decode deadline and every TX start/stop/reason
NFR-071 Retention Runtime 30 d, decode history 7 d, audit 90 d, QSO indefinite
NFR-072 Canonical persistence SQLite transactions; ADIF generated from non-void QSO records
NFR-073 Audited undo QSO undo marks void and records actor/time/reason
NFR-074 Local telemetry No third-party telemetry or cloud error reporting
NFR-075 Diagnostic contents Raw bundle may be sensitive; auth secrets and cookie values are excluded
NFR-076 Health metrics DSP latency/misses, audio overruns, drops, rig/PTT/lease/worker state

5.7 Maintainability and Deployment

ID Requirement Target / Verification
NFR-080 Vendor immutability No edit under wsjtx-3.0.2/; patches in dsp/patched/
NFR-081 DSP boundary All DSP calls via worker and binding.py lock
NFR-082 Frontend structure Vanilla modules; no inline JS logic in index.html
NFR-083 Dual platform Shared app config/code; LaunchAgent and systemd descriptors separate
NFR-084 SDD governance Behavior change updates affected SDD and chapter 14; guardian check clean
NFR-085 LOG window & import provenance GET /logs/qsos and /logs/adif return only the last 7 days (10k-row history must never overload the cockpit); imported QSOs carry source='jtdx' while live completions carry source='live'
NFR-086 DXCC stats GET /api/v1/dxcc returns ok envelope with total / entities / by_band, computed on first open and cached; any QSO write (record / import / void) marks the cache dirty so the next open recomputes (no per-open full scan, no push)
NFR-087 New-DXCC auto-call Decode messages carry is_new_dxcc; with setting auto_call_new_dxcc enabled the server auto-QSOs the first new-DXCC CQ when idle (safety-armed, no lease, never interrupts a QSO)
NFR-088 Propagation-driven band hunt With setting auto_band_hunt enabled and MRRC_FT8_BAND_HUNT_URL configured, the server polls an external /api/band_hunt endpoint (HTTP-only cross-repo boundary) for FT8 bands that nearby grids (within radius_km of our grid) are actively hearing; when idle it tunes the rig to the top band that still has unworked DXCC entities, then auto-call (NFR-087) closes the QSO. Guards: idle-only, min-dwell cooldown, never tunes during TX, endpoint failure skips the round