Skip to content

Automation bridge Phase-3: remaining drivability/observability gaps (deny-word anchoring, popup/drag verbs, Quindar + overlay snapshots) #3845

Description

@ten9876

Summary

A consolidated follow-up collecting the remaining agent-automation-bridge drivability/observability gaps surfaced while dogfooding the bridge through the recent feature PRs. #3819 (Phase-2 fidelity) closed the big ones — closed-menu reachability, slice tx, key ptt/mox, lineedit submit, resize, multi-instance — and #3826 deferred widget click/toggle out of the socket callback. These five are what's left, each found by the PR noted.

Gaps

1. TX-safety deny-word is an unanchored substring match ⚠️ correctness

isTransmitAction (AutomationServer.cpp) flags an action as transmit-keying via a bare contains() on the deny-words mox / ptt / transmit / cwx. An RX-only weather action with objectName aprsSvcWXBOTaprssvcwxbot contains cwx (the c from svc + wx from wxbot) → falsely blocked. It's fail-safe (over-blocks, never under-blocks), so not a safety hole — but it's a real false-positive, and #3819's closed-menu reachability widened the action surface it scans, so collisions are now more likely.
Fix: anchor the deny-words to word/token boundaries (or require an explicit kTxKeyingProperty marker rather than the name-match fallback). (Surfaced in #3828; worked around there with an aprsService… spelling.)

2. Can't drive a QToolButton popup menu (macOS crash)

A synthetic click() on a QToolButton with a menu runs inside the socket-read callback; showing the menu's native popup window from there re-enters the Cocoa stack and segfaults intermittently (QMenu::popup → QCocoaWindow::setVisible). singleShot(0) deferral didn't help — showing the native window is the hazard. #3826 deferred widget click, but the popup show is still unsafe.
Fix: an openMenu/showMenu <button> verb that posts the menu show onto the GUI event loop. (Surfaced in #3828; worked around with pure InstantPopup + closed-menu action triggers.)

3. No mouse-drag / gesture synthesis verb

The bridge can invoke button-style actions but can't synthesize a press-move-release drag, so resize grips and slider handles can't be exercised end-to-end (only their persisted side-effects are checkable).
Fix: a drag <target> dx dy (or mouse <target> down/move/up) verb. (Surfaced in #3824 — the CW panel resize grip.)

4. Quindar firing isn't observable

No quindarPhase/quindarActive field in any get snapshot and ClientQuindarTone has no log category — the only proxy is deferred-unkey timing, so the tone and the quindarActiveChanged chip flash can't be asserted.
Fix: add quindarPhase/quindarActive to the get transmit snapshot, or an lcQuindar log line on intro/outro start. (Surfaced in #3798.)

5. Overlay-derived state isn't in dumpTree/get snapshots

GPU-overlay state drawn in SpectrumWidget (e.g. SliceOverlay::splitPartnerId, the split-pair marker) isn't reflected in dumpTree, so it can only be checked by pixel-grabbing.
Fix: expose splitPartnerId (and similar overlay-derived state) in a get pan/get slice snapshot so split-pairing etc. is assertable without image diffing. (Surfaced in #3794.)

Priority

#1 is the only correctness item (a real, if fail-safe, TX-guard false-positive) and is the most worth doing. #2#5 are drivability/observability conveniences that would let future feature PRs prove themselves headlessly without per-PR workarounds.

Refs #3646, #3819, #3826. cc @jensenpat (bridge author).

Metadata

Metadata

Assignees

No one assigned

    Labels

    GUIUser interfaceaudioAudio engine and streamingenhancementImprovement to existing featuremaintainer-reviewRequires maintainer review before any action is takensafetyEquipment protection concernspectrumPanadapter and waterfall

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions