Skip to content

RTL: add SSB/CW and AM/SAM reception with selected decoder audio. Principle II. - #6432

Merged
jensenpat merged 1 commit into
mainfrom
codex/rtl-am-sam-rx
Oct 17, 2026
Merged

jensenpat merged 1 commit into
mainfrom
codex/rtl-am-sam-rx

Conversation

@Ozy311

@Ozy311 Ozy311 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds the SSB/CW and AM/SAM receive increment of RFC #5468 through RTL's existing shared capture, extractor and WDSP receiver bank. USB, LSB, CW, CWR, AM and synchronous AM produce independent 48 kHz receiver audio. Filter edits affect the passband; each mode recalls its last accepted filter. Receiver AGC, blanking, noise reduction, notches, APF and RIT publish and persist accepted state. CW pitch preserves the displayed RF carrier, and explicit CW/AM tuning prefers a capture clear of converter DC.

The selected receiver feeds CW decoding and Copy Assist before speaker gain/mute. Retuning, parking and selection changes retire stale audio and transcription results. The receive DSP capability record restricts APF to CW/CWR. The receive pitch record enables pitch control without granting TX. RTL retains the existing CWR mode token and scoped settings document.

Includes the reported speaker-icon fix, fixed receive-only antenna availability and Copy Assist teardown ordering. The shared Connected-indicator correction ends discovery on a newly confirmed connection, retains real link-loss alarms, and preserves rescans on repeated connected-tab refreshes. Automation forwards the existing ANF level argument; unsupported DSP-on requests are refused while cleanup off intents remain allowed.

Uses existing DSP dependencies and threads. Normal receiver capacity remains one; 2/4/8 are process-only evaluation settings. FM/FM-N/WFM retain their recipes. Digital broadcast decoding remains in #6002 / RFC #6079. This does not close the umbrella RFC.

Integration and review

Rebased onto main 9dfe8f666775b51a6012534bff7e7737ff0412b1 as signed commit 9df9135d197aadba5f1fefb20abdff4a71ac0241, preserving Ozy311's authorship. Keeps main's neural CW decoder integration, pitch slider, passive DSP readback, transmit acknowledgement route, profile/memory routing and settings consumers. The only final rebase conflict was regenerated log-reference line numbers; the production/test patch is unchanged. CW/CWR helpers use the existing model-layer ModeVocabulary.h owner.

The operator requested review, rebase and merge of this proposed change. The prior runtime-documentation, APF contract, automation cleanup, rescan and pitch-confirmation findings are corrected in this head. No workflow edits, CHANGELOG entry, frozen test-gate expansion or boundary-baseline increase.

New GUI/model touchpoints consume existing selected-receiver models: AsrAudioTap and CopyAssistController use DecoderAudioModel; RadioModel/SliceModel observations provide selection and lifecycle state. AudioButtonIcon shares the existing ThemeManager artwork. No new vendor-header crossing or engine-to-GUI dependency.

Validation

Current head 9df9135d1:

  • Native Apple Silicon app, daemon and 24 selected regression targets built with Qt 6.12.0, ASR and RADE enabled. No RNNoise x86 sources in the ARM build graph. The initial sandboxed iconutil failure cleared on the unchanged permitted incremental build.
  • 24/24 headless CTests pass, 92.61 s: RTL AM/SAM, SSB/CW, FM/WFM pipelines; model acceptance; capture transaction and scoped settings; typed receive intents; ASR engine/native receiver/tap; capability availability; DSP policy; filters; TNF removal; title bar; Phone/CW APF and accepted pitch; CW mode gates; current-main CW RX model and stored-control routing/dialog regressions.
  • Integration mutation on 2e4996250 (unchanged helper and test on the final head): omitting CWR from the shared mode vocabulary causes four CW mode-gate failures; the exact current source passes. No production source was altered for the isolated mutation.
  • Isolated offscreen bridge instance pr6432-final-20261017, PID 10312, explicit socket, fresh settings and autoconnect disabled: only DEMO-0001 connected; whoami reported txAllowed:false, radio state reported transmitting:false. Confirmed USB/CW/USB Copy Assist menu and panel transitions, slice mute readback, reconnect and window shutdown. Copy Assist destruction logged result=ok elapsed_ms=0; the owned process exited with code 0.
  • Engine boundary, touchpoint manifest, capability freeze and command-plane gates pass on main and the head. Same 101 tracked boundary findings, 70 capability booleans and 221 above-seam command strings. Test registration, frozen test gate, seam probe generation, WDSP test links, QSettings, bridge-doc and generated reference/log-rule checks pass. Accessibility warnings match main: 19, with no additions.
  • Exact-head hosted platform, Static checks, CodeQL and Docs results are recorded in this PR’s Checks tab. Required checks gate the protected merge. The preceding 2e4996250 head passed all hosted checks; that evidence is scoped to that head.

Earlier operator validation on the pre-rebase candidates confirmed USB, LSB, CW, AM/SAM reception and CW decoding with an IC-705 signal source, plus ASR on the SSB/CW candidate. Earlier explicit-fixture Whisper inference on demodulated AM/SAM speech produced nonempty transcripts. These are retained historical evidence, not new live RF or inference runs for the rebased head.

Limits

The demo does not exercise RTL USB capture or real SAM acquisition. Current local evidence is generated-IQ production-pipeline testing and shared demo UI behavior. No new live hardware, TX, instrumented RF sensitivity/distortion, portable macOS packaging, transcription accuracy or sustained eight-receiver qualification is claimed. SAM retains the existing ±2 kHz PLL bound; large carrier changes may require retuning. AM/SAM squelch is unavailable; APF is CW-only.

Generated with OpenAI Codex (GPT-6 Astra)

@Ozy311
Ozy311 requested a review from a team as a code owner October 13, 2026 10:11
@github-actions

Copy link
Copy Markdown

Accessibility check findings

This PR touches src/gui/ files with 19 accessibility issue(s).
Full details appear as inline annotations on the diff above.

Files scanned : 23
Files with findings: 6
Total findings : 19

See docs/a11y.md for the canonical
Qt patterns (setAccessibleName, QAccessibleValueChangeEvent,
QAccessibleInterface subclasses, etc.). Structural remediation
(keyboard navigation, custom QAccessibleInterface subclasses)
is tracked in #3288.

Findings are warnings only — the build is not blocked.

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue fit

No bug issue is linked — the PR cites RFC #5468 as its umbrella, which is the right authority for an architectural increment. I read #5468 and its thread: it conditionally approves the shared-capture/viewport/slice architecture, WDSP/r8brain reuse and 48 kHz audio, and it explicitly names "AM/SSB/CW are a later sprint" as in-scope-but-future for this RFC. So the feature is sanctioned. What #5468 does not settle, and says so in its own words, is the per-mode detail this PR now fixes in code:

"Final preset widths and FM deviation values need reviewer agreement and test coverage."
"SAM must be validated for synchronous tracking, not just recovery of a centered AM carrier."
"CW requires the established BFO/filter translation; selecting a WDSP CW enum alone does not create the expected pitch."
"resolve the current FMN/NFM and CWR/CWL differences deliberately"

Mapping those to the diff: the BFO/filter translation requirement is met (RtlReceiveRecipe.h, extractor translation and WDSP filter shift cancelling at the RF boundary). The SAM requirement is met and met well — tests/rtl_am_sam_pipeline_test.cpp:173 asserts ≥15 dB coherent rejection of a quadrature artifact that an envelope detector would demodulate, which is a real discriminator rather than a restatement of the implementation. The CWR/CWL vocabulary question is not resolved deliberately; see nit 3. The preset widths are chosen unilaterally and still want a maintainer's eye.

Verdict: solves the increment it claims. The signal path is the most carefully built RTL work I have reviewed on this RFC. I found no correctness blocker in the DSP, persistence, capability or lifetime paths.

Scope

File / group What it changes Claimed in body? Verdict
src/core/backends/rtl/*, src/core/dsp/WdspChannel.*, third_party/wdsp/include/aether_wdsp.h Native SSB/CW + AM/SAM recipes, tracking-notch bank, amd.c/ANR/ANF declarations Yes In scope
src/core/RtlSliceSettings.* Per-mode filter recall, receiveDsp object, notch bank persistence Yes (Principle V) In scope
src/core/backends/RadioCapabilities.h, ReceiveCommand.h New public capability records ReceiveDspControl, ReceiveCwPitchControl Yes Needs maintainer decision — new capability surface third parties and other backends bind to
src/models/TnfModel.*, TransmitModel.*, SliceModel.* ReceiveControlPolicy::Confirmed extended to notches and CW pitch Yes In scope, but see decision item 1
src/asr/AsrEngine.*, src/gui/AsrAudioTap.*, CopyAssistController.*, src/core/PcmFrame.h Source lease + generation through queue→inference→delivery Yes In scope
src/gui/ControlAvailabilityRegistry.*, RxApplet.cpp, VfoWidget.cpp registerRestriction(), per-mode receive-control dimming, RX/TX ANT availability Yes In scope
src/gui/AudioButtonIcon.h, TitleBar.cpp, RxApplet.cpp, VfoWidget.cpp (commit bb42653) Extracts the existing buildAudioIcon out of TitleBar so slice speaker buttons stop depending on an emoji glyph Yes ("operator-reported speaker-icon fix") Bundled fix — correct and authority-backed (the deleted TitleBar comment itself documents why emoji was wrong), but it is a separate operator report with no issue cited
src/gui/TitleBar.cpp (commit 3867c56) setRadioTabs() now clears m_discovering whenever any tab reads Connected Yes ("Connected indicator fix") Bundled, and cross-family — see decision item 2
src/gui/MainWindow.cpp (commit 0b0e9c0) Deletes m_copyAssistController in preparePanadapterUiForShutdown() Yes ("Copy Assist teardown correction") Bundled fix, no issue cited
src/core/AutomationServer.cpp receiveDspControl gate for slice dsp; plus setAnfLevel now honoured Gate yes; setAnfLevel no Cross-family widening, undisclosed — nit 2
src/core/AetherDspModePolicy.* CWR added to the disable list; mix predicate now requires receiving Not explicitly In scope (CWR is a new RTL mode)
docs/user/src/components/LogAnalyzer/rules.json Line-number churn tracking RadioModel.cpp growth No In scope — required maintenance, Static checks green
docs/architecture/aetherd-touchpoints.md Generated include counts (ThemeManager 178→179, DecoderAudioModel 1→3, RadioModel 53→54, SliceModel 36→37) Checklist mentions touchpoints In scope
docs/rtl-ssb-cw.md, docs/rtl-am-sam.md, docs/user/docs/* New signal contracts + user guide Yes In scope, but rtl-m1-runtime.md is now self-contradictory — nit 1

Four distinct operator-reported fixes ride along with the feature. All four are correct as far as I can tell; none is smuggled preference. But none cites an issue number, and one of them is cross-family.

Blockers

None. I could not find a correctness, canon or lifetime defect that breaks users or fails on current main.

Needs maintainer decision

  1. New public capability surface. src/core/backends/RadioCapabilities.h:63-80 adds ReceiveDspControl and ReceiveCwPitchControl, and ReceiveControlPolicy::Confirmed now reaches TnfModel and TransmitModel. These are declarations other backends and the caps-map doc will bind to for a long time. Per my reading, no FROZEN_BOOL_COUNT ruling is needed — these are std::optional<struct> records, not bools — but the shape itself is a maintainer call, especially given item 3 below. docs/architecture/radio-capabilities-map.md:978-1009 documents them, which is the right half of the AGENTS.md contract.

  2. src/gui/TitleBar.cpp:659-666 is a cross-family behavior change in an RTL PR.

        for (const RadioTabEntry& radio : radios) {
            if (radio.status == RadioTabStatus::Connected) {
                setDiscovering(false);
                break;
            }
        }

    setRadioTabs() runs for every family. Before this, m_discovering was cleared only by TitleBar::onHeartbeat() (TitleBar.cpp:1601) — a network heartbeat. For Flex/HL2/Icom the end state is unchanged (the first heartbeat already cleared it), so the practical effect on network radios is that amber→green happens on tab status rather than first beat. But it also means that starting a new discovery scan (MainWindow.cpp:2449, MainWindow_Session.cpp:439 set setDiscovering(true)) is now silently undone on the next tab refresh whenever any radio is connected. The RTL need — "a USB receiver does not need a network heartbeat" — is real, but the fix is ungated: it does not ask the backend whether it has a heartbeat. I would want this either gated on a capability/backend property or split into its own PR with the operator report linked. The commit message and the rtl-sdr.md:29 paragraph both frame it as RTL-specific; the code is not.

  3. Preset widths and the CWR vocabulary. RtlSdrBackend.cpp:313-321 pins the per-mode filter bounds (USB 0..12000, CW ±12000, AM/SAM ±100..±12000) and initialReceiver() picks 100..2900 for the USB bootstrap. #5468 reserved these for reviewer agreement. Same for CWR as the user-facing token (nit 3).

Nits (non-blocking)

1. docs/rtl-m1-runtime.md now states the opposite of what the code does for AM/SAM — three places. The SSB/CW commit (ed59db3) edited this file; the later AM/SAM commit (a2a45b0) did not come back to it.

  • docs/rtl-m1-runtime.md:103:

    "USB, LSB, CW and CWR use native independent 48 kHz receiver recipes … AM/SAM retain their exclusive legacy DDC and 24 kHz format."

    docs/rtl-am-sam.md:3 says the opposite ("AM and SAM use the existing shared-capture extractor and prepared WDSP receiver bank at 48 kHz"), as does docs/user/docs/rtl-sdr.md:63 ("Both modes have independent 48 kHz audio"). Suggested replacement for that sentence:

    AM and SAM use the same native bank; their carrier and audio-filter contract
    is described in [AM/SAM reception](rtl-am-sam.md).
  • docs/rtl-m1-runtime.md:139 — "FM/FM-N and CW/CWR establishment and necessary capture recentering prefer a hardware center…" omits AM/SAM, but RtlReceiveRecipe.h:25-26 is amplitude(mode) || cw(mode) || Fm || Fmn, so AM/SAM are in the DC-clear preference, and docs/rtl-am-sam.md:27 says so explicitly.

  • docs/rtl-m1-runtime.md:153 — "This DC preference does not alter WFM, SSB or the remaining legacy demodulators." SSB and WFM are right (USB/LSB are not in dcSensitive), but AM/SAM are no longer "remaining legacy demodulators".

This is the one item I would want fixed before merge: DEVELOPER-GUIDE.md now points reviewers at these contract docs, and a maintainer reading rtl-m1-runtime.md would conclude AM/SAM is still legacy 24 kHz.

2. src/core/AutomationServer.cpp:7884-7892 — the confirmed branch refuses turning a control off, where the legacy branch only refused turning it on.

        if (receiveDsp && which != QLatin1String("squelch")) {
            using Feature = ReceiveDspControl::Feature;
            const Feature feature = which == QLatin1String("nr") ? Feature::Nr
                : which == QLatin1String("anf") ? Feature::Anf : Feature::Nb;
            if (!receiveDsp->supports(feature, s->mode())) {

The old code guarded on on && …. A teardown script that issues slice dsp nr off across every slice now gets refused: nr is unavailable in receive mode FM on an RTL FM slice, where it previously succeeded as a no-op. Drop-in:

            if (on && !receiveDsp->supports(feature, s->mode())) {

Also in this hunk: src/core/AutomationServer.cpp:7917 adds if (level >= 0) { s->setAnfLevel(level); }. That is consistent with the nr branch above it and almost certainly right, but it changes slice dsp anf on 50 for every family (the level argument was previously parsed and ignored for anf). Worth a line in the PR body.

3. ReceiveDspControl::supports() is a flat modes × features product, so it cannot express "APF is CW-only" — and APF is declared over all six modes.
src/core/backends/RadioCapabilities.h:70-73:

    bool supports(Feature feature, const QString& mode) const
    {
        return features.contains(feature) && modes.contains(mode);
    }

src/core/backends/rtl/RtlSdrBackend.cpp:268-272 declares modes = {AM, SAM, USB, LSB, CW, CWR} and features including Apf, so supports(Apf, "AM") == true. But src/core/backends/rtl/RtlReceiveRecipe.h:101 applies it only in CW:

        dsp.apfEnabled = cw(receiver.mode) && receiver.apfEnabled;

while RtlSdrBackend.cpp:1137 stores the request unconditionally and RtlSdrBackend.cpp:2180 reports it back as accepted (delta.apf = receiver.apfEnabled). So on an AM slice, a setApf(true) is accepted, published, and persisted (RtlSliceSettings.cpp:77) with no peaking filter running. This contradicts the record's own documented contract in docs/architecture/radio-capabilities-map.md:989 — "a present record makes unlisted features/modes unavailable" — and the repeated doc claim that "APF remains CW-only".

I could not reach it as a user-visible bug: src/gui/VfoWidget.cpp:4940 and :5531 already do m_apfBtn->setVisible(isCw), and the automation bridge's kWhich list has no apf. So today it is latent. If a per-mode feature map is out of scope for this PR, the honest minimum is to drop Feature::Apf from the declared set and keep APF gated by mode as it already is.

4. docs/user/docs/rtl-sdr.md regresses the user-facing CW-reverse label from CW-R to CWR, and the PR is internally inconsistent about it. rtl-sdr.md:33, :49, :55, :91 now say CWR (previously CW-R), while cw-decoder.md:41 and :63 — added in the same PR — say CW-R, and cw-decoder.md:21 says "CWR (shown as CW-R on some radios)". CWR is the internal mode token; the user guide had the friendlier form. This is exactly the "resolve the CWR/CWL difference deliberately" item #5468 asked for, so it is worth one decision rather than two spellings.

5. src/gui/VfoWidget.cpp:6815-6826 — the shared DSP level slider's predicate falls through to return false.

                default: return false;

On any receiveDspControl radio this disables the slider (with "This DSP parameter is unavailable in the current receive mode") for every target that is not LvlNB/LvlNR/LvlAnf/LvlMn — including LvlNone and the LvlNrl/LvlNrs/LvlNrf/LvlAnfl client-chain targets. Benign today: VfoWidget.cpp:3516 hides m_nrlBtn behind m_hasRadioSideDsp && m_hasLmsNoiseFilters, so those targets are unreachable on RTL. But a catch-all false on a widget whose reason string names the receive mode will mislabel the next target someone adds.

6. tests/rtl_slice_settings_test.cpp has no duplicate-notch-id refusal case. RtlTrackingNotches::valid() enforces uniqueness (RtlTrackingNotches.h:28-30) and decode() gets it for free from JSON key uniqueness, but patch() accepts a caller-supplied vector where duplicates are constructible. The width-199 refusal case at :68-71 is exactly the right shape — one more line in the same style would cover it.

7. tests/tests.cmake:1774 — missing blank line between add_test(NAME cw_mode_gate_test …) and add_executable(flex_slice_mode_intent_test. Cosmetic only; every other block in the file is separated.

Socket-test disclosure

No socket-owning test is added, modified or removed by this PR. I grepped every added/changed file under tests/ in the PR head for QTcpServer/QTcpSocket/QUdpSocket/QLocalServer/QWebSocketServer/bind(/listen(/connectToHost/class Fake. The only hit is tests/asr_engine_test.cpp:52 class FakeBackend : public IAsrBackend — a local inference stub, not a fake radio/amplifier/tuner peer, and pre-existing on main. The three new signal-path targets (rtl_am_sam_pipeline_test, rtl_ssb_cw_pipeline_test, cw_mode_gate_test) and asr_native_receiver_test are socket-free, which matches the body's claim. asr_native_receiver_test is correctly joined to AETHER_SETTINGS_CONSUMERS (tests/tests.cmake:8569).

Security audit

A CodeGuard security audit ran over the 41 flagged files and returned no confirmed findings. What it refuted, so this is not mistaken for a blanket clean bill:

  • The ~400 CS-VLN-CMDI-* hits in AutomationServer.cpp are lexical matches on Flex/TCI wire-protocol string literals and Markdown-quoted verbs in comments. No shell is invoked in any changed file.
  • Every CS-PII-*, CS-VLN-SSRF-*, CS-VLN-SQLI-SLEEP and CS-VLN-PATH-* hit is inside docs/user/src/components/LogAnalyzer/rules.json — a data file of regexes whose job is to match diagnostic log lines. The patterns are the rule content.
  • CS-SEC-PASSWORD in CopyAssistController.cpp is the pre-existing keychain-backed remote-ASR key field, line-shifted only.
  • The listener is unchanged: still QLocalServer with UserAccessOption, and the ~11 net new lines in AutomationServer.cpp sit inside doSlice, behind the shared-secret gate. No new bind, no new pre-auth verb.

What I tried to break

Everything below is reasoned from the code in the PR head checkout — I have no build and no way to run the GUI, so none of it was reproduced at runtime.

  • The AM post-detector filter math, because it is the claim most likely to be hand-waved. It holds, and the comment at WdspChannel.cpp:555-558 is accurate. amd.c:142-143 (AM) and :218-219 (SAM) both write identical real audio into out_buff[2i+0] and [2i+1]. RXA.c:647/652/664 puts bp1 after xamd, so the 50 Hz..max(-low, high) bandpass set at WdspChannel.cpp:1594-1597 is a genuine post-detector audio filter and not an RF cut that would strip the carrier; RXANBPSetFreqs keeps the signed RF cuts on nbp0. For input a+ja, a positive-frequency analytic filter yields (a−H{a}) + j(a+H{a}), so 0.5*(L+R) recovers exactly a — and RXAbp1Check (RXA.c:906-920) only adjusts gain, never frequencies, so it cannot silently override the 50 Hz low cut. tests/rtl_am_sam_pipeline_test.cpp:150 pins the resulting absolute level to within 5%, which is what makes that chain of reasoning checkable.
  • Whether AetherDspSliceAudioState::receiving silently disables the CW/NNR auto-disable on Flex. It does not. MainWindow_DspApplets.cpp:223 feeds slice->inCapture(); SliceModel.h:671 defaults m_inCapture{true} and SliceModel.cpp:1901 only moves it when a backend sends SliceDelta::inCapture, which only RTL does. Flex behavior is unchanged. MainWindow_Wiring.cpp:1960 correctly re-runs the policy on inCaptureChanged, so parking an RTL CW slice actually re-evaluates.
  • Whether ReceiveControlPolicy::Confirmed leaks across a radio swap and strands Flex notches. It does not. RadioModel.cpp:4337 and :4348 both reset to Optimistic / false through publishCapabilities(connected) on disconnect, and TransmitModel::resetState() clears m_confirmReceiveCwPitch as well.
  • Whether the confirmed TNF loop actually closes. It does. TnfModel now returns early on confirmsControls() for freq/width/depth/permanent/remove/global-enable, and RtlSdrBackend.cpp:2403/2411/2415 emit notchRemoved, notchChanged and RadioDelta::tnfEnabled after adoption. createTnf needed no guard — it was already intent-only. MainWindow_Wiring.cpp:4480 rebuilds the markers on notchChangeRequested only when confirmed, which is the right side of the fork.
  • Whether maxNotchFilters stays 0 for the whole session. It does not. It is conditional on hasAnalogDsp (RtlSdrBackend.cpp:273), and RtlSdrBackend.cpp:2426 emits capabilitiesChanged() precisely when hasAnalogDsp(prior) != hasAnalogDsp(state), which RadioModel.cpp:1159 turns back into publishCapabilities().
  • state.receivers.front() at RtlSdrBackend.cpp:2419 with no empty guard, ten lines after :2259 defensively handles state.receivers.empty(). Safe: RtlCaptureTransaction.cpp:228 rejects desired.receivers.empty(), and removeSlice() (:871) refuses at size() <= 1, so a confirmed state always has ≥1 receiver.
  • Notch-id overflow and reuse. m_nextNotchId is re-seeded from restored entries with an explicit INT_MAX branch (:1646), and createNotch refuses at INT_MAX (:1156), so the restored-INT_MAX collision I went looking for is closed. Ids are never used as indices — every consumer is find_if/erase_if, and the WDSP slot is a separate local counter (WdspChannel.cpp:1639).
  • The ASR generation/lease race. AsrEngine::reset() bumps m_generation and calls setInputGeneration() directly (atomic, main thread) before queueing requestReset, so an in-flight blocking transcribe fails inputCurrent() immediately rather than after the queued slot runs. requestProcess is queued after, so a stale chunk deterministically fails generation != m_requestedGeneration. The source == 0 sentinel for the legacy pushAudio path is sound: PcmProducer::start() rejects m_source == 0 and s_nextSource starts at 1, so no real producer can masquerade as "no lease".
  • pushNativePcm indexing (AsrEngine.cpp:658-667). frame.current() guarantees a non-null epoch, PcmFormat::channels() is 1 or 2 by construction, and frameCount() is samples.size()/channels, so i*channels + 1 cannot run past the buffer.
  • A hand-edited settings file as a denial-of-reception. RtlReceiveRecipe.h:113-120 drops every notch outside [filterLowHz, filterHighHz] before WDSP, so a persisted 1.7 GHz notch cannot trip the stricter bank validation at WdspChannel.cpp:1406-1413. decode() only assigns output on full success (RtlSliceSettings.cpp:244), and patch() re-decodes before writing, so a refused bank cannot overwrite good state — tests/rtl_slice_settings_test.cpp:68-71 asserts exactly that.
  • The tests themselves, for whether they would pass against unfixed code. They would not. rtl_am_sam_pipeline_test.cpp measures demodulated audio — absolute modulation level (:150), second-harmonic distortion (:151), carrier-DC suppression (:152), quadrature rejection separating SAM from envelope AM (:173), both-sideband MN depth (:288), and epoch invalidation across retune/park/recreate (:221/227/237/243). Receiver controls are verified on audio, not inferred from a setter returning true. rtl_slice_settings_test.cpp has real refusal cases, not just round-trips.
  • The bundled speaker-icon commit, for smuggled preference. It is not. bb42653 extracts the existing buildAudioIcon out of TitleBar.cpp verbatim into AudioButtonIcon.h and reuses it from RxApplet/VfoWidget; the deleted TitleBar comment is itself the authority ("emoji render in the platform's own colour and weight, so they never matched the bar around them and could not follow the theme"). Extending that to the slice speaker buttons is a fix, not a restyle.

Could not check: live RF behavior, SAM PLL acquisition against a real station, and whether the ±2 kHz create_amd bound (RXA.c:180-181) is adequate in practice — the docs are honest that it is not qualified. I also did not evaluate the eight-receiver evaluation path beyond reading its guards.

CI: all 10 checks are green on head 35ea31ae3, including check-windows (the -DENABLE_ASR=OFF lane, which is where an unguarded ASR reference would surface) and check-macos. The body's unchecked "Hosted PR CI" box is now satisfied. Standing caveat: ctest in ci.yml is -R-filtered, so green proves the full-tree build plus a named subset, not the ~240-test suite — the three new pipeline targets are not in that gate.

Recommendation

Needs maintainer decision. There is no blocker: the DSP is correct and well-reasoned, the persistence is capability-shaped and refusal-safe, the confirmed-control loop actually closes, and the tests measure outcomes rather than asserting the implementation back to itself. This is high-quality work and it survived every attack I could mount from static reading.

What needs a human ruling is not correctness but surface: two new public capability records, the unilateral filter-preset and CWR-vocabulary choices that #5468 explicitly reserved for reviewer agreement, and one bundled commit (3867c56, the TitleBar discovery clear) that changes behavior for every radio family while being described as RTL-specific.

Concrete next step for the author, none of which needs a maintainer first: fix the three stale rtl-m1-runtime.md sentences about AM/SAM (nit 1), settle on one user-facing spelling of CW-reverse (nit 4), restore the on && guard in the automation branch (nit 2), and either drop Feature::Apf from RTL's declared set or say in the body that the record is a coarse product (nit 3). Then the open questions are purely the maintainer's: the capability shape, the presets, and whether 3867c56 should be gated or split out.

Thank you for the unusually careful validation write-up — scoping the earlier platform evidence to the pre-integration candidate rather than claiming it for 35ea31ae is the right call and made this much easier to review.


🤖 aethersdr-agent · cost: $21.8387 · model: claude-opus-5

@aethersdr-agent

Copy link
Copy Markdown
Contributor

Cisco CodeGuard — static analysis of this PR (431 finding(s))

  • [MEDIUM] CS-VLN-SSRF-HEX — Vulnerability: CS-VLN-SSRF-HEX in docs/user/src/components/LogAnalyzer/rules.json /tmp/aetherclaude/pr-6432/docs/user/src/components/LogAnalyzer/rules.json:89
  • [HIGH] CS-VLN-PATH-UNC — Vulnerability: CS-VLN-PATH-UNC in docs/user/src/components/LogAnalyzer/rules.json /tmp/aetherclaude/pr-6432/docs/user/src/components/LogAnalyzer/rules.json:744
  • [HIGH] CS-VLN-PATH-UNC — Vulnerability: CS-VLN-PATH-UNC in docs/user/src/components/LogAnalyzer/rules.json /tmp/aetherclaude/pr-6432/docs/user/src/components/LogAnalyzer/rules.json:1003
  • [HIGH] CS-PII-DL-1 — PII detected: drivers_license in docs/user/src/components/LogAnalyzer/rules.json /tmp/aetherclaude/pr-6432/docs/user/src/components/LogAnalyzer/rules.json:88
  • [HIGH] CS-VLN-SSRF-PRIV-192 — Vulnerability: CS-VLN-SSRF-PRIV-192 in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:6982
  • [HIGH] CS-VLN-SSRF-LOCALHOST — Vulnerability: CS-VLN-SSRF-LOCALHOST in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:12256
  • [HIGH] CS-VLN-SSRF-LOCALHOST — Vulnerability: CS-VLN-SSRF-LOCALHOST in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:12257
  • [MEDIUM] CS-VLN-SSRF-HEX — Vulnerability: CS-VLN-SSRF-HEX in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:6192
  • [CRITICAL] CS-VLN-CMDI-SEMI — Vulnerability: CS-VLN-CMDI-SEMI in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:1759
  • [CRITICAL] CS-VLN-CMDI-SEMI — Vulnerability: CS-VLN-CMDI-SEMI in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:7470
  • [CRITICAL] CS-VLN-CMDI-SEMI — Vulnerability: CS-VLN-CMDI-SEMI in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:13047
  • [CRITICAL] CS-VLN-CMDI-AMP — Vulnerability: CS-VLN-CMDI-AMP in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2394
  • [CRITICAL] CS-VLN-CMDI-AMP — Vulnerability: CS-VLN-CMDI-AMP in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:8444
  • [CRITICAL] CS-VLN-CMDI-AMP — Vulnerability: CS-VLN-CMDI-AMP in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:9470
  • [CRITICAL] CS-VLN-CMDI-AMP — Vulnerability: CS-VLN-CMDI-AMP in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:11491
  • [CRITICAL] CS-VLN-CMDI-AMP — Vulnerability: CS-VLN-CMDI-AMP in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:11854
  • [CRITICAL] CS-VLN-CMDI-AMP — Vulnerability: CS-VLN-CMDI-AMP in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:12413
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:299
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:463
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:840
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:949
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:1306
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:1379
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:1531
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:1608
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:1755
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:1785
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:1789
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2003
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2113
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2172
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2180
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2292
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2390
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2421
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2720
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2743
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2816
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:2882
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Vulnerability: CS-VLN-CMDI-BACKTICK in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6432/src/core/AutomationServer.cpp:3353

Automated static scan by Cisco DefenseClaw CodeGuard on the changed files. Advisory — some may be false positives; the review above verifies them.


🤖 aethersdr-agent · cost: $22.2882 · model: claude-opus-5

@aethersdr-agent

Copy link
Copy Markdown
Contributor

Antares Detector — candidate vulnerable file(s)

  • src/core/backends/rtl/RtlRfExtractor.cpp
  • src/core/backends/rtl/RtlRfExtractor.h

RtlRfExtractor uses std::memcpy with an index-based pointer expression (m_convertedI.constData() + index * sizeof(float)). The code increments m_stagedOutput and checks against m_config.blockSize, but does not validate that the computed index is less than m_convertedI.size()/sizeof(float). If index can exceed the number of valid stages, this will write out of bounds, causing a memory-safety vulnerability (CWE-190).

Localized by Cisco Foundation AI Antares-1B running locally in the AetherClaude sandbox, seeded by the Cartographer security map. Advisory only — please verify before acting.


🤖 aethersdr-agent · cost: $22.2882 · model: claude-opus-5

@rfoust rfoust left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implements the SSB/CW and AM/SAM increment of RFC #5468: actual filtering and demodulation, accepted-state controls and persistence, and selected-receiver decoder audio. It preserves the one-receiver production limit. No confirmed correctness blockers; recommendation: Needs maintainer decision on the new capability records and mode-default filters. The RFC reserves final preset widths for reviewer agreement, and GOVERNANCE.md reserves final architecture/UX direction to Jeremy.

Scope

Change group Claimed in title/body? Assessment
RTL extraction, WDSP recipes, filters and DSP controls Yes Within RFC scope
Models, capabilities and persistence Yes Necessary; new capability shape needs maintainer agreement
CW decoder and Copy Assist routing/lifecycle Yes Within stated scope
Speaker artwork and antenna availability Yes Disclosed related fixes
Connection indicator Yes Disclosed; affects every radio family
Tests and documentation Yes Relevant; no CI gate expansion or CHANGELOG entry

No unrelated commits or unexplained file groups found. The body's scope/dependency/settings checklist holds up, subject to the documentation and capability nits below.

Blockers

None confirmed.

Non-blocking findings

  1. Stale runtime documentation: inline comment on docs/rtl-m1-runtime.md:103. AM/SAM now use independent 48 kHz receiver recipes. The bootstrap and DC-placement descriptions in the same guide also need updating.
  2. APF capability overstates support: inline comment on src/core/backends/rtl/RtlSdrBackend.cpp:271. The record advertises APF in every listed analog mode, while dispatch accepts it only in CW/CWR. Existing UI checks mask this, but the capability should describe actual feature-by-mode support.

Verification and attacks that survived

Reviewed main 47aa4098d2b3182c8608d9bd7f4b6d842758d84a, head 35ea31ae3f17cd56b79d24ae934b57c3854e14dd, and merge result 2ae0e10f6bd2421163872f5be7b381c124645da2. The head/base remain unchanged at posting. Current CI is green (release PDF attachment skipped); no existing inline review threads. CI is filtered and does not establish a full-suite pass.

  • Native Apple Silicon application build passed with the prescribed ARM64 toolchain, RADE enabled, ARM64 host/system/executable checks, and no RNNoise x86 sources.
  • All nine focused tests passed: rtl_am_sam_pipeline_test, rtl_ssb_cw_pipeline_test, rtl_model_acceptance_test, rtl_slice_settings_test, receive_intent_routing_test, asr_engine_test, asr_native_receiver_test, control_availability_registry_test, and unified_title_bar_test.
  • Sideband rejection, SAM discrimination, filter/RIT boundaries, sparse restoration, parked-receiver handling, stale PCM/transcript rejection and cross-radio control routing survived these checks. The three signal/model tests passed in 178.13 seconds locally.
  • Mutation evidence: temporarily removing the final ASR delivery generation/lease guards caused exactly two assertions to fail: queued transcript from old generation is suppressed and producer retirement suppresses queued native transcript without a reset callback. Restoring the exact source made the test pass again.
  • Engine boundary, touchpoint manifest, capability-record and command-plane checks passed on main and the PR. Per-file comparison found no increased boundary violations.
  • Socket preflight inspected every changed test source. No socket-owning test was added or changed; the inference stub is not a synthetic firmware peer.
  • Drove the merge-result application offscreen with isolated settings, explicit socket /private/tmp/pr6432-review-971e.sock, and only DEMO-0001. whoami reported txAllowed: false; get radio reported model: "AetherSDR Demo", serial: "DEMO-0001", and transmitting: false. Verified green Connected presentation, mute convergence, Copy Assist visibility across USB/CW transitions, and simulator reconnect. After the mute/CW actions, model output included mode: "CW", audioMute: true, frequency: 14.1, inCapture: true; Copy Assist was hidden in CW.
  • Copy Assist teardown logged phase=asr.controller.destroy event=end result=ok elapsed_ms=0; the window and bridge closed, but the process lingered and required termination. Clean process exit remains unverified. This is an unattributed verification limit, not a PR regression finding without a baseline comparison. Both owned processes were cleaned up.

No live hardware, TX, sustained receiver-capacity qualification, or real-model speech inference was independently performed. The demo cannot exercise RTL USB capture/SAM reception; those conclusions rely on production-pipeline tests. No separate automated review tool was available; the second pass was manual.

Next step: correct the two non-blocking findings and obtain Jeremy's agreement on the new capability shape and mode defaults before landing. This is a comment review, not approval or a merge authorization.

Comment thread docs/rtl-m1-runtime.md Outdated
Comment thread src/core/backends/rtl/RtlSdrBackend.cpp
@github-actions

Copy link
Copy Markdown

Accessibility check findings

This PR touches src/gui/ files with 19 accessibility issue(s).
Full details appear as inline annotations on the diff above.

Files scanned : 24
Files with findings: 6
Total findings : 19

See docs/a11y.md for the canonical
Qt patterns (setAccessibleName, QAccessibleValueChangeEvent,
QAccessibleInterface subclasses, etc.). Structural remediation
(keyboard navigation, custom QAccessibleInterface subclasses)
is tracked in #3288.

Findings are warnings only — the build is not blocked.

@Ozy311

Ozy311 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Addressed the concrete review findings in signed commit d3ce283 (GitHub Verified).

Review item Correction / disposition
AM/SAM runtime documentation Corrected independent 48 kHz recipes, native muted bootstrap, squelch and DC-placement descriptions.
APF capability mismatch Added per-feature mode restrictions. RTL advertises APF only in CW/CWR; common-mode and missing-feature restrictions still apply. The backend already rejected APF outside CW, and this now makes the advertised contract agree.
Automation DSP off Restored the on && admission guard; cleanup NR/ANF/NB/NB2 off intents remain accepted in an unsupported mode. Accepted state is still authoritative. Documented the cross-family ANF-level forwarding in the PR body.
Discovery while connected End discovery only on a newly connected radio ID. Repeated connected snapshots and nickname changes no longer cancel a rescan; reconnect, additional-radio connection and link-loss behavior are covered. This is explicitly described as shared title-bar behavior.
CW-reverse wording Kept CWR, which the RTL backend declares and the VFO displays directly. Corrected the inconsistent decoder guide and explained reverse CW; no runtime token, preset or settings migration was introduced.
VFO slider restriction The receiver-specific restriction no longer disables unrelated client-chain parameter targets. Their existing control logic retains ownership.
Additional tests / formatting Added duplicate caller-supplied notch-ID refusal with unchanged-document verification, capability restriction cases, and the requested CMake block separation.

Validation:

  • rtl_model_acceptance_test, automation_dsp_backend_readback_test, and unified_title_bar_test each failed with the new regressions against the pre-fix implementation, then passed with the fixes.
  • Six focused targets pass on macOS/Clang and Nobara Linux/GCC: the three above plus rtl_slice_settings_test, control_availability_registry_test, and receive_intent_routing_test (38.98 s / 32.02 s).
  • Full Mac and Nobara app builds pass. A clean d3ce2838 offscreen instance, isolated settings and TX disabled, connected only to DEMO-0001, established a slice, switched USB/CW/USB, and closed with exit 0. The reported lingering process did not reproduce in this bounded session; this is not a claim that every Copy Assist inference/shutdown sequence is covered.
  • Documentation production build, generated references/log rules, capability freeze, test registration, engine boundary, command plane, seam probes and WDSP test-link checks pass. Fresh hosted CI is running.

Advisory triage: the 19 accessibility warnings are identical to the trusted main snapshot (no additions). The RtlRfExtractor advisory is not a demonstrated out-of-bounds path: this PR does not change that file, Resampler::process sizes/writes the byte buffer for exactly the returned float count, and the consumer additionally bounds that count to 0..16384 before indexing. No extra extractor change was made.

The new capability shape, confirmed-control integration and filter presets remain for Jeremy's decision. The rescan regression is corrected, and the shared scope of the indicator fix is explicit; whether to keep that bundled correction here is still a maintainer scope call. No approval or merge is implied by this fix report.

73, Ozy K6OZY · Codex

@Ozy311

Ozy311 commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Resolved the new main conflicts in signed commit 3988aa2, incorporating main 83883fc.

The integration preserves the new CW pitch slider and main's passive DSP level readback. RTL pitch requests keep both the slider and editor at the accepted value until backend adoption. The combined generated manifest and log references were regenerated.

Validation on Nobara (Linux/GCC): 9/9 focused control/model/UI tests and 2/2 AM/SAM + SSB/CW pipeline tests pass. Temporarily removing the pitch-confirmation guard produces two assertion failures; restored source passes and the checkout is clean. Docs build and static/generated checks pass. Fresh hosted platform CI is required for this head; prior Windows/macOS results are not being represented as new native runs.

The earlier review fixes remain in place. The capability-shape discussion remains open for maintainer agreement. No merge or auto-merge was requested.

@github-actions

Copy link
Copy Markdown

Accessibility check findings

This PR touches src/gui/ files with 19 accessibility issue(s).
Full details appear as inline annotations on the diff above.

Files scanned : 24
Files with findings: 6
Total findings : 19

See docs/a11y.md for the canonical
Qt patterns (setAccessibleName, QAccessibleValueChangeEvent,
QAccessibleInterface subclasses, etc.). Structural remediation
(keyboard navigation, custom QAccessibleInterface subclasses)
is tracked in #3288.

Findings are warnings only — the build is not blocked.

@jensenpat jensenpat self-assigned this Oct 17, 2026
@jensenpat
jensenpat force-pushed the codex/rtl-am-sam-rx branch from 3988aa2 to 2e49962 Compare October 17, 2026 18:09
@github-actions

Copy link
Copy Markdown

Accessibility check findings

This PR touches src/gui/ files with 19 accessibility issue(s).
Full details appear as inline annotations on the diff above.

Files scanned : 23
Files with findings: 6
Total findings : 19

See docs/a11y.md for the canonical
Qt patterns (setAccessibleName, QAccessibleValueChangeEvent,
QAccessibleInterface subclasses, etc.). Structural remediation
(keyboard navigation, custom QAccessibleInterface subclasses)
is tracked in #3288.

Findings are warnings only — the build is not blocked.

jensenpat
jensenpat previously approved these changes Oct 17, 2026

@jensenpat jensenpat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head 2e49962504bcae7e50ea84e4e65c54a3275506e9, rebased onto main 3c81b3d81df3675122dd7688b2d2e8b343d0cc54. No confirmed correctness blockers remain. The operator explicitly requested review, rebase and merge of this proposed change; this landing retains the corrected capability records, filter presets and disclosed shared title-bar behavior under that direction.

The rebase preserves Ozy311's authorship and the prior review fixes. APF advertisement now matches CW/CWR-only dispatch; runtime documentation matches the 48 kHz native recipes; unsupported DSP-on requests retain cleanup-off behavior; connected-tab refreshes preserve rescans. Current-main pitch-slider confirmation, passive DSP readback, neural CW decoder integration, transmit acknowledgement routing and settings isolation are preserved. The CW/CWR helpers were integrated into main's existing model-layer ModeVocabulary owner rather than duplicated in the GUI header.

Verification on this exact head:

  • Native ARM64 Qt 6.12.0 app, daemon and 22 regression targets built, ASR and RADE enabled; no RNNoise x86 sources in the ARM graph. The initial iconutil sandbox failure cleared on the unchanged permitted incremental build.
  • 22/22 selected headless CTests passed in 89.54 s, including generated-IQ AM/SAM, SSB/CW and FM/WFM production pipelines, accepted RTL model state, transactional/scoped settings, typed cross-radio receive intents, ASR generation and native-source retirement, control availability, title bar, Phone/CW accepted pitch/APF, filter policy, TNF removal, CW mode gates and main's CW RX model.
  • An isolated mutation omitting CWR from the shared mode vocabulary produced four CW mode-gate failures; the exact current implementation reports zero failures. Existing submitted regressions also cover the prior APF, discovery and pitch-confirmation findings; their current passes are included above.
  • Owned offscreen bridge instance PID 6014, isolated settings, explicit socket and disabled autoconnect: only DEMO-0001 connected. whoami reported txAllowed:false; radio state reported transmitting:false. Observed Copy Assist enabled in USB, disabled and unchecked after CW, enabled again in USB; mute readback was audioMute:true, and the demo reconnected successfully. Closing its MainWindow retired Copy Assist with phase=asr.controller.destroy event=end result=ok elapsed_ms=0; the owned process exited.
  • Main/head boundary comparison passes with the same 101 tracked findings, 70 capability booleans and 249 raw above-seam command strings. Generated touchpoints, seam probes, references and bridge docs; log rules; test registration; frozen test gate; WDSP test links; and QSettings checks pass. Accessibility findings match main's 19 existing warnings.
  • Hosted Static checks, Docs and all three CodeQL analyses pass on this head. Linux, Windows and macOS builds are still running; protected auto-merge must wait for all required checks to pass. CI is a build/platform-specific filtered-test gate, not evidence of a full-suite pass.

Both review threads have evidence-bearing replies and are resolved. The extractor security advisory is not a demonstrated out-of-bounds path: Resampler::process sizes the byte output for its returned sample count, and the unchanged consumer bounds that count before indexing. The CodeGuard shell-injection candidates are protocol strings with no shell invocation; the log-rule findings are matching data. The added GUI/model includes consume existing receiver-selection models and existing ThemeManager artwork; no vendor-boundary or baseline weakening was introduced.

No separate automated code-review tool was available; the adversarial pass was manual. No live hardware, RF/TX, current-head real-model speech inference or sustained eight-receiver qualification was performed. The demo cannot prove RTL USB/SAM reception; those current conclusions rely on the generated-IQ production-pipeline tests. Earlier author/operator hardware and inference evidence remains explicitly historical.

@jensenpat
jensenpat enabled auto-merge (squash) October 17, 2026 18:16
@jensenpat
jensenpat disabled auto-merge October 17, 2026 18:38
… II.

Rebase the accepted RTL analog receive increment onto main 9dfe8f6, preserving accepted-state pitch controls, current CW decoder integration, transmit acknowledgement routing and settings isolation. Keep CW/CWR vocabulary in the existing model-layer owner. Preserve all production-pipeline, model, UI and stale-audio regression coverage.

Co-authored-by: jensenpat <patjensen@gmail.com>
@github-actions

Copy link
Copy Markdown

Accessibility check findings

This PR touches src/gui/ files with 19 accessibility issue(s).
Full details appear as inline annotations on the diff above.

Files scanned : 23
Files with findings: 6
Total findings : 19

See docs/a11y.md for the canonical
Qt patterns (setAccessibleName, QAccessibleValueChangeEvent,
QAccessibleInterface subclasses, etc.). Structural remediation
(keyboard navigation, custom QAccessibleInterface subclasses)
is tracked in #3288.

Findings are warnings only — the build is not blocked.

@jensenpat jensenpat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head 9df9135d197aadba5f1fefb20abdff4a71ac0241, rebased onto main 9dfe8f666775b51a6012534bff7e7737ff0412b1. No confirmed correctness blockers remain. The operator explicitly requested review, rebase and merge of this proposed change; this landing retains the corrected capability records, filter presets and disclosed shared title-bar behavior under that direction.

The rebase preserves Ozy311's authorship and the prior review fixes. The final conflict against main #6430 was solely generated log-reference line numbers; regenerated references preserve the exact production/test patch. Current-main stored-control routing and dialog regressions are included in the new 24-test run. APF advertisement now matches CW/CWR-only dispatch; runtime documentation matches the 48 kHz native recipes; unsupported DSP-on requests retain cleanup-off behavior; connected-tab refreshes preserve rescans. Current-main pitch-slider confirmation, passive DSP readback, neural CW decoder integration, transmit acknowledgement routing and settings isolation are preserved. The CW/CWR helpers were integrated into main's existing model-layer ModeVocabulary owner rather than duplicated in the GUI header.

Verification on this exact head:

  • Native ARM64 Qt 6.12.0 app, daemon and 24 regression targets built, ASR and RADE enabled; no RNNoise x86 sources in the ARM graph. The initial iconutil sandbox failure cleared on the unchanged permitted incremental build.
  • 24/24 selected headless CTests passed in 92.61 s, including generated-IQ AM/SAM, SSB/CW and FM/WFM production pipelines, accepted RTL model state, transactional/scoped settings, typed cross-radio receive intents, ASR generation and native-source retirement, control availability, title bar, Phone/CW accepted pitch/APF, filter policy, TNF removal, CW mode gates main's CW RX model and stored-control routing/dialog regressions.
  • An isolated mutation on the preceding 2e4996250 head, with byte-identical helper/test code on this head, omitting CWR from the shared mode vocabulary produced four CW mode-gate failures; the exact current implementation reports zero failures. Existing submitted regressions also cover the prior APF, discovery and pitch-confirmation findings; their current passes are included above.
  • Owned offscreen bridge instance PID 10312, isolated settings, explicit socket and disabled autoconnect: only DEMO-0001 connected. whoami reported txAllowed:false; radio state reported transmitting:false. Observed Copy Assist enabled in USB, disabled and unchecked after CW, enabled again in USB; mute readback was audioMute:true, and the demo reconnected successfully. Closing its MainWindow retired Copy Assist with phase=asr.controller.destroy event=end result=ok elapsed_ms=0; the owned process exited with code 0.
  • Main/head boundary comparison passes with the same 101 tracked findings, 70 capability booleans and 221 raw above-seam command strings. Generated touchpoints, seam probes, references and bridge docs; log rules; test registration; frozen test gate; WDSP test links; and QSettings checks pass. Accessibility findings match main's 19 existing warnings.
  • Hosted checks are running again on this rebased head; protected auto-merge must wait for all required checks to pass. The preceding head 2e4996250 passed Linux, Windows, macOS, Static checks, Docs and CodeQL; those results are scoped to that head. CI is a build/platform-specific filtered-test gate, not evidence of a full-suite pass.

Both review threads have evidence-bearing replies and are resolved. The extractor security advisory is not a demonstrated out-of-bounds path: Resampler::process sizes the byte output for its returned sample count, and the unchanged consumer bounds that count before indexing. The CodeGuard shell-injection candidates are protocol strings with no shell invocation; the log-rule findings are matching data. The added GUI/model includes consume existing receiver-selection models and existing ThemeManager artwork; no vendor-boundary or baseline weakening was introduced.

No separate automated code-review tool was available; the adversarial pass was manual. No live hardware, RF/TX, current-head real-model speech inference or sustained eight-receiver qualification was performed. The demo cannot prove RTL USB/SAM reception; those current conclusions rely on the generated-IQ production-pipeline tests. Earlier author/operator hardware and inference evidence remains explicitly historical.

@jensenpat
jensenpat enabled auto-merge (squash) October 17, 2026 18:42
@jensenpat jensenpat changed the title RTL: add SSB/CW and AM/SAM reception with selected decoder audio RTL: add SSB/CW and AM/SAM reception with selected decoder audio. Principle II. Oct 17, 2026
@jensenpat
jensenpat merged commit bccd4b7 into main Oct 17, 2026
10 checks passed
@jensenpat
jensenpat deleted the codex/rtl-am-sam-rx branch October 17, 2026 19:15
wa2n-code pushed a commit to wa2n-code/AetherSDR that referenced this pull request Oct 21, 2026
…#6637). Principle VIII.

Repair stale test expectations on main after production changes in aethersdr#6432 and aethersdr#6524:

- control_receive_test: locate FM, FMN, and WFM modes dynamically across declared filter modes instead of indexing by position (aethersdr#6432).
- rtl_capture_worker_test: remove obsolete backend-level legacy AM filter block; native receive rejects AM filters wider than ±12 kHz (aethersdr#6432).
- radio_setup_operations_test: account for per-band RCA off/TUNE toggle in TX Band Settings (aethersdr#6524).

Addresses aethersdr#6555.

Co-Authored-By: Jeremy [KK7GWY] <kk7gwy@aethersdr.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants