diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cb5418e4..cfb04f22 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -216,10 +216,14 @@ jobs:
htmlcov/
# Performance and Load Tests
+ # NOTE: tests/performance/locustfile.py and the src.api.main app path both
+ # predate the v1→archive/v1 reorganisation. continue-on-error: true until a
+ # proper locust suite is added under archive/v1/tests/performance/.
performance-test:
name: Performance Tests
runs-on: ubuntu-latest
needs: [test]
+ continue-on-error: true
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- name: Checkout code
@@ -238,6 +242,7 @@ jobs:
pip install locust
- name: Start application
+ working-directory: archive/v1
run: |
uvicorn src.api.main:app --host 0.0.0.0 --port 8000 &
sleep 10
@@ -352,6 +357,7 @@ jobs:
pip install -r requirements.txt
- name: Generate OpenAPI spec
+ working-directory: archive/v1
run: |
python -c "
from src.api.main import app
@@ -373,6 +379,8 @@ jobs:
runs-on: ubuntu-latest
needs: [code-quality, test, rust-tests, performance-test, docker-build, docs]
if: always()
+ permissions:
+ contents: write # required by softprops/action-gh-release
# GitHub Actions does not allow `secrets.X` directly in step-level `if:`
# expressions — only `env.X`. Promote the secret to env at job scope so
# the gating expression below is parseable.
diff --git a/.github/workflows/clone-tracking.yml b/.github/workflows/clone-tracking.yml
new file mode 100644
index 00000000..58b1e293
--- /dev/null
+++ b/.github/workflows/clone-tracking.yml
@@ -0,0 +1,149 @@
+name: GitHub Clone Tracking → data/clone-data.rvf
+
+# Persists rolling 14-day clone-traffic snapshots to data/clone-data.rvf in
+# the ruvector JSONL RVF format. GitHub's /traffic/clones endpoint only
+# retains the last 14 days server-side, so without this scheduled scrape
+# the data is gone forever the moment it falls outside the window.
+#
+# Format: JSONL RVF
+# - line 1 is a `metadata` segment that initializes the file
+# - each subsequent run appends one `clone_snapshot` segment carrying the
+# 14-day rollup PLUS per-day breakdown
+# - file is idempotent: per-day entries are keyed by `timestamp` so a
+# downstream reader can dedupe across overlapping snapshot windows
+#
+# Schedule: every 14 days (1st + 15th of each month, ~14-day cadence in
+# practice). Workflow can also be dispatched manually for backfill or test.
+
+on:
+ schedule:
+ # 01:23 UTC on the 1st and 15th of every month — close to 14-day cadence
+ # without cron's "every 14 days" monthly-reset weirdness. Picking :23
+ # avoids the cron herd on :00.
+ - cron: '23 1 1,15 * *'
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+concurrency:
+ group: clone-tracking
+ cancel-in-progress: false
+
+jobs:
+ snapshot:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Fetch /traffic/clones + /traffic/views from GitHub
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ mkdir -p data
+ gh api repos/${{ github.repository }}/traffic/clones > /tmp/clones.json
+ gh api repos/${{ github.repository }}/traffic/views > /tmp/views.json
+ echo "--- clones rollup ---"
+ jq '{count, uniques, days: (.clones | length)}' /tmp/clones.json
+ echo "--- views rollup ---"
+ jq '{count, uniques, days: (.views | length)}' /tmp/views.json
+
+ - name: Append snapshot to data/clone-data.rvf
+ env:
+ REPO: ${{ github.repository }}
+ run: |
+ set -e
+ RVF="data/clone-data.rvf"
+ FETCHED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
+
+ # Initialize the file with a metadata segment on first run.
+ if [ ! -f "$RVF" ]; then
+ echo "Initializing $RVF with metadata segment"
+ jq -n --arg repo "$REPO" --arg ts "$FETCHED_AT" '{
+ type: "metadata",
+ name: "ruview-clone-traffic-history",
+ version: "1.0.0",
+ schema: "ruvector.rvf.jsonl/v1",
+ format: "github-traffic-snapshots",
+ repo: $repo,
+ source: "GitHub Traffic API /repos/{repo}/traffic/{clones,views}",
+ policy: "GitHub retains only 14 days server-side; this file is the long-term record.",
+ segments: ["metadata", "clone_snapshot", "view_snapshot"],
+ created_at: $ts,
+ custom: {
+ cadence: "twice monthly (1st and 15th, ~14-day intervals)",
+ idempotency_key: "timestamp (per-day records de-duplicate across overlapping snapshot windows)"
+ }
+ }' >> "$RVF"
+ fi
+
+ # Append the clone snapshot.
+ jq --arg ts "$FETCHED_AT" '{
+ type: "clone_snapshot",
+ fetched_at: $ts,
+ window_count: .count,
+ window_uniques: .uniques,
+ per_day: .clones
+ }' /tmp/clones.json >> "$RVF"
+
+ # Append the views snapshot (free with the same auth).
+ jq --arg ts "$FETCHED_AT" '{
+ type: "view_snapshot",
+ fetched_at: $ts,
+ window_count: .count,
+ window_uniques: .uniques,
+ per_day: .views
+ }' /tmp/views.json >> "$RVF"
+
+ echo "--- RVF tail (last 4 lines) ---"
+ tail -4 "$RVF" | jq -c '{type, fetched_at, window_count, window_uniques}' || true
+ echo "--- file size ---"
+ wc -l "$RVF"
+
+ - name: Compute aggregates for the commit summary
+ id: agg
+ run: |
+ # Count distinct per-day entries across all snapshots so we can
+ # show "cumulative observed clones" in the commit message.
+ python3 - <<'PY'
+ import json, os
+ path = "data/clone-data.rvf"
+ per_day_clones = {}
+ per_day_views = {}
+ with open(path, encoding="utf-8") as f:
+ for line in f:
+ if not line.strip():
+ continue
+ d = json.loads(line)
+ if d.get("type") == "clone_snapshot":
+ for entry in d.get("per_day", []):
+ per_day_clones[entry["timestamp"]] = entry
+ elif d.get("type") == "view_snapshot":
+ for entry in d.get("per_day", []):
+ per_day_views[entry["timestamp"]] = entry
+
+ tot_clones = sum(e.get("count", 0) for e in per_day_clones.values())
+ tot_uniq_clones = sum(e.get("uniques", 0) for e in per_day_clones.values())
+ tot_views = sum(e.get("count", 0) for e in per_day_views.values())
+ tot_uniq_views = sum(e.get("uniques", 0) for e in per_day_views.values())
+ print(f"clone days observed: {len(per_day_clones)} total clones: {tot_clones:,} total unique cloners: {tot_uniq_clones:,}")
+ print(f"view days observed: {len(per_day_views)} total views: {tot_views:,} total unique viewers: {tot_uniq_views:,}")
+
+ with open(os.environ["GITHUB_OUTPUT"], "a") as out:
+ out.write(f"clones={tot_clones}\n")
+ out.write(f"clone_days={len(per_day_clones)}\n")
+ out.write(f"views={tot_views}\n")
+ out.write(f"view_days={len(per_day_views)}\n")
+ PY
+
+ - name: Commit + push if changed
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ if git diff --quiet data/clone-data.rvf; then
+ echo "no changes to commit"
+ exit 0
+ fi
+ git add data/clone-data.rvf
+ git commit -m "chore(traffic): clone snapshot — ${{ steps.agg.outputs.clone_days }} days observed → ${{ steps.agg.outputs.clones }} clones, ${{ steps.agg.outputs.view_days }} view-days → ${{ steps.agg.outputs.views }} views"
+ git push
diff --git a/.github/workflows/sensing-server-docker.yml b/.github/workflows/sensing-server-docker.yml
index 1766d24c..6c74a09d 100644
--- a/.github/workflows/sensing-server-docker.yml
+++ b/.github/workflows/sensing-server-docker.yml
@@ -50,6 +50,12 @@ jobs:
with:
submodules: recursive
+ # QEMU is required so the amd64 GitHub runner can cross-build the
+ # linux/arm64 layer below (Dockerfile.rust is arch-agnostic — no `--target`
+ # flag — so buildx + QEMU is all that's needed; arm64 builds are emulated
+ # by the runner, not built on a separate arm64 host).
+ - uses: docker/setup-qemu-action@v3
+
- uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
@@ -90,7 +96,11 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- platforms: linux/amd64
+ # README badge advertises `amd64 + arm64`, and #547 promised multi-arch
+ # as part of the docker publish refresh; arm64 was never actually wired
+ # in, so Apple Silicon Macs hit `no matching manifest for linux/arm64/v8`
+ # on `docker pull ruvnet/wifi-densepose:latest` (#136, #625). Build both.
+ platforms: linux/amd64,linux/arm64
# ---------------------------------------------------------------------
# Smoke-test the freshly-pushed image:
diff --git a/.github/workflows/threejs-pages.yml b/.github/workflows/threejs-pages.yml
new file mode 100644
index 00000000..a542e88f
--- /dev/null
+++ b/.github/workflows/threejs-pages.yml
@@ -0,0 +1,70 @@
+name: three.js demos → GitHub Pages
+
+# Publishes the ADR-097 three.js demos under gh-pages/three.js/.
+# Uses keep_files: true so the existing observatory/, pose-fusion/,
+# pointcloud/, nvsim/, and root index.html demos are preserved.
+#
+# Demos 04 and 05 require a Mixamo "X Bot.fbx" placed in assets/.
+# That file is intentionally gitignored (license boundary), so this
+# workflow does NOT ship it. Demos 01-03 work standalone; the index
+# page documents the FBX requirement honestly.
+
+on:
+ push:
+ branches: [main]
+ paths:
+ - 'examples/three.js/**'
+ - '.github/workflows/threejs-pages.yml'
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+concurrency:
+ group: threejs-pages
+ cancel-in-progress: true
+
+jobs:
+ build-and-deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout main
+ uses: actions/checkout@v4
+
+ - name: Stage demos for Pages
+ run: |
+ mkdir -p _site/three.js
+ # Copy everything except the local Python server (CI doesn't need it)
+ # and any stray scratch screenshots.
+ cp -r examples/three.js/demos _site/three.js/demos
+ cp -r examples/three.js/screenshots _site/three.js/screenshots
+ cp examples/three.js/README.md _site/three.js/README.md
+ # An index.html that lists the 5 demos with the FBX caveat.
+ cp examples/three.js/index.html _site/three.js/index.html
+ # Mixamo FBX is gitignored — assets dir won't exist in CI.
+ # Drop an empty placeholder so the relative path 'assets/' resolves
+ # to a directory listing (404 on missing file) instead of an opaque
+ # network error. Browsers showing the 404 path makes the failure
+ # visible to anyone trying demos 04/05 without their own FBX.
+ mkdir -p _site/three.js/assets
+ cat > _site/three.js/assets/README.txt <<'EOF'
+ The Mixamo "X Bot.fbx" required by demos 04-skinned-fbx.html and
+ 05-skinned-realtime.html is intentionally not redistributed here.
+
+ Download your own from https://mixamo.com (FBX Binary, T-Pose,
+ Without Skin) and place it here as "X Bot.fbx" if you want to
+ run those demos locally. See examples/three.js/README.md in the
+ repo for context.
+ EOF
+ echo "Staged contents:"
+ ls -R _site/three.js/ | head -30
+
+ - name: Deploy to GitHub Pages
+ uses: peaceiris/actions-gh-pages@v3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: _site
+ # Critical: preserve observatory/, pose-fusion/, pointcloud/, nvsim/
+ # and the root index.html already on gh-pages.
+ keep_files: true
+ commit_message: 'three.js demos: ${{ github.event.head_commit.message }}'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44174dd3..20d3a897 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,6 +29,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
process. Swapped for `unwrap_or(Ordering::Equal)`, matching the pattern the
same file already used at lines 149-150 and 155. Per-frame hot path; this was
a real production crash vector.
+- **Completed the #611 NaN-panic audit across the sensing-server crate** (follow-up
+ to #613). The original audit grepped for the literal `partial_cmp(b).unwrap()`
+ and missed seven additional production sites that use comparator variants
+ (`partial_cmp(b.1).unwrap()`, `partial_cmp(&variances[b]).unwrap()`). All share
+ the same crash class — a single `NaN` in CSI-derived state panics the whole
+ sensing-server. Fixed:
+ - `adaptive_classifier.rs:205` — `AdaptiveModel::classify()` argmax over softmax
+ probs. **Same per-frame hot path as #611**; NaN flows through normalise →
+ logits → softmax and still reaches this site even after the #613 IQR fix.
+ - `adaptive_classifier.rs:480, 500` — training-loop argmax in `train()`
+ (training/per-class accuracy reporting).
+ - `main.rs:2446, 2449` and `csi.rs:602, 605` — variance-based source/sink
+ selection in `count_persons_mincut`. The outer `unwrap_or((0, &0))` only
+ catches an empty iterator; it cannot rescue a comparator panic.
+
+ Remaining `partial_cmp(...).unwrap()` sites in the workspace are all inside
+ `#[cfg(test)]` / `#[test]` blocks (`spectrogram.rs:269`, `depth.rs:234`,
+ `connectivity.rs:477`, `vital_signs.rs:737`) where inputs are controlled.
- **`ui/utils/pose-renderer.js` no longer divides by zero** when two render frames land in the same `performance.now()` tick (issue #519 Bug 2). `deltaTime` is now `Math.max(currentTime - lastFrameTime, 1)` before the `1000 / deltaTime` division, capping displayed FPS at 1000 — far above any real render rate, but finite so the EMA `averageFps = averageFps * 0.9 + fps * 0.1` no longer poisons itself to `Infinity` on a single zero-dt tick.
### Removed
diff --git a/README.md b/README.md
index 3820c4b8..753d8caf 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# π RuView
@@ -32,7 +32,7 @@ Built on [RuVector](https://github.com/ruvnet/ruvector/) and [Cognitum Seed](htt
The system learns each environment locally using spiking neural networks that adapt in under 30 seconds, with multi-frequency mesh scanning across 6 WiFi channels that uses your neighbors' routers as free radar illuminators. Every measurement is cryptographically attested via an Ed25519 witness chain.
-RuView also supports pose estimation (17 COCO keypoints via the WiFlow architecture), trained entirely without cameras using 10 sensor signals — a technique pioneered from the original *DensePose From WiFi* research at Carnegie Mellon University.
+RuView turns ordinary WiFi into a contactless sensor. A $9 ESP32 board reads the radio reflections off the people in a room, and a small pretrained model — published on Hugging Face at [`ruvnet/wifi-densepose-pretrained`](https://huggingface.co/ruvnet/wifi-densepose-pretrained) — tells you who's there, how they're breathing, and how their heart rate is trending. The model fits in 8 KB (4-bit quantized), runs in microseconds on a Raspberry Pi, and reports 100% presence accuracy on the validation set. No cameras, no wearables, no app on the user's phone.
### Built for low-power edge applications
@@ -45,20 +45,29 @@ RuView also supports pose estimation (17 COCO keypoints via the WiFlow architect
[](#vital-sign-detection)
[](#esp32-s3-hardware-pipeline)
[](https://crates.io/crates/wifi-densepose-ruvector)
+[](#-edge-module-catalog)
-> | What | How | Speed |
-> |------|-----|-------|
-> | 🦴 **Pose estimation** | CSI subcarrier amplitude/phase → 17 COCO keypoints | 171K emb/s (M4 Pro) |
-> | 🫁 **Breathing detection** | Bandpass 0.1-0.5 Hz → zero-crossing BPM | 6-30 BPM |
-> | 💓 **Heart rate** | Bandpass 0.8-2.0 Hz → zero-crossing BPM | 40-120 BPM |
-> | 👤 **Presence sensing** | Trained model + PIR fusion — 100% accuracy | 0.012 ms latency |
-> | 🧱 **Through-wall** | Fresnel zone geometry + multipath modeling | Up to 5m depth |
-> | 🧠 **Edge intelligence** | 8-dim feature vectors + RVF store on Cognitum Seed | $140 total BOM |
-> | 🎯 **Camera-free training** | 10 sensor signals, no labels needed | 84s on M4 Pro |
-> | 📷 **Camera-supervised training** | MediaPipe + ESP32 CSI → **35%+ PCK@20 target** (ADR-079; eval phases pending) | ~19 min on laptop (pipeline) |
-> | 📡 **Multi-frequency mesh** | Channel hopping across 6 bands, neighbor APs as illuminators | 3x sensing bandwidth |
-> | 🌐 **3D point cloud** *(optional fusion)* | Camera depth (MiDaS) + WiFi CSI + mmWave radar → unified spatial model | 22 ms pipeline · 19K+ points/frame |
+> | What | How | Speed / scale |
+> |------|-----|---------------|
+> | 🫁 **Breathing rate** | Bandpass 0.1–0.5 Hz on wrapped phase, circular variance, zero-crossing BPM ([#593](https://github.com/ruvnet/RuView/issues/593)) | 6–30 BPM, real-time |
+> | 💓 **Heart rate** | Bandpass 0.8–2.0 Hz, zero-crossing BPM | 40–120 BPM, real-time |
+> | 👤 **Presence detection** | Trained head on Hugging Face ([`ruvnet/wifi-densepose-pretrained`](https://huggingface.co/ruvnet/wifi-densepose-pretrained), 100% validation accuracy) + a phase-variance fallback that needs no model | < 1 ms, ~30 s ambient calibration |
+> | 🧬 **CSI embeddings** | 128-dim contrastive encoder shipped on Hugging Face, 4-bit quantised variant fits in 8 KB | **164,183 emb/s** on M4 Pro |
+> | 🦴 **17-keypoint pose estimation** | `cog-pose-estimation` Cog v0.0.1 — signed aarch64 + x86_64 binaries on GCS, loads `pose_v1.safetensors` via Candle. Train your own from paired data in 2.1 s on an RTX 5080 ([ADR-101](docs/adr/ADR-101-pose-estimation-cog.md), [benchmarks](docs/benchmarks/pose-estimation-cog.md)) | 8.4 ms cold-start on a Pi 5 |
+> | 🚶 **Motion / activity** | Motion-band power + phase acceleration | Real-time |
+> | 🤸 **Fall detection** | Phase-acceleration threshold + 3-frame debounce + 5 s cooldown ([#263](https://github.com/ruvnet/RuView/issues/263)) | < 200 ms |
+> | 🧮 **Multi-person count** | Adaptive P95 normalisation + runtime-tunable dedup factor (`/api/v1/config/dedup-factor`, [#491](https://github.com/ruvnet/RuView/pull/491)). Six specialised learned counters available as Cogs: `occupancy-zones`, `elevator-count`, `queue-length`, `customer-flow`, `clean-room`, `person-matching` | Real-time, self-calibrating |
+> | 🧱 **Through-wall sensing** | Fresnel-zone geometry + multipath modeling | Up to ~5 m, signal-dependent |
+> | 🧠 **Edge intelligence** | **105-cog catalog** ([ADR-102](docs/adr/ADR-102-edge-module-registry.md)) live from `app-registry.json` — health, security, building, retail, industrial, research, AI, swarm, signal, network, and developer modules. Optional Cognitum Seed adds persistent vector store + kNN + witness chain | $140 total BOM |
+> | 🎯 **Camera-free pre-training** | Self-supervised contrastive encoder, 12.2M training steps on 60K frames, shipped on Hugging Face | 84 s/epoch retrain on M4 Pro |
+> | 📷 **Camera-supervised fine-tune** | MediaPipe + ESP32 CSI paired training, end-to-end Candle pipeline on RTX 5080 ([ADR-079](docs/adr/ADR-079-camera-supervised-pose-finetune.md)) | 2.1 s for 400 epochs (~5 ms/epoch) |
+> | 📡 **Multi-frequency mesh** | Channel hopping across 6 bands, TDM slot scheduling ([ADR-029](docs/adr/ADR-029-multifrequency-mesh.md)) | 3× sensing bandwidth |
+> | 🌐 **3D point cloud fusion** | Camera depth (MiDaS) + WiFi CSI + mmWave radar → unified spatial model | 22 ms pipeline · 19K+ points/frame |
+>
+> Browse the full 105-module catalog (with practical descriptions, sizes, and difficulty) below in [🧩 Edge Module Catalog](#-edge-module-catalog), or visit [seed.cognitum.one/store](https://seed.cognitum.one/store).
+>
+> 🤗 **Pretrained weights**: download from [`ruvnet/wifi-densepose-pretrained`](https://huggingface.co/ruvnet/wifi-densepose-pretrained) — see [Loading the pretrained model](#loading-the-pretrained-model) below for one-command setup.
```bash
# Option 1: Docker (simulated data, no hardware needed)
@@ -88,10 +97,10 @@ node scripts/mincut-person-counter.js --port 5006 # Correct person counting
>
> | Option | Hardware | Cost | Full CSI | Capabilities |
> |--------|----------|------|----------|-------------|
-> | **ESP32 + Cognitum Seed** (recommended) | ESP32-S3 + [Cognitum Seed](https://cognitum.one) | ~$140 | Yes | Pose, breathing, heartbeat, motion, presence + persistent vector store, kNN search, witness chain, MCP proxy |
-> | **ESP32 Mesh** | 3-6x ESP32-S3 + WiFi router | ~$54 | Yes | Pose, breathing, heartbeat, motion, presence |
+> | **ESP32 + Cognitum Seed** (recommended) | ESP32-S3 + [Cognitum Seed](https://cognitum.one) | ~$140 | Yes | Presence, motion, breathing, heart rate, fall detection, multi-person counting, 17-keypoint pose (signed Cog binary), 105-cog catalog, persistent vector store, kNN search, witness chain, MCP proxy |
+> | **ESP32 Mesh** | 3-6x ESP32-S3 + WiFi router | ~$54 | Yes | Same capabilities as above without the persistent-memory features |
> | **Research NIC** | Intel 5300 / Atheros AR9580 | ~$50-100 | Yes | Full CSI with 3x3 MIMO |
-> | **Any WiFi** | Windows, macOS, or Linux laptop | $0 | No | RSSI-only: coarse presence and motion |
+> | **Any WiFi** | Windows, macOS, or Linux laptop | $0 | No | RSSI-only: coarse presence and motion (see [tutorial #36](https://github.com/ruvnet/RuView/issues/36)) |
>
> No hardware? Verify the signal processing pipeline with the deterministic reference signal: `python archive/v1/data/proof/verify.py`
>
@@ -109,10 +118,211 @@ node scripts/mincut-person-counter.js --port 5006 # Correct person counting
▶ Dual-Modal Pose Fusion Demo
|
▶ Live 3D Point Cloud
+ |
+ ▶ three.js Demos (5)
> The [server](#-quick-start) is optional for visualization and aggregation — the ESP32 [runs independently](#esp32-s3-hardware-pipeline) for presence detection, vital signs, and fall alerts.
>
> **Live ESP32 pipeline**: Connect an ESP32-S3 node → run the [sensing server](#sensing-server) → open the [pose fusion demo](https://ruvnet.github.io/RuView/pose-fusion.html) for real-time dual-modal pose estimation (webcam + WiFi CSI). See [ADR-059](docs/adr/ADR-059-live-esp32-csi-pipeline.md).
+>
+> **three.js scene gallery** at [`/three.js/`](https://ruvnet.github.io/RuView/three.js/) — five progressively richer ADR-097 demos: helpers, cinematic, GLTF skinned, FBX skinned, and a live MediaPipe→Mixamo retargeting feed driven by ESP32 CSI. Demos 04 and 05 require a local Mixamo `X Bot.fbx` (license boundary — not redistributed).
+
+
+## 🤗 Pretrained model on Hugging Face
+
+Pretrained CSI weights live at [`ruvnet/wifi-densepose-pretrained`](https://huggingface.co/ruvnet/wifi-densepose-pretrained) — 12.2M training steps on 60K frames / 610K contrastive triplets, **100% presence accuracy** on the validation set, 4-bit quantized variant fits in 8 KB. The release includes a contrastive **CSI encoder** producing 128-dim embeddings (164,183 emb/s on M4 Pro) and a **presence-detection head**. Per-node LoRA adapters are included for environment-specific fine-tuning.
+
+```bash
+# Download the model bundle
+pip install huggingface_hub
+huggingface-cli download ruvnet/wifi-densepose-pretrained --local-dir models/wifi-densepose-pretrained
+```
+
+**What works today vs. what's pending wiring:**
+
+| Consumer | Format used | Status |
+|----------|-------------|--------|
+| Python training / evaluation / embedding extraction | `model.safetensors` | ✅ Works — load with `safetensors.torch.load_file` |
+| Inspect / re-export the bundle | `model.rvf.jsonl` (line-by-line JSON) | ✅ Works — plain JSONL |
+| Sensing-server `--model ` flag | binary RVF (`RVFS` magic) | ⚠️ Loader does not yet accept the JSONL container |
+
+**Known gap:** the HF model ships in JSONL RVF format, but `v2/crates/wifi-densepose-sensing-server/src/rvf_container.rs` only parses the binary RVF segment format. Pointing `--model` at `model.rvf.jsonl` currently errors with `invalid magic at offset 0: expected 0x52564653, got 0x7974227B` and the live pipeline degrades to null output rather than falling back to heuristic mode — so for the live sensing-server, run **without** `--model` until a JSONL adapter lands (or the model is re-published as binary RVF). Use the weights from Python / training in the meantime.
+
+**Quantization choices** (all in the HF repo): `model-q2.bin` (4 KB) · `model-q4.bin` ⭐ recommended (8 KB) · `model-q8.bin` (16 KB) · `model.safetensors` full (48 KB)
+
+The separate **17-keypoint pose-estimation model** is not in this release — pipeline is implemented but keypoint weights are still pending. Tracked in [#509](https://github.com/ruvnet/RuView/issues/509); see [ADR-079](docs/adr/ADR-079-camera-supervised-pose-finetune.md) phases P7–P9.
+
+
+## 🧩 Edge Module Catalog
+
+
+🧩 105 edge modules ready to install on a Cognitum appliance — live catalog from app-registry.json v2.1.0 (updated 2026-05-13). Browse + install at seed.cognitum.one/store or your local appliance http://<appliance>:9000/cogs.
+
+Each module is a small signed binary (~400 KB) that runs alongside the WiFi-DensePose sensing stack on a Cognitum-V0 appliance. The catalog updates over the air — your appliance fetches it via GET /api/v1/edge/registry ([ADR-102](docs/adr/ADR-102-edge-module-registry.md)) and verifies each binary against an Ed25519 signature ([ADR-100](docs/adr/ADR-100-cog-packaging-specification.md)) before install.
+
+### 🫀 Health — 14 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `air-quality-index` | Track indoor air quality with CO2 and particle sensors | 8 KB | Easy |
+| `baby-cry` | Sustained mid-band energy detector for nursery / infant monitoring. Audio-only, no camera. | 451 KB | Easy |
+| `breathing-sync` | Detects when two people breathe in sync | 10 KB | Hard |
+| `cardiac-arrhythmia` | Spots irregular heartbeats and abnormal heart rhythms | 8 KB | Hard |
+| `cough-detect` | Acoustic transient + spectral cough detector with 30s cluster aggregation. Early-warning signal for respiratory illness. | 451 KB | Easy |
+| `dream-stage` | Tracks your sleep stages — light, deep, and dreaming | 14 KB | Hard |
+| `fall-detect` | Two-stage impact + stillness fall detector over ambient feature stream (ESP32 motion / mic). Optional ruview-mode for CSI-based pose reinforcement. | 402 KB | Easy |
+| `gait-analysis` | Detects walking problems and scores fall risk | 12 KB | Hard |
+| `health-monitor` | Contactless heart rate, breathing, sleep, and fall alerts | 30 KB | Med |
+| `respiratory-distress` | Alerts when breathing becomes labored or dangerously fast | 10 KB | Hard |
+| `seizure-detect` | Recognizes seizures and sends immediate alerts | 10 KB | Hard |
+| `sleep-apnea` | Detects when someone stops breathing during sleep | 4 KB | Easy |
+| `snore-monitor` | Periodic low-band energy tracker for sleep-quality / apnea-risk trending. Companion to sleep-apnea cog. | 451 KB | Easy |
+| `vital-trend` | Tracks breathing and heart rate trends over weeks | 6 KB | Med |
+
+### 🔒 Security — 14 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `audit-logger` | Record every action for compliance — tamper-proof log | 8 KB | Easy |
+| `behavioral-profiler` | Learns normal behavior and flags anything unusual | 12 KB | Hard |
+| `fleet-auth` | Manage device certificates and access across all seeds | 12 KB | Med |
+| `glass-break` | Two-phase bang + shatter acoustic detector. Distinguishes glass break from ordinary impulse noise. | 451 KB | Easy |
+| `gunshot-detect` | Saturating peak + exponential decay acoustic detector with optional ruview CSI motion-drop reinforcement. | 451 KB | Easy |
+| `intrusion` | Alerts when an unauthorized person enters a room | 6 KB | Med |
+| `intrusion-detect-ml` | Detect network attacks using machine learning | 14 KB | Hard |
+| `loitering` | Alerts when someone lingers too long in one spot | 3 KB | Easy |
+| `network-firewall` | Block unauthorized network access per cog | 6 KB | Easy |
+| `panic-motion` | Detects sudden panicked or erratic movement | 6 KB | Med |
+| `perimeter-breach` | Guards multiple zones and shows entry direction | 10 KB | Med |
+| `prompt-shield` | Blocks signal replay and injection attacks on the seed | 10 KB | Med |
+| `tailgating` | Catches when someone sneaks in behind a badge holder | 6 KB | Med |
+| `weapon-detect` | Detects concealed metal objects on a person | 8 KB | Hard |
+
+### 🏢 Building — 11 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `beehive-monitor` | Acoustic hive state classifier. Detects healthy / chaotic / queenless / swarming / robbing via hum-band energy + chaos + piping autocorr. | 451 KB | Easy |
+| `elevator-count` | Counts how many people are in an elevator | 8 KB | Med |
+| `energy-audit` | Learns your schedule and cuts wasted energy | 6 KB | Med |
+| `frost-warning` | Predicts frost 6 hours ahead via temperature trend + dewpoint-depression gate. Field/orchard agriculture. | 451 KB | Easy |
+| `hvac-presence` | Turns heating and cooling on when you arrive | 3 KB | Easy |
+| `lighting-zones` | Turns lights on and off as people move between rooms | 4 KB | Easy |
+| `meeting-room` | Shows if a meeting room is free or occupied | 5 KB | Easy |
+| `occupancy-zones` | Counts people in each room through walls | 8 KB | Med |
+| `predictive-maintenance` | Vibration harmonic analyzer for rotating equipment. Tracks F1 / 2×F1 / high-order / sideband energy to score degradation severity. | 451 KB | Easy |
+| `smoke-fire` | Multi-signal smoke and fire detector. Fuses acoustic crackle, thermal drift proxy, and optional ruview CSI plume signature. Not a UL-listed replacement for code-required smoke alarms. | 451 KB | Easy |
+| `water-leak` | Persistent low-amplitude hiss + periodic drip acoustic detector with multi-minute persistence gate. Two-stage likely → confirmed. | 451 KB | Easy |
+
+### 🛍️ Retail — 7 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `customer-flow` | Counts foot traffic in and out of each entrance | 8 KB | Med |
+| `dwell-heatmap` | Shows where customers spend the most time | 6 KB | Med |
+| `package-detect` | Sustained CSI-shift detector for porch / loading bay package arrivals and departures. Requires ESP32 CSI ruview input. | 451 KB | Easy |
+| `parking-occupancy` | Per-zone parking occupancy via ESP32 CSI subcarrier-amplitude shift. Tracks utilization and churn-per-hour. Requires ruview. | 451 KB | Easy |
+| `queue-length` | Estimates line length and wait time | 6 KB | Med |
+| `shelf-engagement` | Detects when customers interact with products | 6 KB | Med |
+| `table-turnover` | Tracks which restaurant tables are free or occupied | 4 KB | Easy |
+
+### 🏭 Industrial — 7 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `clean-room` | Enforces max headcount in controlled environments | 4 KB | Easy |
+| `confined-space` | Monitors workers in tight spaces for safety | 5 KB | Med |
+| `forklift-proximity` | Warns if a forklift gets too close to workers | 10 KB | Hard |
+| `livestock-monitor` | Monitors animals for distress, escape, or illness | 6 KB | Med |
+| `ppe-compliance` | Cog-composition layer: alerts when ruview-densepose detects presence in a restricted zone without an accompanying PPE-camera-cog confirmation vector. | 387 KB | Easy |
+| `slip-fall-zone` | Pre-fall risk detector. Fires when motion-variance drop, splash audio, and optional cautious-gait CSI all signal elevated slip risk. | 451 KB | Easy |
+| `structural-vibration` | Detects dangerous vibrations in buildings or machines | 8 KB | Hard |
+
+### 🔬 Research — 12 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `emotion-detect` | Reads stress and calm from body language and breathing | 10 KB | Hard |
+| `energy-harvester` | Optimize solar and battery for off-grid seed deployment | 6 KB | Med |
+| `gesture-language` | Recognizes sign language gestures in real time | 12 KB | Hard |
+| `ghost-hunter` | Finds unexplained environmental anomalies — for fun | 10 KB | Hard |
+| `happiness-score` | Estimates well-being from movement and mood signals | 8 KB | Med |
+| `hyperbolic-space` | Maps data into curved space for tree-like structures | 12 KB | Hard |
+| `music-conductor` | Reads a conductor's gestures for tempo and dynamics | 12 KB | Hard |
+| `plant-growth` | Tracks plant growth rate and day/night cycles | 8 KB | Med |
+| `rain-detect` | Detects when rain starts, stops, and how heavy it is | 6 KB | Med |
+| `ruview-densepose` | Full body pose tracking from WiFi — no cameras needed | 50 KB | Hard |
+| `sound-classifier` | Identify sounds like glass break, alarm, or baby cry | 16 KB | Hard |
+| `time-crystal` | Experiments with repeating time-pattern symmetry | 12 KB | Hard |
+
+### 🤖 Ai — 15 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `anomaly-attractor` | Learns what's normal and catches anything weird | 10 KB | Hard |
+| `cognitive-pipeline` | FastGRNN anomaly gate + SmolLM2 sparse-LLM inference for on-device Pi Zero 2W cognitive events | 320 KB | Hard |
+| `dtw-gesture-learn` | Teach custom hand gestures by showing examples | 14 KB | Med |
+| `ewc-lifelong` | Learns new things without forgetting old lessons | 8 KB | Hard |
+| `federated-learning` | Train AI across seeds without sharing raw data | 18 KB | Hard |
+| `goap-autonomy` | Plans and executes goals on its own | 14 KB | Hard |
+| `meta-adapt` | Automatically tunes itself for best performance | 10 KB | Hard |
+| `micro-hnsw` | Fast on-device fingerprinting and classification | 12 KB | Med |
+| `neural-trader` | Spot market patterns and trends from live data | 20 KB | Hard |
+| `pagerank-influence` | Finds the most influential person in a group | 12 KB | Med |
+| `pattern-sequence` | Detects daily routines and repeated habits | 10 KB | Med |
+| `rag-local` | Search your documents using AI — runs on the seed | 14 KB | Med |
+| `spiking-tracker` | Brain-inspired tracker that runs on tiny hardware | 16 KB | Hard |
+| `temporal-logic` | Enforces safety rules on live event streams | 12 KB | Hard |
+| `time-series-forecast` | Predict sensor trends using historical patterns | 12 KB | Med |
+
+### 🐝 Swarm — 11 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `swarm-backup-restore` | Auto-backup data to other seeds — one-click restore | 8 KB | Easy |
+| `swarm-cluster-monitor` | Live dashboard of every seed's health and status | 6 KB | Easy |
+| `swarm-consensus` | Seeds vote before making critical changes together | 16 KB | Hard |
+| `swarm-delta-sync` | Auto-sync data between seeds — only sends changes | 8 KB | Med |
+| `swarm-deploy` | Install or remove cogs on all seeds at once | 10 KB | Med |
+| `swarm-distributed-store` | Spread data across seeds and search them all at once | 14 KB | Hard |
+| `swarm-edge-orchestrator` | Manage all ESP32 sensor nodes from one place | 14 KB | Hard |
+| `swarm-load-balancer` | Spread queries across seeds so no single one overloads | 10 KB | Med |
+| `swarm-mesh-manager` | Find, connect, and monitor all seeds on your network | 12 KB | Easy |
+| `swarm-mqtt-bridge` | Share events between seeds over MQTT messaging | 6 KB | Easy |
+| `swarm-witness-federation` | Share tamper-proof audit trails across seeds | 12 KB | Hard |
+
+### 📡 Signal — 6 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `coherence-gate` | Filters out noisy signals and keeps clean ones | 8 KB | Med |
+| `flash-attention` | Focuses sensing on specific areas for better accuracy | 12 KB | Med |
+| `optimal-transport` | Measures motion using shape-aware signal comparison | 12 KB | Hard |
+| `person-matching` | Tells apart multiple people in the same room | 18 KB | Hard |
+| `sparse-recovery` | Recovers missing signal data from partial readings | 16 KB | Hard |
+| `temporal-compress` | Shrinks old data to save memory without losing meaning | 14 KB | Med |
+
+### 🌐 Network — 1 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `tailscale` | Reach the seed from anywhere via a private WireGuard mesh (Tailscale). Userspace mode — no root. | 700 KB | Med |
+
+### 🛠️ Developer — 7 modules
+
+| ID | What it does | Size | Difficulty |
+|----|--------------|-----:|:----------:|
+| `adversarial` | Detects tampered or spoofed sensor signals | 4 KB | Easy |
+| `coherence` | Monitors signal quality across multiple channels | 4 KB | Easy |
+| `gesture` | Core gesture recognition building block for cogs | 6 KB | Med |
+| `interference-search` | Searches many possibilities at once for fast answers | 14 KB | Hard |
+| `psycho-symbolic` | Reasons over knowledge graphs with multiple styles | 16 KB | Hard |
+| `quantum-coherence` | Quantum-inspired model for advanced signal states | 16 KB | Hard |
+| `self-healing-mesh` | Keeps sensor mesh running even when nodes drop out | 14 KB | Hard |
+
+> ℹ️ Build your own cog: see [ADR-100](docs/adr/ADR-100-cog-packaging-specification.md) for the packaging spec. The first cog this repo ships into the catalog lives in [v2/crates/cog-pose-estimation/](v2/crates/cog-pose-estimation/) (17-keypoint WiFi pose, [ADR-101](docs/adr/ADR-101-pose-estimation-cog.md)).
+
+
## 🔬 How It Works
@@ -228,178 +438,6 @@ These scenarios exploit WiFi's ability to penetrate solid materials — concrete
-
-🧩 Edge Intelligence (ADR-041) — 60 WASM modules across 13 categories, all implemented (609 tests)
-
-Small programs that run directly on the ESP32 sensor — no internet needed, no cloud fees, instant response. Each module is a tiny WASM file (5-30 KB) that you upload to the device over-the-air. It reads WiFi signal data and makes decisions locally in under 10 ms. [ADR-041](docs/adr/ADR-041-wasm-module-collection.md) defines 60 modules across 13 categories — all 60 are implemented with 609 tests passing.
-
-| | Category | Examples |
-|---|----------|---------|
-| 🏥 | [**Medical & Health**](docs/edge-modules/medical.md) | Sleep apnea detection, cardiac arrhythmia, gait analysis, seizure detection |
-| 🔐 | [**Security & Safety**](docs/edge-modules/security.md) | Intrusion detection, perimeter breach, loitering, panic motion |
-| 🏢 | [**Smart Building**](docs/edge-modules/building.md) | Zone occupancy, HVAC control, elevator counting, meeting room tracking |
-| 🛒 | [**Retail & Hospitality**](docs/edge-modules/retail.md) | Queue length, dwell heatmaps, customer flow, table turnover |
-| 🏭 | [**Industrial**](docs/edge-modules/industrial.md) | Forklift proximity, confined space monitoring, structural vibration |
-| 🔮 | [**Exotic & Research**](docs/edge-modules/exotic.md) | Sleep staging, emotion detection, sign language, breathing sync |
-| 📡 | [**Signal Intelligence**](docs/edge-modules/signal-intelligence.md) | Cleans and sharpens raw WiFi signals — focuses on important regions, filters noise, fills in missing data, and tracks which person is which |
-| 🧠 | [**Adaptive Learning**](docs/edge-modules/adaptive-learning.md) | The sensor learns new gestures and patterns on its own over time — no cloud needed, remembers what it learned even after updates |
-| 🗺️ | [**Spatial Reasoning**](docs/edge-modules/spatial-temporal.md) | Figures out where people are in a room, which zones matter most, and tracks movement across areas using graph-based spatial logic |
-| ⏱️ | [**Temporal Analysis**](docs/edge-modules/spatial-temporal.md) | Learns daily routines, detects when patterns break (someone didn't get up), and verifies safety rules are being followed over time |
-| 🛡️ | [**AI Security**](docs/edge-modules/ai-security.md) | Detects signal replay attacks, WiFi jamming, injection attempts, and flags abnormal behavior that could indicate tampering |
-| ⚛️ | [**Quantum-Inspired**](docs/edge-modules/autonomous.md) | Uses quantum-inspired math to map room-wide signal coherence and search for optimal sensor configurations |
-| 🤖 | [**Autonomous & Exotic**](docs/edge-modules/autonomous.md) | Self-managing sensor mesh — auto-heals dropped nodes, plans its own actions, and explores experimental signal representations |
-
-All implemented modules are `no_std` Rust, share a [common utility library](v2/crates/wifi-densepose-wasm-edge/src/vendor_common.rs), and talk to the host through a 12-function API. Full documentation: [**Edge Modules Guide**](docs/edge-modules/README.md). See the [complete implemented module list](#edge-module-list) below.
-
-
-
-
-🧩 Edge Intelligence — All 65 Modules Implemented (ADR-041 complete)
-
-All 60 modules are implemented, tested (609 tests passing), and ready to deploy. They compile to `wasm32-unknown-unknown`, run on ESP32-S3 via WASM3, and share a [common utility library](v2/crates/wifi-densepose-wasm-edge/src/vendor_common.rs). Source: [`crates/wifi-densepose-wasm-edge/src/`](v2/crates/wifi-densepose-wasm-edge/src/)
-
-**Core modules** (ADR-040 flagship + early implementations):
-
-| Module | File | What It Does |
-|--------|------|-------------|
-| Gesture Classifier | [`gesture.rs`](v2/crates/wifi-densepose-wasm-edge/src/gesture.rs) | DTW template matching for hand gestures |
-| Coherence Filter | [`coherence.rs`](v2/crates/wifi-densepose-wasm-edge/src/coherence.rs) | Phase coherence gating for signal quality |
-| Adversarial Detector | [`adversarial.rs`](v2/crates/wifi-densepose-wasm-edge/src/adversarial.rs) | Detects physically impossible signal patterns |
-| Intrusion Detector | [`intrusion.rs`](v2/crates/wifi-densepose-wasm-edge/src/intrusion.rs) | Human vs non-human motion classification |
-| Occupancy Counter | [`occupancy.rs`](v2/crates/wifi-densepose-wasm-edge/src/occupancy.rs) | Zone-level person counting |
-| Vital Trend | [`vital_trend.rs`](v2/crates/wifi-densepose-wasm-edge/src/vital_trend.rs) | Long-term breathing and heart rate trending |
-| RVF Parser | [`rvf.rs`](v2/crates/wifi-densepose-wasm-edge/src/rvf.rs) | RVF container format parsing |
-
-**Vendor-integrated modules** (24 modules, ADR-041 Category 7):
-
-**📡 Signal Intelligence** — Real-time CSI analysis and feature extraction
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Flash Attention | [`sig_flash_attention.rs`](v2/crates/wifi-densepose-wasm-edge/src/sig_flash_attention.rs) | Tiled attention over 8 subcarrier groups — finds spatial focus regions and entropy | S (<5ms) |
-| Coherence Gate | [`sig_coherence_gate.rs`](v2/crates/wifi-densepose-wasm-edge/src/sig_coherence_gate.rs) | Z-score phasor gating with hysteresis: Accept / PredictOnly / Reject / Recalibrate | L (<2ms) |
-| Temporal Compress | [`sig_temporal_compress.rs`](v2/crates/wifi-densepose-wasm-edge/src/sig_temporal_compress.rs) | 3-tier adaptive quantization (8-bit hot / 5-bit warm / 3-bit cold) | L (<2ms) |
-| Sparse Recovery | [`sig_sparse_recovery.rs`](v2/crates/wifi-densepose-wasm-edge/src/sig_sparse_recovery.rs) | ISTA L1 reconstruction for dropped subcarriers | H (<10ms) |
-| Person Match | [`sig_mincut_person_match.rs`](v2/crates/wifi-densepose-wasm-edge/src/sig_mincut_person_match.rs) | Hungarian-lite bipartite assignment for multi-person tracking | S (<5ms) |
-| Optimal Transport | [`sig_optimal_transport.rs`](v2/crates/wifi-densepose-wasm-edge/src/sig_optimal_transport.rs) | Sliced Wasserstein-1 distance with 4 projections | L (<2ms) |
-
-**🧠 Adaptive Learning** — On-device learning without cloud connectivity
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| DTW Gesture Learn | [`lrn_dtw_gesture_learn.rs`](v2/crates/wifi-densepose-wasm-edge/src/lrn_dtw_gesture_learn.rs) | User-teachable gesture recognition — 3-rehearsal protocol, 16 templates | S (<5ms) |
-| Anomaly Attractor | [`lrn_anomaly_attractor.rs`](v2/crates/wifi-densepose-wasm-edge/src/lrn_anomaly_attractor.rs) | 4D dynamical system attractor classification with Lyapunov exponents | H (<10ms) |
-| Meta Adapt | [`lrn_meta_adapt.rs`](v2/crates/wifi-densepose-wasm-edge/src/lrn_meta_adapt.rs) | Hill-climbing self-optimization with safety rollback | L (<2ms) |
-| EWC Lifelong | [`lrn_ewc_lifelong.rs`](v2/crates/wifi-densepose-wasm-edge/src/lrn_ewc_lifelong.rs) | Elastic Weight Consolidation — remembers past tasks while learning new ones | S (<5ms) |
-
-**🗺️ Spatial Reasoning** — Location, proximity, and influence mapping
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| PageRank Influence | [`spt_pagerank_influence.rs`](v2/crates/wifi-densepose-wasm-edge/src/spt_pagerank_influence.rs) | 4x4 cross-correlation graph with power iteration PageRank | L (<2ms) |
-| Micro HNSW | [`spt_micro_hnsw.rs`](v2/crates/wifi-densepose-wasm-edge/src/spt_micro_hnsw.rs) | 64-vector navigable small-world graph for nearest-neighbor search | S (<5ms) |
-| Spiking Tracker | [`spt_spiking_tracker.rs`](v2/crates/wifi-densepose-wasm-edge/src/spt_spiking_tracker.rs) | 32 LIF neurons + 4 output zone neurons with STDP learning | S (<5ms) |
-
-**⏱️ Temporal Analysis** — Activity patterns, logic verification, autonomous planning
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Pattern Sequence | [`tmp_pattern_sequence.rs`](v2/crates/wifi-densepose-wasm-edge/src/tmp_pattern_sequence.rs) | Activity routine detection and deviation alerts | S (<5ms) |
-| Temporal Logic Guard | [`tmp_temporal_logic_guard.rs`](v2/crates/wifi-densepose-wasm-edge/src/tmp_temporal_logic_guard.rs) | LTL formula verification on CSI event streams | S (<5ms) |
-| GOAP Autonomy | [`tmp_goap_autonomy.rs`](v2/crates/wifi-densepose-wasm-edge/src/tmp_goap_autonomy.rs) | Goal-Oriented Action Planning for autonomous module management | S (<5ms) |
-
-**🛡️ AI Security** — Tamper detection and behavioral anomaly profiling
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Prompt Shield | [`ais_prompt_shield.rs`](v2/crates/wifi-densepose-wasm-edge/src/ais_prompt_shield.rs) | FNV-1a replay detection, injection detection (10x amplitude), jamming (SNR) | L (<2ms) |
-| Behavioral Profiler | [`ais_behavioral_profiler.rs`](v2/crates/wifi-densepose-wasm-edge/src/ais_behavioral_profiler.rs) | 6D behavioral profile with Mahalanobis anomaly scoring | S (<5ms) |
-
-**⚛️ Quantum-Inspired** — Quantum computing metaphors applied to CSI analysis
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Quantum Coherence | [`qnt_quantum_coherence.rs`](v2/crates/wifi-densepose-wasm-edge/src/qnt_quantum_coherence.rs) | Bloch sphere mapping, Von Neumann entropy, decoherence detection | S (<5ms) |
-| Interference Search | [`qnt_interference_search.rs`](v2/crates/wifi-densepose-wasm-edge/src/qnt_interference_search.rs) | 16 room-state hypotheses with Grover-inspired oracle + diffusion | S (<5ms) |
-
-**🤖 Autonomous Systems** — Self-governing and self-healing behaviors
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Psycho-Symbolic | [`aut_psycho_symbolic.rs`](v2/crates/wifi-densepose-wasm-edge/src/aut_psycho_symbolic.rs) | 16-rule forward-chaining knowledge base with contradiction detection | S (<5ms) |
-| Self-Healing Mesh | [`aut_self_healing_mesh.rs`](v2/crates/wifi-densepose-wasm-edge/src/aut_self_healing_mesh.rs) | 8-node mesh with health tracking, degradation/recovery, coverage healing | S (<5ms) |
-
-**🔮 Exotic (Vendor)** — Novel mathematical models for CSI interpretation
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Time Crystal | [`exo_time_crystal.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_time_crystal.rs) | Autocorrelation subharmonic detection in 256-frame history | S (<5ms) |
-| Hyperbolic Space | [`exo_hyperbolic_space.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_hyperbolic_space.rs) | Poincare ball embedding with 32 reference locations, hyperbolic distance | S (<5ms) |
-
-**🏥 Medical & Health** (Category 1) — Contactless health monitoring
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Sleep Apnea | [`med_sleep_apnea.rs`](v2/crates/wifi-densepose-wasm-edge/src/med_sleep_apnea.rs) | Detects breathing pauses during sleep | S (<5ms) |
-| Cardiac Arrhythmia | [`med_cardiac_arrhythmia.rs`](v2/crates/wifi-densepose-wasm-edge/src/med_cardiac_arrhythmia.rs) | Monitors heart rate for irregular rhythms | S (<5ms) |
-| Respiratory Distress | [`med_respiratory_distress.rs`](v2/crates/wifi-densepose-wasm-edge/src/med_respiratory_distress.rs) | Alerts on abnormal breathing patterns | S (<5ms) |
-| Gait Analysis | [`med_gait_analysis.rs`](v2/crates/wifi-densepose-wasm-edge/src/med_gait_analysis.rs) | Tracks walking patterns and detects changes | S (<5ms) |
-| Seizure Detection | [`med_seizure_detect.rs`](v2/crates/wifi-densepose-wasm-edge/src/med_seizure_detect.rs) | 6-state machine for tonic-clonic seizure recognition | S (<5ms) |
-
-**🔐 Security & Safety** (Category 2) — Perimeter and threat detection
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Perimeter Breach | [`sec_perimeter_breach.rs`](v2/crates/wifi-densepose-wasm-edge/src/sec_perimeter_breach.rs) | Detects boundary crossings with approach/departure | S (<5ms) |
-| Weapon Detection | [`sec_weapon_detect.rs`](v2/crates/wifi-densepose-wasm-edge/src/sec_weapon_detect.rs) | Metal anomaly detection via CSI amplitude shifts | S (<5ms) |
-| Tailgating | [`sec_tailgating.rs`](v2/crates/wifi-densepose-wasm-edge/src/sec_tailgating.rs) | Detects unauthorized follow-through at access points | S (<5ms) |
-| Loitering | [`sec_loitering.rs`](v2/crates/wifi-densepose-wasm-edge/src/sec_loitering.rs) | Alerts when someone lingers too long in a zone | S (<5ms) |
-| Panic Motion | [`sec_panic_motion.rs`](v2/crates/wifi-densepose-wasm-edge/src/sec_panic_motion.rs) | Detects fleeing, struggling, or panic movement | S (<5ms) |
-
-**🏢 Smart Building** (Category 3) — Automation and energy efficiency
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| HVAC Presence | [`bld_hvac_presence.rs`](v2/crates/wifi-densepose-wasm-edge/src/bld_hvac_presence.rs) | Occupancy-driven HVAC control with departure countdown | S (<5ms) |
-| Lighting Zones | [`bld_lighting_zones.rs`](v2/crates/wifi-densepose-wasm-edge/src/bld_lighting_zones.rs) | Auto-dim/off lighting based on zone activity | S (<5ms) |
-| Elevator Count | [`bld_elevator_count.rs`](v2/crates/wifi-densepose-wasm-edge/src/bld_elevator_count.rs) | Counts people entering/leaving with overload warning | S (<5ms) |
-| Meeting Room | [`bld_meeting_room.rs`](v2/crates/wifi-densepose-wasm-edge/src/bld_meeting_room.rs) | Tracks meeting lifecycle: start, headcount, end, availability | S (<5ms) |
-| Energy Audit | [`bld_energy_audit.rs`](v2/crates/wifi-densepose-wasm-edge/src/bld_energy_audit.rs) | Tracks after-hours usage and room utilization rates | S (<5ms) |
-
-**🛒 Retail & Hospitality** (Category 4) — Customer insights without cameras
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Queue Length | [`ret_queue_length.rs`](v2/crates/wifi-densepose-wasm-edge/src/ret_queue_length.rs) | Estimates queue size and wait times | S (<5ms) |
-| Dwell Heatmap | [`ret_dwell_heatmap.rs`](v2/crates/wifi-densepose-wasm-edge/src/ret_dwell_heatmap.rs) | Shows where people spend time (hot/cold zones) | S (<5ms) |
-| Customer Flow | [`ret_customer_flow.rs`](v2/crates/wifi-densepose-wasm-edge/src/ret_customer_flow.rs) | Counts ins/outs and tracks net occupancy | S (<5ms) |
-| Table Turnover | [`ret_table_turnover.rs`](v2/crates/wifi-densepose-wasm-edge/src/ret_table_turnover.rs) | Restaurant table lifecycle: seated, dining, vacated | S (<5ms) |
-| Shelf Engagement | [`ret_shelf_engagement.rs`](v2/crates/wifi-densepose-wasm-edge/src/ret_shelf_engagement.rs) | Detects browsing, considering, and reaching for products | S (<5ms) |
-
-**🏭 Industrial & Specialized** (Category 5) — Safety and compliance
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Forklift Proximity | [`ind_forklift_proximity.rs`](v2/crates/wifi-densepose-wasm-edge/src/ind_forklift_proximity.rs) | Warns when people get too close to vehicles | S (<5ms) |
-| Confined Space | [`ind_confined_space.rs`](v2/crates/wifi-densepose-wasm-edge/src/ind_confined_space.rs) | OSHA-compliant worker monitoring with extraction alerts | S (<5ms) |
-| Clean Room | [`ind_clean_room.rs`](v2/crates/wifi-densepose-wasm-edge/src/ind_clean_room.rs) | Occupancy limits and turbulent motion detection | S (<5ms) |
-| Livestock Monitor | [`ind_livestock_monitor.rs`](v2/crates/wifi-densepose-wasm-edge/src/ind_livestock_monitor.rs) | Animal presence, stillness, and escape alerts | S (<5ms) |
-| Structural Vibration | [`ind_structural_vibration.rs`](v2/crates/wifi-densepose-wasm-edge/src/ind_structural_vibration.rs) | Seismic events, mechanical resonance, structural drift | S (<5ms) |
-
-**🔮 Exotic & Research** (Category 6) — Experimental sensing applications
-
-| Module | File | What It Does | Budget |
-|--------|------|-------------|--------|
-| Dream Stage | [`exo_dream_stage.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_dream_stage.rs) | Contactless sleep stage classification (wake/light/deep/REM) | S (<5ms) |
-| Emotion Detection | [`exo_emotion_detect.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_emotion_detect.rs) | Arousal, stress, and calm detection from micro-movements | S (<5ms) |
-| Gesture Language | [`exo_gesture_language.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_gesture_language.rs) | Sign language letter recognition via WiFi | S (<5ms) |
-| Music Conductor | [`exo_music_conductor.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_music_conductor.rs) | Tempo and dynamic tracking from conducting gestures | S (<5ms) |
-| Plant Growth | [`exo_plant_growth.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_plant_growth.rs) | Monitors plant growth, circadian rhythms, wilt detection | S (<5ms) |
-| Ghost Hunter | [`exo_ghost_hunter.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_ghost_hunter.rs) | Environmental anomaly classification (draft/insect/wind/unknown) | S (<5ms) |
-| Rain Detection | [`exo_rain_detect.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_rain_detect.rs) | Detects rain onset, intensity, and cessation via signal scatter | S (<5ms) |
-| Breathing Sync | [`exo_breathing_sync.rs`](v2/crates/wifi-densepose-wasm-edge/src/exo_breathing_sync.rs) | Detects synchronized breathing between multiple people | S (<5ms) |
-
-
---
diff --git a/data/clone-data.rvf b/data/clone-data.rvf
new file mode 100644
index 00000000..16592910
--- /dev/null
+++ b/data/clone-data.rvf
@@ -0,0 +1,3 @@
+{"type": "metadata", "name": "ruview-clone-traffic-history", "version": "1.0.0", "schema": "ruvector.rvf.jsonl/v1", "format": "github-traffic-snapshots", "repo": "ruvnet/RuView", "source": "GitHub Traffic API /repos/{repo}/traffic/{clones,views}", "policy": "GitHub retains only 14 days server-side; this file is the long-term record.", "segments": ["metadata", "clone_snapshot", "view_snapshot"], "created_at": "2026-05-19T23:16:22Z", "custom": {"cadence": "twice monthly (1st and 15th, ~14-day intervals)", "idempotency_key": "timestamp (per-day records de-duplicate across overlapping snapshot windows)"}}
+{"type": "clone_snapshot", "fetched_at": "2026-05-19T23:16:22Z", "window_count": 27887, "window_uniques": 6611, "per_day": [{"timestamp": "2026-05-05T00:00:00Z", "count": 620, "uniques": 218}, {"timestamp": "2026-05-06T00:00:00Z", "count": 477, "uniques": 232}, {"timestamp": "2026-05-07T00:00:00Z", "count": 685, "uniques": 268}, {"timestamp": "2026-05-08T00:00:00Z", "count": 703, "uniques": 276}, {"timestamp": "2026-05-09T00:00:00Z", "count": 352, "uniques": 184}, {"timestamp": "2026-05-10T00:00:00Z", "count": 205, "uniques": 151}, {"timestamp": "2026-05-11T00:00:00Z", "count": 1160, "uniques": 234}, {"timestamp": "2026-05-12T00:00:00Z", "count": 599, "uniques": 207}, {"timestamp": "2026-05-13T00:00:00Z", "count": 5141, "uniques": 1152}, {"timestamp": "2026-05-14T00:00:00Z", "count": 3420, "uniques": 972}, {"timestamp": "2026-05-15T00:00:00Z", "count": 1974, "uniques": 764}, {"timestamp": "2026-05-16T00:00:00Z", "count": 2917, "uniques": 617}, {"timestamp": "2026-05-17T00:00:00Z", "count": 6690, "uniques": 1169}, {"timestamp": "2026-05-18T00:00:00Z", "count": 2944, "uniques": 625}]}
+{"type": "view_snapshot", "fetched_at": "2026-05-19T23:16:22Z", "window_count": 162314, "window_uniques": 75464, "per_day": [{"timestamp": "2026-05-05T00:00:00Z", "count": 5540, "uniques": 2690}, {"timestamp": "2026-05-06T00:00:00Z", "count": 5111, "uniques": 2393}, {"timestamp": "2026-05-07T00:00:00Z", "count": 5585, "uniques": 2708}, {"timestamp": "2026-05-08T00:00:00Z", "count": 7004, "uniques": 3261}, {"timestamp": "2026-05-09T00:00:00Z", "count": 5395, "uniques": 2531}, {"timestamp": "2026-05-10T00:00:00Z", "count": 4761, "uniques": 2219}, {"timestamp": "2026-05-11T00:00:00Z", "count": 4275, "uniques": 2044}, {"timestamp": "2026-05-12T00:00:00Z", "count": 3466, "uniques": 1688}, {"timestamp": "2026-05-13T00:00:00Z", "count": 13561, "uniques": 8473}, {"timestamp": "2026-05-14T00:00:00Z", "count": 21867, "uniques": 12527}, {"timestamp": "2026-05-15T00:00:00Z", "count": 26182, "uniques": 14609}, {"timestamp": "2026-05-16T00:00:00Z", "count": 17406, "uniques": 8868}, {"timestamp": "2026-05-17T00:00:00Z", "count": 28444, "uniques": 14541}, {"timestamp": "2026-05-18T00:00:00Z", "count": 13717, "uniques": 7819}]}
diff --git a/docs/adr/ADR-100-cog-packaging-specification.md b/docs/adr/ADR-100-cog-packaging-specification.md
new file mode 100644
index 00000000..cf9aab18
--- /dev/null
+++ b/docs/adr/ADR-100-cog-packaging-specification.md
@@ -0,0 +1,165 @@
+# ADR-100: Cognitum Cog Packaging Specification
+
+- **Status:** Accepted (formalises existing convention) — **first conforming cog shipped 2026-05-19** (`cog-pose-estimation@0.0.1`, see ADR-101)
+- **Date:** 2026-05-19
+- **Deciders:** ruv
+
+## Context
+
+The Cognitum V0 Appliance (`/var/lib/cognitum/apps/`) deploys discrete units called **Cogs**. They appear in the Appliance dashboard (`http://cognitum-v0:9000/cogs`) under an app-store UI (Today / Apps / Categories / Search / Updates). Until this ADR, the packaging convention has been **implicit** — derived from inspecting installed cogs (`anomaly-detect`, `presence`, `seizure-detect`, etc.) on a live appliance. Bringing new Cogs to the platform required reverse-engineering the layout each time.
+
+This ADR formalises the layout so:
+
+1. A repo crate can be built into a Cog with a deterministic Makefile / CI pipeline.
+2. Cog binaries can be cross-compiled for every supported architecture from a single source.
+3. The appliance's installer (`cognitum-cog-gateway`) can verify manifests without bespoke per-cog adapters.
+4. Future Cogs in this repo (starting with `cog-pose-estimation` — see ADR-101) follow a single rule.
+
+## Decision
+
+### On-device layout
+
+Each installed Cog lives at:
+
+```
+/var/lib/cognitum/apps//
+├── cog-- # single self-contained executable
+├── manifest.json # immutable; signed by the publisher
+├── config.json # mutable; runtime config, owned by the appliance
+├── pid # current PID when running; absent when stopped
+├── output.log # stdout (truncated on rotation)
+└── error.log # stderr (truncated on rotation)
+```
+
+`` is kebab-case, ASCII, `[a-z0-9-]{2,32}`. `` is one of:
+
+| arch | target triple | hardware |
+|------|---------------|----------|
+| `arm` | `aarch64-unknown-linux-gnu` | Raspberry Pi 5 (cognitum-v0, cluster Pis) |
+| `x86_64` | `x86_64-unknown-linux-gnu` | ruvultra, generic Linux dev |
+| `hailo8` | `aarch64-unknown-linux-gnu` + Hailo HEF sidecar | Pi + Hailo-8 hat (26 TOPS) |
+| `hailo10` | `aarch64-unknown-linux-gnu` + Hailo HEF sidecar | Pi + Hailo-10 hat (40 TOPS) |
+
+### `manifest.json` schema
+
+```json
+{
+ "id": "anomaly-detect",
+ "version": "0.1.0",
+ "binary_url": "https://storage.googleapis.com/cognitum-apps/cogs/arm/cog-anomaly-detect-arm",
+ "binary_bytes": 461904,
+ "binary_sha256": "",
+ "binary_signature": "",
+ "installed_at": 1778772536,
+ "status": "installed"
+}
+```
+
+Fields:
+
+- `id`, `version`, `binary_url`, `binary_bytes`, `installed_at`, `status` — already implemented and observed in production manifests (e.g. `anomaly-detect@0.0.0`). Documented here without change.
+- `binary_sha256`, `binary_signature` — **new**, REQUIRED for any Cog shipped from this repo. Backwards-compatible with existing manifests: the appliance gateway treats both fields as optional today, MUST verify them when present. ADR-103 (witness chain) covers the trust model in more detail.
+- `status` values: `"installed"`, `"running"`, `"stopped"`, `"failed"`, `"updating"`.
+
+### Binary hosting
+
+Cog binaries live in **Google Cloud Storage**, public-read, at:
+
+```
+gs://cognitum-apps/cogs//cog--
+```
+
+The HTTPS form is `https://storage.googleapis.com/cognitum-apps/cogs//cog--` (no trailing extension; the URL is the canonical artifact). For Hailo variants, the HEF model file is sibling: `cog--.hef`.
+
+Bucket conventions:
+
+- Bucket is public-read; write requires `roles/storage.objectAdmin` in project `cognitum-20260110`.
+- Per-version artifacts must be content-addressed: `cogs//cog--@` is the immutable copy; the un-suffixed name is a symlink that updates on release.
+- `COGNITUM_OWNER_SIGNING_KEY` (GCP Secret Manager) signs every binary before upload.
+
+### Source-tree layout (this repo)
+
+Each Cog lives under `v2/crates/cog-/`:
+
+```
+v2/crates/cog-/
+├── Cargo.toml # crate name = cog-; binary = cog-
+├── src/
+│ ├── main.rs # CLI: cog- run | status | version
+│ ├── lib.rs
+│ └── inference.rs # the actual work
+├── cog/
+│ ├── manifest.template.json
+│ ├── config.schema.json # JSON schema for runtime config
+│ ├── README.md # consumer-facing description (used by the App Store UI)
+│ ├── icon.svg # 1024×1024 icon (used by App Store hero)
+│ └── Makefile # build / sign / upload targets
+└── tests/
+ ├── smoke.rs
+ └── manifest_signature.rs
+```
+
+### Build pipeline
+
+```
+cd v2/crates/cog-
+make build-arm # cross-compile to aarch64-unknown-linux-gnu
+make build-x86_64 # x86_64 Linux build
+make build-hailo8 # arm + HEF compilation (requires Hailo Dataflow Compiler)
+make build-hailo10 # arm + HEF compilation
+make sign # produce binary_sha256 + binary_signature
+make upload # gsutil cp to gs://cognitum-apps/cogs//
+make manifest # emit manifest.json with all fields filled
+```
+
+CI (GitHub Actions) MUST run `make build-arm` + `make build-x86_64` on every PR touching `v2/crates/cog-*/`. Hailo HEF compilation requires the proprietary Hailo SDK and runs only on the Hailo-capable runners (currently a labelled self-hosted runner on the Pi cluster — TBD, separate ADR).
+
+### Runtime contract
+
+A Cog binary MUST implement:
+
+| Subcommand | Behaviour |
+|-----------|-----------|
+| `cog- version` | Print `` and exit 0. |
+| `cog- manifest` | Print the embedded manifest JSON and exit 0. |
+| `cog- run --config /path/to/config.json` | Long-running. Writes structured JSON logs to stdout (parsed by `cognitum-cog-gateway`). Exit code 0 on graceful shutdown, non-zero on fatal error. |
+| `cog- health` | One-shot. Exit 0 if the cog could come up healthy; non-zero with diagnostic on stderr. Called by the gateway before `run`. |
+
+stdout JSON line format (one event per line):
+
+```json
+{"ts": 1779210883.444, "level": "info", "event": "", "fields": { ... }}
+```
+
+## Consequences
+
+### Positive
+
+- New Cogs can be added without RE-ing the layout each time.
+- CI can verify the manifest schema before merge.
+- Signed binaries close a real supply-chain gap — current installed cogs (`anomaly-detect@0.0.0`) have no signature, and a compromised GCS object could push malicious code to every appliance.
+- The runtime contract (`run | health | version | manifest`) is uniform across cogs, so `cognitum-cog-gateway` can stop carrying per-cog adapters.
+
+### Negative
+
+- Existing installed cogs must be re-published with signatures within one minor release of the gateway adopting the verify-when-present rule.
+- Hailo HEF cross-compile is gated on a self-hosted runner; we accept that PRs touching Hailo variants will be slower to land.
+
+### Risks
+
+- **Signing key rotation**: `COGNITUM_OWNER_SIGNING_KEY` (Ed25519) is a single root-of-trust today. ADR-103 (witness chain) describes the rotation/recovery path; this ADR depends on that.
+- **GCS bucket misconfiguration**: a public-read bucket with versioning-off could allow rollback attacks. Bucket MUST have Object Versioning enabled + 90-day non-current-version retention.
+
+## Migration
+
+1. ✅ Land this ADR.
+2. ✅ Land ADR-101 (`cog-pose-estimation` — first Cog built to this spec). Shipped in PR #642 + #643 on 2026-05-19; signed `arm` and `x86_64` binaries live at `gs://cognitum-apps/cogs/{arm,x86_64}/`; install verified on cognitum-v0.
+3. After two clean releases of `cog-pose-estimation`, re-publish the existing cogs (`anomaly-detect`, `presence`, etc.) with `binary_sha256` + `binary_signature`. Track in a follow-up issue.
+4. Flip `cognitum-cog-gateway` from "verify when present" to "require signature" — separate ADR, separate review.
+
+## See also
+
+- ADR-101: Pose Estimation Cog (first Cog built to this spec).
+- ADR-103: Witness chain trust model (signing key rotation, future ADR).
+- `docs/adr/ADR-079-camera-ground-truth-training.md` — the training pipeline behind `cog-pose-estimation`.
+- `CLAUDE.local.md` § "Fleet Infrastructure (Tailscale)" — appliance layout this ADR describes.
diff --git a/docs/adr/ADR-101-pose-estimation-cog.md b/docs/adr/ADR-101-pose-estimation-cog.md
new file mode 100644
index 00000000..815ca5b2
--- /dev/null
+++ b/docs/adr/ADR-101-pose-estimation-cog.md
@@ -0,0 +1,208 @@
+# ADR-101: Pose Estimation Cog (WiFi-DensePose side)
+
+- **Status:** Accepted — **v0.0.1 shipped 2026-05-19** (merged in PRs #642 + #643, signed binaries on GCS, live install on cognitum-v0)
+- **Date:** 2026-05-19
+- **Deciders:** ruv
+- **Companion ADR (v0-appliance side):** v0-appliance ADR-225 (cognitum-pose-estimation crate)
+
+## Context
+
+ADR-079 designed the 17-keypoint COCO pose-estimation training pipeline. ADR-100 formalised the Cognitum Cog packaging spec. This ADR is the bridge: it specifies how the wifi-densepose training pipeline produces an artifact that ships as a Cog (`cog-pose-estimation`) onto the Cognitum V0 appliance and out to the Pi+Hailo cluster.
+
+It is the next product step beyond the published `presence` Cog (binary head trained from the contrastive encoder on Hugging Face at `ruvnet/wifi-densepose-pretrained`). Where `presence` reports a single boolean per tick, `cog-pose-estimation` reports 17 (x, y) keypoints per person, per tick.
+
+## Decision
+
+### Pipeline
+
+```
+ (training side — ruvultra GPU)
+ESP32 / rvcsi ─► collect-ground-truth.py + sensing-server recording
+ │
+ ▼
+ data/paired/*.paired.jsonl (CSI window + camera keypoints)
+ │
+ ▼
+ v2/crates/wifi-densepose-train ──► Rust + libtorch trainer
+ (uses RTX 5080 / CUDA 12.x) │
+ init from ruvnet/wifi-densepose-pretrained
+ │
+ ▼
+ model.safetensors (encoder + pose head)
+ │
+ ─────────────┴─────────────
+ │ │
+ ▼ ▼
+ v2/crates/cog-pose-estimation export to ONNX
+ (this repo) │
+ • emits manifest.json ▼
+ • produces cog binary cognitum-hailo
+ • signs + uploads to GCS (v0-appliance side)
+ │
+ ▼
+ cog-pose-estimation.hef
+ │
+ ▼
+ (appliance side — cognitum-v0 + Pi+Hailo cluster)
+
+ gs://cognitum-apps/cogs/{arm,hailo8,hailo10}/cog-pose-estimation-
+ │
+ ▼
+ `cognitum-cog-gateway` pulls artifact + manifest, verifies signature, installs
+ into /var/lib/cognitum/apps/pose-estimation/
+ │
+ ▼
+ run loop: read CSI frames from local sensing-server
+ → encoder → pose head → emit `{ts, persons: [{keypoints: [...17 x,y...] }]}`
+ on stdout as the Cog runtime contract requires
+```
+
+### Architecture (model)
+
+| Stage | Module | Notes |
+|-------|--------|-------|
+| Input | `[56 subcarriers × 20 frames]` per CSI window | matches today's `data/paired/wiflow-p7-*.paired.jsonl` |
+| Encoder | TCN-lite or contrastive encoder lifted from HF presence model | 128-dim embedding; weights init from `ruvnet/wifi-densepose-pretrained/model.safetensors` |
+| Pose head | 2-layer MLP `(128 → 256 → 34)` | 34 = 17 × (x, y) |
+| Output | `[B, 17, 2]` keypoints in `[0, 1]` image-normalised coords | confidence is implicit in keypoint variance over time; ADR-079 P9 will add explicit per-joint confidence |
+| Loss | Confidence-weighted SmoothL1 (frame-level) + bone-length regulariser + temporal smoothness | per ADR-079 Phase 3 refinement |
+| Init | Encoder = HF presence weights (frozen for 50 epochs, then jointly fine-tuned) | unblocks the sigmoid-saturation failure mode observed in #645 |
+| Training | `v2/crates/wifi-densepose-train` with libtorch backend on RTX 5080 | replaces the pure-JS SPSA trainer that produced 0% PCK in #645 |
+
+### Repo layout
+
+```
+v2/crates/cog-pose-estimation/ # NEW (this ADR)
+├── Cargo.toml
+├── src/
+│ ├── main.rs # CLI: run | health | version | manifest
+│ ├── lib.rs
+│ ├── inference.rs # ONNX runtime + Hailo HEF runtime dispatch
+│ ├── frame_subscriber.rs # local sensing-server subscriber
+│ └── publisher.rs # emits structured JSON events per Cog contract
+├── cog/
+│ ├── manifest.template.json
+│ ├── config.schema.json
+│ ├── README.md
+│ ├── icon.svg
+│ └── Makefile # build-arm | build-x86_64 | sign | upload
+└── tests/
+ ├── manifest_signature.rs
+ └── inference_smoke.rs
+```
+
+### Runtime contract
+
+Honours ADR-100's per-Cog CLI contract:
+
+- `cog-pose-estimation version` → `pose-estimation 0.0.1`
+- `cog-pose-estimation manifest` → JSON
+- `cog-pose-estimation health` → 0 if encoder+head load and a synthetic frame produces a finite output
+- `cog-pose-estimation run --config /etc/cognitum/cogs/pose-estimation/config.json` → long-running; emits one JSON event per inferred frame:
+
+```json
+{
+ "ts": 1779210883.444,
+ "level": "info",
+ "event": "pose.frame",
+ "fields": {
+ "tick": 12345,
+ "n_persons": 1,
+ "persons": [
+ {"keypoints": [[0.48, 0.31], [0.52, 0.28], ...], "confidence": 0.81}
+ ]
+ }
+}
+```
+
+### Hardware deployment
+
+| Target | arch | runtime | notes |
+|--------|------|---------|-------|
+| ruvultra (dev) | `x86_64` | ONNX Runtime CPU/CUDA | development & smoke tests |
+| cognitum-v0 (Pi 5) | `arm` | ONNX Runtime ARM | reference deploy; ~20 ms/frame |
+| Pi + Hailo-8 hat | `hailo8` | Hailo HEF runtime via `cognitum-hailo` | ~2 ms/frame, 26 TOPS budget |
+| Pi + Hailo-10 hat | `hailo10` | Hailo HEF runtime via `cognitum-hailo` | ~1 ms/frame, 40 TOPS budget |
+
+### Acceptance gates
+
+1. **Validates:** `cargo test -p cog-pose-estimation` green; `cog-pose-estimation health` returns 0 against a synthetic CSI window.
+2. **Benchmarks:** end-to-end frame latency on each target arch logged in `target/criterion/`; published in `docs/benchmarks/pose-estimation-cog.md`.
+3. **Optimised:** the Hailo-targeted ONNX graph passes through Hailo Dataflow Compiler without quantisation-aware-training warnings.
+4. **Published:** signed binary at `gs://cognitum-apps/cogs//cog-pose-estimation-`; manifest valid against the JSON schema in ADR-100; appliance installer can pull and run it.
+
+PCK@20 is intentionally **not** an acceptance gate of this ADR. Achieving the ADR-079 ≥35% target is a separate, data-bound milestone tracked in #645. This ADR ships the **vehicle**, not the model accuracy.
+
+### First measured run — v0.0.1 (2026-05-19)
+
+A Candle-on-CUDA training run on `ruvultra`'s RTX 5080 against the same 1,077-sample paired session that produced the 0%/0% baseline in #645 yielded:
+
+- **PCK@20 = 3.0%**, **PCK@50 = 18.5%**, **MPJPE = 0.093** (normalized).
+- 400 epochs in **2.1 s** wall time (~5 ms/epoch, full-batch).
+- Loss reduction 13× (0.181 → 0.014, eval 0.010).
+- Strongest signal at `r_hip` (PCK@50 = 76.9%), `r_knee` (35.2%), `l_elbow` (26.4%).
+
+This confirms the pipeline trains end-to-end and produces a signal-bearing model. The remaining gap to PCK@20 ≥ 35% is data-bound (1,077 samples is ≪ the ADR-079 target of ~30K). See `docs/benchmarks/pose-estimation-cog.md` for the full result dump.
+
+## Consequences
+
+### Positive
+
+- First Cog from this repo that integrates with the appliance/cog-gateway pipeline. Future cogs (e.g. `cog-vitals`, `cog-fall-alert`) follow the same template.
+- Closes the loop from data collection → training → quantisation → cluster deployment with a single repo-anchored artifact.
+- Forces a real signature on cog binaries (per ADR-100), which improves supply-chain hygiene across the whole appliance.
+
+### Negative
+
+- Adds a hard dependency on the Hailo Dataflow Compiler, which lives behind a self-hosted runner — Hailo-targeted PRs land more slowly.
+- The first published binary will have low PCK (data + training time gap, #645) — UX needs to surface this clearly so end users do not interpret bad keypoints as a bug.
+
+### Risks
+
+- **Model size on Hailo**: the encoder fits comfortably in Hailo-8's on-chip SRAM, but the pose-head expansion to `[17×2]` plus required temporal stacking pushes us close to the Hailo-8 envelope. Mitigation: Hailo-10 path is the primary deploy target; Hailo-8 is a stretch.
+- **Sensing-server schema drift**: the cog subscribes to `/api/v1/sensing/latest` JSON. If the appliance's sensing-server schema changes, the cog fails open (logs warning, emits nothing). The `frame_subscriber.rs` module pins to schema version `2`.
+
+## Migration / rollout
+
+1. Land this ADR + ADR-100 on `main` of RuView.
+2. Land companion ADR-225 + crate on `main` of v0-appliance.
+3. First release `cog-pose-estimation@0.0.1` ships **only** to `ruvultra` and `cognitum-v0`. Not pushed to the cluster Pis yet.
+4. After P7→P9 data work (#645) brings PCK above a usable threshold, rebuild + re-publish; only then enable cluster rollout via `cognitum-cog-gateway`'s OTA channel.
+
+## v0.0.1 shipping status — 2026-05-19
+
+PRs `#642` (scaffold + arm release + ONNX + live install) and `#643` (x86_64 release) landed on `main`. Acceptance gates from ADR-100 met as follows:
+
+| Gate | Status |
+|------|--------|
+| Cog binary exists per arch | ✅ arm (`3,741,976 B`) + x86_64 (`4,548,856 B`) on GCS |
+| Manifest matches schema | ✅ `cog/artifacts/manifests/{arm,x86_64}/manifest.json` |
+| Binary sha256 + Ed25519 signature | ✅ both signed with `COGNITUM_OWNER_SIGNING_KEY`, round-trip verified |
+| Public-readable GCS | ✅ anonymous HTTP GET works, SHA matches |
+| Live install on a real appliance | ✅ `/var/lib/cognitum/apps/pose-estimation/` on `cognitum-v0` (Pi 5), same layout as `anomaly-detect` |
+| Runtime contract (`version \| manifest \| health \| run`) | ✅ all four return correct output; `run` emits `pose.frame` events |
+| Real weights loaded (not stub) | ✅ `cargo test` asserts `backend.starts_with("candle-")` + non-zero confidence |
+| ONNX artifact (for downstream HEF) | ✅ `pose_v1.onnx` (12 KB), parity vs torch = 8.94e-8 |
+
+| Metric | Value |
+|--------|-------|
+| Training time (RTX 5080 / Candle CUDA) | 2.1 s for 400 epochs |
+| PCK@20 / PCK@50 / MPJPE (1,077-sample seated-desk session) | 3.0% / 18.5% / 0.093 |
+| Cold-start: Windows x86_64 | 76 ms |
+| Cold-start: ruvultra x86_64 | **5.4 ms** |
+| Cold-start: Pi 5 aarch64 | **8.4 ms** |
+| Tests | 5/5 pass |
+
+Open follow-ups carried forward from this ADR's "Acceptance gates" section:
+
+- **Hailo HEF cross-compile** — `pose_v1.onnx` is ready; still gated on Hailo Dataflow Compiler + self-hosted runner provisioning. Tracked separately.
+- **PCK@20 ≥ 35%** — explicitly not an acceptance gate of this ADR, but the limiting factor on practical usefulness. Tracked in [#645](https://github.com/ruvnet/RuView/issues/645): needs ~30× more paired samples + multi-room camera framing. Today's seated-desk session is the demonstrated bottleneck.
+
+## See also
+
+- ADR-079: Camera-supervised pose training pipeline (the model we're shipping).
+- ADR-100: Cog packaging specification (the format we're shipping in).
+- v0-appliance ADR-225: cognitum-pose-estimation crate (the appliance-side runtime).
+- v0-appliance ADR-220: cog management surface (where this cog appears in the dashboard).
+- Issue #645: PCK gap (current 3% / 18.5% → ≥35% target).
+- `docs/benchmarks/pose-estimation-cog.md`: full benchmark log, all measured numbers.
diff --git a/docs/adr/ADR-102-edge-module-registry.md b/docs/adr/ADR-102-edge-module-registry.md
new file mode 100644
index 00000000..f8022de5
--- /dev/null
+++ b/docs/adr/ADR-102-edge-module-registry.md
@@ -0,0 +1,171 @@
+# ADR-102: Edge Module Registry Integration
+
+- **Status:** Accepted
+- **Date:** 2026-05-19
+- **Deciders:** ruv
+
+## Context
+
+The Cognitum app ecosystem publishes a canonical app store catalog at:
+
+```
+https://storage.googleapis.com/cognitum-apps/app-registry.json
+```
+
+As of v2.1.0 (2026-05-13) the registry advertises **105 cogs across 11 categories** (health, security, building, retail, industrial, research, ai, swarm, signal, network, developer). Each entry carries `id`, `name`, `category`, `version`, `description`, `size_kb`, `difficulty`, `sha256`, `binary_size`, and a `config[]` schema describing the runtime parameters the appliance offers when installing the cog.
+
+RuView today has no live awareness of this catalog. The `README.md` capability table is hand-curated; the UI surfaces only the capabilities the dashboard's HTML knows about; nothing in `wifi-densepose-sensing-server` references the registry. Result: when Cognitum ships a new cog (the registry was last updated 6 days ago — a fast cadence), RuView stays unaware until someone manually edits the README. Customers running the RuView dashboard against a real appliance see a 10-capability bag in the UI while the appliance is actually capable of installing 105 cogs.
+
+Today's `cog-pose-estimation@0.0.1` release (PRs #642 / #643, ADR-100, ADR-101) is the first cog this repo ships to that registry. We need the discovery side to match.
+
+## Decision
+
+`wifi-densepose-sensing-server` will fetch `app-registry.json` on demand, cache it in process memory with a TTL, and serve it back through a new endpoint:
+
+```
+GET /api/v1/edge/registry
+GET /api/v1/edge/registry?refresh=1 (force-bypass cache, log if abused)
+```
+
+The registry is **passively surfaced**, not modified. RuView is a presentation layer for the canonical Cognitum catalog; it never re-signs entries or re-hosts binaries.
+
+### Module
+
+`v2/crates/wifi-densepose-sensing-server/src/edge_registry.rs` — small, ~150 lines.
+
+```rust
+pub struct EdgeRegistry {
+ cached: RwLock