feat(plugins): RuView Claude Code + Codex marketplace plugin
Add `plugins/ruview` — an end-to-end toolkit for working with RuView (WiFi-DensePose) from Claude Code, mirrored as Codex prompts. Marketplace: `plugins/.claude-plugin/marketplace.json` (one plugin, `ruview`). Skills (9): ruview-quickstart, ruview-hardware-setup, ruview-configure, ruview-applications, ruview-model-training, ruview-advanced-sensing, ruview-cli-api, ruview-mmwave, ruview-verify — shell-first (cargo / python / idf.py / docker / node), no claude-flow MCP dependency. Commands (7): /ruview-start, /ruview-flash, /ruview-provision, /ruview-app, /ruview-train, /ruview-advanced, /ruview-verify. Agents (3): ruview-onboarding-guide, ruview-config-engineer, ruview-training-engineer. Codex mirror: codex/AGENTS.md + codex/README.md + codex/prompts/*.md (full command parity, enforced by scripts/smoke.sh). Docs: docs/adrs/0001-ruview-plugin-contract.md (Proposed). Verification: scripts/smoke.sh (13 structural checks). Provisioning docs reflect the full `provision.py` flag set (TDM mesh, edge tiers, vitals, hop channels, Cognitum Seed, swarm intervals) and the issue #391 NVS-namespace-replace gotcha. Verified: `claude plugin validate` (plugin + marketplace), loads via `claude --plugin-dir`, smoke 13/13, and confirmed against an attached ESP32-S3 on COM8 running the RuView CSI firmware (live adaptive_ctrl + csi_collector serial output). Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
19ee207d51
commit
8ff7c2c35a
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "ruview",
|
||||||
|
"description": "RuView Marketplace: Claude Code + Codex plugins for WiFi sensing — configuration, applications, model training, and onboarding, from practical to advanced",
|
||||||
|
"owner": {
|
||||||
|
"name": "ruvnet",
|
||||||
|
"url": "https://github.com/ruvnet/RuView"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "ruview",
|
||||||
|
"source": "./ruview",
|
||||||
|
"description": "End-to-end RuView toolkit: getting started, ESP32 hardware setup, configuration, sensing applications (presence / vitals / pose / sleep / MAT), camera-free + camera-supervised model training, advanced multistatic sensing, and witness verification"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "ruview",
|
||||||
|
"description": "End-to-end RuView (WiFi-DensePose) toolkit for Claude Code: onboarding, ESP32 hardware setup, configuration, sensing applications, model training, advanced multistatic sensing, and witness verification — from practical to advanced.",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"author": {
|
||||||
|
"name": "ruvnet",
|
||||||
|
"url": "https://github.com/ruvnet/RuView"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/ruvnet/RuView",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"ruview",
|
||||||
|
"wifi-densepose",
|
||||||
|
"wifi-sensing",
|
||||||
|
"csi",
|
||||||
|
"esp32",
|
||||||
|
"pose-estimation",
|
||||||
|
"vital-signs",
|
||||||
|
"edge-ai",
|
||||||
|
"model-training",
|
||||||
|
"onboarding"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
# ruview — Claude Code + Codex plugin for WiFi sensing
|
||||||
|
|
||||||
|
End-to-end toolkit for **RuView** (WiFi-DensePose): onboarding, ESP32 hardware setup, configuration, sensing applications, model training, advanced multistatic sensing, and witness verification — from practical to advanced.
|
||||||
|
|
||||||
|
Part of the **`ruview` marketplace** (`plugins/.claude-plugin/marketplace.json`).
|
||||||
|
|
||||||
|
## Install / test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Try it locally without installing
|
||||||
|
claude --plugin-dir ./plugins/ruview
|
||||||
|
|
||||||
|
# Or add the whole marketplace
|
||||||
|
claude plugin marketplace add ./plugins
|
||||||
|
claude plugin install ruview@ruview
|
||||||
|
```
|
||||||
|
|
||||||
|
For Codex (OpenAI CLI), see [`codex/`](codex/) — all seven `/ruview-*` commands mirrored as Codex prompts, plus an `AGENTS.md` and install instructions in [`codex/README.md`](codex/README.md).
|
||||||
|
|
||||||
|
## What's inside
|
||||||
|
|
||||||
|
### Skills (auto-discovered from `skills/`)
|
||||||
|
|
||||||
|
| Skill | What it does |
|
||||||
|
|-------|--------------|
|
||||||
|
| `ruview-quickstart` | Onboarding & first run — Docker demo, repo build, fastest path to a live dashboard |
|
||||||
|
| `ruview-hardware-setup` | ESP32-S3 / C6 firmware build, flash, WiFi provisioning, serial monitoring |
|
||||||
|
| `ruview-configure` | sdkconfig variants, NVS provisioning, channel/MAC overrides (ADR-060), edge modules (ADR-041), sensing-server flags, mesh, Cognitum Seed |
|
||||||
|
| `ruview-applications` | Run presence, vitals, pose (WiFlow), sleep, environment mapping, MAT, point-cloud fusion, novel RF apps |
|
||||||
|
| `ruview-model-training` | Camera-free pose, camera-supervised pose (92.9% PCK@20, ADR-079), RuVector embeddings (AETHER), domain generalization (MERIDIAN), local SNN, GPU on GCloud, HF publishing |
|
||||||
|
| `ruview-advanced-sensing` | RuvSense multistatic, cross-viewpoint fusion, RF tomography, persistent field model, intention signals, adversarial detection, mesh security |
|
||||||
|
| `ruview-cli-api` | `wifi-densepose` CLI binary (incl. MAT subcommands), REST API (`wifi-densepose-api`), browser/WASM (`wifi-densepose-wasm`, `wifi-densepose-wasm-edge`) |
|
||||||
|
| `ruview-mmwave` | mmWave / FMCW radar — ESP32-C6 + MR60BHA2 (60 GHz HR/BR/presence), HLK-LD2410 (24 GHz), mmWave↔CSI fusion (48-byte fused vitals) |
|
||||||
|
| `ruview-verify` | Rust tests, deterministic Python proof, firmware hashes, ADR-028 witness bundle + self-verification, pre-merge checklist |
|
||||||
|
|
||||||
|
### Commands (`commands/`)
|
||||||
|
|
||||||
|
| Command | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `/ruview-start` | Get started — pick Docker / build / hardware and walk through it |
|
||||||
|
| `/ruview-flash` | Build + flash ESP32 firmware (8MB / 4MB), confirm CSI stream |
|
||||||
|
| `/ruview-provision` | Provision WiFi creds, sink IP, channel / MAC-filter onto a node |
|
||||||
|
| `/ruview-app` | Run a sensing application |
|
||||||
|
| `/ruview-train` | Train / evaluate / publish a model (incl. GPU) |
|
||||||
|
| `/ruview-advanced` | Use multistatic / tomography / cross-viewpoint / mesh-security features |
|
||||||
|
| `/ruview-verify` | Run the trust pipeline + pre-merge checklist |
|
||||||
|
|
||||||
|
### Agents (`agents/`)
|
||||||
|
|
||||||
|
| Agent | Role |
|
||||||
|
|-------|------|
|
||||||
|
| `ruview-onboarding-guide` | Walks a newcomer from zero to a working setup |
|
||||||
|
| `ruview-config-engineer` | Sets up / tunes a deployment (firmware, NVS, edge modules, mesh, Seed) |
|
||||||
|
| `ruview-training-engineer` | Trains, evaluates, and ships models |
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
- **Claude Code** — skills, commands, and agents are auto-discovered; no `claude-flow` MCP server required (skills drive RuView's own tooling: `cargo`, `python`, `idf.py`, `docker`, `node`). Optional: `npx @claude-flow/cli@latest security scan` is referenced for security changes.
|
||||||
|
- **Codex (OpenAI CLI)** — workflows mirrored under `codex/prompts/`; drop them in `~/.codex/prompts/` (or point Codex at `codex/`). `codex/AGENTS.md` carries the project rules.
|
||||||
|
- **Target repo** — assumes the [`ruvnet/RuView`](https://github.com/ruvnet/RuView) / `wifi-densepose` layout: `v2/crates/`, `firmware/esp32-csi-node/`, `archive/v1/`, `scripts/`, `docs/adr/`. On Windows, ESP-IDF builds go through the Python-subprocess pattern in `CLAUDE.local.md`.
|
||||||
|
|
||||||
|
## Namespace coordination
|
||||||
|
|
||||||
|
This plugin claims the kebab-case `ruview-*` namespace for its skills, commands, and agents (skills: `ruview-quickstart`, `ruview-hardware-setup`, `ruview-configure`, `ruview-applications`, `ruview-model-training`, `ruview-advanced-sensing`, `ruview-cli-api`, `ruview-mmwave`, `ruview-verify`; commands: `/ruview-start`, `/ruview-flash`, `/ruview-provision`, `/ruview-app`, `/ruview-train`, `/ruview-advanced`, `/ruview-verify`; agents: `ruview-onboarding-guide`, `ruview-config-engineer`, `ruview-training-engineer`). It does not write to any `claude-flow` memory namespace. If combined with the `ruflo` marketplace, defer to `ruflo-agentdb` ADR-0001 §"Namespace convention" — there is no overlap (`ruview-*` vs. `ruflo-*`).
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash plugins/ruview/scripts/smoke.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Structural contract: plugin.json has `version` + `keywords` and does **not** enumerate skills/commands/agents; every skill/command/agent file exists with valid frontmatter; README has a Compatibility section and a Namespace coordination block; ADR-0001 exists with status `Proposed`; no wildcard tools in skills; Codex mirror present **and parity** — every `commands/<name>.md` has a matching `codex/prompts/<name>.md`.
|
||||||
|
|
||||||
|
## Architecture Decisions
|
||||||
|
|
||||||
|
- [`docs/adrs/0001-ruview-plugin-contract.md`](docs/adrs/0001-ruview-plugin-contract.md) — plugin contract (Proposed): structure, namespace, compatibility surface, smoke scope, Codex mirror policy.
|
||||||
|
|
||||||
|
## Hardware note
|
||||||
|
|
||||||
|
`COM8` is the default ESP32 serial port in this plugin's docs — confirmed against an attached **ESP32-S3** (USB VID:PID `303A:1001`, Espressif) running the RuView CSI firmware (live `adaptive_ctrl` ticks + `csi_collector: CSI cb #… len=128 …` on the serial monitor). The repo's `CLAUDE.local.md` historically referenced `COM7`; some README snippets reference `COM9`. Always confirm the actual port (`python -c "import serial.tools.list_ports as l; print([p.device for p in l.comports()])"`, or Device Manager) before flashing. On Windows, `provision.py --help` needs `PYTHONUTF8=1` to print (non-ASCII in the help text); the build/flash path goes through the Python-subprocess pattern in `CLAUDE.local.md` (ESP-IDF v5.4 ≠ Git Bash).
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
name: ruview-config-engineer
|
||||||
|
description: Configures RuView deployments — ESP32 firmware variants (8MB/4MB/Heltec), sdkconfig, NVS provisioning, WiFi channel / MAC-filter overrides (ADR-060), edge intelligence modules (ADR-041), sensing-server flags, multi-node mesh, and Cognitum Seed integration. Use to set up or tune a RuView system without changing source code.
|
||||||
|
model: sonnet
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Config Engineer
|
||||||
|
|
||||||
|
You own everything tunable in a RuView deployment — from a single provision flag to a full mesh + Cognitum Seed.
|
||||||
|
|
||||||
|
## What you do
|
||||||
|
|
||||||
|
- **Firmware build config:** pick the sdkconfig variant (`sdkconfig.defaults.template` for 8MB no-mock, `sdkconfig.defaults.4mb`, `sdkconfig.defaults.heltec_n16r2`), copy it to `sdkconfig.defaults`, rebuild via the Windows Python-subprocess command (`CLAUDE.local.md`). **Never test in mock mode.**
|
||||||
|
- **Device runtime config (`provision.py`):** writes the `csi_cfg` NVS namespace over serial. Always check `python firmware/esp32-csi-node/provision.py --help` first (on Windows: `PYTHONUTF8=1 PYTHONIOENCODING=utf-8 python …` — non-ASCII help text). Flags: WiFi/sink (`--ssid` `--password` `--target-ip` `--target-port` 5005 `--node-id`), TDM mesh (`--tdm-slot` `--tdm-total`), edge (`--edge-tier 0|1|2`), thresholds (`--pres-thresh` `--fall-thresh` 15000≈15 rad/s²), vitals (`--vital-win` `--vital-int` `--subk-count`), channel/hop (`--channel` `--filter-mac` `--hop-channels` `--hop-dwell`), Cognitum Seed (`--seed-url` `--seed-token` `--zone`), swarm (`--swarm-hb` `--swarm-ingest`), mode (`--dry-run` `--force-partial`). ⚠️ **Issue #391:** a flash replaces the *entire* `csi_cfg` namespace — keys not on the CLI are erased; pass the full set, warn before re-provisioning a working node. Fleet: `scripts/generate_nvs_matrix.py`.
|
||||||
|
- **Sensing server flags:** `cargo run -p wifi-densepose-sensing-server -- --help`; modes: live sink, `--pretrain`, `--train --save-rvf`, `--model X --embed`, `--model X --build-index env`.
|
||||||
|
- **Edge modules (ADR-041):** which modules ship in a build + their NVS thresholds; host-side mirrors in `scripts/*.js` (apnea, gait, material, passive-radar, mincut, fingerprint).
|
||||||
|
- **Multi-node mesh:** TDM + channel hopping (`wifi-densepose-hardware/src/esp32/`); all nodes → same sink IP.
|
||||||
|
- **Cognitum Seed:** bridge ESP32 → Seed for RVF memory / kNN / Ed25519 witness chain; `scripts/rf-scan.js`, `scripts/snn-csi-processor.js`; `docs/tutorials/cognitum-seed-pretraining.md`.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
1. Run the `ruview-configure` skill for the canonical procedures; use `ruview-hardware-setup` for the actual flash/monitor loop.
|
||||||
|
2. Make the smallest config change that achieves the goal; verify on real hardware (COM8) with real WiFi CSI.
|
||||||
|
3. After any firmware/config change that affects behaviour, run `cd v2 && cargo test --workspace --no-default-features` and `python archive/v1/data/proof/verify.py`, then regenerate the witness bundle if needed (`/ruview-verify`).
|
||||||
|
|
||||||
|
## Ground rules
|
||||||
|
|
||||||
|
- Read before edit. No new files unless required. No secrets / `.env` in commits.
|
||||||
|
- Reference ADR-022, 028, 041, 060, 061, 081; `CLAUDE.md` / `CLAUDE.local.md`; `example.env`.
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
name: ruview-onboarding-guide
|
||||||
|
description: Walks a newcomer through RuView (WiFi-DensePose) from zero to a working sensing setup — picks the right path (Docker demo / repo build / live ESP32), explains the physics and the hardware caveats, and points to the next steps. Use when someone is new to the project or asks "how do I get started".
|
||||||
|
model: sonnet
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Onboarding Guide
|
||||||
|
|
||||||
|
You help people get started with **RuView** — WiFi-based human sensing from Channel State Information (CSI). Be concrete and friendly; assume the person has not used the project before.
|
||||||
|
|
||||||
|
## Your job
|
||||||
|
|
||||||
|
1. **Figure out what they have.** No hardware? → Docker demo. Want to build? → Rust workspace + Python proof. Have an ESP32-S3/C6? → flash + provision + sensing server.
|
||||||
|
2. **Run the `ruview-quickstart` skill** for the canonical steps. For hardware, hand to `ruview-hardware-setup`.
|
||||||
|
3. **Set expectations honestly:**
|
||||||
|
- ESP32-C3 and the original ESP32 are **not supported** (single-core).
|
||||||
|
- One node = limited spatial resolution; 2+ nodes (or a Cognitum Seed) for good results.
|
||||||
|
- Camera-free pose is modest; camera-supervised training reaches 92.9% PCK@20 (ADR-079).
|
||||||
|
- Everything runs on the edge — no cloud, no cameras, no internet required.
|
||||||
|
4. **Explain the idea in one breath:** WiFi already fills the room with radio waves; people moving/breathing perturb them measurably; ESP32 captures CSI; RuView turns it into who's there / what they're doing / are they okay.
|
||||||
|
5. **Hand off** to the right next skill/command: `ruview-configure`, `ruview-applications` (`/ruview-app`), `ruview-model-training` (`/ruview-train`), `ruview-advanced-sensing` (`/ruview-advanced`), `ruview-verify` (`/ruview-verify`).
|
||||||
|
|
||||||
|
## Ground rules
|
||||||
|
|
||||||
|
- Read a file before editing it. Don't create files unless asked.
|
||||||
|
- Don't commit secrets or `.env`.
|
||||||
|
- Use the project's own tooling: `cargo`, `python`, `idf.py` (via the Python-subprocess on Windows — see `CLAUDE.local.md`), `docker`, `node` scripts.
|
||||||
|
- Reference, don't paraphrase: `README.md`, `docs/user-guide.md`, `docs/build-guide.md`, `docs/TROUBLESHOOTING.md`, `docs/tutorials/`, `examples/`.
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
name: ruview-training-engineer
|
||||||
|
description: Trains, evaluates, and ships RuView models — camera-free WiFlow pose, camera-supervised pose (MediaPipe + ESP32 CSI → 92.9% PCK@20, ADR-079), RuVector contrastive embeddings (AETHER, ADR-024), domain generalization (MERIDIAN, ADR-027), local SNN environment adaptation, GPU training on GCloud, and Hugging Face publishing. Use for any model-building task.
|
||||||
|
model: sonnet
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Training Engineer
|
||||||
|
|
||||||
|
You build and ship RuView models. Know the tracks, the data layout, and the validation gate.
|
||||||
|
|
||||||
|
## Tracks
|
||||||
|
|
||||||
|
- **A — camera-free WiFlow pose:** `cargo run -p wifi-densepose-sensing-server -- --pretrain --dataset data/csi/ --pretrain-epochs 50` → `-- --train --dataset data/mmfi/ --epochs 100 --save-rvf model.rvf`. ~84 s on M4 Pro; modest accuracy. Bench: `node scripts/benchmark-wiflow.js`; eval: `node scripts/eval-wiflow.js`.
|
||||||
|
- **B — camera-supervised pose (ADR-079):** `python scripts/collect-ground-truth.py` (MediaPipe), `python scripts/collect-training-data.py` (CSI), `node scripts/align-ground-truth.js`, train on `data/paired/`, eval `eval-wiflow.js` → reports PCK@20. ~19 min on a laptop; 92.9% PCK@20. Needs `data/pose_landmarker_lite.task`.
|
||||||
|
- **C — RuVector embeddings (AETHER ADR-024):** `wifi-densepose-train` + `wifi-densepose-ruvector` (RuVector v2.0.4); `-- --model model.rvf --embed`, `-- --build-index env`. Spectrogram embeddings: ADR-076.
|
||||||
|
- **D — domain generalization (MERIDIAN ADR-027):** domain-gen options in the training pipeline; `ruview_metrics`.
|
||||||
|
- **E — local SNN adaptation:** `node scripts/snn-csi-processor.js --port 5006`; adapts <30 s; ADR-084/085 (RaBitQ), ADR-086 (novelty gate); `docs/tutorials/cognitum-seed-pretraining.md`.
|
||||||
|
|
||||||
|
## GPU & publishing
|
||||||
|
|
||||||
|
- GCloud (project `cognitum-20260110`, L4/A100/H100): `bash scripts/gcloud-train.sh [--dry-run] [--gpu l4|a100|h100] [--hours N] [--config FILE] [--sweep] [--keep-vm]`. VM auto-deletes. Local Mac: `bash scripts/mac-mini-train.sh`. Bench: `python scripts/benchmark-model.py`.
|
||||||
|
- Publish: `python scripts/publish-huggingface.py` (or the `.sh`); `docs/huggingface/`.
|
||||||
|
|
||||||
|
## Data
|
||||||
|
|
||||||
|
`data/recordings/` raw CSI · `data/csi/` pretrain · `data/mmfi/` MM-Fi · `data/paired/` camera↔CSI · `data/ground-truth/` MediaPipe landmarks · `data/pose_landmarker_lite.task` · `models/`. Record more: `python scripts/record-csi-udp.py`.
|
||||||
|
|
||||||
|
## Validation gate (always, after a training change)
|
||||||
|
|
||||||
|
1. `cd v2 && cargo test --workspace --no-default-features` — 1,400+ pass, 0 fail.
|
||||||
|
2. `cd .. && python archive/v1/data/proof/verify.py` — VERDICT: PASS.
|
||||||
|
3. Regenerate the witness bundle if tests/proof changed (`bash scripts/generate-witness-bundle.sh`; self-verify 7/7).
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
Run the `ruview-model-training` skill for canonical commands. Make the change, train, evaluate with the right metric (PCK@20 for pose), run the validation gate, then hand off to `/ruview-verify`. Read before edit; no new files unless required; no secrets in commits.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
ADRs 015, 016, 017, 024, 027, 076, 079, 084, 085, 095, 096; crates `wifi-densepose-train`, `-nn`, `-ruvector`, `-sensing-server`; `CLAUDE.md` build/test section.
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
# AGENTS.md — RuView (WiFi-DensePose)
|
||||||
|
|
||||||
|
Project rules for Codex (and any agent) working in the `ruvnet/RuView` / `wifi-densepose` repo. Mirrors the Claude Code `ruview` plugin.
|
||||||
|
|
||||||
|
## What this repo is
|
||||||
|
|
||||||
|
WiFi-based human sensing from Channel State Information (CSI). Dual codebase: Rust port in `v2/` (15 crates), Python v1 in `archive/v1/`. ESP32-S3 / ESP32-C6 firmware in `firmware/esp32-csi-node/`. 96 ADRs in `docs/adr/`.
|
||||||
|
|
||||||
|
## Hard rules
|
||||||
|
|
||||||
|
- Do exactly what's asked — nothing more, nothing less.
|
||||||
|
- Never create files (especially `*.md`/README) unless required for the task. Prefer editing an existing file.
|
||||||
|
- Never save working files/tests/notes to the repo root — use `v2/crates/`, `tests/`, `docs/`, `scripts/`, `examples/`.
|
||||||
|
- Read a file before editing it.
|
||||||
|
- Never commit secrets, credentials, or `.env`.
|
||||||
|
- Validate user input at system boundaries; sanitize file paths.
|
||||||
|
- ESP32-C3 and the original ESP32 are **not supported** (single-core). Use ESP32-S3 (8MB/4MB) or ESP32-C6.
|
||||||
|
|
||||||
|
## Build & test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Rust workspace (1,400+ tests, ~2 min)
|
||||||
|
cd v2 && cargo test --workspace --no-default-features
|
||||||
|
# Single crate, no GPU
|
||||||
|
cargo check -p wifi-densepose-train --no-default-features
|
||||||
|
# Deterministic Python pipeline proof (SHA-256 Trust Kill Switch)
|
||||||
|
python archive/v1/data/proof/verify.py # must print VERDICT: PASS
|
||||||
|
# Python v1 tests
|
||||||
|
cd archive/v1 && python -m pytest tests/ -x -q
|
||||||
|
```
|
||||||
|
|
||||||
|
## ESP32 firmware (Windows)
|
||||||
|
|
||||||
|
ESP-IDF v5.4 does **not** work under Git Bash/MSYS2 and `cmd.exe /C` hangs when called from bash. Build/flash via the **Espressif Python venv as a subprocess with `MSYSTEM*` env vars stripped** — the exact command is in `CLAUDE.local.md`. Default ESP32 serial port: **COM8** (confirm with `mode` / Device Manager — older docs say COM7 or COM9). Provision WiFi: `python firmware/esp32-csi-node/provision.py --port COM8 --ssid ... --password ... --target-ip ... [--channel N] [--filter-mac MAC]`. Serial monitor via pyserial, not `idf.py monitor`. Always test with real WiFi CSI, never mock mode.
|
||||||
|
|
||||||
|
## Witness verification (ADR-028)
|
||||||
|
|
||||||
|
After significant changes: run the Rust tests + Python proof, then `bash scripts/generate-witness-bundle.sh`, then `cd dist/witness-bundle-ADR028-*/ && bash VERIFY.sh` (7/7 PASS). Pre-merge checklist lives in `CLAUDE.md`.
|
||||||
|
|
||||||
|
## Prompt files in `codex/prompts/`
|
||||||
|
|
||||||
|
| Prompt | Purpose |
|
||||||
|
|--------|---------|
|
||||||
|
| `ruview-start` | Onboarding — Docker demo / repo build / live ESP32 |
|
||||||
|
| `ruview-flash` | Build + flash ESP32 firmware (8MB / 4MB) |
|
||||||
|
| `ruview-provision` | Provision WiFi creds + sink IP + channel/MAC overrides |
|
||||||
|
| `ruview-app` | Run a sensing application (presence / vitals / pose / sleep / MAT / point cloud) |
|
||||||
|
| `ruview-train` | Train / evaluate / publish a model (incl. GPU on GCloud) |
|
||||||
|
| `ruview-verify` | Run the trust pipeline + pre-merge checklist |
|
||||||
|
|
||||||
|
Install: copy `codex/prompts/*.md` into `~/.codex/prompts/`, or run Codex with this directory on its prompt path.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
`README.md`, `docs/user-guide.md`, `docs/wifi-mat-user-guide.md`, `docs/build-guide.md`, `docs/TROUBLESHOOTING.md`, `docs/adr/`, `docs/tutorials/`, `examples/`, `CLAUDE.md`, `CLAUDE.local.md`.
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
# RuView prompts for Codex (OpenAI CLI)
|
||||||
|
|
||||||
|
This directory mirrors the Claude Code `ruview` plugin's operator commands as Codex prompts, plus an `AGENTS.md` carrying the RuView project rules.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `AGENTS.md` | Project rules — repo layout, hard rules, build/test, ESP32 firmware on Windows, witness verification |
|
||||||
|
| `prompts/ruview-start.md` | Onboarding — Docker demo / repo build / live ESP32 |
|
||||||
|
| `prompts/ruview-flash.md` | Build + flash ESP32 firmware (8MB / 4MB) |
|
||||||
|
| `prompts/ruview-provision.md` | Provision WiFi creds + sink IP + channel/MAC overrides |
|
||||||
|
| `prompts/ruview-app.md` | Run a sensing application (presence / vitals / pose / sleep / MAT / point cloud) |
|
||||||
|
| `prompts/ruview-train.md` | Train / evaluate / publish a model (incl. GPU on GCloud) |
|
||||||
|
| `prompts/ruview-advanced.md` | Multistatic / tomography / cross-viewpoint / field-model / mesh-security |
|
||||||
|
| `prompts/ruview-verify.md` | Run the trust pipeline + pre-merge checklist |
|
||||||
|
|
||||||
|
Prompt parity with the Claude Code plugin is enforced by `plugins/ruview/scripts/smoke.sh` (every `commands/<name>.md` must have a matching `codex/prompts/<name>.md`).
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
**Per-user prompts** — copy the prompt files into Codex's prompt directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.codex/prompts
|
||||||
|
cp plugins/ruview/codex/prompts/*.md ~/.codex/prompts/
|
||||||
|
# now in the codex TUI: /ruview-start /ruview-flash /ruview-app /ruview-train /ruview-verify /ruview-advanced
|
||||||
|
```
|
||||||
|
|
||||||
|
**Project rules** — point Codex at the `AGENTS.md`. Codex auto-discovers an `AGENTS.md` at the repo root and in the working directory; either symlink it or copy it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ln -s plugins/ruview/codex/AGENTS.md AGENTS.md # repo root (if you don't already have one)
|
||||||
|
# — or, if a root AGENTS.md exists, append the relevant sections from plugins/ruview/codex/AGENTS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
**Config (optional)** — to keep prompts in-repo instead of `~/.codex/prompts`, add to `~/.codex/config.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# Codex reads prompts from ~/.codex/prompts by default; symlinking keeps them versioned with the repo:
|
||||||
|
# ln -s "$PWD/plugins/ruview/codex/prompts" ~/.codex/prompts/ruview (then prompts appear as /ruview/ruview-start, etc.)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The Codex mirror is the **operator-facing subset** — the seven `/ruview-*` commands. The Claude Code plugin additionally ships skills (`ruview-quickstart`, `ruview-hardware-setup`, `ruview-configure`, `ruview-applications`, `ruview-model-training`, `ruview-advanced-sensing`, `ruview-cli-api`, `ruview-mmwave`, `ruview-verify`) and agents (`ruview-onboarding-guide`, `ruview-config-engineer`, `ruview-training-engineer`) that have no Codex equivalent — their content is folded into `AGENTS.md` and the prompt files.
|
||||||
|
- On Windows, ESP-IDF firmware builds go through the Python-subprocess pattern documented in `CLAUDE.local.md` (Git Bash / MSYS2 is not supported by ESP-IDF v5.4). Default ESP32 serial port: **COM8**.
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
# /ruview-advanced — advanced RuView capabilities
|
||||||
|
|
||||||
|
Drive RuView's research-grade / multi-node features. Topic: `$ARGUMENTS` (one of `multistatic`, `cross-viewpoint`, `tomography`, `field-model`, `intention`, `adversarial`, `security`; if empty, ask).
|
||||||
|
|
||||||
|
- **multistatic** (ADR-029) — treat every WiFi link in range (incl. neighbours' APs) as a bistatic radar pair, then fuse. `v2/crates/wifi-densepose-signal/src/ruvsense/multistatic.rs` (attention-weighted fusion, geometric diversity), `phase_align.rs` (iterative LO phase-offset, circular mean), `multiband.rs`, `coherence.rs` / `coherence_gate.rs` (Z-score scoring; Accept / PredictOnly / Reject / Recalibrate).
|
||||||
|
- **cross-viewpoint** (ADR-016 viewpoint module) — combine 2+ nodes geometrically. `v2/crates/wifi-densepose-ruvector/src/viewpoint/`: `attention.rs` (CrossViewpointAttention, GeometricBias, softmax with `G_bias`), `geometry.rs` (GeometricDiversityIndex, Cramér–Rao bounds, Fisher Information), `coherence.rs` (phase-phasor coherence, hysteresis gate), `fusion.rs` (MultistaticArray aggregate root). Explore geometry first: `node scripts/mesh-graph-transformer.js`, `node scripts/deep-scan.js`.
|
||||||
|
- **tomography** — `ruvsense/tomography.rs` reconstructs a voxel occupancy grid via an ISTA L1 solver (sparse — most voxels empty); pair with cross-viewpoint geometry for through-wall volumetric imaging. RuVector solver crates back the 114→56 subcarrier sparse interpolation.
|
||||||
|
- **field-model** (ADR-030) — `ruvsense/field_model.rs` builds an SVD eigenstructure of the room, persists it (RVF, ideally on a Cognitum Seed); new frames are projected against it and the residual is the perturbation. Survives restarts; answers "what's different from the empty-room baseline?"
|
||||||
|
- **intention** — `ruvsense/intention.rs`, pre-movement lead signals 200–500 ms ahead.
|
||||||
|
- **adversarial** — `ruvsense/adversarial.rs`, rejects physically impossible signals + cross-checks multi-link consistency.
|
||||||
|
- **security** (ADR-032, multistatic mesh hardening) — using neighbour APs and pooling links across a mesh expands the attack surface. Mitigations: `adversarial.rs` + `coherence_gate.rs` quarantine (Reject / Recalibrate) + Ed25519 witness chain (ADR-028). Run a security review (`docs/security-audit-wasm-edge-vendor.md`); see `/ruview-verify`.
|
||||||
|
|
||||||
|
Also relevant: ADR-031 (sensing-first RF mode), ADR-081 (adaptive CSI mesh firmware kernel), ADR-083 (per-cluster π compute hop), ADR-095/096 (on-ESP32 temporal modeling, sparse GQA).
|
||||||
|
|
||||||
|
Validate: `cd v2 && cargo test -p wifi-densepose-signal --no-default-features && cargo test -p wifi-densepose-ruvector --no-default-features`, then `cd .. && python archive/v1/data/proof/verify.py`.
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# /ruview-app — run a RuView sensing application
|
||||||
|
|
||||||
|
Run a RuView application. Which one: `$ARGUMENTS` (one of `presence`, `vitals`, `pose`, `sleep`, `environment`, `mat`, `pointcloud`, or a novel-RF app name; if empty, show the catalogue and ask).
|
||||||
|
|
||||||
|
- **presence / vitals / pose / environment** → `cd v2 && cargo run -p wifi-densepose-sensing-server` against a live ESP32 sink, or the Docker demo (`docker run -p 3000:3000 ruvnet/wifi-densepose:latest`) for simulated CSI. For environment also `-- --model model.rvf --build-index env`. Vitals: breathing 6–30 BPM (bandpass 0.1–0.5 Hz), heart rate 40–120 BPM (bandpass 0.8–2.0 Hz), `wifi-densepose-vitals` crate (ADR-021). Pose: 17 COCO keypoints via WiFlow (ADR-059 live pipeline) — train for accuracy (`/ruview-train`).
|
||||||
|
- **sleep** → `examples/sleep/` + `node scripts/apnea-detector.js` (sleep-stage classification, apnea screening).
|
||||||
|
- **mat** (Mass Casualty Assessment — disaster survivor detection) → `wifi-densepose-mat` crate, `docs/wifi-mat-user-guide.md`.
|
||||||
|
- **pointcloud** → `python scripts/mmwave_fusion_bridge.py` (camera depth via MiDaS + WiFi CSI + mmWave radar → unified spatial model, ~22 ms, 19K+ pts/frame; ADR-094).
|
||||||
|
- **novel RF** → `scripts/passive-radar.js`, `material-classifier.js`, `device-fingerprint.js`, `mincut-person-counter.js`, `gait-analyzer.js` (ADR-077/078).
|
||||||
|
|
||||||
|
No hardware? Fall back to the Docker demo or `python examples/ruview_live.py`. Visualisers: `node scripts/csi-spectrogram.js`, `node scripts/csi-graph-visualizer.js`.
|
||||||
|
|
||||||
|
Help me pick: through-wall → presence/activity (≤5 m depth); stationary subject → vitals/sleep; need skeletons → pose (train it); search & rescue → MAT; best spatial accuracy → 2+ ESP32 nodes + cross-viewpoint fusion (`v2/crates/wifi-densepose-ruvector/src/viewpoint/`), optionally + Cognitum Seed. Examples: `examples/{environment,medical,sleep,stress,happiness-vector}/`.
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
# /ruview-flash — build + flash ESP32 firmware
|
||||||
|
|
||||||
|
Build and flash RuView ESP32 firmware. Variant + port: `$ARGUMENTS` (default `8mb`, port `COM8`).
|
||||||
|
|
||||||
|
1. **Variant.** `8mb` → ensure it builds from `firmware/esp32-csi-node/sdkconfig.defaults.template` (no mock — real WiFi CSI). `4mb` → `cp firmware/esp32-csi-node/sdkconfig.defaults.4mb firmware/esp32-csi-node/sdkconfig.defaults` first (display disabled, dual OTA via `partitions_4mb.csv`). `heltec` → `sdkconfig.defaults.heltec_n16r2`.
|
||||||
|
2. **Build (Windows).** ESP-IDF v5.4 does NOT work under Git Bash; `cmd.exe /C` hangs. Use the Espressif Python venv as a subprocess with `MSYSTEM*` env vars stripped — the exact command is in `CLAUDE.local.md` (`[python, idf_py, 'build']`, cwd = `firmware/esp32-csi-node`). Outputs in `firmware/esp32-csi-node/build/{bootloader/bootloader.bin, partition_table/partition-table.bin, esp32-csi-node.bin, ota_data_initial.bin}`.
|
||||||
|
3. **Flash.** Same subprocess with `[python, idf_py, '-p', 'COM8', 'flash']`, or:
|
||||||
|
```
|
||||||
|
python -m esptool --chip esp32s3 --port COM8 --baud 460800 write_flash \
|
||||||
|
0x0 firmware/esp32-csi-node/build/bootloader/bootloader.bin \
|
||||||
|
0x8000 firmware/esp32-csi-node/build/partition_table/partition-table.bin \
|
||||||
|
0xf000 firmware/esp32-csi-node/build/ota_data_initial.bin \
|
||||||
|
0x20000 firmware/esp32-csi-node/build/esp32-csi-node.bin
|
||||||
|
```
|
||||||
|
4. **Confirm.** Serial monitor via pyserial on `COM8` @ 115200 (NOT `idf.py monitor` — it hangs in a subprocess). Then `cd v2 && cargo run -p wifi-densepose-sensing-server` — frames should arrive. If not: re-run `/ruview-provision`, match the AP channel, drop any `--filter-mac`.
|
||||||
|
|
||||||
|
Never test in mock mode — the Kconfig fall-threshold bug only showed up with real CSI.
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
# /ruview-provision — provision an ESP32 sensing node
|
||||||
|
|
||||||
|
Write NVS config to a RuView ESP32 node. Args: `$ARGUMENTS` (expect `--port`, `--ssid`, `--password`, `--target-ip`, optional `--channel`, `--filter-mac`). Default port `COM8`.
|
||||||
|
|
||||||
|
First get the authoritative flag list: `python firmware/esp32-csi-node/provision.py --help` (on Windows prefix `PYTHONUTF8=1 PYTHONIOENCODING=utf-8` — the help text has non-ASCII and crashes under cp1252). Then run:
|
||||||
|
|
||||||
|
```
|
||||||
|
python firmware/esp32-csi-node/provision.py --port COM8 \
|
||||||
|
--ssid "<SSID>" --password "<PW>" --target-ip <SINK_IP> --target-port 5005 --node-id <0-255> \
|
||||||
|
[--channel <N>] [--filter-mac <AA:BB:CC:DD:EE:FF>] [--hop-channels 1,6,11 --hop-dwell 200] \
|
||||||
|
[--tdm-slot <i> --tdm-total <n>] [--edge-tier 0|1|2] [--pres-thresh 50] [--fall-thresh 15000] \
|
||||||
|
[--vital-win 300] [--vital-int 1000] [--subk-count 32] \
|
||||||
|
[--seed-url http://10.1.10.236 --seed-token <bearer> --zone lobby] [--swarm-hb 30] [--swarm-ingest 5] [--dry-run]
|
||||||
|
```
|
||||||
|
|
||||||
|
Trade-offs:
|
||||||
|
- `--channel <N>` pins the node to one WiFi channel (set it to the AP's channel). Omit it and pass `--hop-channels 1,6,11` for the firmware's multi-band hopping schedule (more sensing bandwidth, uses neighbour APs as illuminators; `--hop-dwell` ms per channel).
|
||||||
|
- `--filter-mac <MAC>` restricts CSI capture to one transmitter (cleaner signal); omit for all transmitters (more data, more noise).
|
||||||
|
- `--edge-tier` 0/1/2 = off / stats / vitals (ADR-041). `--tdm-slot`/`--tdm-total` slot a multi-node mesh. `--fall-thresh 15000` ≈ 15.0 rad/s² (raise to cut false falls).
|
||||||
|
|
||||||
|
⚠️ **Issue #391:** flashing rewrites the *entire* `csi_cfg` NVS namespace — every key not on the CLI is erased. Pass the full set you want; warn before re-provisioning a working node. `--dry-run` builds the NVS binary without flashing; `--force-partial` allows config without WiFi creds (knowingly).
|
||||||
|
|
||||||
|
Fleet provisioning: `python scripts/generate_nvs_matrix.py` (subprocess-first — the `esp_idf_nvs_partition_gen` API changed across versions).
|
||||||
|
|
||||||
|
Verify: serial monitor (pyserial on `COM8`, 115200) should show `adaptive_ctrl` ticks + `csi_collector: CSI cb #… len=128 rssi=… ch=…` lines; the sink `cd v2 && cargo run -p wifi-densepose-sensing-server` should report incoming UDP frames if `--target-ip` points at this host. If no frames: wrong channel, MAC filter too tight, target-ip not this host, or WiFi creds wrong — re-run with corrected args.
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
# /ruview-start — onboard onto RuView
|
||||||
|
|
||||||
|
Help me get started with RuView (WiFi-DensePose). Path: `$ARGUMENTS` (one of `docker`, `build`, `hardware`; if empty, ask which hardware I have).
|
||||||
|
|
||||||
|
- **docker** (no hardware): `docker pull ruvnet/wifi-densepose:latest && docker run -p 3000:3000 ruvnet/wifi-densepose:latest`, then open http://localhost:3000 (simulated CSI, full UI).
|
||||||
|
- **build** (from source): `cd v2 && cargo test --workspace --no-default-features`, then `cd .. && python archive/v1/data/proof/verify.py` (expect `VERDICT: PASS`). Single-crate sanity: `cargo check -p wifi-densepose-train --no-default-features`.
|
||||||
|
- **hardware** (ESP32-S3/C6): use `/ruview-flash` then `/ruview-provision`, then `cd v2 && cargo run -p wifi-densepose-sensing-server` to consume the UDP CSI stream. Also: `node scripts/rf-scan.js --port 5006`, `node scripts/snn-csi-processor.js --port 5006`.
|
||||||
|
|
||||||
|
Warn me about: ESP32-C3 / original ESP32 are unsupported (single-core); one node = limited spatial resolution (use 2+ or add a Cognitum Seed); camera-free pose is modest — camera-supervised training reaches 92.9% PCK@20 (ADR-079); no cloud/cameras/internet needed.
|
||||||
|
|
||||||
|
Then point me at next steps: `/ruview-app`, `/ruview-train`, `/ruview-verify`, and the configuration workflow (sdkconfig variants, NVS provisioning, edge modules, mesh, Cognitum Seed). Reference `README.md`, `docs/user-guide.md`, `docs/build-guide.md`, `docs/TROUBLESHOOTING.md`, `examples/`.
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
# /ruview-train — train a RuView model
|
||||||
|
|
||||||
|
Train / evaluate / publish a RuView model. Track: `$ARGUMENTS` (one of `camera-free`, `camera-supervised`, `embeddings`, `domain-gen`, `snn`, `gpu`; if empty, ask).
|
||||||
|
|
||||||
|
- **camera-free** (WiFlow pose, no labels): `cd v2 && cargo run -p wifi-densepose-sensing-server -- --pretrain --dataset data/csi/ --pretrain-epochs 50`, then `-- --train --dataset data/mmfi/ --epochs 100 --save-rvf model.rvf`. ~84 s on M4 Pro, modest accuracy. Bench `node scripts/benchmark-wiflow.js`, eval `node scripts/eval-wiflow.js`.
|
||||||
|
- **camera-supervised** (ADR-079, 92.9% PCK@20, ~19 min): `python scripts/collect-ground-truth.py` (MediaPipe landmarks; needs `data/pose_landmarker_lite.task`), `python scripts/collect-training-data.py` (CSI capture), `node scripts/align-ground-truth.js` (timestamp align), then `cd v2 && cargo run -p wifi-densepose-sensing-server -- --train --dataset data/paired/ --epochs <N> --save-rvf model.rvf`, eval `node scripts/eval-wiflow.js` (reports PCK@20).
|
||||||
|
- **embeddings** (AETHER ADR-024 / spectrogram ADR-076): `wifi-densepose-train` + `wifi-densepose-ruvector`; `-- --model model.rvf --embed`, `-- --model model.rvf --build-index env`. 171K emb/s on M4 Pro.
|
||||||
|
- **domain-gen** (MERIDIAN ADR-027): domain-generalization options in the training pipeline + `ruview_metrics`.
|
||||||
|
- **snn** (local env adaptation, <30 s): `node scripts/snn-csi-processor.js --port 5006`; `docs/tutorials/cognitum-seed-pretraining.md`; ADR-084/085 (RaBitQ), ADR-086 (novelty gate).
|
||||||
|
- **gpu**: `gcloud auth login && gcloud config set project cognitum-20260110`, then `bash scripts/gcloud-train.sh --dry-run` (smoke), `bash scripts/gcloud-train.sh --gpu l4 --hours 2` (proto, ~$0.80/hr), `bash scripts/gcloud-train.sh --gpu a100 --config scripts/training-config-sweep.json` (~$3.60/hr), `bash scripts/gcloud-train.sh --sweep` (full sweep). VM auto-deletes unless `--keep-vm`. Local Mac: `bash scripts/mac-mini-train.sh`. Bench: `python scripts/benchmark-model.py`.
|
||||||
|
|
||||||
|
Data: `data/recordings/` raw CSI · `data/csi/` pretrain · `data/mmfi/` MM-Fi · `data/paired/` camera↔CSI · `data/ground-truth/` MediaPipe · `models/` artifacts. Record more: `python scripts/record-csi-udp.py`.
|
||||||
|
|
||||||
|
After training: `cd v2 && cargo test --workspace --no-default-features`, `cd .. && python archive/v1/data/proof/verify.py` (VERDICT: PASS). Publish: `python scripts/publish-huggingface.py` (or `.sh`; `docs/huggingface/`). Then run `/ruview-verify`.
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
# /ruview-verify — run the RuView trust pipeline
|
||||||
|
|
||||||
|
Verify a RuView build. Scope: `$ARGUMENTS` (one of `tests`, `proof`, `bundle`, `all`; default `all`).
|
||||||
|
|
||||||
|
1. **tests** — `cd v2 && cargo test --workspace --no-default-features` → must be 1,400+ passed, 0 failed (~2 min). Single-crate: `cargo test -p wifi-densepose-signal --no-default-features`, etc.
|
||||||
|
2. **proof** — `cd .. && python archive/v1/data/proof/verify.py` → must print `VERDICT: PASS`. If a hash mismatch from a legitimate numpy/scipy bump: `python archive/v1/data/proof/verify.py --generate-hash`, then re-run. Optional: `cd archive/v1 && python -m pytest tests/ -x -q`.
|
||||||
|
3. **bundle** — `bash scripts/generate-witness-bundle.sh` produces `dist/witness-bundle-ADR028-<sha>.tar.gz` (WITNESS-LOG-028.md, ADR-028 audit, proof, rust test log, firmware hash manifest, crate versions, VERIFY.sh). Then `cd dist/witness-bundle-ADR028-*/ && bash VERIFY.sh` → must be 7/7 PASS.
|
||||||
|
4. **all** — do 1→3 in order.
|
||||||
|
|
||||||
|
If this follows a code change, walk the pre-merge checklist from `CLAUDE.md`: Rust tests pass; Python proof passes; README updated if scope changed; CLAUDE.md updated if scope changed; CHANGELOG `[Unreleased]` entry; `docs/user-guide.md` updated if new data sources/CLI flags/setup; ADR count bumped in README if a new ADR added; witness bundle regenerated if tests/proof hash changed; Docker image rebuilt only if Dockerfile/deps/runtime changed; crate publishing only if a published crate's public API changed (publish in dependency order — see CLAUDE.md); `.gitignore` updated for new artifacts; security review for new hardware/network-boundary modules.
|
||||||
|
|
||||||
|
For security-related changes also run `npx @claude-flow/cli@latest security scan`. QEMU firmware CI (ADR-061): local helpers `scripts/qemu-esp32s3-test.sh`, `qemu-mesh-test.sh`, `qemu-chaos-test.sh`, `install-qemu.sh`.
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
description: Use advanced RuView capabilities — multistatic sensing, cross-viewpoint fusion, RF tomography, persistent field model, intention signals, adversarial detection, mesh security.
|
||||||
|
argument-hint: "[multistatic|cross-viewpoint|tomography|field-model|intention|adversarial|security]"
|
||||||
|
---
|
||||||
|
|
||||||
|
# /ruview-advanced
|
||||||
|
|
||||||
|
Drive RuView's research-grade / multi-node features.
|
||||||
|
|
||||||
|
1. Invoke the **`ruview-advanced-sensing`** skill.
|
||||||
|
2. Route on `$ARGUMENTS`:
|
||||||
|
- **multistatic** (ADR-029) — `wifi-densepose-signal/src/ruvsense/multistatic.rs`, `phase_align.rs`, `coherence_gate.rs`; neighbours' APs as illuminators.
|
||||||
|
- **cross-viewpoint** (ADR-016 viewpoint) — `wifi-densepose-ruvector/src/viewpoint/`; needs 2+ nodes; `node scripts/mesh-graph-transformer.js`.
|
||||||
|
- **tomography** — `ruvsense/tomography.rs` (ISTA L1 voxel solver) + cross-viewpoint geometry; through-wall volumetric.
|
||||||
|
- **field-model** (ADR-030) — `ruvsense/field_model.rs`, SVD room eigenstructure persisted to RVF (Cognitum Seed); residual = perturbation.
|
||||||
|
- **intention** — `ruvsense/intention.rs`, 200–500 ms pre-movement lead signals.
|
||||||
|
- **adversarial** — `ruvsense/adversarial.rs`, physically-impossible-signal + multi-link consistency checks.
|
||||||
|
- **security** (ADR-032) — mesh hardening: adversarial gate + coherence quarantine + Ed25519 witness chain; run a security review (`docs/security-audit-wasm-edge-vendor.md`), see `/ruview-verify`.
|
||||||
|
3. Validate: `cd v2 && cargo test -p wifi-densepose-signal --no-default-features && cargo test -p wifi-densepose-ruvector --no-default-features`, then `python archive/v1/data/proof/verify.py`.
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
description: Run a RuView sensing application — presence, vitals, pose, sleep, environment mapping, MAT, point cloud, or a novel RF app.
|
||||||
|
argument-hint: "[presence|vitals|pose|sleep|environment|mat|pointcloud|<name>]"
|
||||||
|
---
|
||||||
|
|
||||||
|
# /ruview-app
|
||||||
|
|
||||||
|
Launch a RuView application.
|
||||||
|
|
||||||
|
1. Invoke the **`ruview-applications`** skill.
|
||||||
|
2. Map `$ARGUMENTS` to an application; if empty, show the catalogue and ask. Quick mappings:
|
||||||
|
- `presence` / `vitals` / `pose` / `environment` → `cd v2 && cargo run -p wifi-densepose-sensing-server` (live ESP32 sink) or the Docker demo for simulated CSI; for environment also `--build-index env`.
|
||||||
|
- `sleep` → `examples/sleep/` + `node scripts/apnea-detector.js`.
|
||||||
|
- `mat` (Mass Casualty Assessment) → `wifi-densepose-mat` crate, `docs/wifi-mat-user-guide.md`.
|
||||||
|
- `pointcloud` → `python scripts/mmwave_fusion_bridge.py` (camera depth + CSI + mmWave).
|
||||||
|
- novel RF → `scripts/passive-radar.js`, `material-classifier.js`, `device-fingerprint.js`, `mincut-person-counter.js`.
|
||||||
|
3. If no hardware: fall back to `docker run -p 3000:3000 ruvnet/wifi-densepose:latest` or `python examples/ruview_live.py`.
|
||||||
|
4. Help pick the right modality (through-wall → presence/activity; stationary subject → vitals/sleep; need skeletons → pose, train it for accuracy; search & rescue → MAT; best accuracy → 2+ nodes + cross-viewpoint fusion via `/ruview-advanced`).
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
description: Build and flash RuView ESP32 firmware (8MB or 4MB), then confirm the CSI stream.
|
||||||
|
argument-hint: "[8mb|4mb] [COM port]"
|
||||||
|
---
|
||||||
|
|
||||||
|
# /ruview-flash
|
||||||
|
|
||||||
|
Build + flash RuView firmware to an ESP32-S3 sensing node.
|
||||||
|
|
||||||
|
1. Invoke the **`ruview-hardware-setup`** skill.
|
||||||
|
2. Determine variant from `$ARGUMENTS` (default `8mb`). For `4mb`: `cp firmware/esp32-csi-node/sdkconfig.defaults.4mb firmware/esp32-csi-node/sdkconfig.defaults` first. For `8mb`: ensure it's built from `sdkconfig.defaults.template` (no mock).
|
||||||
|
3. Build using the **Python-subprocess** command from `CLAUDE.local.md` (ESP-IDF v5.4 does NOT work under Git Bash — strip `MSYSTEM*` env vars). Never use `cmd.exe /C` from bash.
|
||||||
|
4. Flash: same subprocess, `[python, idf_py, '-p', '<COM port>', 'flash']` (default port **COM8**), or `python -m esptool ... write_flash ...` with the four binaries.
|
||||||
|
5. Confirm: serial monitor via pyserial (not `idf.py monitor`), then `cd v2 && cargo run -p wifi-densepose-sensing-server` to see frames arrive.
|
||||||
|
6. If no frames: re-run `/ruview-provision`, check channel matches the AP, drop any `--filter-mac`.
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
description: Provision WiFi credentials, sink IP, and optional channel / MAC-filter overrides onto a RuView ESP32 node.
|
||||||
|
argument-hint: "--port COM8 --ssid ... --password ... --target-ip ... [--channel N] [--filter-mac AA:BB:..]"
|
||||||
|
---
|
||||||
|
|
||||||
|
# /ruview-provision
|
||||||
|
|
||||||
|
Write NVS config to an ESP32 sensing node.
|
||||||
|
|
||||||
|
1. Invoke the **`ruview-configure`** skill (§"Runtime device config" — has the full `provision.py` flag table).
|
||||||
|
2. Run `python firmware/esp32-csi-node/provision.py --help` for the authoritative options (on Windows: `PYTHONUTF8=1 PYTHONIOENCODING=utf-8 python …` — the help text has non-ASCII). Collect any missing params (port — default **COM8**, SSID, password, target sink IP, `--target-port` default 5005, `--node-id`).
|
||||||
|
3. Run:
|
||||||
|
```bash
|
||||||
|
python firmware/esp32-csi-node/provision.py --port <PORT> \
|
||||||
|
--ssid "<SSID>" --password "<PW>" --target-ip <IP> --target-port 5005 --node-id <0-255> \
|
||||||
|
[--channel <N>] [--filter-mac <MAC>] [--hop-channels 1,6,11 --hop-dwell 200] \
|
||||||
|
[--tdm-slot <i> --tdm-total <n>] [--edge-tier {0|1|2}] [--pres-thresh 50] [--fall-thresh 15000] \
|
||||||
|
[--vital-win 300] [--vital-int 1000] [--subk-count 32] \
|
||||||
|
[--seed-url http://… --seed-token … --zone lobby] [--swarm-hb 30] [--swarm-ingest 5] [--dry-run]
|
||||||
|
```
|
||||||
|
4. Explain trade-offs: `--channel` pins the node (AP's channel) vs. `--hop-channels` for ADR-061 multi-freq hopping; `--filter-mac` restricts to one transmitter vs. omit for all (more data, more noise); `--edge-tier` 0/1/2 = off/stats/vitals; `--tdm-slot`/`--tdm-total` slot a multi-node mesh.
|
||||||
|
5. ⚠️ **Issue #391**: flashing rewrites the *entire* `csi_cfg` NVS namespace — every key not on the CLI is erased. Pass the full set you want; warn the user before re-provisioning a working node. `--force-partial` bypasses the WiFi-creds requirement (knowingly). `--dry-run` builds the NVS binary without flashing.
|
||||||
|
6. Fleet provisioning: `scripts/generate_nvs_matrix.py` (subprocess-first).
|
||||||
|
7. Verify: serial monitor (pyserial on the port, 115200) should show `adaptive_ctrl` ticks + `csi_collector: CSI cb #… len=128 …` lines; the sink (`cd v2 && cargo run -p wifi-densepose-sensing-server`) should report incoming UDP frames if `--target-ip` points at this host.
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
description: Get started with RuView — pick the fastest path (Docker demo, repo build, or live ESP32) and walk through it.
|
||||||
|
argument-hint: "[docker|build|hardware]"
|
||||||
|
---
|
||||||
|
|
||||||
|
# /ruview-start
|
||||||
|
|
||||||
|
Onboard the user onto RuView (WiFi-DensePose).
|
||||||
|
|
||||||
|
1. Invoke the **`ruview-quickstart`** skill.
|
||||||
|
2. If `$ARGUMENTS` names a tier (`docker`, `build`, `hardware`), go straight to it; otherwise ask which hardware they have:
|
||||||
|
- **No hardware** → Tier 0: `docker run -p 3000:3000 ruvnet/wifi-densepose:latest`, open `http://localhost:3000`.
|
||||||
|
- **Want to build from source** → Tier 1: `cd v2 && cargo test --workspace --no-default-features`, then `python archive/v1/data/proof/verify.py`.
|
||||||
|
- **Have an ESP32-S3 / C6** → Tier 2: hand off to `/ruview-flash` then `/ruview-provision`, then `cargo run -p wifi-densepose-sensing-server`.
|
||||||
|
3. Warn about the gotchas: ESP32-C3 / original ESP32 unsupported; single node = limited spatial resolution; camera-free pose is modest (use camera-supervised for 92.9% PCK@20).
|
||||||
|
4. Point to next steps: `/ruview-app`, `/ruview-train`, `/ruview-advanced`, `/ruview-verify`, and the `ruview-configure` skill.
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
description: Train a RuView model — camera-free WiFlow pose, camera-supervised pose (92.9% PCK@20), RuVector embeddings, domain generalization, local SNN, with optional GPU on GCloud.
|
||||||
|
argument-hint: "[camera-free|camera-supervised|embeddings|domain-gen|snn|gpu] [--epochs N]"
|
||||||
|
---
|
||||||
|
|
||||||
|
# /ruview-train
|
||||||
|
|
||||||
|
Train, fine-tune, evaluate, or publish a RuView model.
|
||||||
|
|
||||||
|
1. Invoke the **`ruview-model-training`** skill.
|
||||||
|
2. Pick the track from `$ARGUMENTS`; if empty, ask which:
|
||||||
|
- **camera-free** (Track A) — `cargo run -p wifi-densepose-sensing-server -- --pretrain --dataset data/csi/ --pretrain-epochs 50` then `-- --train --dataset data/mmfi/ --epochs 100 --save-rvf model.rvf`. ~84 s on M4 Pro, modest accuracy.
|
||||||
|
- **camera-supervised** (Track B, ADR-079) — `python scripts/collect-ground-truth.py`, `python scripts/collect-training-data.py`, `node scripts/align-ground-truth.js`, then train on `data/paired/`, eval with `node scripts/eval-wiflow.js`. ~19 min, 92.9% PCK@20. Needs `data/pose_landmarker_lite.task`.
|
||||||
|
- **embeddings** (Track C, AETHER ADR-024) — `wifi-densepose-train` + `wifi-densepose-ruvector`; `-- --model model.rvf --embed`, `-- --build-index env`.
|
||||||
|
- **domain-gen** (Track D, MERIDIAN ADR-027) / **snn** (Track E) — `node scripts/snn-csi-processor.js --port 5006`; cognitum-seed-pretraining tutorial.
|
||||||
|
- **gpu** — `gcloud config set project cognitum-20260110`; `bash scripts/gcloud-train.sh --gpu l4 --hours 2` (or `--gpu a100 --sweep`, `--dry-run` to smoke-test). VM auto-deletes unless `--keep-vm`.
|
||||||
|
3. After training: `cd v2 && cargo test --workspace --no-default-features`, `python archive/v1/data/proof/verify.py`. To publish: `python scripts/publish-huggingface.py`.
|
||||||
|
4. Hand off to `/ruview-verify` for the witness bundle.
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
description: Verify a RuView build — Rust tests, deterministic Python proof, firmware hashes, ADR-028 witness bundle + self-verification, and the pre-merge checklist.
|
||||||
|
argument-hint: "[tests|proof|bundle|all]"
|
||||||
|
---
|
||||||
|
|
||||||
|
# /ruview-verify
|
||||||
|
|
||||||
|
Run RuView's trust pipeline.
|
||||||
|
|
||||||
|
1. Invoke the **`ruview-verify`** skill.
|
||||||
|
2. Based on `$ARGUMENTS` (default `all`):
|
||||||
|
- **tests** — `cd v2 && cargo test --workspace --no-default-features` (1,400+ pass, 0 fail).
|
||||||
|
- **proof** — `python archive/v1/data/proof/verify.py` (must print `VERDICT: PASS`; if hash drift from a legit numpy/scipy bump, `--generate-hash` then re-run). Optionally `cd archive/v1 && python -m pytest tests/ -x -q`.
|
||||||
|
- **bundle** — `bash scripts/generate-witness-bundle.sh`, then `cd dist/witness-bundle-ADR028-*/ && bash VERIFY.sh` (must be 7/7 PASS).
|
||||||
|
- **all** — do all of the above in order.
|
||||||
|
3. If this follows a code change, walk the **pre-merge checklist** from `CLAUDE.md` (README/CLAUDE.md/CHANGELOG/user-guide updates, ADR count, witness bundle regen, Docker rebuild only if needed, crate publishing in dependency order, `.gitignore`, security review for hardware/network modules).
|
||||||
|
4. For security-related changes also run `npx @claude-flow/cli@latest security scan`.
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
# ADR-0001 — ruview plugin contract
|
||||||
|
|
||||||
|
- **Status:** Proposed
|
||||||
|
- **Date:** 2026-05-11
|
||||||
|
- **Scope:** `plugins/ruview` (and the enclosing `plugins/.claude-plugin/marketplace.json`)
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
RuView (WiFi-DensePose) is a large dual-codebase project (Rust `v2/`, Python `archive/v1/`, ESP32 firmware, 96 ADRs). Newcomers and operators repeatedly re-derive the same workflows: spin up the Docker demo, flash and provision an ESP32, run a sensing application, train a pose model, run the witness verification. We want those workflows packaged as a single discoverable Claude Code plugin (and mirrored for Codex), spanning practical → advanced.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
1. **One mega-plugin, marketplace-listed.** A single plugin `ruview` under `plugins/ruview/`, listed by `plugins/.claude-plugin/marketplace.json` (marketplace name `ruview`). No sub-plugins; the breadth is organized by skill instead.
|
||||||
|
|
||||||
|
2. **Directory contract.**
|
||||||
|
```
|
||||||
|
plugins/.claude-plugin/marketplace.json
|
||||||
|
plugins/ruview/.claude-plugin/plugin.json # name, description, version, author, homepage, license, keywords — NO skills/commands/agents arrays
|
||||||
|
plugins/ruview/skills/<name>/SKILL.md # frontmatter: name, description, allowed-tools
|
||||||
|
plugins/ruview/commands/<name>.md # frontmatter: description (+ argument-hint)
|
||||||
|
plugins/ruview/agents/<name>.md # frontmatter: name, description, model
|
||||||
|
plugins/ruview/docs/adrs/0001-ruview-plugin-contract.md
|
||||||
|
plugins/ruview/scripts/smoke.sh # structural contract
|
||||||
|
plugins/ruview/codex/AGENTS.md + codex/prompts/*.md # Codex mirror
|
||||||
|
plugins/ruview/README.md # Compatibility + Namespace coordination + Verification + ADR sections
|
||||||
|
```
|
||||||
|
Skills/commands/agents are **auto-discovered** from the directory tree — they are deliberately *not* enumerated in `plugin.json`.
|
||||||
|
|
||||||
|
3. **Shell-first skills.** Skills drive RuView's own tooling — `cargo`, `python`, `idf.py` (via the Windows Python-subprocess pattern in `CLAUDE.local.md`), `docker`, `node` scripts. `allowed-tools` is limited to core tools (`Bash Read Write Edit Glob Grep`); **no `mcp__claude-flow__*` dependency** and **no wildcard tools**. The only external CLI referenced is `npx @claude-flow/cli@latest security scan`, and only as an optional step for security changes.
|
||||||
|
|
||||||
|
4. **Namespace.** The plugin claims the `ruview-*` namespace for skills (`ruview-quickstart`, `ruview-hardware-setup`, `ruview-configure`, `ruview-applications`, `ruview-model-training`, `ruview-advanced-sensing`, `ruview-verify`), commands (`/ruview-*`), and agents (`ruview-*`). It writes to no `claude-flow` memory namespace. Coexists with the `ruflo` marketplace with zero overlap (`ruview-*` vs. `ruflo-*`); if both are present, defer to `ruflo-agentdb` ADR-0001 §"Namespace convention".
|
||||||
|
|
||||||
|
5. **Codex mirror — full command parity.** Every `/ruview-*` command (`ruview-start`, `ruview-flash`, `ruview-provision`, `ruview-app`, `ruview-train`, `ruview-advanced`, `ruview-verify`) has a matching `codex/prompts/<name>.md`; `codex/AGENTS.md` carries the project rules and `codex/README.md` documents installation. The mirror covers the operator-facing **commands** in full; the additional **skills** (`ruview-quickstart`, `ruview-hardware-setup`, `ruview-configure`, `ruview-applications`, `ruview-model-training`, `ruview-advanced-sensing`, `ruview-cli-api`, `ruview-mmwave`, `ruview-verify`) and **agents** have no Codex equivalent — their knowledge is folded into `AGENTS.md` and the prompt files. The smoke script enforces command↔prompt parity.
|
||||||
|
|
||||||
|
6. **Compatibility surface.** Targets the `ruvnet/RuView` / `wifi-densepose` repo layout (`v2/crates/`, `firmware/esp32-csi-node/`, `archive/v1/`, `scripts/`, `docs/adr/`). Hardware docs default to ESP32 on `COM8` and tell the reader to confirm the port.
|
||||||
|
|
||||||
|
7. **Smoke contract** (`scripts/smoke.sh`, ≥12 checks): marketplace.json valid + lists `ruview`; plugin.json has `name`/`description`/`version`/`keywords` and does **not** contain `skills`/`commands`/`agents` arrays; every `skills/*/SKILL.md` has `name` + `description` + `allowed-tools`; no wildcard (`*`) in any `allowed-tools`; the expected skill set is present; every `commands/*.md` has a `description`; every `agents/*.md` has `name` + `description` + `model`; README contains a `## Compatibility` section and a `Namespace coordination` block; this ADR exists with `Status: Proposed`; `codex/AGENTS.md` and `codex/prompts/*.md` exist **and** every `commands/<name>.md` has a matching `codex/prompts/<name>.md` (command↔prompt parity); nothing is misplaced under `.claude-plugin/`.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- **Good:** one `claude --plugin-dir ./plugins/ruview` gives newcomers and operators the whole RuView workflow surface; no MCP-server prerequisite; Codex users get the same operator commands; the smoke script makes drift visible.
|
||||||
|
- **Cost:** a mega-plugin means coarser install granularity (you get all 9 skills or none); the Codex mirror must be kept in sync by hand (the smoke script checks command↔prompt *presence* parity, not content parity); a skill stem (`ruview-verify`) collides with a command stem — tolerated by Claude Code (both resolve), but `claude plugin details` lists it twice.
|
||||||
|
- **Follow-ups:** if the skill set grows past comfortable browsing (it's at 9), revisit the "one mega-plugin" decision and split by lifecycle (`ruview-edge`, `ruview-train`, …); add a *content*-parity lint between commands and Codex prompts; consider renaming `/ruview-verify` to drop the skill/command stem collision; consider pinning a tested `claude-flow` CLI minor for the security-scan step if that step becomes load-bearing; verify the underlying RuView command flags (`sensing-server --help`, `gcloud-train.sh`, `provision.py`) against the live tree rather than from README/scripts.
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Structural smoke test for the `ruview` Claude Code plugin.
|
||||||
|
# Run from anywhere: bash plugins/ruview/scripts/smoke.sh
|
||||||
|
set -u
|
||||||
|
|
||||||
|
# Resolve plugin root (this file lives in <root>/scripts/smoke.sh)
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
MARKET="$(cd "$ROOT/.." && pwd)/.claude-plugin/marketplace.json"
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
ok() { echo " PASS $1"; PASS=$((PASS+1)); }
|
||||||
|
bad() { echo " FAIL $1"; FAIL=$((FAIL+1)); }
|
||||||
|
has() { grep -q "$1" "$2" 2>/dev/null; }
|
||||||
|
|
||||||
|
echo "ruview plugin smoke test"
|
||||||
|
echo "root: $ROOT"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 1. marketplace.json exists and lists the ruview plugin
|
||||||
|
if [ -f "$MARKET" ] && has '"ruview"' "$MARKET"; then ok "marketplace.json present and lists 'ruview'"; else bad "marketplace.json missing or does not list 'ruview' ($MARKET)"; fi
|
||||||
|
|
||||||
|
# 2. plugin.json exists with required fields
|
||||||
|
PJ="$ROOT/.claude-plugin/plugin.json"
|
||||||
|
if [ -f "$PJ" ] && has '"name"' "$PJ" && has '"description"' "$PJ" && has '"version"' "$PJ"; then ok "plugin.json has name/description/version"; else bad "plugin.json missing or incomplete"; fi
|
||||||
|
|
||||||
|
# 3. plugin.json has keywords
|
||||||
|
if has '"keywords"' "$PJ"; then ok "plugin.json has keywords"; else bad "plugin.json missing keywords"; fi
|
||||||
|
|
||||||
|
# 4. plugin.json does NOT enumerate skills/commands/agents (auto-discovered)
|
||||||
|
if has '"skills"' "$PJ" || has '"commands"' "$PJ" || has '"agents"' "$PJ"; then bad "plugin.json must NOT contain skills/commands/agents arrays"; else ok "plugin.json does not enumerate skills/commands/agents"; fi
|
||||||
|
|
||||||
|
# 5. every skill has SKILL.md with name + description + allowed-tools, and no wildcard tools
|
||||||
|
SKILL_OK=1
|
||||||
|
for d in "$ROOT"/skills/*/; do
|
||||||
|
[ -d "$d" ] || continue
|
||||||
|
f="$d/SKILL.md"
|
||||||
|
if [ ! -f "$f" ]; then bad "missing $f"; SKILL_OK=0; continue; fi
|
||||||
|
has '^name:' "$f" || { bad "$f missing 'name:'"; SKILL_OK=0; }
|
||||||
|
has '^description:' "$f" || { bad "$f missing 'description:'"; SKILL_OK=0; }
|
||||||
|
has '^allowed-tools:' "$f" || { bad "$f missing 'allowed-tools:'"; SKILL_OK=0; }
|
||||||
|
if grep -E '^allowed-tools:.*(\*|\ball tools\b)' "$f" >/dev/null 2>&1; then bad "$f uses wildcard tools"; SKILL_OK=0; fi
|
||||||
|
done
|
||||||
|
[ "$SKILL_OK" = 1 ] && ok "all skills have valid frontmatter, no wildcard tools"
|
||||||
|
|
||||||
|
# 6. expected skills present
|
||||||
|
EXPECTED_SKILLS="ruview-quickstart ruview-hardware-setup ruview-configure ruview-applications ruview-model-training ruview-advanced-sensing ruview-cli-api ruview-mmwave ruview-verify"
|
||||||
|
SKILLS_PRESENT=1
|
||||||
|
for s in $EXPECTED_SKILLS; do
|
||||||
|
[ -f "$ROOT/skills/$s/SKILL.md" ] || { bad "expected skill missing: $s"; SKILLS_PRESENT=0; }
|
||||||
|
done
|
||||||
|
[ "$SKILLS_PRESENT" = 1 ] && ok "expected skill set present ($(echo $EXPECTED_SKILLS | wc -w) skills)"
|
||||||
|
|
||||||
|
# 7. every command has a description in frontmatter
|
||||||
|
CMD_OK=1
|
||||||
|
for f in "$ROOT"/commands/*.md; do
|
||||||
|
[ -f "$f" ] || { bad "no command files found"; CMD_OK=0; break; }
|
||||||
|
has '^description:' "$f" || { bad "$f missing 'description:'"; CMD_OK=0; }
|
||||||
|
done
|
||||||
|
[ "$CMD_OK" = 1 ] && ok "all commands have a description"
|
||||||
|
|
||||||
|
# 8. every agent has name + description + model
|
||||||
|
AG_OK=1
|
||||||
|
for f in "$ROOT"/agents/*.md; do
|
||||||
|
[ -f "$f" ] || { bad "no agent files found"; AG_OK=0; break; }
|
||||||
|
has '^name:' "$f" || { bad "$f missing 'name:'"; AG_OK=0; }
|
||||||
|
has '^description:' "$f" || { bad "$f missing 'description:'"; AG_OK=0; }
|
||||||
|
has '^model:' "$f" || { bad "$f missing 'model:'"; AG_OK=0; }
|
||||||
|
done
|
||||||
|
[ "$AG_OK" = 1 ] && ok "all agents have name/description/model"
|
||||||
|
|
||||||
|
# 9. README has Compatibility + Namespace coordination
|
||||||
|
RM="$ROOT/README.md"
|
||||||
|
if has '## Compatibility' "$RM" && has 'Namespace coordination' "$RM"; then ok "README has Compatibility + Namespace coordination"; else bad "README missing Compatibility or Namespace coordination section"; fi
|
||||||
|
|
||||||
|
# 10. ADR-0001 exists with Status: Proposed
|
||||||
|
ADR="$ROOT/docs/adrs/0001-ruview-plugin-contract.md"
|
||||||
|
if [ -f "$ADR" ] && grep -qi 'Status:.*Proposed' "$ADR"; then ok "ADR-0001 present with Status: Proposed"; else bad "ADR-0001 missing or not 'Proposed'"; fi
|
||||||
|
|
||||||
|
# 11. Codex mirror present
|
||||||
|
if [ -f "$ROOT/codex/AGENTS.md" ] && ls "$ROOT"/codex/prompts/*.md >/dev/null 2>&1; then ok "Codex mirror present (AGENTS.md + prompts/)"; else bad "Codex mirror missing"; fi
|
||||||
|
|
||||||
|
# 11b. command <-> Codex prompt parity
|
||||||
|
PARITY=1
|
||||||
|
for f in "$ROOT"/commands/*.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
base="$(basename "$f")"
|
||||||
|
[ -f "$ROOT/codex/prompts/$base" ] || { bad "no Codex prompt for command $base"; PARITY=0; }
|
||||||
|
done
|
||||||
|
[ "$PARITY" = 1 ] && ok "every command has a matching Codex prompt"
|
||||||
|
|
||||||
|
# 12. no skills/commands/agents accidentally placed inside .claude-plugin/
|
||||||
|
if ls "$ROOT"/.claude-plugin/skills "$ROOT"/.claude-plugin/commands "$ROOT"/.claude-plugin/agents >/dev/null 2>&1; then bad "skills/commands/agents must not live under .claude-plugin/"; else ok ".claude-plugin/ contains only plugin.json"; fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "----------------------------------------"
|
||||||
|
echo "PASS: $PASS FAIL: $FAIL"
|
||||||
|
[ "$FAIL" -eq 0 ] || exit 1
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
---
|
||||||
|
name: ruview-advanced-sensing
|
||||||
|
description: Advanced RuView capabilities — RuvSense multistatic sensing (attention-weighted fusion, geometric diversity, persistent field model), cross-viewpoint fusion across multiple nodes, RF tomography (ISTA L1 solver, voxel grids), longitudinal biomechanics drift, pre-movement intention signals, adversarial signal detection, and multistatic mesh security hardening. Use for research-grade or multi-node deployments.
|
||||||
|
allowed-tools: Bash Read Write Edit Glob Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Advanced Sensing
|
||||||
|
|
||||||
|
The deep end: multistatic mesh, tomography, persistent field models, and the security model that protects them. Most of this lives in `wifi-densepose-signal/src/ruvsense/` (14 modules) and `wifi-densepose-ruvector/src/viewpoint/` (5 modules).
|
||||||
|
|
||||||
|
## RuvSense multistatic mode (ADR-029)
|
||||||
|
|
||||||
|
Treat every WiFi link in range — including neighbours' APs — as a bistatic radar pair, then fuse them.
|
||||||
|
|
||||||
|
| Module (`signal/src/ruvsense/`) | Purpose |
|
||||||
|
|--------------------------------|---------|
|
||||||
|
| `multiband.rs` | Multi-band CSI frame fusion, cross-channel coherence |
|
||||||
|
| `phase_align.rs` | Iterative LO phase-offset estimation, circular mean |
|
||||||
|
| `multistatic.rs` | Attention-weighted fusion, geometric diversity |
|
||||||
|
| `coherence.rs` / `coherence_gate.rs` | Z-score coherence scoring; Accept / PredictOnly / Reject / Recalibrate gate decisions |
|
||||||
|
| `pose_tracker.rs` | 17-keypoint Kalman tracker with AETHER re-ID embeddings |
|
||||||
|
| `field_model.rs` | SVD room eigenstructure, perturbation extraction |
|
||||||
|
| `tomography.rs` | RF tomography, ISTA L1 solver, voxel grid |
|
||||||
|
| `longitudinal.rs` | Welford stats, biomechanics drift detection |
|
||||||
|
| `intention.rs` | Pre-movement lead signals (200–500 ms ahead) |
|
||||||
|
| `cross_room.rs` | Environment fingerprinting, transition graph |
|
||||||
|
| `gesture.rs` | DTW template-matching gesture classifier |
|
||||||
|
| `adversarial.rs` | Physically-impossible-signal detection, multi-link consistency |
|
||||||
|
|
||||||
|
## Cross-viewpoint fusion (ADR-016 viewpoint module)
|
||||||
|
|
||||||
|
Combine 2+ nodes geometrically — more nodes, more independent looks, tighter localization.
|
||||||
|
|
||||||
|
| Module (`ruvector/src/viewpoint/`) | Purpose |
|
||||||
|
|------------------------------------|---------|
|
||||||
|
| `attention.rs` | CrossViewpointAttention, GeometricBias, softmax with `G_bias` |
|
||||||
|
| `geometry.rs` | GeometricDiversityIndex, Cramér–Rao bounds, Fisher Information |
|
||||||
|
| `coherence.rs` | Phase-phasor coherence, hysteresis gate |
|
||||||
|
| `fusion.rs` | MultistaticArray aggregate root, domain events |
|
||||||
|
|
||||||
|
Host-side helpers to explore the geometry before deploying: `node scripts/mesh-graph-transformer.js`, `node scripts/passive-radar.js`, `node scripts/deep-scan.js`.
|
||||||
|
|
||||||
|
## Persistent field model (ADR-030)
|
||||||
|
|
||||||
|
`field_model.rs` builds an SVD eigenstructure of the room and stores it (RVF, ideally on a Cognitum Seed). New CSI frames are projected against it; the residual *is* the perturbation. Lets you ask "what's different from the empty-room baseline?" and survive restarts.
|
||||||
|
|
||||||
|
## RF tomography
|
||||||
|
|
||||||
|
`tomography.rs` reconstructs a voxel occupancy grid from the multistatic link set via an ISTA L1 solver (sparse — most voxels are empty). Use with cross-viewpoint geometry for through-wall volumetric imaging. RuVector solver crates back the sparse interpolation (114→56 subcarriers).
|
||||||
|
|
||||||
|
## Sensing-first RF mode & adaptive mesh kernel
|
||||||
|
|
||||||
|
- ADR-031 (RuView sensing-first RF mode), ADR-081 (adaptive CSI mesh firmware kernel), ADR-083 (per-cluster π compute hop), ADR-095/096 (on-ESP32 temporal modeling with sparse GQA attention — runs the temporal head on-device).
|
||||||
|
|
||||||
|
## Security (ADR-032 — multistatic mesh hardening)
|
||||||
|
|
||||||
|
Using neighbours' APs as illuminators and pooling links across a mesh expands the attack surface. Mitigations:
|
||||||
|
- `adversarial.rs` rejects physically impossible signals and cross-checks multi-link consistency.
|
||||||
|
- `coherence_gate.rs` quarantines low-coherence / suspicious links (Reject / Recalibrate).
|
||||||
|
- Ed25519 witness chain (ADR-028) attests every measurement.
|
||||||
|
- Run a security review when touching anything on the hardware/network boundary (see `ruview-verify` and `docs/security-audit-wasm-edge-vendor.md`).
|
||||||
|
|
||||||
|
## Validate advanced changes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd v2 && cargo test --workspace --no-default-features # incl. ruvsense + viewpoint tests
|
||||||
|
cargo test -p wifi-densepose-signal --no-default-features
|
||||||
|
cargo test -p wifi-densepose-ruvector --no-default-features
|
||||||
|
cd .. && python archive/v1/data/proof/verify.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- ADRs: 014 (SOTA signal processing), 029 (multistatic mode), 030 (persistent field model), 031 (sensing-first RF), 032 (mesh security hardening), 081/083/095/096
|
||||||
|
- `v2/crates/wifi-densepose-signal/src/ruvsense/` · `v2/crates/wifi-densepose-ruvector/src/viewpoint/`
|
||||||
|
- `docs/research/`, `docs/security-audit-wasm-edge-vendor.md`
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
---
|
||||||
|
name: ruview-applications
|
||||||
|
description: Run RuView sensing applications — presence/occupancy, breathing & heart rate, activity & fall detection, 17-keypoint pose estimation (WiFlow), sleep monitoring & apnea screening, environment mapping, Mass Casualty Assessment (MAT), and the 3D point-cloud fusion demo. Use when someone wants to actually *do* something with a working RuView setup.
|
||||||
|
allowed-tools: Bash Read Write Edit Glob Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Applications
|
||||||
|
|
||||||
|
What RuView can sense, and how to run each one. Assumes you have either the Docker demo (simulated CSI) or a live ESP32 sink (see `ruview-quickstart` / `ruview-hardware-setup`).
|
||||||
|
|
||||||
|
## Application catalogue
|
||||||
|
|
||||||
|
| Application | What it does | Entry point |
|
||||||
|
|-------------|--------------|-------------|
|
||||||
|
| **Presence / occupancy** | Detect people through walls, count them, track entries/exits (trained model + PIR fusion, ~0.012 ms latency) | sensing-server live mode; `examples/environment/` |
|
||||||
|
| **Vital signs** | Breathing 6–30 BPM (bandpass 0.1–0.5 Hz), heart rate 40–120 BPM (bandpass 0.8–2.0 Hz), contactless while sleeping/sitting | `wifi-densepose-vitals` crate (ADR-021); `examples/medical/` |
|
||||||
|
| **Activity recognition** | Walking, sitting, gestures, falls — from temporal CSI patterns | RuvSense `gesture.rs` (DTW), `pose_tracker.rs`; `scripts/gait-analyzer.js` |
|
||||||
|
| **Pose estimation** | 17 COCO keypoints via WiFlow architecture; dual-modal webcam+WiFi fusion demo | `cargo run -p wifi-densepose-sensing-server` + pose-fusion demo (ADR-059); see `ruview-model-training` to train |
|
||||||
|
| **Sleep monitoring** | Overnight monitoring, sleep-stage classification, apnea screening | `examples/sleep/`; `scripts/apnea-detector.js` |
|
||||||
|
| **Environment mapping** | RF fingerprinting identifies rooms, detects moved furniture, spots new objects | sensing-server `--build-index env`; RuvSense `field_model.rs`, `cross_room.rs` |
|
||||||
|
| **Mass Casualty Assessment (MAT)** | Disaster survivor detection — find people in rubble/smoke | `wifi-densepose-mat` crate; `docs/wifi-mat-user-guide.md`; `examples/medical/` |
|
||||||
|
| **3D point cloud** *(optional fusion)* | Camera depth (MiDaS) + WiFi CSI + mmWave radar → unified spatial model (~22 ms, 19K+ pts/frame) | `scripts/mmwave_fusion_bridge.py`; ADR-094 (GitHub Pages deploy) |
|
||||||
|
| **Novel RF apps** | Passive radar, material classification, device fingerprinting, mincut person-counting | `scripts/passive-radar.js`, `material-classifier.js`, `device-fingerprint.js`, `mincut-person-counter.js` (ADR-077/078) |
|
||||||
|
|
||||||
|
## Quick recipes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Docker demo — everything, simulated CSI
|
||||||
|
docker run -p 3000:3000 ruvnet/wifi-densepose:latest # http://localhost:3000
|
||||||
|
|
||||||
|
# Live sensing server (consumes ESP32 UDP CSI)
|
||||||
|
cd v2 && cargo run -p wifi-densepose-sensing-server
|
||||||
|
|
||||||
|
# Live RF room scan (Cognitum Seed on :5006)
|
||||||
|
node scripts/rf-scan.js --port 5006
|
||||||
|
node scripts/snn-csi-processor.js --port 5006
|
||||||
|
|
||||||
|
# Embed a trained model + build an environment index
|
||||||
|
cd v2
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --embed
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --build-index env
|
||||||
|
|
||||||
|
# Python live demo
|
||||||
|
python examples/ruview_live.py
|
||||||
|
|
||||||
|
# Spectrogram / graph visualisers
|
||||||
|
node scripts/csi-spectrogram.js
|
||||||
|
node scripts/csi-graph-visualizer.js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Picking the right modality
|
||||||
|
|
||||||
|
- **Through a wall, no line of sight** → presence + activity; expect ≤5 m depth (Fresnel-zone geometry).
|
||||||
|
- **Person stationary (sleeping / sitting)** → vitals (breathing first, heart rate needs cleaner signal) + sleep staging.
|
||||||
|
- **Need skeletons** → pose (WiFlow). Camera-free works but is modest; camera-supervised gets 92.9% PCK@20 — train it (`ruview-model-training`).
|
||||||
|
- **Search & rescue** → MAT (`docs/wifi-mat-user-guide.md`).
|
||||||
|
- **"What changed in this room?"** → environment mapping / RF fingerprint index.
|
||||||
|
- **Best spatial accuracy** → 2+ ESP32 nodes + cross-viewpoint fusion (`ruview-advanced-sensing`), optionally + Cognitum Seed.
|
||||||
|
|
||||||
|
## Examples directory map
|
||||||
|
|
||||||
|
`examples/environment/` · `examples/medical/` · `examples/sleep/` · `examples/stress/` · `examples/happiness-vector/` · `examples/ruview_live.py` — each has a README.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- `README.md` — feature matrix, latency/throughput numbers
|
||||||
|
- `docs/user-guide.md`, `docs/wifi-mat-user-guide.md`
|
||||||
|
- ADRs: 021 (vitals), 024 (AETHER contrastive embeddings), 027 (MERIDIAN domain generalization), 041 (edge modules), 059 (live ESP32 pipeline), 077/078 (novel RF apps), 082 (pose tracker output filter), 094 (point cloud)
|
||||||
|
- RuvSense modules: `v2/crates/wifi-densepose-signal/src/ruvsense/` (14 modules)
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
---
|
||||||
|
name: ruview-cli-api
|
||||||
|
description: Use the RuView `wifi-densepose` CLI binary (incl. MAT scan/status/zones/survivors/alerts/export subcommands), the REST API (`wifi-densepose-api`, Axum), and the browser/WASM build (`wifi-densepose-wasm`, `wifi-densepose-wasm-edge`). Use when integrating RuView into another program, scripting it from the shell, exposing it over HTTP, or shipping it to the browser / ESP32-WASM3.
|
||||||
|
allowed-tools: Bash Read Write Edit Glob Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView CLI, API & WASM
|
||||||
|
|
||||||
|
The programmatic surfaces of RuView — the `wifi-densepose` binary, the HTTP API, and the WebAssembly builds.
|
||||||
|
|
||||||
|
## 1. The `wifi-densepose` CLI binary (`wifi-densepose-cli`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd v2
|
||||||
|
cargo run -p wifi-densepose-cli -- --help # or: cargo build -p wifi-densepose-cli --release → target/release/wifi-densepose
|
||||||
|
cargo run -p wifi-densepose-cli -- version
|
||||||
|
```
|
||||||
|
|
||||||
|
Top-level subcommands: `version`, and `mat` (Mass Casualty Assessment Tool).
|
||||||
|
|
||||||
|
### `wifi-densepose mat …` — disaster survivor detection
|
||||||
|
|
||||||
|
| Subcommand | Purpose | Key flags |
|
||||||
|
|------------|---------|-----------|
|
||||||
|
| `mat scan [zone]` | Start scanning for survivors | `--disaster-type <…>`, `--sensitivity 0.0–1.0`, `--max-depth <m>`, `--continuous`, `--interval <ms>`, `--simulate` |
|
||||||
|
| `mat status` | Current scan status | `--detailed`, `--format <…>`, `--watch` |
|
||||||
|
| `mat zones …` | Manage scan zones | `zones list [--active-only]`, plus add/remove/update |
|
||||||
|
| `mat survivors` | List detected survivors with triage status | |
|
||||||
|
| `mat alerts` | View / manage alerts | |
|
||||||
|
| `mat export` | Export scan data | JSON or CSV |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```bash
|
||||||
|
cargo run -p wifi-densepose-cli -- mat scan rubble-A --disaster-type earthquake --sensitivity 0.7 --max-depth 5 --continuous --interval 2000
|
||||||
|
cargo run -p wifi-densepose-cli -- mat survivors --format json
|
||||||
|
cargo run -p wifi-densepose-cli -- mat export --format csv > survivors.csv
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `--simulate` for testing without hardware. Background and user guide: `docs/wifi-mat-user-guide.md`, `wifi-densepose-mat` crate.
|
||||||
|
|
||||||
|
## 2. REST API (`wifi-densepose-api`, Axum)
|
||||||
|
|
||||||
|
Library crate (`v2/crates/wifi-densepose-api/src/lib.rs`) — the Axum router/handlers; configured via the `wifi-densepose-config` crate. It's wired into the server binaries (e.g. the sensing server / Docker image), not a standalone `cargo run` target by itself.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Easiest way to exercise it: the Docker image exposes the API + dashboard on :3000
|
||||||
|
docker run -p 3000:3000 ruvnet/wifi-densepose:latest
|
||||||
|
# Then hit the HTTP endpoints (see the API module / docs for routes) and open http://localhost:3000
|
||||||
|
|
||||||
|
# v1 Python service config reference: example.env, pyproject.toml (archive/v1/)
|
||||||
|
```
|
||||||
|
|
||||||
|
When embedding the API crate in your own binary, take the router from `wifi_densepose_api`, supply config via `wifi-densepose-config`, and serve with Axum/Tokio. Keep input validation at the boundary (project rule).
|
||||||
|
|
||||||
|
## 3. WASM / browser & ESP32-WASM3
|
||||||
|
|
||||||
|
- **`wifi-densepose-wasm`** — compiles the stack to `wasm32-unknown-unknown` with a JS-friendly API:
|
||||||
|
```bash
|
||||||
|
cd v2/crates/wifi-densepose-wasm
|
||||||
|
wasm-pack build --target web --features mat # recommended (produces pkg/)
|
||||||
|
cargo build --target wasm32-unknown-unknown --features mat # plain cargo build
|
||||||
|
```
|
||||||
|
See `v2/crates/wifi-densepose-wasm/README.md` for the exported surface.
|
||||||
|
- **`wifi-densepose-wasm-edge`** — 60 edge modules (609 tests) that compile to `wasm32-unknown-unknown` and run on ESP32-S3 via WASM3; shared utils in `src/vendor_common.rs`. These are the ADR-041 edge-intelligence modules in WASM form.
|
||||||
|
- Browser demos: pose-fusion (ADR-059), point-cloud (ADR-094) — deployed via GitHub Pages from the WASM build.
|
||||||
|
|
||||||
|
## 4. Where it fits
|
||||||
|
|
||||||
|
| You want to… | Use |
|
||||||
|
|--------------|-----|
|
||||||
|
| Script a survivor scan / export results | `wifi-densepose mat …` |
|
||||||
|
| Expose sensing over HTTP | `wifi-densepose-api` (via a server binary / Docker) |
|
||||||
|
| Run sensing in a browser | `wifi-densepose-wasm` → `wasm-pack build --target web` |
|
||||||
|
| Run an edge module on an ESP32 in WASM | `wifi-densepose-wasm-edge` + WASM3 |
|
||||||
|
| A long-running CSI sink + training | `wifi-densepose-sensing-server` (see `ruview-applications` / `ruview-model-training`) |
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- Crates: `wifi-densepose-cli`, `wifi-densepose-api`, `wifi-densepose-config`, `wifi-densepose-wasm`, `wifi-densepose-wasm-edge`, `wifi-densepose-mat`
|
||||||
|
- ADRs: 041 (edge modules), 059 (live ESP32 pipeline), 094 (point-cloud GitHub Pages)
|
||||||
|
- `docs/wifi-mat-user-guide.md`, `docs/edge-modules/`, `docs/security-audit-wasm-edge-vendor.md`
|
||||||
|
- Validate after changes: `cd v2 && cargo test -p wifi-densepose-cli -p wifi-densepose-api -p wifi-densepose-wasm --no-default-features`
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
---
|
||||||
|
name: ruview-configure
|
||||||
|
description: Configure RuView — ESP32 sdkconfig variants, NVS provisioning, WiFi channel / MAC filter overrides (ADR-060), edge intelligence modules (ADR-041), sensing-server flags, multi-node mesh, and Cognitum Seed integration. Use when adjusting how a deployed RuView system behaves without changing code.
|
||||||
|
allowed-tools: Bash Read Write Edit Glob Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Configuration
|
||||||
|
|
||||||
|
Everything you can tune in a RuView deployment, from a one-line provision flag to a full mesh + Cognitum Seed setup.
|
||||||
|
|
||||||
|
## 1. Firmware build-time config (sdkconfig)
|
||||||
|
|
||||||
|
| Variant | File | When |
|
||||||
|
|---------|------|------|
|
||||||
|
| 8MB (default) | `firmware/esp32-csi-node/sdkconfig.defaults.template` | ESP32-S3 8MB, full feature set, real WiFi CSI |
|
||||||
|
| 4MB | `firmware/esp32-csi-node/sdkconfig.defaults.4mb` | ESP32-S3 SuperMini 4MB — display disabled, dual OTA slots (`partitions_4mb.csv`, ~1.856 MB each) |
|
||||||
|
| Heltec N16R2 | `firmware/esp32-csi-node/sdkconfig.defaults.heltec_n16r2` | Heltec boards |
|
||||||
|
|
||||||
|
Switch: `cp firmware/esp32-csi-node/sdkconfig.defaults.<variant> firmware/esp32-csi-node/sdkconfig.defaults`, then rebuild (see `ruview-hardware-setup`). **Never test in mock mode** — the Kconfig fall-threshold bug only showed up with real CSI.
|
||||||
|
|
||||||
|
## 2. Runtime device config (NVS via provision.py)
|
||||||
|
|
||||||
|
`provision.py` writes the `csi_cfg` NVS namespace over the serial port. **Run `python firmware/esp32-csi-node/provision.py --help` for the authoritative flag list** (on Windows force `PYTHONUTF8=1 PYTHONIOENCODING=utf-8` — the help text contains non-ASCII and crashes under cp1252).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python firmware/esp32-csi-node/provision.py --port COM8 \
|
||||||
|
--ssid "WiFi" --password "secret" \
|
||||||
|
--target-ip 192.168.1.20 --target-port 5005 \ # aggregator UDP sink (port default 5005)
|
||||||
|
--node-id 1 \ # 0-255
|
||||||
|
--channel 6 --filter-mac AA:BB:CC:DD:EE:FF # ADR-060: pin channel + filter transmitter
|
||||||
|
```
|
||||||
|
|
||||||
|
| Flag group | Flags | Notes |
|
||||||
|
|------------|-------|-------|
|
||||||
|
| WiFi / sink | `--ssid` `--password` `--target-ip` `--target-port` (5005) `--node-id` | `--node-id` 0-255 |
|
||||||
|
| TDM mesh | `--tdm-slot` `--tdm-total` | 0-based slot index + total node count — this is how multi-node mesh is slotted |
|
||||||
|
| Edge processing | `--edge-tier {0,1,2}` | 0=off, 1=stats, 2=vitals (ADR-041) |
|
||||||
|
| Detection thresholds | `--pres-thresh` (50) `--fall-thresh` (15000 → 15.0 rad/s²) | raise `--fall-thresh` to cut false falls in high-traffic areas (issue #263) |
|
||||||
|
| Vitals | `--vital-win` (300 frames) `--vital-int` (1000 ms) `--subk-count` (32, top-K subcarriers) | |
|
||||||
|
| Channel / hopping | `--channel` (1-14 / 36-177, overrides AP auto-detect) `--filter-mac` `--hop-channels` (`1,6,11`) `--hop-dwell` (200 ms) | omit `--channel` + set `--hop-channels` for ADR-061 multi-freq hopping; omit `--filter-mac` to capture all transmitters |
|
||||||
|
| Cognitum Seed | `--seed-url` (`http://10.1.10.236`) `--seed-token` (Bearer, from pairing) `--zone` (`lobby`) | |
|
||||||
|
| Swarm | `--swarm-hb` (30 s) `--swarm-ingest` (5 s) | heartbeat + vector ingest intervals |
|
||||||
|
| Mode | `--dry-run` (build NVS bin, don't flash) `--baud` (460800) `--force-partial` | |
|
||||||
|
|
||||||
|
> ⚠️ **NVS namespace is replaced wholesale (issue #391).** Flashing rewrites the *entire* `csi_cfg` namespace — **any key you don't pass on the CLI is erased**. Always pass the full set you want, or use `--force-partial` knowingly. Read the device's current values off the serial boot log first (`adaptive_ctrl` / `csi_collector` lines) if you're unsure.
|
||||||
|
|
||||||
|
- NVS partition images for fleet provisioning: `scripts/generate_nvs_matrix.py` (subprocess-first — the `esp_idf_nvs_partition_gen` API changed across versions).
|
||||||
|
|
||||||
|
## 3. Sensing server flags
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd v2
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --help
|
||||||
|
|
||||||
|
# Common modes:
|
||||||
|
cargo run -p wifi-densepose-sensing-server # live sink, default port
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --pretrain --dataset data/csi/ --pretrain-epochs 50
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --train --dataset data/mmfi/ --epochs 100 --save-rvf model.rvf
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --embed
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --build-index env
|
||||||
|
```
|
||||||
|
|
||||||
|
`wifiscan` server (multi-BSSID, ADR-022): `cargo run -p wifi-densepose-sensing-server` consumes `wifi-densepose-wifiscan` output; use neighbour APs as free radar illuminators.
|
||||||
|
|
||||||
|
## 4. Edge intelligence modules (ADR-041)
|
||||||
|
|
||||||
|
Small Rust/WASM programs that run on the ESP32 itself — no internet, instant response. See `docs/edge-modules/` and `docs/adr/ADR-041-*`. Each module declares its CSI feature inputs (8-dim feature vectors) and an RVF store target (Cognitum Seed). Configure which modules ship in a build via the firmware component config; configure their thresholds via NVS keys.
|
||||||
|
|
||||||
|
Helper scripts that mirror edge-module logic on the host (useful for tuning before flashing):
|
||||||
|
`scripts/apnea-detector.js`, `gait-analyzer.js`, `material-classifier.js`, `passive-radar.js`, `mincut-person-counter.js`, `device-fingerprint.js`, `mesh-graph-transformer.js`, `material-detector.js`.
|
||||||
|
|
||||||
|
## 5. Multi-node mesh
|
||||||
|
|
||||||
|
- 2+ nodes give real spatial resolution. Each node provisioned to the same `--target-ip` sink.
|
||||||
|
- TDM protocol + channel hopping coordinated by `wifi-densepose-hardware` (`v2/crates/wifi-densepose-hardware/src/esp32/`).
|
||||||
|
- Cross-viewpoint fusion combines nodes — see `ruview-advanced-sensing`.
|
||||||
|
|
||||||
|
## 6. Cognitum Seed integration ($140 total BOM)
|
||||||
|
|
||||||
|
ESP32 streams CSI → bridge forwards to a Cognitum Seed for persistent RVF memory, kNN over environments, and an Ed25519 witness chain.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node scripts/rf-scan.js --port 5006 # live RF room scan → Seed
|
||||||
|
node scripts/snn-csi-processor.js --port 5006 # SNN real-time learning on-Seed
|
||||||
|
```
|
||||||
|
|
||||||
|
See `docs/tutorials/cognitum-seed-pretraining.md` and ADR-028 (capability audit + witness verification).
|
||||||
|
|
||||||
|
## 7. App-level config
|
||||||
|
|
||||||
|
- API: `wifi-densepose-api` (Axum) — config via `wifi-densepose-config` crate; see `example.env` / `pyproject.toml` for the v1 Python service.
|
||||||
|
- Docker: `docker run -p 3000:3000 ruvnet/wifi-densepose:latest` (env-var overrides documented in `README.md` / `docker/`).
|
||||||
|
- Dashboard: served on `:3000`; nvsim dashboard (ADR-092) is separate.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- `docs/adr/` (96 ADRs) — esp. ADR-022 (wifiscan), ADR-028 (capability audit), ADR-041 (edge modules), ADR-060 (channel/MAC override), ADR-061 (QEMU + mesh), ADR-081 (adaptive CSI mesh kernel)
|
||||||
|
- `CLAUDE.md` / `CLAUDE.local.md` — crate map, build env, QEMU CI fixes
|
||||||
|
- `example.env`, `Makefile`, `firmware/esp32-csi-node/`
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
---
|
||||||
|
name: ruview-hardware-setup
|
||||||
|
description: ESP32-S3 / ESP32-C6 firmware build, flash, WiFi provisioning, and serial monitoring for RuView CSI sensing nodes. Use when setting up physical hardware, reflashing a node, or debugging a device that isn't streaming CSI.
|
||||||
|
allowed-tools: Bash Read Write Edit Glob Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Hardware Setup
|
||||||
|
|
||||||
|
Bring a RuView sensing node online: build firmware → flash → provision WiFi → confirm CSI stream.
|
||||||
|
|
||||||
|
## Supported devices
|
||||||
|
|
||||||
|
| Device | Flash | Chip | Role |
|
||||||
|
|--------|-------|------|------|
|
||||||
|
| ESP32-S3 (8MB) | 8 MB | Xtensa dual-core | WiFi CSI sensing node (default) |
|
||||||
|
| ESP32-S3 SuperMini | 4 MB | Xtensa dual-core | Compact CSI node — use `sdkconfig.defaults.4mb` |
|
||||||
|
| ESP32-C6 + Seeed MR60BHA2 | — | RISC-V + 60 GHz FMCW | mmWave HR/BR/presence |
|
||||||
|
|
||||||
|
**Not supported:** original ESP32, ESP32-C3 (single-core).
|
||||||
|
|
||||||
|
## 1. Build firmware (Windows — Python subprocess, NOT bash directly)
|
||||||
|
|
||||||
|
ESP-IDF v5.4 does not support MSYS2/Git Bash. Use the Espressif Python venv as a subprocess with `MSYSTEM*` env vars stripped. The proven command lives in `CLAUDE.local.md` — reproduce it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/c/Espressif/tools/python/v5.4/venv/Scripts/python.exe -c "
|
||||||
|
import subprocess, os
|
||||||
|
env = os.environ.copy()
|
||||||
|
for k in ['MSYSTEM','MSYSTEM_CHOST','MSYSTEM_PREFIX','MINGW_PREFIX','CHERE_INVOKING']:
|
||||||
|
env.pop(k, None)
|
||||||
|
env['IDF_PATH'] = r'C:\Users\ruv\esp\v5.4\esp-idf'
|
||||||
|
env['IDF_PYTHON_ENV_PATH'] = r'C:\Espressif\tools\python\v5.4\venv'
|
||||||
|
env['IDF_TOOLS_PATH'] = r'C:\Espressif'
|
||||||
|
env['PATH'] = (
|
||||||
|
r'C:\Espressif\tools\xtensa-esp-elf\esp-14.2.0_20241119\xtensa-esp-elf\bin;'
|
||||||
|
r'C:\Espressif\tools\cmake\3.30.2\cmake-3.30.2-windows-x86_64\bin;'
|
||||||
|
r'C:\Espressif\tools\ninja\1.12.1;'
|
||||||
|
r'C:\Espressif\tools\idf-exe\1.0.3;'
|
||||||
|
r'C:\Espressif\tools\ccache\4.10.2\ccache-4.10.2-windows-x86_64;'
|
||||||
|
r'C:\Espressif\tools\python\v5.4\venv\Scripts;'
|
||||||
|
+ env['PATH']
|
||||||
|
)
|
||||||
|
python = r'C:\Espressif\tools\python\v5.4\venv\Scripts\python.exe'
|
||||||
|
idf_py = os.path.join(env['IDF_PATH'], 'tools', 'idf.py')
|
||||||
|
r = subprocess.run([python, idf_py, 'build'], # flash: [python, idf_py, '-p', 'COM8', 'flash']
|
||||||
|
cwd=r'C:\Users\ruv\Projects\wifi-densepose\firmware\esp32-csi-node',
|
||||||
|
env=env, capture_output=True, text=True, timeout=300)
|
||||||
|
print(r.stdout[-3000:]); print(r.stderr[-2000:]); print('RC:', r.returncode)
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
- **8MB build:** uses `sdkconfig.defaults.template` (no mock — real WiFi CSI).
|
||||||
|
- **4MB build:** `cp firmware/esp32-csi-node/sdkconfig.defaults.4mb firmware/esp32-csi-node/sdkconfig.defaults` first, then build.
|
||||||
|
- Build outputs: `firmware/esp32-csi-node/build/{bootloader/bootloader.bin, partition_table/partition-table.bin, esp32-csi-node.bin, ota_data_initial.bin}`.
|
||||||
|
|
||||||
|
## 2. Flash to the device
|
||||||
|
|
||||||
|
Same subprocess pattern, swap `[python, idf_py, 'build']` → `[python, idf_py, '-p', 'COM8', 'flash']`. Or with esptool directly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m esptool --chip esp32s3 --port COM8 --baud 460800 \
|
||||||
|
write_flash 0x0 firmware/esp32-csi-node/build/bootloader/bootloader.bin \
|
||||||
|
0x8000 firmware/esp32-csi-node/build/partition_table/partition-table.bin \
|
||||||
|
0xf000 firmware/esp32-csi-node/build/ota_data_initial.bin \
|
||||||
|
0x20000 firmware/esp32-csi-node/build/esp32-csi-node.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
(The default device port in this workspace is **COM8**. Some docs reference COM9 — confirm with the user.)
|
||||||
|
|
||||||
|
## 3. Provision WiFi + sink address
|
||||||
|
|
||||||
|
Runs directly — no ESP-IDF env needed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python firmware/esp32-csi-node/provision.py --port COM8 \
|
||||||
|
--ssid "YourWiFi" --password "secret" --target-ip 192.168.1.20 --target-port 5005 --node-id 1
|
||||||
|
|
||||||
|
# Optional ADR-060 overrides:
|
||||||
|
python firmware/esp32-csi-node/provision.py --port COM8 --channel 6 --filter-mac AA:BB:CC:DD:EE:FF
|
||||||
|
```
|
||||||
|
|
||||||
|
`--help` lists the full flag set (TDM mesh slotting, edge tier, detection thresholds, vitals window, hop channels, Cognitum Seed, swarm intervals) — see the `ruview-configure` skill for the table. **Gotcha (issue #391):** flashing replaces the *entire* `csi_cfg` NVS namespace — any key not on the CLI is erased; pass the full set you want. On Windows, `provision.py --help` needs `PYTHONUTF8=1` to print (non-ASCII in the help text).
|
||||||
|
|
||||||
|
## 4. Confirm CSI stream
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Serial monitor (use pyserial — idf.py monitor hangs in a subprocess)
|
||||||
|
/c/Espressif/tools/python/v5.4/venv/Scripts/python.exe -c "
|
||||||
|
import serial, time
|
||||||
|
ser = serial.Serial('COM8', 115200, timeout=1); start = time.time()
|
||||||
|
while time.time() - start < 15:
|
||||||
|
line = ser.readline()
|
||||||
|
if line: print(line.decode('utf-8', errors='replace').strip())
|
||||||
|
ser.close()
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then start the sink and watch frames arrive:
|
||||||
|
```bash
|
||||||
|
cd v2 && cargo run -p wifi-densepose-sensing-server # listens for ESP32 UDP CSI
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common issues
|
||||||
|
|
||||||
|
| Symptom | Cause | Fix |
|
||||||
|
|---------|-------|-----|
|
||||||
|
| `MSys/Mingw is no longer supported` | ESP-IDF detected Git Bash | Use the Python-subprocess command above with `MSYSTEM*` stripped |
|
||||||
|
| `cmd.exe /C` hangs | Interactive prompt from Git Bash | Don't use `cmd.exe /C` — use the Python subprocess |
|
||||||
|
| `cmake not found` | Wrong path | It's `cmake\3.30.2\cmake-3.30.2-windows-x86_64\bin`, not `cmake\3.30.2\bin` |
|
||||||
|
| `python_env not found` | Missing env var | Set `IDF_PYTHON_ENV_PATH=C:\Espressif\tools\python\v5.4\venv` |
|
||||||
|
| No CSI frames at the sink | WiFi not provisioned, wrong channel, or MAC filter too tight | Re-run `provision.py`; try `--channel` matching your AP; drop `--filter-mac` |
|
||||||
|
| False fall alerts | Old `fall_thresh` default | Issue #263 raised it to 15.0 rad/s² + debounce — reflash latest firmware |
|
||||||
|
|
||||||
|
## Firmware release process (for maintainers)
|
||||||
|
|
||||||
|
1. Build 8MB from `sdkconfig.defaults.template` (no mock)
|
||||||
|
2. Build 4MB from `sdkconfig.defaults.4mb` (no mock)
|
||||||
|
3. Save 6 binaries: `esp32-csi-node.bin`, `bootloader.bin`, `partition-table.bin`, `ota_data_initial.bin`, `esp32-csi-node-4mb.bin`, `partition-table-4mb.bin`
|
||||||
|
4. `git tag v0.X.Y-esp32 && git push origin v0.X.Y-esp32`
|
||||||
|
5. `gh release create v0.X.Y-esp32 <binaries> --title "..." --notes-file ...`
|
||||||
|
6. Verify on real hardware (COM8) before publishing — **always test with real WiFi CSI, not mock mode** (mock missed the Kconfig threshold bug)
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- `CLAUDE.local.md` — exact ESP-IDF build env, paths, QEMU CI notes
|
||||||
|
- `firmware/esp32-csi-node/` — C firmware (channel hopping, NVS config, TDM protocol)
|
||||||
|
- `docs/adr/ADR-028-esp32-capability-audit.md`, `docs/build-guide.md`, `docs/TROUBLESHOOTING.md`
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
name: ruview-mmwave
|
||||||
|
description: Set up and run RuView mmWave / FMCW radar sensing — ESP32-C6 + Seeed MR60BHA2 (60 GHz, heart rate / breathing rate / presence) and HLK-LD2410 (24 GHz, presence + distance), plus mmWave↔WiFi-CSI sensor fusion (48-byte fused vitals, MR60BHA2/LD2410 auto-detect, v0.5.0+). Use when the deployment includes a millimetre-wave radar alongside or instead of WiFi CSI.
|
||||||
|
allowed-tools: Bash Read Write Edit Glob Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView mmWave / FMCW Radar
|
||||||
|
|
||||||
|
The radio side-channel: 60 GHz and 24 GHz FMCW radar, standalone and fused with WiFi CSI.
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
|
||||||
|
| Device | Port | Band | Provides | ~Cost |
|
||||||
|
|--------|------|------|----------|-------|
|
||||||
|
| ESP32-C6 + Seeed MR60BHA2 | COM4 (typical) | 60 GHz FMCW | Heart rate, breathing rate, presence | ~$15 |
|
||||||
|
| HLK-LD2410 | — | 24 GHz FMCW | Presence + distance (gated zones) | ~$3 |
|
||||||
|
|
||||||
|
The C6 is RISC-V and can run the radar pipeline; it is **not** a WiFi-CSI node (use an ESP32-S3 for CSI). LD2410 is a UART module wired to a host or to the C6.
|
||||||
|
|
||||||
|
## 1. Firmware with mmWave fusion (v0.5.0+)
|
||||||
|
|
||||||
|
The ESP32 firmware auto-detects an attached MR60BHA2 or LD2410 and emits **48-byte fused vitals** records (CSI-derived + radar-derived, reconciled). Binary is ~12 KB larger than the CSI-only build. Build/flash as in `ruview-hardware-setup` (Windows: Python-subprocess; ESP-IDF v5.4 ≠ Git Bash). Recommended stable firmware tag: `v0.5.0-esp32` or later — see `docs/user-guide.md` release table.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Provision the radar/fusion node (same provision.py; the firmware probes for the radar on boot)
|
||||||
|
python firmware/esp32-csi-node/provision.py --port COM8 --ssid "WiFi" --password "secret" --target-ip 192.168.1.20
|
||||||
|
# Confirm: serial monitor should report which radar was detected and start emitting fused vitals
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. mmWave ↔ WiFi-CSI fusion bridge (host side)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/mmwave_fusion_bridge.py # bridges radar HR/BR + CSI → unified spatial model
|
||||||
|
node scripts/passive-radar.js # passive-radar style processing for exploration
|
||||||
|
```
|
||||||
|
|
||||||
|
The 3D point-cloud demo fuses **camera depth (MiDaS) + WiFi CSI + mmWave radar** → unified spatial model (~22 ms pipeline, 19K+ pts/frame; ADR-094). Drive it with `scripts/mmwave_fusion_bridge.py` plus the point-cloud front-end.
|
||||||
|
|
||||||
|
## 3. Standalone radar use
|
||||||
|
|
||||||
|
- **MR60BHA2 (60 GHz)** — best for contactless vitals on a (near-)stationary subject: blood pressure proxy, heart rate, breathing rate; $15 hardware, no wearable. See `examples/medical/README.md`.
|
||||||
|
- **LD2410 (24 GHz)** — best for cheap presence + coarse distance / gated zones; complements CSI presence (PIR-style fusion) for higher confidence.
|
||||||
|
|
||||||
|
## 4. When to use mmWave vs. WiFi CSI
|
||||||
|
|
||||||
|
| Situation | Prefer |
|
||||||
|
|-----------|--------|
|
||||||
|
| Contactless vitals, subject stationary, line of sight | **MR60BHA2** (cleaner HR/BR than CSI alone) |
|
||||||
|
| Cheap, robust presence / occupancy in a defined zone | **LD2410** (or LD2410 + CSI) |
|
||||||
|
| Through-wall presence / activity, no line of sight | **WiFi CSI** (mmWave doesn't penetrate walls) |
|
||||||
|
| Pose / skeletons | **WiFi CSI** (WiFlow) — mmWave doesn't do this here |
|
||||||
|
| Highest-confidence vitals | **Fusion** — 48-byte fused vitals reconcile CSI + radar |
|
||||||
|
| Volumetric 3D | **Fusion** — camera depth + CSI + mmWave point cloud |
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- Hardware tables: `README.md`, `docs/user-guide.md` (release table — v0.5.0 mmWave fusion notes, binary sizes)
|
||||||
|
- `scripts/mmwave_fusion_bridge.py`, `scripts/passive-radar.js`
|
||||||
|
- `examples/medical/README.md` (60 GHz mmWave vitals)
|
||||||
|
- ADR-094 (point-cloud GitHub Pages deployment)
|
||||||
|
- Validate firmware changes with the QEMU helpers and `ruview-verify`
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
---
|
||||||
|
name: ruview-model-training
|
||||||
|
description: Train RuView models — camera-free WiFlow pose (10 sensor signals, no labels), camera-supervised pose (MediaPipe + ESP32 CSI → 92.9% PCK@20, ADR-079), RuVector contrastive embeddings (AETHER, ADR-024), domain generalization (MERIDIAN, ADR-027), local SNN environment adaptation, plus GPU training on GCloud and Hugging Face publishing. Use when building, fine-tuning, evaluating, or shipping a model.
|
||||||
|
allowed-tools: Bash Read Write Edit Glob Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Model Training
|
||||||
|
|
||||||
|
RuView trains several kinds of model. Pick the track that matches the goal; all of them run on a laptop, with an optional GPU path.
|
||||||
|
|
||||||
|
## Track A — Camera-free pose (WiFlow), no cameras, no labels
|
||||||
|
|
||||||
|
Trains 17-keypoint pose from 10 sensor signals. Fast, fully unsupervised, modest accuracy.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd v2
|
||||||
|
# Pretrain on raw CSI (contrastive)
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --pretrain --dataset data/csi/ --pretrain-epochs 50
|
||||||
|
# Train pose head, save an RVF artifact
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --train --dataset data/mmfi/ --epochs 100 --save-rvf model.rvf
|
||||||
|
```
|
||||||
|
|
||||||
|
~84 s on an M4 Pro. Benchmarks: `node scripts/benchmark-wiflow.js`, eval: `node scripts/eval-wiflow.js`.
|
||||||
|
|
||||||
|
## Track B — Camera-supervised pose (ADR-079) → 92.9% PCK@20
|
||||||
|
|
||||||
|
Uses a webcam + MediaPipe as ground truth, paired with ESP32 CSI. ~19 min on a laptop.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Collect paired data (camera + CSI)
|
||||||
|
python scripts/collect-ground-truth.py # MediaPipe pose landmarks
|
||||||
|
python scripts/collect-training-data.py # CSI capture, time-synced
|
||||||
|
node scripts/align-ground-truth.js # align camera ↔ CSI timestamps
|
||||||
|
|
||||||
|
# 2. Train (the camera-supervised path through the sensing-server / train crate)
|
||||||
|
cd v2
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --train --dataset data/paired/ --epochs <N> --save-rvf model.rvf
|
||||||
|
|
||||||
|
# 3. Evaluate
|
||||||
|
cd .. && node scripts/eval-wiflow.js # reports PCK@20
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires `data/pose_landmarker_lite.task` (MediaPipe model). See `docs/adr/ADR-079-camera-ground-truth-training.md`.
|
||||||
|
|
||||||
|
## Track C — RuVector contrastive embeddings (AETHER, ADR-024)
|
||||||
|
|
||||||
|
CSI subcarrier amplitude/phase → embeddings for re-ID and retrieval (171K emb/s on M4 Pro). Driven by `wifi-densepose-train` + `wifi-densepose-ruvector` (RuVector v2.0.4). Spectrogram embeddings: ADR-076.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd v2
|
||||||
|
cargo check -p wifi-densepose-train --no-default-features # sanity
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --embed
|
||||||
|
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --build-index env
|
||||||
|
```
|
||||||
|
|
||||||
|
## Track D — Domain generalization (MERIDIAN, ADR-027)
|
||||||
|
|
||||||
|
Make a model transfer across environments without retraining. Configured through the training pipeline's domain-generalization options; see ADR-027 and `wifi-densepose-train` + `ruview_metrics`.
|
||||||
|
|
||||||
|
## Track E — Local SNN environment adaptation
|
||||||
|
|
||||||
|
Spiking neural network that adapts to a new room in <30 s, on-device or on a Cognitum Seed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node scripts/snn-csi-processor.js --port 5006
|
||||||
|
```
|
||||||
|
|
||||||
|
See `docs/tutorials/cognitum-seed-pretraining.md`, ADR-084/085 (RaBitQ similarity sensor), ADR-086 (edge novelty gate).
|
||||||
|
|
||||||
|
## GPU training on GCloud
|
||||||
|
|
||||||
|
Project `cognitum-20260110` has L4 / A100 / H100 quota.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gcloud auth login
|
||||||
|
gcloud config set project cognitum-20260110
|
||||||
|
|
||||||
|
bash scripts/gcloud-train.sh --dry-run # smoke test, synthetic data
|
||||||
|
bash scripts/gcloud-train.sh --gpu l4 --hours 2 # prototyping
|
||||||
|
bash scripts/gcloud-train.sh --gpu a100 --config scripts/training-config-sweep.json
|
||||||
|
bash scripts/gcloud-train.sh --sweep # full hyperparameter sweep
|
||||||
|
# VM is auto-deleted after training unless --keep-vm. Cost: L4 ~$0.80/hr, A100 40GB ~$3.60/hr.
|
||||||
|
```
|
||||||
|
|
||||||
|
Local Mac training: `bash scripts/mac-mini-train.sh`. Model benchmark: `python scripts/benchmark-model.py`.
|
||||||
|
|
||||||
|
## Publishing a trained model
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/publish-huggingface.py # or: bash scripts/publish-huggingface.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Pushes the RVF artifact + card to Hugging Face. See `docs/huggingface/`.
|
||||||
|
|
||||||
|
## Data layout
|
||||||
|
|
||||||
|
| Path | Contents |
|
||||||
|
|------|----------|
|
||||||
|
| `data/recordings/` | Raw CSI captures (`*.csi.jsonl`), overnight runs |
|
||||||
|
| `data/csi/` | CSI datasets for pretraining |
|
||||||
|
| `data/mmfi/` | MM-Fi dataset (ADR-015) |
|
||||||
|
| `data/paired/` | Camera ↔ CSI paired samples (ADR-079) |
|
||||||
|
| `data/ground-truth/` | MediaPipe pose landmarks |
|
||||||
|
| `data/pose_landmarker_lite.task` | MediaPipe model file |
|
||||||
|
| `models/` | Trained artifacts |
|
||||||
|
|
||||||
|
Record more data: `python scripts/record-csi-udp.py` (UDP CSI capture from a live node).
|
||||||
|
|
||||||
|
## Validation after a training change
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd v2 && cargo test --workspace --no-default-features # 1,400+ pass, 0 fail
|
||||||
|
cd .. && python archive/v1/data/proof/verify.py # VERDICT: PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Then hand off to `ruview-verify` for the witness bundle.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- ADRs: 015 (MM-Fi + Wi-Pose datasets), 016 (RuVector training integration — complete), 017 (RuVector signal + MAT), 024 (AETHER), 027 (MERIDIAN), 076 (spectrogram embeddings), 079 (camera ground truth), 084/085 (RaBitQ), 095/096 (on-ESP32 temporal modeling, sparse GQA)
|
||||||
|
- Crates: `wifi-densepose-train`, `wifi-densepose-nn`, `wifi-densepose-ruvector`, `wifi-densepose-sensing-server`
|
||||||
|
- `scripts/gcloud-train.sh`, `mac-mini-train.sh`, `benchmark-wiflow.js`, `eval-wiflow.js`, `benchmark-model.py`
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
---
|
||||||
|
name: ruview-quickstart
|
||||||
|
description: Onboarding and first-run for RuView (WiFi-DensePose) — Docker demo with simulated data, repo build, and the fastest path to a live sensing dashboard. Use when someone is new to RuView or wants the shortest path to "it works on my machine".
|
||||||
|
allowed-tools: Bash Read Write Edit Glob Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Quickstart
|
||||||
|
|
||||||
|
Get a newcomer from zero to a running RuView sensing dashboard. Three tiers, pick the one that matches the hardware on hand.
|
||||||
|
|
||||||
|
## Tier 0 — Docker, no hardware (2 minutes)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker pull ruvnet/wifi-densepose:latest
|
||||||
|
docker run -p 3000:3000 ruvnet/wifi-densepose:latest
|
||||||
|
# open http://localhost:3000 — simulated CSI, full UI
|
||||||
|
```
|
||||||
|
|
||||||
|
Use this to demo the dashboard, explore the API, or develop UI without a sensor.
|
||||||
|
|
||||||
|
## Tier 1 — Build the repo from source
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Rust workspace (1,400+ tests, ~2 min)
|
||||||
|
cd v2
|
||||||
|
cargo test --workspace --no-default-features
|
||||||
|
|
||||||
|
# Single-crate sanity check (no GPU)
|
||||||
|
cargo check -p wifi-densepose-train --no-default-features
|
||||||
|
|
||||||
|
# Python proof (deterministic SHA-256 pipeline check)
|
||||||
|
cd ..
|
||||||
|
python archive/v1/data/proof/verify.py # must print VERDICT: PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
If `verify.py` fails on a hash mismatch after a numpy/scipy bump:
|
||||||
|
```bash
|
||||||
|
python archive/v1/data/proof/verify.py --generate-hash
|
||||||
|
python archive/v1/data/proof/verify.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tier 2 — Live sensing with an ESP32-S3 ($9)
|
||||||
|
|
||||||
|
This is the real thing. Hand off to the `ruview-hardware-setup` skill for the flash/provision/monitor loop, then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lightweight sensing server (consumes the ESP32 UDP CSI stream)
|
||||||
|
cd v2
|
||||||
|
cargo run -p wifi-densepose-sensing-server
|
||||||
|
# Live RF room scan / SNN learning helpers:
|
||||||
|
node ../scripts/rf-scan.js --port 5006
|
||||||
|
node ../scripts/snn-csi-processor.js --port 5006
|
||||||
|
```
|
||||||
|
|
||||||
|
## What to know before you start
|
||||||
|
|
||||||
|
- **ESP32-C3 and the original ESP32 are NOT supported** — single-core, can't run the CSI DSP pipeline. Use ESP32-S3 (8MB or 4MB) or ESP32-C6.
|
||||||
|
- A **single ESP32** has limited spatial resolution — 2+ nodes (or add a Cognitum Seed) for good results.
|
||||||
|
- Camera-free pose accuracy is limited (~84s to train, modest PCK). For 92.9% PCK@20 use camera-supervised training (see `ruview-model-training` skill, ADR-079).
|
||||||
|
- No cloud, no internet, no cameras required — everything runs on edge hardware.
|
||||||
|
|
||||||
|
## Next steps to suggest
|
||||||
|
|
||||||
|
| Goal | Skill / command |
|
||||||
|
|------|-----------------|
|
||||||
|
| Flash & provision an ESP32 node | `ruview-hardware-setup` · `/ruview-flash` · `/ruview-provision` |
|
||||||
|
| Tune channels / MAC filter / edge modules | `ruview-configure` |
|
||||||
|
| Run a sensing application (presence, vitals, pose, sleep, MAT) | `ruview-applications` · `/ruview-app` |
|
||||||
|
| Train a pose / sensing model | `ruview-model-training` · `/ruview-train` |
|
||||||
|
| Multistatic mesh, tomography, cross-viewpoint fusion | `ruview-advanced-sensing` · `/ruview-advanced` |
|
||||||
|
| Verify the build + generate a witness bundle | `ruview-verify` · `/ruview-verify` |
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- `README.md` — feature matrix, hardware table, install options
|
||||||
|
- `docs/user-guide.md`, `docs/wifi-mat-user-guide.md`, `docs/build-guide.md`, `docs/TROUBLESHOOTING.md`
|
||||||
|
- `docs/tutorials/`, `examples/` — runnable examples (environment, medical, sleep, stress, `ruview_live.py`)
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
---
|
||||||
|
name: ruview-verify
|
||||||
|
description: Verify a RuView build — full Rust workspace tests, the deterministic Python pipeline proof (SHA-256 Trust Kill Switch), firmware hash manifest, and the ADR-028 witness bundle with one-command self-verification. Use after any significant change, before merging a PR, or to produce an attestation bundle for a recipient.
|
||||||
|
allowed-tools: Bash Read Write Edit Glob Grep
|
||||||
|
---
|
||||||
|
|
||||||
|
# RuView Verification & Witness Bundle
|
||||||
|
|
||||||
|
The trust pipeline for RuView. Run this after meaningful changes and before merging.
|
||||||
|
|
||||||
|
## 1. Rust workspace tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd v2
|
||||||
|
cargo test --workspace --no-default-features # must be 1,400+ passed, 0 failed (~2 min)
|
||||||
|
```
|
||||||
|
|
||||||
|
Single-crate checks (no GPU): `cargo check -p wifi-densepose-train --no-default-features`, `cargo test -p wifi-densepose-signal --no-default-features`, etc.
|
||||||
|
|
||||||
|
## 2. Deterministic Python proof (Trust Kill Switch)
|
||||||
|
|
||||||
|
Feeds a reference CSI signal through the **production** pipeline and hashes the output. Any behavioural drift changes the hash.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ..
|
||||||
|
python archive/v1/data/proof/verify.py # must print VERDICT: PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
If it fails on a hash mismatch after a legitimate numpy/scipy bump:
|
||||||
|
```bash
|
||||||
|
python archive/v1/data/proof/verify.py --generate-hash
|
||||||
|
python archive/v1/data/proof/verify.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Artifacts: `archive/v1/data/proof/verify.py`, `expected_features.sha256`, `sample_csi_data.json` (1,000 synthetic frames, seed=42).
|
||||||
|
|
||||||
|
## 3. Python test suite (v1)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd archive/v1 && python -m pytest tests/ -x -q
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Generate the witness bundle (ADR-028)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash scripts/generate-witness-bundle.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Produces `dist/witness-bundle-ADR028-<sha>.tar.gz` containing:
|
||||||
|
- `WITNESS-LOG-028.md` — 33-row attestation matrix, evidence per capability
|
||||||
|
- `ADR-028-esp32-capability-audit.md` — full audit findings
|
||||||
|
- `proof/verify.py` + `expected_features.sha256` — the deterministic proof
|
||||||
|
- `test-results/rust-workspace-tests.log` — full cargo test output
|
||||||
|
- `firmware-manifest/source-hashes.txt` — SHA-256 of all 7 ESP32 firmware files
|
||||||
|
- `crate-manifest/versions.txt` — all 15 crates + versions
|
||||||
|
- `VERIFY.sh` — one-command self-verification for recipients
|
||||||
|
|
||||||
|
## 5. Self-verify the bundle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd dist/witness-bundle-ADR028-*/
|
||||||
|
bash VERIFY.sh # must be 7/7 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pre-merge checklist (from CLAUDE.md)
|
||||||
|
|
||||||
|
1. Rust tests pass (1,400+, 0 fail)
|
||||||
|
2. Python proof passes (VERDICT: PASS)
|
||||||
|
3. `README.md` updated if scope changed (platform/crate/hardware tables, feature summaries)
|
||||||
|
4. `CLAUDE.md` updated if scope changed (crate table, ADR list, module tables, version)
|
||||||
|
5. `CHANGELOG.md` — entry under `[Unreleased]`
|
||||||
|
6. `docs/user-guide.md` updated if new data sources / CLI flags / setup steps
|
||||||
|
7. ADR index — bump ADR count in README docs table if a new ADR was added
|
||||||
|
8. Witness bundle regenerated if tests or proof hash changed
|
||||||
|
9. Docker Hub image rebuilt only if Dockerfile / deps / runtime behaviour changed
|
||||||
|
10. Crate publishing only if a published crate's public API changed (publish in dependency order — see CLAUDE.md)
|
||||||
|
11. `.gitignore` updated for new build artifacts/binaries
|
||||||
|
12. Security review for new modules touching hardware/network boundaries
|
||||||
|
|
||||||
|
## Security scan
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @claude-flow/cli@latest security scan # after security-related changes
|
||||||
|
```
|
||||||
|
|
||||||
|
Also see `docs/security-audit-wasm-edge-vendor.md`, `docs/qe-reports/`, ADR-080 (QE remediation plan), ADR-093 (dashboard gap analysis).
|
||||||
|
|
||||||
|
## QEMU firmware CI (ADR-061)
|
||||||
|
|
||||||
|
11-job workflow ("Firmware QEMU Tests"). Local QEMU helpers: `scripts/qemu-esp32s3-test.sh`, `qemu-mesh-test.sh`, `qemu-chaos-test.sh`, `qemu-snapshot-test.sh`, `install-qemu.sh`. Notes: `espressif/idf:v5.4` container needs `source $IDF_PATH/export.sh` before `pip`; QEMU needs `esptool merge_bin --fill-flash-size 8MB`; WARNs (no real WiFi) are treated as OK in CI.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- `docs/WITNESS-LOG-028.md`, `docs/adr/ADR-028-esp32-capability-audit.md`
|
||||||
|
- `scripts/generate-witness-bundle.sh`, `archive/v1/data/proof/verify.py`
|
||||||
|
- `CLAUDE.md` → "Validation & Witness Verification" + "Pre-Merge Checklist"
|
||||||
|
- `CLAUDE.local.md` → QEMU CI pipeline fixes
|
||||||
Loading…
Reference in New Issue