HUD: MenuBarIconController.transition(to:) is production-dead — icon never animates per agent state #41

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

Summary

MenuBarIconController.transition(to:) is production-dead. The full CABasicAnimation surface (breath / rotate / shimmer / glow per state) ships and works in unit tests, but no production code ever calls transition(to:). HudStateCoordinator's emit closure fans HudState to the webview bridge only. The menu-bar icon never animates regardless of agent state. Only applyHealth(_:) (Round 4) is wired.

Evidence

  • File: App/MenuBar/MenuBarIconController.swift:65-96
  • Production call sites (verified):
    App/AppDelegate.swift:106: var menuBarController: MenuBarIconController?
    App/AppDelegate.swift:768: menuBarController?.applyHealth(snapshot.overallHealth)
    App/AppDelegate.swift:1305: ... contextMenu ...
    App/AppDelegate.swift:2290: ... contextMenu ...
    App/AppDelegate.swift:2393: menuBarController = controller
    
  • File: App/AppDelegate.swift:2475-2480 — HudStateCoordinator emit closure only calls WebviewBridge.send(.hudState(_:))

Root cause / hypothesis

transition(to:) and its CABasicAnimation surface compile, ship, and unit-test. The decision to remove it from the production wire (or never add it) isn't documented in a Plan or DECISION.md. Subsystem CAN'T see the state because the coordinator never broadcasts to it.

Recommended fix

Decide intent, then either:

  1. If menu-bar icon should animate per state: Subscribe MenuBarIconController.transition(to:) to the same broadcast the bus emit consumes. Expand the emit closure on AppDelegate.swift:2475 to also call menuBarController?.transition(to:). Not a HUD-08 single-writer violation — transition(to:) writes the icon's currentState, not BusOutbound.hudState.

  2. If icon is intentionally static, ring is dynamic: Delete transition(to:) entirely and its tests. Keep applyHealth as the only public mutator.

Document the decision in .planning/architecture/ either way.

Test

  • Behavioral: HUD state transition .idle → .thinking → assert menu-bar icon CABasicAnimation key set OR explicit assertion of "static" decision

Source

  • Audit: .planning/audit-2026-05-12/bus-hud-audit.md (2026-05-12) — finding S1 (MenuBarIconController)
## Summary `MenuBarIconController.transition(to:)` is production-dead. The full CABasicAnimation surface (breath / rotate / shimmer / glow per state) ships and works in unit tests, but no production code ever calls `transition(to:)`. `HudStateCoordinator`'s emit closure fans HudState to the webview bridge only. The menu-bar icon never animates regardless of agent state. Only `applyHealth(_:)` (Round 4) is wired. ## Evidence - File: `App/MenuBar/MenuBarIconController.swift:65-96` - Production call sites (verified): ``` App/AppDelegate.swift:106: var menuBarController: MenuBarIconController? App/AppDelegate.swift:768: menuBarController?.applyHealth(snapshot.overallHealth) App/AppDelegate.swift:1305: ... contextMenu ... App/AppDelegate.swift:2290: ... contextMenu ... App/AppDelegate.swift:2393: menuBarController = controller ``` - File: `App/AppDelegate.swift:2475-2480` — `HudStateCoordinator` emit closure only calls `WebviewBridge.send(.hudState(_:))` ## Root cause / hypothesis `transition(to:)` and its CABasicAnimation surface compile, ship, and unit-test. The decision to remove it from the production wire (or never add it) isn't documented in a Plan or DECISION.md. Subsystem CAN'T see the state because the coordinator never broadcasts to it. ## Recommended fix Decide intent, then either: 1. **If menu-bar icon should animate per state:** Subscribe `MenuBarIconController.transition(to:)` to the same broadcast the bus emit consumes. Expand the emit closure on `AppDelegate.swift:2475` to also call `menuBarController?.transition(to:)`. Not a HUD-08 single-writer violation — `transition(to:)` writes the icon's `currentState`, not `BusOutbound.hudState`. 2. **If icon is intentionally static, ring is dynamic:** Delete `transition(to:)` entirely and its tests. Keep `applyHealth` as the only public mutator. Document the decision in `.planning/architecture/` either way. ## Test - Behavioral: HUD state transition `.idle → .thinking` → assert menu-bar icon CABasicAnimation key set OR explicit assertion of "static" decision ## Source - Audit: `.planning/audit-2026-05-12/bus-hud-audit.md` (2026-05-12) — finding S1 (MenuBarIconController)
KofTwentyTwo commented 2026-05-13 11:52:11 +00:00 (Migrated from github.com)

Closed by v0.1 cluster merges on 2026-05-13. Develop now at a8c7f1a0.

Closed by v0.1 cluster merges on 2026-05-13. Develop now at `a8c7f1a0`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: KofTwentyTwo/Jarvis#41