You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: improve RuvSense domain model and add DDD index
- Add intro explaining DDD purpose and bounded context overview table
- Add Edge Intelligence bounded context (ruvnet#7) for on-device sensing
- Add ubiquitous language terms: Edge Tier, WASM Module
- Fix frame rate 20 Hz -> 28 Hz (measured on hardware)
- Link each context to its source files and ADRs
- Add NVS configuration table and invariants for edge processing
- Create docs/ddd/README.md introducing all 3 domain models
- Update main README docs table to link to DDD index
Co-Authored-By: claude-flow <[email protected]>
This folder contains Domain-Driven Design (DDD) specifications for each major subsystem in RuView.
4
+
5
+
DDD organizes the codebase around the problem being solved — not around technical layers. Each *bounded context* owns its own data, rules, and language. Contexts communicate through domain events, not by sharing mutable state. This makes the system easier to reason about, test, and extend — whether you're a person or an AI agent.
Copy file name to clipboardExpand all lines: docs/ddd/ruvsense-domain-model.md
+177-4Lines changed: 177 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,32 @@
1
1
# RuvSense Domain Model
2
2
3
+
RuvSense is the multistatic WiFi sensing subsystem of RuView. It turns raw radio signals from multiple ESP32 sensors into tracked human poses, vital signs, and spatial awareness — all without cameras.
4
+
5
+
This document defines the system using [Domain-Driven Design](https://martinfowler.com/bliki/DomainDrivenDesign.html) (DDD): bounded contexts that own their data and rules, aggregate roots that enforce invariants, value objects that carry meaning, and domain events that connect everything. The goal is to make the system's structure match the physics it models — so that anyone reading the code (or an AI agent modifying it) understands *why* each piece exists, not just *what* it does.
| 1 |[Multistatic Sensing](#1-multistatic-sensing-context)| Collect and fuse CSI from multiple nodes and channels |[ADR-029](../adr/ADR-029-ruvsense-multistatic-sensing-mode.md)|`signal/src/ruvsense/{multiband,phase_align,multistatic}.rs`|
12
+
| 2 |[Coherence](#2-coherence-context)| Monitor signal quality, gate bad data |[ADR-029](../adr/ADR-029-ruvsense-multistatic-sensing-mode.md)|`signal/src/ruvsense/{coherence,coherence_gate}.rs`|
13
+
| 3 |[Pose Tracking](#3-pose-tracking-context)| Track people as persistent skeletons with re-ID |[ADR-024](../adr/ADR-024-contrastive-csi-embedding-model.md), [ADR-037](../adr/ADR-037-multi-person-pose-detection.md)|`signal/src/ruvsense/pose_tracker.rs`|
| 5 |[Longitudinal Monitoring](#5-longitudinal-monitoring-context)| Track health trends over days/weeks |[ADR-030](../adr/ADR-030-ruvsense-persistent-field-model.md)|`signal/src/ruvsense/longitudinal.rs`|
16
+
| 6 |[Spatial Identity](#6-spatial-identity-context)| Cross-room tracking via environment fingerprints |[ADR-030](../adr/ADR-030-ruvsense-persistent-field-model.md)|`signal/src/ruvsense/cross_room.rs`|
17
+
| 7 |[Edge Intelligence](#7-edge-intelligence-context)| On-device sensing (no server needed) |[ADR-039](../adr/ADR-039-esp32-edge-intelligence.md), [ADR-040](../adr/ADR-040-wasm-programmable-sensing.md)|`firmware/esp32-csi-node/main/edge_processing.c`|
18
+
19
+
All code paths shown are relative to `rust-port/wifi-densepose-rs/crates/wifi-densepose-` unless otherwise noted.
20
+
21
+
---
22
+
3
23
## Domain-Driven Design Specification
4
24
5
25
### Ubiquitous Language
6
26
7
27
| Term | Definition |
8
28
|------|------------|
9
-
|**Sensing Cycle**| One complete TDMA round (all nodes TX once): 50ms at 20 Hz |
29
+
|**Sensing Cycle**| One complete TDMA round (all nodes TX once): ~35ms at 28.5 Hz (measured)|
10
30
|**Link**| A single TX-RX pair; with N nodes there are N×(N-1) directed links |
11
31
|**Multi-Band Frame**| Fused CSI from one node hopping across multiple channels in one dwell cycle |
12
32
|**Fused Sensing Frame**| Aggregated observation from all nodes at one sensing cycle, ready for inference |
@@ -15,6 +35,8 @@
15
35
|**Pose Track**| A temporally persistent per-person 17-keypoint trajectory with Kalman state |
16
36
|**Track Lifecycle**| State machine: Tentative → Active → Lost → Terminated |
17
37
|**Re-ID Embedding**| 128-dim AETHER contrastive vector encoding body identity |
38
+
|**Edge Tier**| Processing level on the ESP32: 0 = raw passthrough, 1 = signal cleanup, 2 = vitals, 3 = WASM modules |
39
+
|**WASM Module**| A small program compiled to WebAssembly that runs on the ESP32 for custom on-device sensing |
18
40
|**Node**| An ESP32-S3 device acting as both TX and RX in the multistatic mesh |
19
41
|**Aggregator**| Central device (ESP32/RPi/x86) that collects CSI from all nodes and runs fusion |
20
42
|**Sensing Schedule**| TDMA slot assignment: which node transmits when |
@@ -194,7 +216,7 @@
194
216
**Domain Services:**
195
217
-`PersonSeparationService` — Min-cut partitioning of cross-link correlation graph
196
218
-`TrackAssignmentService` — Bipartite matching of detections to existing tracks
197
-
-`KalmanPredictionService` — Predict step at 20 Hz (decoupled from measurement rate)
219
+
-`KalmanPredictionService` — Predict step at 28 Hz (decoupled from measurement rate)
198
220
-`KalmanUpdateService` — Gated measurement update (subject to coherence gate)
199
221
-`EmbeddingIdentifierService` — AETHER cosine similarity for re-ID
200
222
@@ -575,7 +597,7 @@ pub trait MeshRepository {
575
597
### Multistatic Sensing
576
598
- At least 2 nodes must be active for multistatic fusion (fallback to single-node mode otherwise)
577
599
- Channel hop sequence must contain at least 1 non-overlapping channel
578
-
- TDMA cycle period must be ≤50ms for 20 Hz output
600
+
- TDMA cycle period must be ≤50ms for 28 Hz output
579
601
- Guard interval must be ≥2× clock drift budget (≥1ms for 50ms cycle)
- Transition graph is append-only (immutable audit trail)
1026
1048
- No image data stored — only 128-dim embeddings and structural events
1027
1049
- Maximum 100 rooms indexed per deployment (HNSW scaling constraint)
1050
+
1051
+
---
1052
+
1053
+
## Part III: Edge Intelligence Bounded Context (ADR-039, ADR-040, ADR-041)
1054
+
1055
+
### 7. Edge Intelligence Context
1056
+
1057
+
**Responsibility:** Run signal processing and sensing algorithms directly on the ESP32-S3, without requiring a server. The node detects presence, measures breathing and heart rate, alerts on falls, and runs custom WASM modules — all locally with instant response.
1058
+
1059
+
This is the only bounded context that runs on the microcontroller rather than the aggregator. It operates independently: the server is optional for visualization, but the ESP32 handles real-time sensing on its own.
0 commit comments