Skip to content

Add experimental IC-7610/IC-7760 dual-receiver Ethernet bring-up - #6912

Open
jensenpat wants to merge 8 commits into
aethersdr:mainfrom
jensenpat:aether/icom-dual-receiver-bringup
Open

jensenpat wants to merge 8 commits into
aethersdr:mainfrom
jensenpat:aether/icom-dual-receiver-bringup

Conversation

@jensenpat

@jensenpat jensenpat commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #6910.
Closes #5714.
Closes #5341.
Closes #5154.
Closes #5096.
Closes #5084.
Closes #6920.

Adds an initial Ethernet/RS-BA1 bring-up path for the IC-7610 and IC-7760: two fixed MAIN/SUB receive slices and panadapters, native scope geometry, separate receive audio feeds plus a monitor mix, and one shared PTT/mono transmit-audio path. Both models are marked experimental.

Integrates the connection-dialog changes from #6885 and #6889.

Related issues

IC-7610 device reports:

IC-7760 device reports and support evidence:

Related Icom bring-up, control and receiver-presentation context:

The links include historical reports and shared Icom context.

What changes

  • Recognize IC-7760 model ID B2 and provide model-specific IC-7610/7760 profiles. CI-V 19 00 supplies the canonical model independently of the configurable bus address and network nickname. That identity reaches the status-bar model label through the existing RadioModel information update.
  • Keep MAIN and SUB as fixed receiver resources with separate state and pans. Use absolute 25 rr/26 rr addressing, retain DATA OFF/D1/D2/D3 and FIL1/FIL2/FIL3, and qualify command-29 controls by the exact model guides. Global TX controls remain unwrapped. Editing SUB does not change the radio's TX route.
  • Install the actual scope geometry before decoding. The old 475-bin decoder truncated 689-bin sweeps, shifting native bin positions on the rendered frequency axis. Each new receiver now preserves 689 bins and its own metadata. Center uses centre ± half-span; Fixed/scroll use reported edges. Spectrum and waterfall consume identical ordered amplitudes and edges. No IQ conjugation or FFT rotation is applied to these cooked display traces.
  • Negotiate stereo PCM16 receive audio independently of mono PCM16 transmit audio. Preserve stereo frame alignment across packets, use independent receiver resamplers/decoder feeds, and mix monitor audio with per-slice gain, mute and balance. LAN AF/IF is inspected; IF is withheld from AF playback with guidance rather than silently rewriting the radio's menu.
  • Keep one global PTT/readback path and TX coordinator. Split determines MAIN/SUB TX; actual TX frequency is read through 1C 03. Key-on waits for receiver mode/frequency and split readbacks. The active TX receiver's DATA variant chooses the appropriate model-specific modulation register.
  • Mark the model choices experimental using the same policy as the radio-tab strip. Both receive the EXPERIMENTAL badge; IC-7300MK2 retains its supported treatment. Preserve the new dialog's saved CI-V values, Locations, paths and scoped credentials.

Protocol authority: the operator's Icom oracle §§13.2–13.6/13.13 and the official IC-7610 A7380-7EX-4 and IC-7760 A7788-8EX-2 CI-V guides. Profiles record official-guide evidence, not live-hardware qualification. The IC-9700 retains its existing single selectable scope.

Validation

  • macOS app configured and built with 8-way compilation.
  • 16 focused CTest targets passed: Icom dual receiver, scope, audio, family, pan capacity, identity, backend seam, session lease, scheduler, PTT authority, scoped credentials, connection workspace, source selection, dialog sizing, startup lockout and unified title bar.
  • Socket-free production-backend injection covers both model identities at a custom address; distinct pans/slices; full bin positions; shared spectrum/waterfall rows and axes; malformed, foreign and stale frames; reordered receiver replies; D2/D3; split/focus; global PTT/unkey; independent codec negotiation; monitor mixing; and decoder audio surviving monitor mute.
  • Captured production uplink packets for both models verify 20 ms mono PCM framing/downmix level, 24→48 kHz conversion after acoustic filter delay, rejection without keying/audio authority, and queued-audio cancellation on unkey. The updated dual-receiver, audio and PTT-authority tests passed together.
  • Mutation check: replacing the native geometry with 475 bins causes the new receiver/render assertions to fail. Restoring the production geometry returns the suite to green.
  • Automation bridge on an isolated, disconnected app, with autoconnect off and TX automation disabled: exercised the Radio connection workspace with Locations, operator profiles and SmartLink accounts #6885/Radio tab actions, saved ordering, and connection handoff #6889 Add radio by IP flow, selected Icom, inspected both experimental model entries and selected IC-7760. Captured the dialog/list below.
  • User documentation build and engine-boundary, command-plane, capability-record, touchpoint and test-registration checks passed.

Screenshots

The dialog/list are live automation-bridge captures from the integrated offline app. The tab strips are explicitly offline TitleBar fixtures; they are not hardware evidence.

Experimental CI-V model choices

IC-7760 in the new connection dialog

IC-7610 experimental tab strip — offline fixture

IC-7760 experimental tab strip — offline fixture

Share saved connection identities between workspace tabs and Locations; fence superseded startup attempts; confirm and sequence single-session replacements; retain precise dialog recovery context. Persist browser-style tab ordering and use named canon colors for every menu selection state. Add bridge, rendered-menu, lifecycle and startup regression coverage plus user documentation and screenshots.
Preserve the selected-radio hierarchy from aethersdr#6885 while retaining active-path disabling and confirmed single-session switching.

@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

Partially. The Icom half of this PR is genuinely good work, and the root-cause claim holds up under reading. On main, IcomCivBackend::m_scope is default-constructed (ScopeDecoder m_scope;), so it always ran at ScopeGeometry::points = kScopePointsIc705 = 475 regardless of model — while IcomModels.cpp has carried 689 for the IC-7610 since before this PR. The single-frame WLAN path then did m_partial.raw.resize(475, 0), truncating the sweep, and the downstream geom at IcomCivBackend.cpp:2523 mapped it across the full reported edges. A signal at true centre (bin 344 of 689) lands at 344/475 ≈ 72% of the display width — "about halfway between the center and the right side", which is #6871's wording verbatim, and the displacement scales with span, which is #5714's. src/core/backends/icom/IcomCivBackend.cpp:1462-1466 installs the model geometry at identity adoption and is the actual fix. That is a well-identified bug with a one-line cause, and the diagnosis is independently checkable in-tree.

What does not fit: six issues are on Closes: lines, five of them (#5714, #5341, #5154, #5096, #5084) IC-7610 hardware displacement reports, closed on offline fixtures alone — see Blocker 4. And roughly 70% of the diff is not this issue (Scope, below).

Scope

Files What it changes Claimed? Verdict
src/core/backends/icom/{IcomCivBackend*,IcomModels*,IcomScope*,IcomAudio*,IcomSession*,CivCodec}, tests/icom_{dual_receiver,scope,audio,family,panadapter_capacity}_test.cpp Dual-receiver bring-up, 689-bin geometry, stereo RX, split/TX Yes In scope
src/models/ConnectionWorkspace.{h,cpp}, src/gui/{ConnectionPanel,MainWindow,MainWindow_Session,RadioTabBar}.*, src/core/{SettingsCredentialPolicy.h,AppSettings.cpp,AutomationServer.cpp,IConnectionAutomation.h}, src/core/backends/flex/SmartLinkClient.*, src/core/backends/icom/IcomCredentials.*, tests/{connection_workspace,connection_panel_size,connection_panel_source_pick,startup_autoconnect_lockout,unified_title_bar,backend_family_switch,icom_credentials_singleflight}_test.cpp #6885 + #6889 verbatim (~4,500 lines) Disclosed as "integrates" Needs maintainer decision
docs/user/docs/station-profiles.md (new, 134 lines), 15 new screenshots, screens.json, sidebars.js, 8 rewritten user pages, docs/architecture/window-chrome.md, aetherd-touchpoint* #6885/#6889 documentation Disclosed Same
docs/{icom-dual-receiver-bringup.md,user/docs/networked-icom.md,user/docs/supported-radios.md} This PR's docs Yes In scope
CMakeLists.txt, tests/tests.cmake Source + test registration Yes In scope
docs/BUILDING.md:33 Adds -DREQUIRE_KEYCHAIN=ON to the macOS configure line No requirement explains it Nit (the option does exist, CMakeLists.txt:34)
CHANGELOG.md Untouched — Correct — don't add one

Commits e5a66a1, 7a3fdbd, 136dba0, d878d7e are #6885 and #6889, and git merge-base confirms this branch sits on main (155850f5), not on either of those branches. Both are open. I'm not calling that concealment — the body says so plainly — but "integrates" and "stacked on" are different things, and only the maintainer can decide the ordering.

Blockers

1. src/models/ConnectionWorkspace.cpp:1 + src/gui/ConnectionPanel.cpp — this PR carries two other open PRs in full.

Merging #6912 merges #6885 and #6889, and their own reviews never happen under their own titles. #6885 in particular adds a new versioned feature document, a whole new connection UX, two new bridge verbs and a new credential-key class — the kind of change GOVERNANCE.md routes through an RFC, and it should get that scrutiny on its own PR, not as a prerequisite inside an Icom PR. If either changes in review, this branch diverges silently.

The Icom backend work is independent of the dialog: IcomCivBackend*, IcomModels*, IcomScope*, IcomAudio* and tests/icom_* touch nothing in #6885/#6889. Only the model-chooser EXPERIMENTAL badge does. Recommendation: merge #6885 → #6889 → rebase this, or rebase the Icom commits onto main and ship them first with the badge deferred. Maintainer's call on which.

2. src/core/backends/icom/IcomCivBackend_DualReceiver.cpp:306 — an unanswered LAN AF/IF read silently withholds all receive audio, which is the symptom #6872 reports.

        || m_lanOutput != 0 || !m_dualInitialised

and the same gate in the mono path at src/core/backends/icom/IcomCivBackend.cpp:4066:

    if (hasDualReceivers() && m_lanOutput != 0) { return; }

m_lanOutput initialises to -1 (IcomCivBackend.h:378) and resets to -1 on disconnect (IcomCivBackend.cpp:1065). The only thing that moves it off -1 is the 1A 05 <item> reply matched at IcomCivBackend.cpp:3436-3446, keyed on profileFor(*m_model).dualReceiver->lanOutputItem — 86 on the IC-7610, 123 on the IC-7760, both read from the guides and not yet confirmed on hardware. The operator warning only fires on changed && m_lanOutput != 0, i.e. only when a well-formed reply says IF:

                if (changed && m_lanOutput != 0) {
                    emit configurationWarning(QStringLiteral(
                        "LAN output is IF. Select AF in the radio's LAN AF/IF Output menu for PC receive audio."));

So if the item number is wrong for a firmware revision, or the radio NAKs the read, or the SET-menu encoding differs, m_lanOutput stays -1 forever, every audio frame is dropped at the top of onDualAudio/onAudio, and nothing is logged or surfaced. The operator sees working spectrum, working frequency readout, and dead audio — which is exactly #6872, one of the two reports this path is meant to address. The -1 case needs to be distinguishable from 1:

        || m_lanOutput != 0 || !m_dualInitialised

→ keep the drop, but make the unknown state visible. Either warn once after the item read has gone unanswered for a bounded number of pollDualReceivers() cycles, or fail open to audio while m_lanOutput < 0 and warn that the AF/IF menu could not be read. Whichever you pick, lanOutput: -1 should not be a state the operator can only find by reading IcomCivBackend.cpp:6933's bridge snapshot.

3. tests/icom_scope_test.cpp:233-236 — an existing assertion was rewritten to accommodate a behavior change on the already-supported radios.

Before:

    auto last = d.feed(makeContinuation(11, 11, chunk));
    check(last->raw.size() == static_cast<std::size_t>(kScopePointsIc705),
          "and is padded/trimmed to the geometry");

After:

    auto last = d.feed(makeContinuation(11, 11, std::vector<std::uint8_t>(25, 0x20)));
    check(last->raw.size() == static_cast<std::size_t>(kScopePointsIc705),
          "and contains exactly the native geometry");

The input was changed to be exactly the right size, so the assertion no longer tests anything about a mismatch. That matters because IcomScope.cpp:130-132 and IcomScope.cpp:163-166 changed the shared decoder from pad/trim to reject:

            if (m_partial.raw.size() != static_cast<std::size_t>(m_geom.points)) {
                return std::nullopt;
            }

ScopeDecoder is shared by every Icom model. A sweep whose byte count differs from the table figure by even one now drops the entire sweep, silently, with no qCWarning — where main rendered a padded or trimmed trace. The models this lands on are not hypothetical: the IC-9700's 475 is measured, verified = false; the IC-7300's 475 and the IC-785x's 689 are cross-referenced and unverified. On any of those, a geometry discrepancy turns the panadapter permanently black with nothing in the log to say why. IcomScope.cpp:75-78 makes the same pad-vs-reject flip for an out-of-range mode byte (previously clamped to Fixed).

The PR body says "Existing Icom tests protect the previous models." This hunk is the counterexample. Either keep the old lenient path for models that aren't verified and reject only where the geometry is guide-confirmed, or keep the strictness and add a rate-limited qCWarning(lcIcomPan) naming the expected and received byte counts — plus a test that feeds a mismatched length and asserts the new behavior deliberately, rather than one that no longer exercises it.

4. The Closes: lines contradict this PR's own documentation.

docs/icom-dual-receiver-bringup.md:108 states the rule:

Do not describe the devices as qualified or close #6871/#6872 from offline tests alone.

The body then closes #5714, #5341, #5154, #5096 and #5084 — five IC-7610 waterfall-displacement reports, the same symptom class, the same evidence level, from the same offline fixtures. The geometry arithmetic above makes the fix likely correct, but likely is not what closing a device report asserts. Move those five to Related and let a hardware confirmation close them. (#6910 is fine to close — it is the author's own issue, created minutes before the PR with this body pasted into it.)

Nits

  • src/models/ConnectionWorkspace.cpp:206 and :222 — if (!save(document)) { return {}; }. A valid document was just loaded and validated; if a cosmetic one-time edit (renaming "Existing preferences" → "Radio operator", appending starter Locations) cannot be written back because the store is momentarily unavailable, the whole workspace is discarded and the operator sees an empty connection window. The m_workspace.isEmpty() guards at ConnectionPanel.cpp:4666/4681/4743 do stop it overwriting the good data, so this is degradation rather than loss — but returning the loaded document and dropping only the failed cosmetic edit would be strictly better.
  • src/core/SettingsCredentialPolicy.h:63-72 — isScopedCredentialKey requires exactly prefix + 64 + suffix. Correct today (both ids are SHA-256 hex), but it means a future id format silently un-reserves the key rather than failing loudly. Worth a comment tying the 64 to ConnectionWorkspace::accountId/connectionCredentialId.
  • src/core/backends/icom/IcomCivBackend_DualReceiver.cpp:116-120 — mod->dataOffInputItem dereferences the optional returned by currentModulationProfile() unchecked. Safe today (both new profiles set modulation), but a future profile with dualReceiver and no modulation crashes here rather than degrading.
  • src/core/backends/icom/IcomCivBackend_DualReceiver.cpp:109 — the scope reference read is queued under the literal key "scope.reference." + N, while semanticKey() (IcomCivBackend.cpp:4301-4304) would compute "scope.<sub>.<data0>" for the same frame. Two keys for one request means no coalescing between them if another site ever queues it.
  • docs/BUILDING.md:41-43 — the REQUIRE_KEYCHAIN=ON guidance is unrelated to either issue. Not wrong (the option exists at CMakeLists.txt:34), just undisclosed.
  • docs/icom-dual-receiver-bringup.md:30 says "Center mode is centre ± half-span", which reads as centre ± span/2; the code at IcomScope.cpp:95-99 does centre ∓ span because Icom's reported span is the half-width. Both are defensible readings of the sentence — worth one clarifying word.
  • src/core/backends/icom/IcomCivBackend.cpp:1462-1466 also fixes the IC-785x (689 points, unverified) by the same mechanism. That is almost certainly an improvement and it goes unmentioned in the body.
  • onDualAudio returns without output if streams[0].size() != streams[1].size(). Two independent Resamplers can transiently disagree after construction; a dropped frame is the right call, but it is silent.

Socket-test disclosure: none. I grepped the added and modified tests (connection_workspace_test, icom_dual_receiver_test, unified_title_bar_test, startup_autoconnect_lockout_test, backend_family_switch_test, connection_panel_size_test, icom_credentials_singleflight_test) for QTcpServer/QUdpSocket/QLocalServer/QWebSocketServer/connectToHost/listen(/bind( — zero hits. icom_dual_receiver_test reaches the production backend through friend test-access structs with an unstarted IcomSession and a m_testWriter capture hook; no socket is opened. Going the other way, connection_panel_source_pick_test removed its SKIP_RETURN_CODE 77 host dependence by injecting a fixed m_manualSourceCandidates snapshot instead of enumerating the host's real interfaces — that is the right direction and not a finding.

CodeGuard: every listed hit is noise on this change and I'm dropping all of them — backticks inside the JSON note strings in aetherd-touchpoint-tags.json, &&/; as C++ operators in AppSettings.cpp/AutomationServer.cpp, and the 192.0.2.x RFC-5737 documentation addresses plus the example email in screens.json. None is a shell invocation, an outbound request, or real PII. A security-audit subagent pass was launched over the credential, deserialization and audio/scope-indexing paths; it had not reported back when I posted, so treat the credential and bounds review below as mine rather than its.

What I tried to break

  • 0x29 wrapper round-trip. receiverCommand() (IcomCivBackend_DualReceiver.cpp:31-60) rewrites whitelisted MAIN level/meter/function reads into 29 00 <cmd> <sub> …, and handleDualReceiverFrame returns false for 29 00 replies. If nothing unwrapped them, every MAIN readback on these models would be dropped and the scheduler would time out on all of them. It does unwrap, at IcomCivBackend.cpp:2759-2764, rebuilding the inner frame before the register switch. Survived.
  • MAIN/SUB request coalescing. If semanticKey() keyed only on command, 25 00 and 25 01 would collapse into one queue entry and SUB frequency would never be read. IcomCivBackend.cpp:4288-4299 tags the receiver sub into the key for 0x25/0x26/0x29, including the wrapped inner cmd+sub for 0x29. The body's "MAIN and SUB use separate semantic generations" claim is real. Survived.
  • Monitor-mix gain inversion. monitorScale computes 2.0 * balance and 2.0 * (1.0 - balance) from monitorPan / 100.0. If pan were the ±100 convention, one channel's scale would go negative and invert phase. monitorPan defaults to 50 (IcomCivBackend.h:364) and SliceAudioRequest::valid() (src/core/backends/ReceiveCommand.h:94-100) bounds it to 0..100, so balance ∈ [0,1] and both scales stay in [0,1] after the std::min. Survived.
  • Transceive-push amplification. IcomCivBackend.cpp:2515-2519 fires a full pollDualReceivers() (≈12 reads, four of them SET-menu) on every inbound 00/01/03/04 frame. With CI-V Transceive on, a spun VFO knob pushes those continuously. I expected an unbounded queue; queueRead passes coalesce through to the scheduler and the keys are stable, so outstanding work is bounded at ~12 entries. Worth confirming you measured it, but I could not construct a flood from the code.
  • CI-V stall recovery. That same early return precedes recoveryFrequencyCandidate's consumption at IcomCivBackend.cpp:2660, so I expected the dual path to strand an in-flight recovery. It cannot: recovery requires IcomFeature::CivDataRestart (IcomCivBackend.cpp:8350), and kDualReceiverEvidence declares only Core/Scope/VfoMode/ModulationInput/AntennaTuner — so these models never enter recovery and keep main's warn-only stall behavior. Survived. The same return also skips the m_lastInboundCivAtMs = frameAtMs at line 2634, but the reads it queues refresh the clock via handleDualReceiverFrame, so a genuine silence still stalls correctly.
  • SET-menu item numbering against the docs. ModulationProfile{-1, -1, 90, 91, 92, 0x05, …} unpacks to networkLevelItem=90, dataOffInputItem=91, dataInputItem=92 and DualReceiverProfile{86, {92,93,94}}, matching the bring-up doc's "LAN=05, DATA OFF item 91, D1/D2/D3 items 92/93/94" exactly; the IC-7760's 128/129/130 + {130,131,132} matches its row too. No off-by-one despite the overlapping ranges. Survived.
  • Credentials reaching the settings store. ConnectionWorkspace::validate rejects any document containing a key matching password/token/secret at any depth (ConnectionWorkspace.cpp:26-39), which also means workspaceSnapshot() — returned verbatim to the connect profiles bridge verb — cannot carry one by construction. AppSettings::extractCredentials strips scoped keys into the session vault before anything persists. The one thing that does reach both the store and the bridge is the imported Icom network username (ConnectionWorkspace.cpp:245); low sensitivity over a QLocalSocket, but you should know it's there.
  • Observe-only gating on the new verbs. connect profiles is whitelisted read-only (AutomationServer.cpp:2777-2779); the mutating connect profile stations|operators <id> is not, so it is refused in observe-only — matching docs/automation-bridge.md. It is also handled before the isConnected() guard, so it works while a radio is live, also as documented. Survived.
  • Scope decoder bounds. m_partial.raw.size() + frame.data.size() - kOffContinuation at IcomScope.cpp:152 underflows if a continuation frame is shorter than 3 bytes — but the result is a huge value that trips the > m_geom.points reject, so it fails safe rather than over-reading. Every m_receivers[...] index in handleDualReceiverFrame is guarded by a preceding data[0] > 1 / sub > 1 check.
  • Could not check: anything requiring a build or execution. I never compiled, never ran a test, and never drove the GUI — every finding above is read off the source at the cited line, not reproduced at runtime. I also cannot verify the IC-7610 A7380-7EX-4 or IC-7760 A7788-8EX-2 guide figures (689 bins, 0–200, 15-byte header, SET items 86/90-94 and 123/128-132), the rr-addressed 29 whitelist, or the MAIN-left/SUB-right channel assumption — those rest on documents only the author holds, and the PR is appropriately explicit that they are guide-derived rather than hardware-qualified. CI is green on all 11 checks for 543e8dc, but build/check-macos/check-windows run -R-filtered ctest subsets, so green here does not mean the ~240-test suite passed.

Recommendation

Needs maintainer decision. The Icom diagnosis is the best part of this PR and I'd like to see it land soon — the 475-vs-689 geometry bug is real, cheaply confirmed, and explains five open reports. But it arrives wrapped around two other open PRs (Blocker 1), and that is an ordering question only a maintainer can settle.

Independent of that ordering, three things want fixing on this branch: the m_lanOutput == -1 silent audio drop (Blocker 2), the shared-decoder strictness change and the test assertion that was rewritten around it (Blocker 3), and the five Closes: lines that the PR's own documentation says not to close offline (Blocker 4). Blocker 4 is a two-minute edit to the body. Concrete next step: get the maintainer's ruling on sequencing, fix 2 and 3 in the Icom commits either way, and reduce the closure list to #6910.

Thanks for the unusually careful evidence discipline here — separating guide evidence from hardware evidence in FeatureEvidence, labelling the tab-strip screenshots as offline fixtures rather than hardware, and writing the "do not close these from offline tests" rule into the doc. That last one is the right instinct; the Closes: list just needs to catch up with it.


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

@aethersdr-agent

Copy link
Copy Markdown
Contributor

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

  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in docs/architecture/aetherd-touchpoint-tags.json /tmp/aetherclaude/pr-6912/docs/architecture/aetherd-touchpoint-tags.json:10
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in docs/architecture/aetherd-touchpoint-tags.json /tmp/aetherclaude/pr-6912/docs/architecture/aetherd-touchpoint-tags.json:1187
  • [MEDIUM] CS-PII-EMAIL — PII detected: email in docs/user/screens.json /tmp/aetherclaude/pr-6912/docs/user/screens.json:3865
  • [LOW] CS-PII-IP — PII detected: ip_address in docs/user/screens.json /tmp/aetherclaude/pr-6912/docs/user/screens.json:1124
  • [LOW] CS-PII-IP — PII detected: ip_address in docs/user/screens.json /tmp/aetherclaude/pr-6912/docs/user/screens.json:2595
  • [LOW] CS-PII-IP — PII detected: ip_address in docs/user/screens.json /tmp/aetherclaude/pr-6912/docs/user/screens.json:2742
  • [LOW] CS-PII-IP — PII detected: ip_address in docs/user/screens.json /tmp/aetherclaude/pr-6912/docs/user/screens.json:2783
  • [LOW] CS-PII-IP — PII detected: ip_address in docs/user/screens.json /tmp/aetherclaude/pr-6912/docs/user/screens.json:4825
  • [LOW] CS-PII-IP — PII detected: ip_address in docs/user/screens.json /tmp/aetherclaude/pr-6912/docs/user/screens.json:4902
  • [LOW] CS-PII-IP — PII detected: ip_address in docs/user/screens.json /tmp/aetherclaude/pr-6912/docs/user/screens.json:4976
  • [LOW] CS-PII-IP — PII detected: ip_address in docs/user/screens.json /tmp/aetherclaude/pr-6912/docs/user/screens.json:5045
  • [CRITICAL] CS-VLN-CMDI-AMP — Possible shell command injection pattern in src/core/AppSettings.cpp /tmp/aetherclaude/pr-6912/src/core/AppSettings.cpp:1182
  • [HIGH] CS-VLN-SSRF-PRIV-192 — Possible server-side request forgery target in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:7088
  • [HIGH] CS-VLN-SSRF-LOCALHOST — Possible server-side request forgery target in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:12444
  • [HIGH] CS-VLN-SSRF-LOCALHOST — Possible server-side request forgery target in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:12445
  • [MEDIUM] CS-VLN-SSRF-HEX — Possible server-side request forgery target in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:6286
  • [CRITICAL] CS-VLN-CMDI-SEMI — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:1768
  • [CRITICAL] CS-VLN-CMDI-SEMI — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:7576
  • [CRITICAL] CS-VLN-CMDI-SEMI — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:13235
  • [CRITICAL] CS-VLN-CMDI-AMP — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:2422
  • [CRITICAL] CS-VLN-CMDI-AMP — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:8615
  • [CRITICAL] CS-VLN-CMDI-AMP — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:9648
  • [CRITICAL] CS-VLN-CMDI-AMP — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:11679
  • [CRITICAL] CS-VLN-CMDI-AMP — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:12042
  • [CRITICAL] CS-VLN-CMDI-AMP — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:12601
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:300
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:464
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:841
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:950
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:1307
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:1380
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:1532
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:1611
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:1764
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:1795
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:1799
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:2031
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:2141
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:2200
  • [CRITICAL] CS-VLN-CMDI-BACKTICK — Possible shell command injection pattern in src/core/AutomationServer.cpp /tmp/aetherclaude/pr-6912/src/core/AutomationServer.cpp:2208

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: $20.7900 · model: claude-opus-5

@jensenpat jensenpat linked an issue Oct 31, 2026 that may be closed by this pull request

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment