HUD: DevOverlay hollow shell — DevSnapshotEmitter never built, broadcaster drained to /dev/null #42

Closed
opened 2026-05-12 19:08:09 +00:00 by KofTwentyTwo · 1 comment
KofTwentyTwo commented 2026-05-12 19:08:09 +00:00 (Migrated from github.com)

Summary

DevOverlay is a hollow shell. DevOverlayWindow opens with a default DevOverlayViewModel holding DevSnapshot.initial. The .devOverlay broadcaster subscription on AppDelegate.swift:1808-1813 drains events into _ with a comment "reserved for the DevOverlay emitter wiring in a follow-on plan." DevOverlayBridge is never instantiated. DevSnapshotEmitter exists in AgentCore but is never constructed. Opening the overlay shows static initial values (state=idle, 0 tokens, empty turn id) forever.

Evidence

  • File: App/AppDelegate.swift:2652-2659 (toggleDevOverlay())
  • File: App/AppDelegate.swift:1803-1813:
    // DevOverlay subscriber (lossy — observational; reserved for the DevOverlay emitter wiring in a follow-on plan).
    let devSub = await broadcaster.subscribe(priority: .devOverlay, capacity: 32)
    devOverlaySubscriberTask = Task {
        for await _ in devSub.stream {
            if Task.isCancelled { break }
        }
    }
    
  • File: packages/DevOverlay/Sources/DevOverlay/DevOverlayBridge.swift — exists, never instantiated
  • File: packages/AgentCore/Sources/AgentOrchestrator/DevSnapshotEmitter.swift — exists, fully implemented, has tests; grep -rn DevSnapshotEmitter App/ returns zero hits except a stale comment at AppDelegate.swift:381

Root cause / hypothesis

Three independent breaks: emitter never built, broadcaster subscriber drains to _, bridge never attached. Same calibration-bug shape as the rest of the audit.

Designed flow:

OrchestratorEvent → DevSnapshotEmitter → BoundedAsyncChannel<DevSnapshot> → DevOverlayBridge → viewModel.apply(_:)

Built flow:

OrchestratorEvent → broadcaster.subscribe(.devOverlay) → /dev/null
DevOverlayWindow → DevOverlayViewModel(.initial) → render (initial only)

Recommended fix

In installAgent (where broadcaster exists):

  1. Instantiate DevSnapshotEmitter subscribing to orchestrator events
  2. Instantiate DevOverlayBridge.attach(channel: emitter.snapshotChannel)
  3. Pass bridge into DevOverlayWindow so it gets the live DevOverlayViewModel reference
  4. Replace the no-op drain on line 1809-1813 with the bridge (or delete the subscriber if bridge owns it)

The intended flow from the audit's "as designed" diagram should land verbatim.

User intent (per devoverlay-diagnosis.md): state / last-5 tools / token counters / latency. PLUS missing-but-wanted: subsystem health (BootHealth), HUD/voice/presence state fields, live log stream from every part of system (no broadcast handler exists for swift-log yet).

Test

  • Behavioral: open Dev Overlay during active turn → assert lastFiveToolCalls, tokenCount, currentTurnId populated within 1s
  • Integration: emit a tool_use event → DevOverlayViewModel's apply() is called with that tool call

Source

  • Audit: .planning/audit-2026-05-12/bus-hud-audit.md (2026-05-12) — finding S1 (DevOverlay)
  • Audit: .planning/audit-2026-05-12/devoverlay-diagnosis.md (2026-05-12) — detailed diagnosis

Cross-references

  • Related: #7 (M-3 Diagnostics surface — DevOverlay moves here)
## Summary DevOverlay is a hollow shell. `DevOverlayWindow` opens with a default `DevOverlayViewModel` holding `DevSnapshot.initial`. The `.devOverlay` broadcaster subscription on `AppDelegate.swift:1808-1813` drains events into `_` with a comment "reserved for the DevOverlay emitter wiring in a follow-on plan." `DevOverlayBridge` is never instantiated. `DevSnapshotEmitter` exists in AgentCore but is never constructed. Opening the overlay shows static initial values (state=idle, 0 tokens, empty turn id) forever. ## Evidence - File: `App/AppDelegate.swift:2652-2659` (`toggleDevOverlay()`) - File: `App/AppDelegate.swift:1803-1813`: ```swift // DevOverlay subscriber (lossy — observational; reserved for the DevOverlay emitter wiring in a follow-on plan). let devSub = await broadcaster.subscribe(priority: .devOverlay, capacity: 32) devOverlaySubscriberTask = Task { for await _ in devSub.stream { if Task.isCancelled { break } } } ``` - File: `packages/DevOverlay/Sources/DevOverlay/DevOverlayBridge.swift` — exists, never instantiated - File: `packages/AgentCore/Sources/AgentOrchestrator/DevSnapshotEmitter.swift` — exists, fully implemented, has tests; `grep -rn DevSnapshotEmitter App/` returns zero hits except a stale comment at `AppDelegate.swift:381` ## Root cause / hypothesis Three independent breaks: emitter never built, broadcaster subscriber drains to `_`, bridge never attached. Same calibration-bug shape as the rest of the audit. Designed flow: ``` OrchestratorEvent → DevSnapshotEmitter → BoundedAsyncChannel<DevSnapshot> → DevOverlayBridge → viewModel.apply(_:) ``` Built flow: ``` OrchestratorEvent → broadcaster.subscribe(.devOverlay) → /dev/null DevOverlayWindow → DevOverlayViewModel(.initial) → render (initial only) ``` ## Recommended fix In `installAgent` (where broadcaster exists): 1. Instantiate `DevSnapshotEmitter` subscribing to orchestrator events 2. Instantiate `DevOverlayBridge.attach(channel: emitter.snapshotChannel)` 3. Pass bridge into `DevOverlayWindow` so it gets the live `DevOverlayViewModel` reference 4. Replace the no-op drain on line 1809-1813 with the bridge (or delete the subscriber if bridge owns it) The intended flow from the audit's "as designed" diagram should land verbatim. User intent (per devoverlay-diagnosis.md): state / last-5 tools / token counters / latency. PLUS missing-but-wanted: subsystem health (BootHealth), HUD/voice/presence state fields, live log stream from every part of system (no broadcast handler exists for swift-log yet). ## Test - Behavioral: open Dev Overlay during active turn → assert `lastFiveToolCalls`, `tokenCount`, `currentTurnId` populated within 1s - Integration: emit a `tool_use` event → DevOverlayViewModel's `apply()` is called with that tool call ## Source - Audit: `.planning/audit-2026-05-12/bus-hud-audit.md` (2026-05-12) — finding S1 (DevOverlay) - Audit: `.planning/audit-2026-05-12/devoverlay-diagnosis.md` (2026-05-12) — detailed diagnosis ## Cross-references - Related: #7 (M-3 Diagnostics surface — DevOverlay moves here)
KofTwentyTwo commented 2026-05-13 16:27:45 +00:00 (Migrated from github.com)

Confirmed wired on develop: DevSnapshotEmitter built end-to-end in 50c2783 (4-tab AppKit NSPanel), live log stream wired in 6ea2852. Verified by AppDelegate import + tests in App/Tests/AppTests. Closing — was already done at the time of yesterday's handoff but never formally closed.

Confirmed wired on develop: DevSnapshotEmitter built end-to-end in 50c2783 (4-tab AppKit NSPanel), live log stream wired in 6ea2852. Verified by AppDelegate import + tests in App/Tests/AppTests. Closing — was already done at the time of yesterday's handoff but never formally closed.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: KofTwentyTwo/Jarvis#42