diff --git a/dashboard/src/components/nv-app.ts b/dashboard/src/components/nv-app.ts
index 8e54ba8a..bdfb8629 100644
--- a/dashboard/src/components/nv-app.ts
+++ b/dashboard/src/components/nv-app.ts
@@ -17,8 +17,9 @@ import './nv-palette';
import './nv-debug-hud';
import './nv-settings-drawer';
import './nv-onboarding';
+import './nv-ghost-murmur';
-export type View = 'scene' | 'apps' | 'settings';
+export type View = 'scene' | 'apps' | 'inspector' | 'witness' | 'ghost-murmur';
@customElement('nv-app')
export class NvApp extends LitElement {
@@ -78,9 +79,16 @@ export class NvApp extends LitElement {
- ${this.view === 'apps' ? html` ` : html` `}
+ ${this.view === 'apps'
+ ? html` `
+ : this.view === 'ghost-murmur'
+ ? html` `
+ : html` `}
-
+
+
diff --git a/dashboard/src/components/nv-ghost-murmur.ts b/dashboard/src/components/nv-ghost-murmur.ts
new file mode 100644
index 00000000..1c6a7e98
--- /dev/null
+++ b/dashboard/src/components/nv-ghost-murmur.ts
@@ -0,0 +1,339 @@
+/* Ghost Murmur β research view.
+ *
+ * Walks through the publicly-reported April 2026 CIA program and maps
+ * the physically-defensible parts onto RuView's three-tier heartbeat
+ * mesh. Source: docs/research/quantum-sensing/16-ghost-murmur-ruview-spec.md
+ *
+ * This view is reference material, not an operational mode. It exists
+ * so practitioners (and journalists) can audit the physics-vs-press
+ * gap in the open. ADR-092 Β§14b.
+ */
+
+import { LitElement, html, css } from 'lit';
+import { customElement } from 'lit/decorators.js';
+
+@customElement('nv-ghost-murmur')
+export class NvGhostMurmur extends LitElement {
+ static styles = css`
+ :host {
+ display: block;
+ height: 100%;
+ overflow-y: auto;
+ background: radial-gradient(ellipse at 50% 30%, var(--bg-2) 0%, var(--bg-0) 70%);
+ padding: 24px 28px 60px;
+ }
+ h1 {
+ margin: 0 0 4px;
+ font-size: 22px;
+ letter-spacing: -0.02em;
+ color: var(--ink);
+ }
+ .subtitle {
+ color: var(--ink-3);
+ font-size: 13px;
+ margin-bottom: 22px;
+ }
+ .links {
+ display: flex; flex-wrap: wrap; gap: 6px;
+ margin-bottom: 22px;
+ }
+ .links a {
+ padding: 5px 10px;
+ background: var(--bg-2);
+ border: 1px solid var(--line);
+ border-radius: 999px;
+ font-size: 11.5px;
+ font-family: var(--mono);
+ color: var(--accent-2);
+ text-decoration: none;
+ }
+ .links a:hover { border-color: var(--accent-2); }
+ h2 {
+ font-size: 14px;
+ font-weight: 600;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ color: var(--ink-3);
+ margin: 28px 0 10px;
+ }
+ .grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ gap: 12px;
+ }
+ .card {
+ background: var(--bg-2);
+ border: 1px solid var(--line);
+ border-radius: var(--radius);
+ padding: 14px;
+ }
+ .card h3 {
+ margin: 0 0 8px;
+ font-size: 13.5px; font-weight: 600;
+ color: var(--ink);
+ }
+ .card p {
+ font-size: 12.5px; color: var(--ink-2);
+ margin: 0 0 8px;
+ line-height: 1.5;
+ }
+ .card p:last-child { margin-bottom: 0; }
+ .stat {
+ display: inline-flex; align-items: baseline; gap: 6px;
+ margin-right: 10px;
+ }
+ .stat .v {
+ font-family: var(--mono); font-size: 16px; font-weight: 600;
+ color: var(--accent);
+ }
+ .stat .l {
+ font-size: 10px; color: var(--ink-3);
+ text-transform: uppercase; letter-spacing: 0.04em;
+ }
+ table {
+ width: 100%; border-collapse: collapse;
+ font-size: 12.5px;
+ }
+ th, td {
+ padding: 8px 10px;
+ text-align: left;
+ border-bottom: 1px solid var(--line);
+ }
+ th {
+ color: var(--ink-3);
+ font-weight: 600;
+ font-size: 11px;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ }
+ td.amber { color: var(--accent); font-family: var(--mono); }
+ td.cyan { color: var(--accent-2); font-family: var(--mono); }
+ td.bad { color: var(--bad); font-family: var(--mono); }
+ .pill {
+ display: inline-block;
+ padding: 1px 6px;
+ border-radius: 4px;
+ font-family: var(--mono);
+ font-size: 10px;
+ border: 1px solid var(--line);
+ }
+ .pill.ok { color: var(--ok); border-color: oklch(0.78 0.14 145 / 0.4); }
+ .pill.skeptical { color: var(--bad); border-color: oklch(0.65 0.22 25 / 0.4); }
+ .pill.partial { color: var(--warn); border-color: oklch(0.7 0.18 35 / 0.4); }
+ .architecture {
+ font-family: var(--mono);
+ font-size: 11px;
+ color: var(--ink-2);
+ background: var(--bg-3);
+ padding: 16px;
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--line);
+ white-space: pre;
+ overflow-x: auto;
+ line-height: 1.4;
+ }
+ .ethics {
+ background: linear-gradient(180deg, var(--bg-2) 0%, oklch(0.65 0.22 25 / 0.04) 100%);
+ border: 1px solid oklch(0.65 0.22 25 / 0.25);
+ border-radius: var(--radius);
+ padding: 16px;
+ }
+ .ethics h3 { color: var(--bad); margin-top: 0; }
+ .ethics ul { padding-left: 18px; margin: 8px 0; }
+ .ethics li { font-size: 12.5px; color: var(--ink-2); margin-bottom: 4px; }
+ `;
+
+ override render() {
+ return html`
+ Ghost Murmur β open-source reality check
+
+ The physics-vs-press audit for the publicly-reported April 2026
+ CIA NV-diamond heartbeat detector, and how RuView's existing
+ stack maps onto an honest, civilian version of the same idea.
+
+
+
+
+ What the press reported
+
+
+
The story
+
3 Apr 2026: USAF F-15E pilot "Dude 44 Bravo" goes down in southern Iran during the regional exchange and evades for ~2 days.
+
President Trump publicly suggests detection from 40 miles away on a mountainside at night; CIA Director Ratcliffe says "invisible to the enemy, but not to the CIA."
+
+
+
The named tech
+
"Ghost Murmur" β Lockheed Skunk Works system using NV defects in synthetic diamond + AI to extract a heartbeat from environmental noise.
+
Outlets: Newsweek, Scientific American, Military.com, WION, Open The Magazine, Yahoo, Calcalist + HN thread #47679241.
+
+
+
What physicists said
+
Wikswo (Vanderbilt), Orzel (Union College), Roth (Oakland) β all pushing back hard.
+
"At 1 km, the heartbeat field drops to ~10β»ΒΉΒ² of its 10 cm value." MCG-only at multi-mile range is not consistent with published physics .
+
+
+
+ Physics reality check
+
+
+
+ Distance Cardiac MCG (peak QRS) vs Earth field (~50 Β΅T)
+
+
+ 10 cm 50 pT 10βΉΓ weaker
+ 1 m 50 fT 10ΒΉΒ²Γ weaker
+ 10 m 50 aT 10ΒΉβ΅Γ weaker
+ 1 km 5 Γ 10β»Β²Β³ T 10Β²β·Γ weaker
+ 40 mi (65 km) ~10β»Β²βΈ T 10Β³Β³Γ weaker
+
+
+
+ Best published NV-ensemble lab record: 0.9 pT/βHz [Wolf 2015].
+ Best SQUID in a shielded room: ~1 fT/βHz . To detect a single heartbeat at 10 m
+ you'd need ~2 billionΓ more sensitivity than any published ensemble has ever shown,
+ in a magnetically silent environment. 40 miles is press-release physics.
+
+
+
+ RuView's three-tier mesh β what is actually buildable
+ ββββββββββββββββββββββββββββ
+ β Tier 3 β NV-diamond β Range: 0.1β2 m (lab)
+ β magnetometer ring β Status: nvsim simulator only
+ β (close-confirm) β Hardware: $$$ (β₯$8k DNV-B1)
+ ββββββββββββ¬ββββββββββββββββ
+ β
+ ββββββββββββ΄ββββββββββββββββ
+ β Tier 2 β 60 GHz FMCW β Range: 1β10 m HR/BR
+ β mmWave radar mesh β Status: shipping (ADR-021)
+ β (vital signs, posture) β Hardware: $15 (MR60BHA2 + ESP32-C6)
+ ββββββββββββ¬ββββββββββββββββ
+ β
+ ββββββββββββ΄ββββββββββββββββ
+ β Tier 1 β WiFi CSI mesh β Range: 10β30 m through-wall
+ β (presence, breathing, β Status: shipping (ADR-014, ADR-029)
+ β pose, intention) β Hardware: $9 (ESP32-S3 8MB)
+ ββββββββββββ¬ββββββββββββββββ
+ β
+ βΌ
+ ββββββββββββββββββββββββββββββββββ
+ β RuvSense multistatic fusion β
+ β + cross-viewpoint attention β
+ β + AETHER re-ID embeddings β
+ β + Cramer-Rao gating β
+ ββββββββββββββββββββββββββββββββββ
+
+ Press claim β RuView equivalent
+
+
+
+ Press claim RuView equivalent today Crate / ADR Honest range
+
+
+
+ NV-diamond magnetometry
+ Deterministic NV pipeline simulator
+ nvsim Β· ADR-089
+ Simulator only
+
+
+ "AI strips environmental noise"
+ RuvSense multistatic fusion + AETHER
+ signal/ruvsense/ Β· ADR-029
+ Mature
+
+
+ Heartbeat at distance
+ 60 GHz FMCW HR/BR + WiFi CSI breathing
+ vitals Β· ADR-021
+ 1β5 m HR Β· 10β30 m presence
+
+
+ Long-range localisation
+ Multistatic time-of-flight + CRLB
+ ruvector/viewpoint/
+ Limited by node spacing
+
+
+ 40-mile single-heartbeat detection
+ Not feasible at any tier
+ β
+ Press-release physics
+
+
+
+
+
+ Build today on $165
+
+
+
Bill of materials
+
+ 3 Γ ESP32-S3 8 MB ($9 ea)
+ 3 Γ PoE injector + cat6 ($6 ea)
+ 1 Γ ESP32-C6 + Seeed MR60BHA2 ($15)
+ 1 Γ Raspberry Pi 5 8 GB ($80)
+ 1 Γ unmanaged GbE switch ($25)
+
+
Total: $165
+
+
+
Honest performance
+ 95% TPR (LOS, 0β15 m)
+ Β±2 bpm HR (LOS 0β3 m)
+ Β±1 br/min BR (any mode)
+ ~10 cm pose error
+ 80β150 ms end-to-end latency
+
+
+
Determinism
+
Same (scene, config, seed) β byte-identical SHA-256 witness across browsers, OSes, transports.
+
Reference: cc8de9b01b0ff5bdβ¦
+
Try the Witness tab on the right β it re-derives the hash live in this browser and compares against the published reference.
+
+
+
+ Privacy, ethics, legal
+
+
This is the open-source version. Same physics, opposite governance.
+
+ Civilian opt-in only β search-and-rescue, elder-care, occupancy, ICU vitals. Not surveillance.
+ No directional pursuit β no beam-steering, target-following, or remote person-of-interest tracking.
+ Data minimisation β fused output is (presence, HR, BR, pose, p_alive); raw streams discarded at the edge.
+ PII gates (ADR-040) block identifying biometric streams from leaving the local mesh without consent.
+ Adversarial-signal detection flags physically-impossible signal patterns from compromised mesh nodes.
+ No export-controlled hardware β RuView targets < $50 COTS. ITAR/EAR sub-THz coherent radars and shielded NV ensembles are out of scope.
+
+
+ RuView is not affiliated with the United States government, the CIA, Lockheed Martin,
+ or any classified program. References to "Ghost Murmur" in this view refer
+ exclusively to the publicly-reported program of that name as covered in the open
+ press in April 2026.
+
+
+
+ Cross-references
+
+
+ ADRs: 014 (signal) Β· 021 (vitals) Β· 024 (AETHER) Β· 027 (MERIDIAN) Β·
+ 028 (witness audit) Β· 029 (RuvSense) Β· 040 (PII gates) Β· 086 (ESP32 RaBitQ) Β·
+ 089 (nvsim, Accepted) Β· 090 (Lindblad, Proposed-conditional) Β·
+ 091 (sub-THz radar research) Β· 092 (this dashboard) .
+ Primary physics: Cohen 1970 Β· Bison 2009 Β· Wolf 2015 Β· Barry RMP 2020 Β· Doherty 2013 Β· Jackson 3e Β§5.6/Β§5.8.
+
+
+ `;
+ }
+}
diff --git a/dashboard/src/components/nv-inspector.ts b/dashboard/src/components/nv-inspector.ts
index e33690c1..158cab38 100644
--- a/dashboard/src/components/nv-inspector.ts
+++ b/dashboard/src/components/nv-inspector.ts
@@ -1,6 +1,6 @@
/* Inspector β tabbed: Signal / Frame / Witness. */
-import { LitElement, html, css, svg } from 'lit';
-import { customElement, state } from 'lit/decorators.js';
+import { LitElement, html, css, svg, type PropertyValues } from 'lit';
+import { customElement, state, property } from 'lit/decorators.js';
import { effect } from '@preact/signals-core';
import {
traceX, traceY, traceZ, stripBars, lastFrame,
@@ -13,6 +13,8 @@ type Tab = 'signal' | 'frame' | 'witness';
@customElement('nv-inspector')
export class NvInspector extends LitElement {
@state() private tab: Tab = 'signal';
+ /** When set by the parent, force the tab and pulse-highlight it. */
+ @property({ attribute: false }) pinTab: Tab | null = null;
static styles = css`
:host {
@@ -123,6 +125,16 @@ export class NvInspector extends LitElement {
});
}
+ override willUpdate(changed: PropertyValues): void {
+ // Apply parent-driven tab pin during willUpdate so the new tab value
+ // participates in this same render pass β avoids the "update after
+ // update completed" Lit warning that would fire if we did this in
+ // updated().
+ if (changed.has('pinTab') && this.pinTab && this.tab !== this.pinTab) {
+ this.tab = this.pinTab;
+ }
+ }
+
private async verify(): Promise {
const c = getClient(); if (!c) return;
witnessVerified.value = 'pending';
diff --git a/dashboard/src/components/nv-rail.ts b/dashboard/src/components/nv-rail.ts
index bca45c0f..d947c7b3 100644
--- a/dashboard/src/components/nv-rail.ts
+++ b/dashboard/src/components/nv-rail.ts
@@ -50,6 +50,7 @@ export class NvRail extends LitElement {
content: ''; position: absolute; left: -10px; top: 8px; bottom: 8px;
width: 2px; background: var(--accent); border-radius: 2px;
}
+ .btn.ghost.active::before { background: var(--accent-3); }
.spacer { flex: 1; }
svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; }
`;
@@ -69,16 +70,27 @@ export class NvRail extends LitElement {
@click=${() => this.navigate('apps')}>
- this.navigate('scene')}>
+ this.navigate('inspector')}>
-
+ this.navigate('witness')}>
+ this.navigate('ghost-murmur')}>
+
+
+
+
+
+
this.dispatchEvent(new CustomEvent('open-settings', { bubbles: true, composed: true }))}>
-
+
`;
}