Skip to content

Consolidate duplicate aether.ax25 Q_LOGGING_CATEGORY declarations (#2763). Principle III.#2770

Merged
ten9876 merged 2 commits into
mainfrom
aetherclaude/issue-2763
May 17, 2026
Merged

Consolidate duplicate aether.ax25 Q_LOGGING_CATEGORY declarations (#2763). Principle III.#2770
ten9876 merged 2 commits into
mainfrom
aetherclaude/issue-2763

Conversation

@aethersdr-agent

Copy link
Copy Markdown
Contributor

Summary

Fixes #2763

What was changed

Consolidate duplicate aether.ax25 Q_LOGGING_CATEGORY declarations (#2763). Principle III.

Files modified

  • src/core/tnc/AetherAx25LibmodemShim.cpp
  • src/gui/Ax25HfPacketDecodeDialog.cpp
 src/core/tnc/AetherAx25LibmodemShim.cpp | 12 +++++-------
 src/gui/Ax25HfPacketDecodeDialog.cpp    |  8 +++-----
 2 files changed, 8 insertions(+), 12 deletions(-)

Generated by AetherClaude (automated agent for AetherSDR)

). Principle III.

PR #2753 introduced two local Q_LOGGING_CATEGORY("aether.ax25") declarations
alongside the centralized lcAx25 in LogManager. Both lcAetherAx25Shim and
lcAetherAx25Dialog resolved to the same underlying QLoggingCategory at
runtime, so behavior was identical, but the duplication sat outside the
LogManager registry and would silently drift if the central category's
metadata (default level, toggle hook) ever changed.

Replace both local declarations with #include "core/LogManager.h" and
update all qCDebug callsites to use lcAx25 directly. The <QLoggingCategory>
include is dropped from both files since LogManager.h pulls it in.

Logging behavior is unchanged: same messages at same levels, same single
"aether.ax25" toggle in Help → Support — which is the user-visible label
this consolidation protects (Principle III: user-facing names match the
visible UI labels, and the Help → Support toggle is the authoritative
surface for this category).

Blast radius: risk_score=0.228, 7 high-risk affected (top: MainWindow,
MainWindow::wirePanadapter, MainWindow::registerShortcutActions). The
dialog is structurally central to MainWindow, but the edit only swaps
include directives and renames a local logging-category symbol — the
dialog's public API (constructor, signals, slots) is untouched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR #2770's shim now uses lcAx25 (declared in LogManager.h, defined in
LogManager.cpp), but the test target only linked the shim itself —
producing a missing-symbol link error for AetherSDR::lcAx25(). Add
LogManager.cpp, AsyncLogWriter.cpp, and AppSettings.cpp to the test
target so the lcAx25 reference (and its transitive m_writer member
on LogManager) resolves at link time.

The main AetherSDR target was already linking these through the
core sources block; this is purely a test-isolation fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ten9876 added a commit to ten9876/aetherclaude that referenced this pull request May 17, 2026
Closes the orchestrator gap exposed by aethersdr/AetherSDR#2770:
when the agent moves a symbol from one translation unit to another
(or replaces a local declaration with a reference to one in a shared
module), the main app keeps linking cleanly because it pulls in
the full CORE/MODEL/GUI source lists. But unit-test targets that
link a minimal subset fail with `undefined reference to ...` —
caught only by CI after a full build cycle, requiring a maintainer
patch on top.

New step 6 (between Implement and Commit) mandates a grep + local
build of every affected test target before commit. Calls out the
transitive-dependency case (LogManager.cpp → AsyncLogWriter.cpp →
AppSettings.cpp) that caught #2770 specifically, and gives the
agent a heuristic shortcut (the words "consolidate", "extract",
"share", "centralize", "deduplicate" → always run the audit).

The existing step 6 (commit-message construction with constitution
principle citation) becomes step 7. No other behavioral change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 merged commit d760a3e into main May 17, 2026
5 checks passed
@ten9876 ten9876 deleted the aetherclaude/issue-2763 branch May 17, 2026 00:36
aethersdr-agent Bot added a commit that referenced this pull request May 17, 2026
Covers the matrix from the issue: disabled hot-path no-op, window
aggregation count/p95, window-reset isolation, the full stall-threshold
matrix (panUpdate / waterfallUpdate / render / frameAge / udpDrain /
input), drag-aware UI lag thresholds (50 ms idle / 33 ms drag), the
frame-restart counter, percentile-95 boundary cases (empty / single /
[1..100] sorted / 100 reversed), and the 1 s window cadence (no fire
at 950 ms, fire at 1100 ms).

Two purely additive test seams land on PerfTelemetry:
`setClockOverrideForTest(qint64)` pins nowNs() to a synthetic value so
window timing is deterministic without real sleeps, and `resetForTest()`
zeroes aggregation state between cases so the singleton doesn't leak
between tests. The clock override is a single relaxed atomic load in
the hot path; when zero (production default) the original steady_clock
path is used unchanged, so the existing record* call surface that the
17 high-risk callers reach is untouched in shape or behavior.

The test executable links LogManager.cpp + AsyncLogWriter.cpp +
AppSettings.cpp instead of redeclaring its own Q_LOGGING_CATEGORY for
`aether.perf` — this honors Principle III's consolidation (one
canonical definition site per category, per #2770) and matches the
linkage pattern established by `ax25_libmodem_shim_test`. Output is
captured via qInstallMessageHandler filtered to `aether.perf` and
matched on key=value field extraction from emitted PerfStall and
PerfSummary lines.

Blast radius: risk_score=0.418, 17 high-risk affected (top:
MainWindow::MainWindow, MainWindow::wirePanadapter, MainWindow::buildUI,
RadioModel::onStatusReceived, MainWindow::buildMenuBar). All these
reach PerfTelemetry through its existing public record* API which is
unchanged; the additions are two new public test-only methods plus one
relaxed atomic load in nowNs() that is a no-op when the override is
the default zero.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ten9876 added a commit that referenced this pull request May 17, 2026
## Summary

Fixes #2500

### What was changed

Covers the matrix from the issue: disabled hot-path no-op, window
aggregation count/p95, window-reset isolation, the full stall-threshold
matrix (panUpdate / waterfallUpdate / render / frameAge / udpDrain /
input), drag-aware UI lag thresholds (50 ms idle / 33 ms drag), the
frame-restart counter, percentile-95 boundary cases (empty / single /
[1..100] sorted / 100 reversed), and the 1 s window cadence (no fire
at 950 ms, fire at 1100 ms).

Two purely additive test seams land on PerfTelemetry:
`setClockOverrideForTest(qint64)` pins nowNs() to a synthetic value so
window timing is deterministic without real sleeps, and `resetForTest()`
zeroes aggregation state between cases so the singleton doesn't leak
between tests. The clock override is a single relaxed atomic load in
the hot path; when zero (production default) the original steady_clock
path is used unchanged, so the existing record* call surface that the
17 high-risk callers reach is untouched in shape or behavior.

The test executable links LogManager.cpp + AsyncLogWriter.cpp +
AppSettings.cpp instead of redeclaring its own Q_LOGGING_CATEGORY for
`aether.perf` — this honors Principle III's consolidation (one
canonical definition site per category, per #2770) and matches the
linkage pattern established by `ax25_libmodem_shim_test`. Output is
captured via qInstallMessageHandler filtered to `aether.perf` and
matched on key=value field extraction from emitted PerfStall and
PerfSummary lines.

Blast radius: risk_score=0.418, 17 high-risk affected (top:
MainWindow::MainWindow, MainWindow::wirePanadapter, MainWindow::buildUI,
RadioModel::onStatusReceived, MainWindow::buildMenuBar). All these
reach PerfTelemetry through its existing public record* API which is
unchanged; the additions are two new public test-only methods plus one
relaxed atomic load in nowNs() that is a no-op when the override is
the default zero.

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

### Recovery note

This PR is being opened manually. The aetherclaude orchestrator (trace
fe2b51d0) pushed the signed commit at 17:53 PDT but died at the next
bash line due to a set -e race with commit-signed.js's exit code. Root
cause + fix shipped as 4832725 (run-agent: guard commit-signed +
create-pr against set -e silent death).

---
Generated by AetherClaude (automated agent for AetherSDR) — PR creation
completed manually after orchestrator interrupt.

---------

Co-authored-by: aethersdr-agent[bot] <273844287+aethersdr-agent[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
ten9876 added a commit that referenced this pull request May 17, 2026
…ust/#2780) (#2786)

## Summary

Cherry-pick of @rfoust's panadapter persistence and macOS GPU lifecycle
work from PR #2780, applied cleanly onto current main with the
stale-snapshot reverts left out.

## Why a cherry-pick rather than merge of #2780

PR #2780 was based on commit \`a0512d99\` (PR #2772 merge), and its
single Codex-generated commit included **stale-snapshot content for
files outside the intended scope**. Squash-merging #2780 as-is would
have silently reverted two recently-landed PRs:

- **PR #2770** (\`aether.ax25\` Q_LOGGING_CATEGORY consolidation) —
\`AetherAx25LibmodemShim.cpp\`, \`Ax25HfPacketDecodeDialog.cpp\`, plus
the test-target linkage in \`CMakeLists.txt\`
- **PR #2772** (RadioSetupDialog → PersistentDialog migration) —
\`RadioSetupDialog.{cpp,h}\`

Verified by three-way merge dry run: post-merge state showed \`class
RadioSetupDialog : public QDialog\` (pre-#2772) and 5 occurrences of
\`lcAetherAx25Shim\` (pre-#2770).

The actual panadapter work in PR #2780 is real and valuable, so this PR
extracts it onto a fresh branch from current main and skips the
unintentional reverts.

## What's in this PR (= the intended scope of #2780)

Cherry-picked verbatim from #2780:

| File | Change |
|---|---|
| \`src/gui/MainWindow.{cpp,h}\` | Persist/restore PanadapterLayout +
FloatingPanIds; expand layout count handling from 4 to 8 pans; preserve
unseen floating IDs across reconnect |
| \`src/gui/PanadapterStack.{cpp,h}\` | Sensible-fallback
docked-splitter layouts when some pans are floating or saved layout
count mismatches |
| \`src/gui/SpectrumWidget.{cpp,h}\` | macOS QRhiWidget lifecycle:
\`WindowAboutToChangeInternal\` before reparent; QRhi resource release
during shutdown while parent backing stores are valid; guarded late
callbacks; auto FFT floor relock after geometry/ypixels changes |
| \`src/core/PanadapterStream.cpp\` | Defensive dBm-range clamping (-180
floor, ≥10 dB span); FFT decode clamps pixel input and dbm output to
range |
| \`src/models/RadioModel.cpp\` | Use actual FFT pane height for radio
\`ypixels\` rather than total widget height |

Net: **+548 / -215** across 8 files.

## What was NOT cherry-picked (stale-snapshot reverts)

| File | Reason |
|---|---|
| \`CMakeLists.txt\` | -7 lines reverting #2770's test-target linkage I
added to fix the link error |
| \`src/core/tnc/AetherAx25LibmodemShim.cpp\` | Robbie's content has
local \`Q_LOGGING_CATEGORY(lcAetherAx25Shim, ...)\` — pre-#2770. Main
has the consolidated \`lcAx25\` from LogManager |
| \`src/gui/Ax25HfPacketDecodeDialog.cpp\` | Same pattern —
\`lcAetherAx25Dialog\` local, pre-#2770 |
| \`src/gui/RadioSetupDialog.{cpp,h}\` | Robbie's diff was **100% pure
revert** of #2772 — no new content, no panadapter-related additions.
Confirmed by inspecting the full \`git diff a0512d9..e72d7e4 --
RadioSetupDialog.cpp\` output |

## Attribution

Commit author is set to **Robbie Foust** so his contribution shows in
\`git log\` and the contributor stats. PR #2780 is being reset to
**Draft** (not closed) so Robbie has a clean reference point + can
update with fresh work if he wants.

## Test plan

- [x] Local build clean (402/402 link, only pre-existing warnings)
- [x] Three-way merge dry-run against current main: clean
- [ ] Manual on Linux: multi-pan layout, detached panadapter, restart,
confirm layout + detached state restore
- [ ] Manual on macOS GPU build: two detached panadapter windows, Cmd-Q,
restart, confirm both restore without the QRhi cleanup callback crash
- [ ] Manual: detach/redock panadapter and confirm auto FFT floor
relocks

## Cross-references

- Replaces #2780 (will be set to Draft after this PR opens)
- Same stale-snapshot pattern as aetherclaude #34 (Claude Code), but
from OpenAI Codex this time — worth a heads-up to whoever's watching
agent-output quality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Robbie Foust <rfoust@duke.edu>
Co-authored-by: Claude Opus 4.7 (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.

Consolidate duplicate Q_LOGGING_CATEGORY declarations for "aether.ax25"

1 participant