M-3: Diagnostics surface (HUD state + banner queue + DevSnapshot + replay stream) #7

Open
opened 2026-05-12 19:02:07 +00:00 by KofTwentyTwo · 0 comments
KofTwentyTwo commented 2026-05-12 19:02:07 +00:00 (Migrated from github.com)

Goal

Land Diagnostics surface. HUD state moves here per F-003 amendment (Diagnostics.hudStateChanged). Banner queue, DevSnapshot stream, replay-log stream, and hardBlockTriggered all exposed through the typed API.

Scope — surfaces in this phase

  • JarvisAPI.Diagnostics with: getDevSnapshot, devSnapshotUpdated, toggleDevOverlay
  • Diagnostics.hudStateChanged + getHudState (F-003 amendment — HUD state OFF Turn surface, ON Diagnostics)
  • systemBannerEnqueued + systemBannerDismissed + dismissBanner
  • streamReplayEvents + snapshotReplayEvents — replay-event side-effect contract (one API event = one replay row + one bus event) (R-017)
  • hardBlockTriggered event + 1s pre-termination delay (G-012 — replaces direct NSAlert.runModal)
  • copyStateDump command (clipboard write) + emitted banner event

Files (created/modified)

  • packages/JarvisAPI/Sources/JarvisAPI/Surfaces/Diagnostics+Adapter.swift (new) — wraps DevOverlay + HUDBannerCoordinator
  • App/AppDelegate.swift — delete BusForwarder.hudState emit; route through HudStateCoordinator only
  • packages/DevOverlay/... — surface bridge
  • packages/Harness/Tests/HarnessTests/DiagnosticsScenarioTests.swift (new)

Test contract

Scenarios S-DIAG-001..S-DIAG-009 — all run in BOTH transport modes per UQ-5:

  • DevSnapshot stream round-trip
  • HUD state writer = exactly ONE event reaches bus client (behavioral single-writer gate from M-0.6)
  • Banner enqueue produces exactly ONE event (no AppKit panel independent emit)
  • Replay roundtrip: Memory.applyOp(.add, …) produces ONE replay row AND one bus event (R-017)
  • hardBlockTriggered then 1s delay then process exit (G-012 — no modal)
  • copyStateDump writes clipboard + emits banner

Acceptance criteria

  • bash scripts/check-single-writer-hudstate.sh (behavioral) green AFTER HUD migration — old BusOutbound.hudState emit MUST be deleted
  • bash scripts/check-no-modal-presentation.sh green
  • All Diagnostics scenarios green via .inProcessActor runner
  • All Diagnostics scenarios green via .jsonRoundTripWebView runner
  • Banner enqueue produces exactly one event (no AppKit independent emit)
  • Replay roundtrip: 1 API event = 1 replay row + 1 bus event
  • PR merged to develop

Carry-forward closures

None — substrate for HUD state observability.

Dependencies

  • Blocked by: #6 (M-2)
  • Blocks: #8 (M-4 Memory)

Related issues

  • Will dissolve: DevOverlay hollow-shell + BridgeNavigationDelegate silent-failure (bus-hud audit S1 findings)

Sub-issues

  • #109 — M-3: Diagnostics surface — getDevSnapshot/devSnapshotUpdated/toggleDevOverlay
  • #110 — M-3: HUD state moves to Diagnostics (F-003); delete legacy hudState emit
  • #111 — M-3: Diagnostics banner queue — enqueued/dismissed/dismissBanner + copyStateDump (F-016)
  • #112 — M-3: Diagnostics.streamReplayEvents + snapshotReplayEvents (R-017 single-emit)
  • #113 — M-3: Diagnostics.hardBlockTriggered + 1s pre-termination delay (G-012)
  • #114 — M-3: harness scenarios S-DIAG-001..009 in both transport modes (UQ-5)

Estimate

1.0–1.5 engineer-days

Source

  • .planning/architecture/JARVIS-API-MIGRATION-PLAN.md §2.4
  • .planning/architecture/JARVIS-API-DESIGN-v0.1.md — Diagnostics surface
  • .planning/architecture/JARVIS-API-DESIGN-v0.2.md — F-003 amendment (HUD on Diagnostics)
  • .planning/architecture/REVIEW-MIGRATION-RISK.md R-004, R-017
  • Parent epic: v1.0 API Migration — UI/Backend separation (M-0..M-7) (#76)
## Goal Land Diagnostics surface. HUD state moves here per F-003 amendment (`Diagnostics.hudStateChanged`). Banner queue, DevSnapshot stream, replay-log stream, and `hardBlockTriggered` all exposed through the typed API. ## Scope — surfaces in this phase - **`JarvisAPI.Diagnostics`** with: `getDevSnapshot`, `devSnapshotUpdated`, `toggleDevOverlay` - `Diagnostics.hudStateChanged` + `getHudState` (F-003 amendment — HUD state OFF Turn surface, ON Diagnostics) - `systemBannerEnqueued` + `systemBannerDismissed` + `dismissBanner` - `streamReplayEvents` + `snapshotReplayEvents` — replay-event side-effect contract (one API event = one replay row + one bus event) (R-017) - `hardBlockTriggered` event + 1s pre-termination delay (G-012 — replaces direct `NSAlert.runModal`) - `copyStateDump` command (clipboard write) + emitted banner event ## Files (created/modified) - `packages/JarvisAPI/Sources/JarvisAPI/Surfaces/Diagnostics+Adapter.swift` (new) — wraps `DevOverlay` + `HUDBannerCoordinator` - `App/AppDelegate.swift` — delete `BusForwarder.hudState` emit; route through `HudStateCoordinator` only - `packages/DevOverlay/...` — surface bridge - `packages/Harness/Tests/HarnessTests/DiagnosticsScenarioTests.swift` (new) ## Test contract Scenarios `S-DIAG-001..S-DIAG-009` — all run in BOTH transport modes per UQ-5: - DevSnapshot stream round-trip - HUD state writer = exactly ONE event reaches bus client (behavioral single-writer gate from M-0.6) - Banner enqueue produces exactly ONE event (no AppKit panel independent emit) - Replay roundtrip: `Memory.applyOp(.add, …)` produces ONE replay row AND one bus event (R-017) - `hardBlockTriggered` then 1s delay then process exit (G-012 — no modal) - `copyStateDump` writes clipboard + emits banner ## Acceptance criteria - [ ] `bash scripts/check-single-writer-hudstate.sh` (behavioral) green AFTER HUD migration — old `BusOutbound.hudState` emit MUST be deleted - [ ] `bash scripts/check-no-modal-presentation.sh` green - [ ] All Diagnostics scenarios green via `.inProcessActor` runner - [ ] All Diagnostics scenarios green via `.jsonRoundTripWebView` runner - [ ] Banner enqueue produces exactly one event (no AppKit independent emit) - [ ] Replay roundtrip: 1 API event = 1 replay row + 1 bus event - [ ] PR merged to develop ## Carry-forward closures None — substrate for HUD state observability. ## Dependencies - Blocked by: #6 (M-2) - Blocks: #8 (M-4 Memory) ## Related issues - Will dissolve: DevOverlay hollow-shell + BridgeNavigationDelegate silent-failure (bus-hud audit S1 findings) ## Sub-issues - #109 — M-3: Diagnostics surface — getDevSnapshot/devSnapshotUpdated/toggleDevOverlay - #110 — M-3: HUD state moves to Diagnostics (F-003); delete legacy hudState emit - #111 — M-3: Diagnostics banner queue — enqueued/dismissed/dismissBanner + copyStateDump (F-016) - #112 — M-3: Diagnostics.streamReplayEvents + snapshotReplayEvents (R-017 single-emit) - #113 — M-3: Diagnostics.hardBlockTriggered + 1s pre-termination delay (G-012) - #114 — M-3: harness scenarios S-DIAG-001..009 in both transport modes (UQ-5) ## Estimate 1.0–1.5 engineer-days ## Source - `.planning/architecture/JARVIS-API-MIGRATION-PLAN.md` §2.4 - `.planning/architecture/JARVIS-API-DESIGN-v0.1.md` — `Diagnostics` surface - `.planning/architecture/JARVIS-API-DESIGN-v0.2.md` — F-003 amendment (HUD on Diagnostics) - `.planning/architecture/REVIEW-MIGRATION-RISK.md` R-004, R-017 - Parent epic: #76
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: KofTwentyTwo/Jarvis#7