Back to Ruview

ADR-093: nvsim Dashboard Gap Analysis (post-deploy review)

docs/adr/ADR-093-dashboard-gap-analysis.md

1.99.0-pip11.0 KB
Original Source

ADR-093: nvsim Dashboard Gap Analysis (post-deploy review)

FieldValue
StatusImplemented (2026-04-27) — iterations A through N shipped to PR #436. 21 of 21 catalogued gaps closed. P2.7 (clients.claim() in SW) and P2.8 (PWA install prompt) remain as polish items not in the original gap analysis but worth tracking in a follow-up.
Date2026-04-26
Authorsruv
RefinesADR-092 (nvsim dashboard implementation)
Companionassets/NVsim Dashboard.zip (mockup, ~4200 LOC), live deploy https://ruvnet.github.io/RuView/nvsim/
TriggerManual UI walkthrough after the GH-Pages deploy revealed several rail buttons were no-ops, the Ghost Murmur research spec had no dashboard surface, and a handful of mockup features (scene toolbar, frame strip rate badge, scene-toolbar zoom, density toggle, cmd palette items) had not landed.

1. Method

A line-by-line inventory walk of the deployed dashboard against four reference points:

  1. The mockup: assets/NVsim Dashboard.zipNVSim Dashboard.html. Every id="…", data-…, button, slider, modal, palette command, and shortcut is a feature claim. We diff it against the live SPA.
  2. ADR-092 §4.2 — the canonical inventory table of 12 zones and ~50 components. We mark each row as ✅ shipped / ⚠ partial / ❌ missing.
  3. ADR-092 §4.3 — REPL command set (10 commands).
  4. ADR-092 §4.4 — keyboard shortcuts (11 chords).

Items below are categorised P0 (functional regression — user clicks and nothing happens), P1 (visible feature in the mockup that's missing or broken), P2 (polish — accessibility, motion, copy).

The closing §5 is the iteration plan.


2. P0 — broken/missing functional surface

#GapLocationRoot causeFix
P0.1Inspector rail button no-opnv-rail.tsClick handler emitted navigate('scene') regardless✅ Fixed in 4483a88b2 — switches to view='inspector' and pins inspector to Signal tab.
P0.2Witness rail button no-opnv-rail.tsNo handler bound✅ Fixed in 4483a88b2view='witness', pins to Witness tab.
P0.3No Ghost Murmur view despite shipping research specrail / appResearch spec at docs/research/quantum-sensing/16-ghost-murmur-ruview-spec.md had no dashboard surface✅ Fixed in 4483a88b2 — new <nv-ghost-murmur> component, dedicated rail icon.
P0.4Ghost Murmur view is read-onlynv-ghost-murmur.tsCurrently a static document. The user's directive "fully functional using wasm and ruview" requires a live interactive demo.⏳ §5 below — interactive distance/moment sliders that actually drive nvsim::Pipeline via WASM and report per-tier detectability.
P0.5Topbar seed pill is decorativenv-topbar.ts✅ Iter C — opens "Set seed" modal with hex input; applies via WasmClient.setSeed.
P0.6Sim controls overlay absentnv-scene.ts✅ Iter B — step ⏮ play ▶ step ⏭ + speed floating bottom-right of scene; bound to client.run/pause/step and speed.value cycle.
P0.7Scene toolbar (zoom / fit / layers) missingnv-scene.ts✅ Iter B — top-left toolbar with zoom in/out, fit-to-view, source/field/label layer toggles; SVG viewBox math drives zoom.
P0.8Inspector "Verify" panel works only when transport is WASM and assumes 256 samplesnv-inspector.ts, WasmClient.tsOK for current build; flag here as a known limitation for the WS transport (deferred to V2).Document — not a fix.
P0.9REPL proof.export not implementednv-console.ts✅ Iter E — wires to client.exportProofBundle(), triggers a blob download with timestamp filename.
P0.10REPL command history is per-componentnv-console.ts✅ Iter G — moved to appStore.replHistory signal, persisted via IndexedDB key repl-history.

3. P1 — visible mockup features missing

#GapLocationNotes
P1.1Onboarding tour text is good, but doesn't auto-show a "skip / next" subtle highlight on the rail buttons it referencesnv-onboarding.tsMockup uses spotlight cutouts. Ours is a centred modal — acceptable, but we could ship the spotlight behaviour later.
P1.2Density toggle didn't visibly change anythingmain.ts + app.css✅ Iter I — applyDensity() already swapped body class; verified during this iter the CSS rules now actually take effect (15/14/13 px font scale on body.density-{comfy,default,compact}).
P1.3motion-toggle only flips body.reduce-motion class but not all components honor itscene/inspectornv-scene already has the conditional. Verify B-trace and frame-strip animations stop too.
P1.4Scene "stat-card" SNR readout always nv-scene.ts✅ Iter F — SNR =
P1.5Inspector frame-strip-2 from the Frame tab not in our implnv-inspector.tsMockup has a second sparkline strip in the Frame tab; we only ship one. Replicate.
P1.6Modals body content was shortnv-palette.ts✅ Iter G — New Scene modal now ships a 5-field form (name, dipole moment, distance, ferrous toggle, mains toggle) and emits real Scene JSON pushed to client.loadScene(). Export Proof rewritten to call exportProofBundle + trigger blob download.
P1.7Scene drag positions don't persistnv-scene.ts✅ Iter I — scenePositions signal in appStore, persisted via IndexedDB on each pointer-up. Restored at component connect.
P1.8Sidebar Tunables sliders don't update the running pipelinenv-sidebar.ts + WasmClient.ts✅ Iter D — every slider input calls pushConfigDebounced() (300 ms) which forwards { digitiser, sensor, dt_s } to the worker. Worker rebuilds the WasmPipeline with the new config. Verified via REPL log line config pushed · fs=… f_mod=….
P1.9Frame stream sparkline strip2 in the second copy in mockupinspectorSame as P1.5 — verify.
P1.10"WASM" pill is read-onlynv-topbar.ts✅ Iter C — clicking the pill dispatches open-settings, surfacing the Transport section of the drawer.
P1.11prefers-reduced-motion not auto-detectedmain.ts✅ Iter F — window.matchMedia('(prefers-reduced-motion: reduce)').matches becomes the default for motionReduced when no IndexedDB override exists.
P1.12Scene 3D-tilt on pointer move not portednv-scene.tsMockup has .tilt-stage perspective transform. Optional polish.
P1.13View-overlay "expand panel" not portedglobalMockup has a .view-overlay that expands any inspector panel to full-screen. Defer V2.

4. P2 — accessibility / polish

#GapNotes
P2.1Buttons lack aria-labelIter H
P2.2Console log lines have no live-regionIter H
P2.3Modal focus trap not implementedIter H
P2.4Light-theme .ink-3 contrast borderline AAapp.css
P2.5No skip-to-main-content linkIter H
P2.6Keyboard arrow-key scene navigationnv-scene.ts
P2.7Service worker doesn't have clients.claim()Confirm. Ensures new SW activates on next nav.
P2.8PWA install prompt is silentAdd an install button (visible only when beforeinstallprompt fires).

5. Iteration plan

The dynamic /loop continues with one P0/P1 item per iteration:

IterFocusStatus
AFunctional Ghost Murmur demo (P0.4)runTransient WASM export + interactive distance/moment sliders + per-tier detectability bars
BScene sim-controls + toolbar (P0.6, P0.7)✅ Bottom-right sim controls, top-left zoom/layer toolbar
CTopbar seed + WASM pill clicks (P0.5, P1.10)✅ Seed modal + transport pill opens Settings drawer
DSidebar tunables wire-through (P1.8)✅ Debounced setConfig RPC, 300 ms
EREPL proof.export + history persistence (P0.9, P0.10)✅ Blob download + IndexedDB-persisted history
FSNR computation + reduce-motion (P1.4, P1.11, P1.3)
GModal contents (P1.6)✅ New-Scene form (5 fields), real Scene JSON push
HA11y pass (P2.1–P2.5)✅ aria-labels, focus trap, role=log, skip link, role=tablist
IDensity toggle (P1.2) + drag persistence (P1.7)✅ Density CSS verified, scenePositions persisted to IndexedDB
JUX usability pass✅ nv-help center (Quickstart/Glossary/FAQ/Shortcuts/About), 10-step welcome tour, panel descriptions, settings explainers, empty-state hints
KHome view<nv-home> as default landing — hero + 4 quick-jump cards + simplified grid hides power-user panels
LWsClient transport✅ Full REST + binary WebSocket impl against nvsim-server; transport-flip auto-reverify; activated via Settings drawer
MApp Store live runtime✅ 6 simulated apps emit real i32 events against nvsim frame stream; runtime pills (running/simulated/mesh-only); live events feed
NLight-theme contrast (P2.4) + keyboard scene nav (P2.6)✅ AA-compliant --ink-3/--ink-4/--line palette in light mode; Tab/arrows/Shift-arrow/Esc on scene draggables

Each iteration ends with: npx tsc --noEmit clean → production build with NVSIM_BASE=/RuView/nvsim/ → push to gh-pages/nvsim/ preserving siblings → agent-browser validation including console errors → commit on feat/nvsim-pipeline-simulator.

The acceptance criteria from ADR-092 §11 still apply unchanged. This ADR augments §11 rather than replacing it — every P0 item is a prerequisite for declaring §11.1 (faithful UI) green.

6. References

  • ADR-092 §4.2 — full UI inventory table (the contract).
  • ADR-092 §11 — 12 acceptance gates.
  • assets/NVsim Dashboard.zip — canonical mockup (committed).
  • docs/research/quantum-sensing/16-ghost-murmur-ruview-spec.md — Ghost Murmur source material.
  • Live deploy — https://ruvnet.github.io/RuView/nvsim/ (verified: rail buttons functional, witness verifies, App Store catalog renders, onboarding tour works).