Skip to content

fix(tx): setSbMonitor caches m_sbMonitor optimistically (#3719). Principle II.#3734

Merged
aethersdr-agent[bot] merged 1 commit into
mainfrom
aetherclaude/issue-3719
Jun 23, 2026
Merged

fix(tx): setSbMonitor caches m_sbMonitor optimistically (#3719). Principle II.#3734
aethersdr-agent[bot] merged 1 commit into
mainfrom
aetherclaude/issue-3719

Conversation

@aethersdr-agent

Copy link
Copy Markdown
Contributor

Summary

Fixes #3719

What was changed

fix(tx): setSbMonitor caches m_sbMonitor optimistically (#3719). Principle II.

Files modified

  • src/models/TransmitModel.cpp
 src/models/TransmitModel.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

Generated by AetherClaude (automated agent for AetherSDR)


🤖 aethersdr-agent · cost: $2.9189 · model: claude-opus-4-8

…ciple II.

TransmitModel::setSbMonitor sent "transmit set mon=" but never updated its
local m_sbMonitor, so transmitModel().sbMonitor() read stale until the radio
echoed sb_monitor (measured non-convergent over a 410 ms window on a
FLEX-8400M). Same defect class as #3712 (setAmCarrierLevel).

Mirror the sibling pattern: write m_sbMonitor optimistically on change and
emit micStateChanged() — the signal the MON button's model->widget sync
(PhoneCwApplet::syncPhoneFromModel, connected to micStateChanged) actually
binds to, matching setMonGainSb. NOT phoneStateChanged() (that drives
syncCwFromModel, which never touches the MON button). No feedback loop: the
sync wraps its body in m_updatingFromModel and the toggled handler early-
returns on that flag, so the optimistic setChecked cannot re-emit the command.

Principle II: the command path stays client->radio; the radio's sb_monitor
status echo (parsed at TransmitModel.cpp:104-106) supersedes the optimistic
value, with no feedback loop. Command/status split per Principle I (FlexLib:
command "mon", status key "sb_monitor", Radio.cs:10615).

Blast radius: risk_score=0.411, 23 high-risk affected (top:
MainWindow::MainWindow, MainWindow::wireRadioModel, RadioModel::
troubleshootingSnapshot). All structural noise from class-level granularity;
the change only adds an existing signal emit already wired and feedback-
guarded, no signature/symbol/dependency change. Test-target link surface
unchanged (no new external symbol or include). Note: cmake unavailable in this
environment, so a full build was not run; the edit uses only pre-declared
members/signals isomorphic to verified sibling setters in the same TU.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Looks good — clean, correct, and minimal. Thanks for the fix! 🙏

I traced the change against the surrounding code and it holds up:

Correctness

  • setSbMonitor previously emitted only commandReady, leaving m_sbMonitor stale until the radio echoed sb_monitor. Any unrelated micStateChanged in that window would run PhoneCwApplet::syncPhoneFromModel()m_monBtn->setChecked(m_model->sbMonitor()) (PhoneCwApplet.cpp:741) and snap the MON button back. The optimistic update fixes exactly that — same Principle II class as the setMonGainSb sibling and the recent setAmCarrierLevel (#3711) / setDax fixes.
  • No feedback loop: the resulting setChecked runs inside syncPhoneFromModel(), which sets m_updatingFromModel = true (PhoneCwApplet.cpp:713), and the MON toggle handler is gated on !m_updatingFromModel (PhoneCwApplet.cpp:349). So the optimistic setChecked can't re-emit the command. The comment's explanation is accurate.
  • Echo still supersedes: the radio's incremental status genuinely echoes sb_monitor (TransmitModel.cpp:104-106), so a divergent radio state will correct the optimistic value — good, this isn't masking a missing echo.
  • The if (m_sbMonitor != on) guard correctly suppresses a redundant micStateChanged while always forwarding the command, which is the right behavior.

All six CI checks are green. No concerns.


🤖 aethersdr-agent · cost: $3.3604 · model: claude-opus-4-8

@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.

Optimistic meter update on state change before radio sends update. Found via agent automation testing.

@aethersdr-agent aethersdr-agent Bot merged commit 04ab599 into main Jun 23, 2026
6 checks passed
@aethersdr-agent aethersdr-agent Bot deleted the aetherclaude/issue-3719 branch June 23, 2026 01:19
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.

TX monitor (sub-band monitor) reads stale: setSbMonitor() omits the optimistic local update

1 participant