mirror of
https://github.com/ruvnet/RuView.git
synced 2026-04-28 05:59:32 +00:00
chore(repo): move v1/ → archive/v1/ + add archive/README.md (#430)
The Rust port at v2/ has been the primary codebase since the rename in #427. The Python implementation at v1/ is no longer the active target; the only load-bearing path is the deterministic proof bundle at v1/data/proof/ (per ADR-011 / ADR-028 witness verification). Move the whole Python tree into archive/v1/ and document the policy in archive/README.md: no new features, bug fixes only when they affect a still-load-bearing path (currently just the proof), CI continues to verify the proof on every push and PR. Path references updated in 26 files via path-pattern sed (only matches v1/<known-child> patterns, never bare v1 or API URLs like /api/v1/). Two double-prefix typos (archive/archive/v1/) caught and hand-fixed in verify-pipeline.yml and ADR-011. Validated: - Python proof verify.py imports cleanly at archive/v1/data/proof/ (numpy/scipy still required; CI installs requirements-lock.txt from archive/v1/ now) - cargo test --workspace --no-default-features → 1,539 passed, 0 failed, 8 ignored (unaffected by Python tree relocation) - ESP32-S3 on COM7 untouched (no firmware paths changed) After-merge: contributors should re-run any local `python v1/...` commands as `python archive/v1/...` (CLAUDE.md and CHANGELOG already updated).
This commit is contained in:
parent
74233cfb23
commit
81cc241b9e
183 changed files with 290 additions and 216 deletions
|
|
@ -133,7 +133,7 @@ cargo test -p wifi-densepose-train --no-default-features
|
|||
### Step 9: Verify Python Proof System
|
||||
|
||||
```bash
|
||||
python v1/data/proof/verify.py
|
||||
python archive/v1/data/proof/verify.py
|
||||
```
|
||||
|
||||
**Expected:** PASS (hash `8c0680d7...` matches `expected_features.sha256`).
|
||||
|
|
|
|||
|
|
@ -20,31 +20,31 @@ The following code paths produce fake data **in the default configuration** or a
|
|||
|
||||
| File | Line | Issue | Impact |
|
||||
|------|------|-------|--------|
|
||||
| `v1/src/core/csi_processor.py` | 390 | `doppler_shift = np.random.rand(10) # Placeholder` | **Real feature extractor returns random Doppler** - kills credibility of entire feature pipeline |
|
||||
| `v1/src/hardware/csi_extractor.py` | 83-84 | `amplitude = np.random.rand(...)` in CSI extraction fallback | Random data silently substituted when parsing fails |
|
||||
| `v1/src/hardware/csi_extractor.py` | 129-135 | `_parse_atheros()` returns `np.random.rand()` with comment "placeholder implementation" | Named as if it parses real data, actually random |
|
||||
| `v1/src/hardware/router_interface.py` | 211-212 | `np.random.rand(3, 56)` in fallback path | Silent random fallback |
|
||||
| `v1/src/services/pose_service.py` | 431 | `mock_csi = np.random.randn(64, 56, 3) # Mock CSI data` | Mock CSI in production code path |
|
||||
| `v1/src/services/pose_service.py` | 293-356 | `_generate_mock_poses()` with `random.randint` throughout | Entire mock pose generator in service layer |
|
||||
| `v1/src/services/pose_service.py` | 489-607 | Multiple `random.randint` for occupancy, historical data | Fake statistics that look real in API responses |
|
||||
| `v1/src/api/dependencies.py` | 82, 408 | "return a mock user for development" | Auth bypass in default path |
|
||||
| `archive/v1/src/core/csi_processor.py` | 390 | `doppler_shift = np.random.rand(10) # Placeholder` | **Real feature extractor returns random Doppler** - kills credibility of entire feature pipeline |
|
||||
| `archive/v1/src/hardware/csi_extractor.py` | 83-84 | `amplitude = np.random.rand(...)` in CSI extraction fallback | Random data silently substituted when parsing fails |
|
||||
| `archive/v1/src/hardware/csi_extractor.py` | 129-135 | `_parse_atheros()` returns `np.random.rand()` with comment "placeholder implementation" | Named as if it parses real data, actually random |
|
||||
| `archive/v1/src/hardware/router_interface.py` | 211-212 | `np.random.rand(3, 56)` in fallback path | Silent random fallback |
|
||||
| `archive/v1/src/services/pose_service.py` | 431 | `mock_csi = np.random.randn(64, 56, 3) # Mock CSI data` | Mock CSI in production code path |
|
||||
| `archive/v1/src/services/pose_service.py` | 293-356 | `_generate_mock_poses()` with `random.randint` throughout | Entire mock pose generator in service layer |
|
||||
| `archive/v1/src/services/pose_service.py` | 489-607 | Multiple `random.randint` for occupancy, historical data | Fake statistics that look real in API responses |
|
||||
| `archive/v1/src/api/dependencies.py` | 82, 408 | "return a mock user for development" | Auth bypass in default path |
|
||||
|
||||
#### Moderate Severity (mock gated behind flags but confusing)
|
||||
|
||||
| File | Line | Issue |
|
||||
|------|------|-------|
|
||||
| `v1/src/config/settings.py` | 144-145 | `mock_hardware=False`, `mock_pose_data=False` defaults - correct, but mock infrastructure exists |
|
||||
| `v1/src/core/router_interface.py` | 27-300 | 270+ lines of mock data generation infrastructure in production code |
|
||||
| `v1/src/services/pose_service.py` | 84-88 | Silent conditional: `if not self.settings.mock_pose_data` with no logging of real-mode |
|
||||
| `v1/src/services/hardware_service.py` | 72-375 | Interleaved mock/real paths throughout |
|
||||
| `archive/v1/src/config/settings.py` | 144-145 | `mock_hardware=False`, `mock_pose_data=False` defaults - correct, but mock infrastructure exists |
|
||||
| `archive/v1/src/core/router_interface.py` | 27-300 | 270+ lines of mock data generation infrastructure in production code |
|
||||
| `archive/v1/src/services/pose_service.py` | 84-88 | Silent conditional: `if not self.settings.mock_pose_data` with no logging of real-mode |
|
||||
| `archive/v1/src/services/hardware_service.py` | 72-375 | Interleaved mock/real paths throughout |
|
||||
|
||||
#### Low Severity (placeholders/TODOs)
|
||||
|
||||
| File | Line | Issue |
|
||||
|------|------|-------|
|
||||
| `v1/src/core/router_interface.py` | 198 | "Collect real CSI data from router (placeholder implementation)" |
|
||||
| `v1/src/api/routers/health.py` | 170-171 | `uptime_seconds = 0.0 # TODO` |
|
||||
| `v1/src/services/pose_service.py` | 739 | `"uptime_seconds": 0.0 # TODO` |
|
||||
| `archive/v1/src/core/router_interface.py` | 198 | "Collect real CSI data from router (placeholder implementation)" |
|
||||
| `archive/v1/src/api/routers/health.py` | 170-171 | `uptime_seconds = 0.0 # TODO` |
|
||||
| `archive/v1/src/services/pose_service.py` | 739 | `"uptime_seconds": 0.0 # TODO` |
|
||||
|
||||
### Root Cause Analysis
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ def _parse_atheros(self, raw_data: bytes) -> CSIData:
|
|||
**All mock code moves to a dedicated module. Default execution NEVER touches mock paths.**
|
||||
|
||||
```
|
||||
v1/src/
|
||||
archive/v1/src/
|
||||
├── core/
|
||||
│ ├── csi_processor.py # Real processing only
|
||||
│ └── router_interface.py # Real hardware interface only
|
||||
|
|
@ -157,7 +157,7 @@ if MOCK_MODE:
|
|||
A small real CSI capture file + one-command verification pipeline:
|
||||
|
||||
```
|
||||
v1/data/proof/
|
||||
archive/v1/data/proof/
|
||||
├── README.md # How to verify
|
||||
├── sample_csi_capture.bin # Real CSI data (1 second, ~50 KB)
|
||||
├── sample_csi_capture_meta.json # Capture metadata (hardware, env)
|
||||
|
|
@ -172,7 +172,7 @@ v1/data/proof/
|
|||
"""Verify WiFi-DensePose pipeline produces deterministic output from real CSI data.
|
||||
|
||||
Usage:
|
||||
python v1/data/proof/verify.py
|
||||
python archive/v1/data/proof/verify.py
|
||||
|
||||
Expected output:
|
||||
PASS: Pipeline output matches expected hash
|
||||
|
|
@ -265,13 +265,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
WORKDIR /app
|
||||
|
||||
# Pinned requirements (not a reference to missing file)
|
||||
COPY v1/requirements-lock.txt ./requirements.txt
|
||||
COPY archive/v1/requirements-lock.txt ./requirements.txt
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY v1/ ./v1/
|
||||
COPY archive/v1/ ./v1/
|
||||
|
||||
# Proof of reality: verify pipeline on build
|
||||
RUN cd v1 && python data/proof/verify.py
|
||||
RUN cd archive/v1 && python data/proof/verify.py
|
||||
|
||||
EXPOSE 8000
|
||||
# Default: REAL mode (mock requires explicit opt-in)
|
||||
|
|
@ -281,7 +281,7 @@ CMD ["uvicorn", "v1.src.api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|||
|
||||
**Key change**: `RUN python data/proof/verify.py` **during build** means the Docker image cannot be created unless the pipeline produces correct output from real CSI data.
|
||||
|
||||
**Requirements lockfile** (`v1/requirements-lock.txt`):
|
||||
**Requirements lockfile** (`archive/v1/requirements-lock.txt`):
|
||||
```
|
||||
# Core (required)
|
||||
fastapi==0.115.6
|
||||
|
|
@ -307,9 +307,9 @@ name: Verify Signal Pipeline
|
|||
|
||||
on:
|
||||
push:
|
||||
paths: ['v1/src/**', 'v1/data/proof/**']
|
||||
paths: ['archive/v1/src/**', 'archive/v1/data/proof/**']
|
||||
pull_request:
|
||||
paths: ['v1/src/**']
|
||||
paths: ['archive/v1/src/**']
|
||||
|
||||
jobs:
|
||||
verify:
|
||||
|
|
@ -322,11 +322,11 @@ jobs:
|
|||
- name: Install minimal deps
|
||||
run: pip install numpy scipy pydantic pydantic-settings
|
||||
- name: Verify pipeline determinism
|
||||
run: python v1/data/proof/verify.py
|
||||
run: python archive/v1/data/proof/verify.py
|
||||
- name: Verify no random in production paths
|
||||
run: |
|
||||
# Fail if np.random appears in production code (not in testing/)
|
||||
! grep -r "np\.random\.\(rand\|randn\|randint\)" v1/src/ \
|
||||
! grep -r "np\.random\.\(rand\|randn\|randint\)" archive/v1/src/ \
|
||||
--include="*.py" \
|
||||
--exclude-dir=testing \
|
||||
|| (echo "FAIL: np.random found in production code" && exit 1)
|
||||
|
|
@ -336,23 +336,23 @@ jobs:
|
|||
|
||||
| File | Action | Description |
|
||||
|------|--------|-------------|
|
||||
| `v1/src/core/csi_processor.py:390` | **Replace** | Real Doppler extraction from temporal CSI history |
|
||||
| `v1/src/hardware/csi_extractor.py:83-84` | **Replace** | Hard error with descriptive message when parsing fails |
|
||||
| `v1/src/hardware/csi_extractor.py:129-135` | **Replace** | Real Atheros CSI parser or hard error with hardware instructions |
|
||||
| `v1/src/hardware/router_interface.py:198-212` | **Replace** | Hard error for unimplemented hardware, or real `iwconfig` + CSI tool integration |
|
||||
| `v1/src/services/pose_service.py:293-356` | **Move** | Move `_generate_mock_poses()` to `v1/src/testing/mock_pose_generator.py` |
|
||||
| `v1/src/services/pose_service.py:430-431` | **Remove** | Remove mock CSI generation from production path |
|
||||
| `v1/src/services/pose_service.py:489-607` | **Replace** | Real statistics from database, or explicit "no data" response |
|
||||
| `v1/src/core/router_interface.py:60-300` | **Move** | Move mock generator to `v1/src/testing/mock_csi_generator.py` |
|
||||
| `v1/src/api/dependencies.py:82,408` | **Replace** | Real auth check or explicit dev-mode bypass with logging |
|
||||
| `v1/data/proof/` | **Create** | Proof bundle (sample capture + expected hash + verify script) |
|
||||
| `v1/requirements-lock.txt` | **Create** | Pinned minimal dependencies |
|
||||
| `archive/v1/src/core/csi_processor.py:390` | **Replace** | Real Doppler extraction from temporal CSI history |
|
||||
| `archive/v1/src/hardware/csi_extractor.py:83-84` | **Replace** | Hard error with descriptive message when parsing fails |
|
||||
| `archive/v1/src/hardware/csi_extractor.py:129-135` | **Replace** | Real Atheros CSI parser or hard error with hardware instructions |
|
||||
| `archive/v1/src/hardware/router_interface.py:198-212` | **Replace** | Hard error for unimplemented hardware, or real `iwconfig` + CSI tool integration |
|
||||
| `archive/v1/src/services/pose_service.py:293-356` | **Move** | Move `_generate_mock_poses()` to `archive/v1/src/testing/mock_pose_generator.py` |
|
||||
| `archive/v1/src/services/pose_service.py:430-431` | **Remove** | Remove mock CSI generation from production path |
|
||||
| `archive/v1/src/services/pose_service.py:489-607` | **Replace** | Real statistics from database, or explicit "no data" response |
|
||||
| `archive/v1/src/core/router_interface.py:60-300` | **Move** | Move mock generator to `archive/v1/src/testing/mock_csi_generator.py` |
|
||||
| `archive/v1/src/api/dependencies.py:82,408` | **Replace** | Real auth check or explicit dev-mode bypass with logging |
|
||||
| `archive/v1/data/proof/` | **Create** | Proof bundle (sample capture + expected hash + verify script) |
|
||||
| `archive/v1/requirements-lock.txt` | **Create** | Pinned minimal dependencies |
|
||||
| `.github/workflows/verify-pipeline.yml` | **Create** | CI verification |
|
||||
|
||||
### Hardware Documentation
|
||||
|
||||
```
|
||||
v1/docs/hardware-setup.md (to be created)
|
||||
archive/v1/docs/hardware-setup.md (to be created)
|
||||
|
||||
# Supported Hardware Matrix
|
||||
|
||||
|
|
@ -368,17 +368,17 @@ v1/docs/hardware-setup.md (to be created)
|
|||
2. Capture 10 seconds of empty-room baseline
|
||||
3. Have one person walk through at normal pace
|
||||
4. Capture 10 seconds during walk-through
|
||||
5. Run calibration: `python v1/scripts/calibrate.py --baseline empty.dat --activity walk.dat`
|
||||
5. Run calibration: `python archive/v1/scripts/calibrate.py --baseline empty.dat --activity walk.dat`
|
||||
```
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
- **"Clone, build, verify" in one command**: `docker build . && docker run --rm wifi-densepose python v1/data/proof/verify.py` produces a deterministic PASS
|
||||
- **"Clone, build, verify" in one command**: `docker build . && docker run --rm wifi-densepose python archive/v1/data/proof/verify.py` produces a deterministic PASS
|
||||
- **No silent fakes**: Random data never appears in production output
|
||||
- **CI enforcement**: PRs that introduce `np.random` in production paths fail automatically
|
||||
- **Credibility anchor**: SHA-256 verified output from real CSI capture is unchallengeable proof
|
||||
- **Clear mock boundary**: Mock code exists only in `v1/src/testing/`, never imported by production modules
|
||||
- **Clear mock boundary**: Mock code exists only in `archive/v1/src/testing/`, never imported by production modules
|
||||
|
||||
### Negative
|
||||
- **Requires real CSI capture**: Someone must capture and commit a real CSI sample (one-time effort)
|
||||
|
|
@ -390,7 +390,7 @@ v1/docs/hardware-setup.md (to be created)
|
|||
|
||||
A stranger can:
|
||||
1. `git clone` the repository
|
||||
2. Run ONE command (`docker build .` or `python v1/data/proof/verify.py`)
|
||||
2. Run ONE command (`docker build .` or `python archive/v1/data/proof/verify.py`)
|
||||
3. See `PASS: Pipeline output matches expected hash` with a specific SHA-256
|
||||
4. Confirm no `np.random` in any non-test file via CI badge
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# ADR-013: Feature-Level Sensing on Commodity Gear (Option 3)
|
||||
|
||||
## Status
|
||||
Accepted — Implemented (36/36 unit tests pass, see `v1/src/sensing/` and `v1/tests/unit/test_sensing.py`)
|
||||
Accepted — Implemented (36/36 unit tests pass, see `archive/v1/src/sensing/` and `archive/v1/tests/unit/test_sensing.py`)
|
||||
|
||||
## Date
|
||||
2026-02-28
|
||||
|
|
@ -323,7 +323,7 @@ class PresenceClassifier:
|
|||
### Proof Bundle for Commodity Sensing
|
||||
|
||||
```
|
||||
v1/data/proof/commodity/
|
||||
archive/v1/data/proof/commodity/
|
||||
├── rssi_capture_30sec.json # 30 seconds of RSSI from 3 receivers
|
||||
├── rssi_capture_meta.json # Hardware: Intel AX200, Router: TP-Link AX1800
|
||||
├── scenario.txt # "Person walks through room at t=10s, sits at t=20s"
|
||||
|
|
@ -375,7 +375,7 @@ class CommodityBackend(SensingBackend):
|
|||
|
||||
### Implementation Status
|
||||
|
||||
The full commodity sensing pipeline is implemented in `v1/src/sensing/`:
|
||||
The full commodity sensing pipeline is implemented in `archive/v1/src/sensing/`:
|
||||
|
||||
| Module | File | Description |
|
||||
|--------|------|-------------|
|
||||
|
|
@ -384,7 +384,7 @@ The full commodity sensing pipeline is implemented in `v1/src/sensing/`:
|
|||
| Classifier | `classifier.py` | `PresenceClassifier` with ABSENT/PRESENT_STILL/ACTIVE levels, confidence scoring |
|
||||
| Backend | `backend.py` | `CommodityBackend` wiring collector → extractor → classifier, reports PRESENCE + MOTION capabilities |
|
||||
|
||||
**Test coverage**: 36 tests in `v1/tests/unit/test_sensing.py` — all passing:
|
||||
**Test coverage**: 36 tests in `archive/v1/tests/unit/test_sensing.py` — all passing:
|
||||
- `TestRingBuffer` (4), `TestSimulatedCollector` (5), `TestFeatureExtractor` (8), `TestCusum` (4), `TestPresenceClassifier` (7), `TestCommodityBackend` (6), `TestBandPower` (2)
|
||||
|
||||
**Dependencies**: `numpy`, `scipy` (for FFT and spectral analysis)
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ This ADR answers *how* to build it — the concrete development sequence, the sp
|
|||
| Frame types | `wifi-densepose-hardware/src/csi_frame.rs` | Complete — `CsiFrame`, `CsiMetadata`, `SubcarrierData`, `to_amplitude_phase()` |
|
||||
| Parse error types | `wifi-densepose-hardware/src/error.rs` | Complete — `ParseError` enum with 6 variants |
|
||||
| Signal processing pipeline | `wifi-densepose-signal` crate | Complete — Hampel, Fresnel, BVP, Doppler, spectrogram |
|
||||
| CSI extractor (Python) | `v1/src/hardware/csi_extractor.py` | Stub — `_read_raw_data()` raises `NotImplementedError` |
|
||||
| Router interface (Python) | `v1/src/hardware/router_interface.py` | Stub — `_parse_csi_response()` raises `RouterConnectionError` |
|
||||
| CSI extractor (Python) | `archive/v1/src/hardware/csi_extractor.py` | Stub — `_read_raw_data()` raises `NotImplementedError` |
|
||||
| Router interface (Python) | `archive/v1/src/hardware/router_interface.py` | Stub — `_parse_csi_response()` raises `RouterConnectionError` |
|
||||
|
||||
**Not yet implemented:**
|
||||
|
||||
|
|
@ -211,10 +211,10 @@ The bridge test: parse a known binary frame, convert to `CsiData`, assert `ampli
|
|||
|
||||
### Layer 4 — Python `_read_raw_data()` Real Implementation
|
||||
|
||||
Replace the `NotImplementedError` stub in `v1/src/hardware/csi_extractor.py` with a UDP socket reader. This allows the Python pipeline to receive real CSI from the aggregator while the Rust pipeline is being integrated.
|
||||
Replace the `NotImplementedError` stub in `archive/v1/src/hardware/csi_extractor.py` with a UDP socket reader. This allows the Python pipeline to receive real CSI from the aggregator while the Rust pipeline is being integrated.
|
||||
|
||||
```python
|
||||
# v1/src/hardware/csi_extractor.py
|
||||
# archive/v1/src/hardware/csi_extractor.py
|
||||
# Replace _read_raw_data() stub:
|
||||
|
||||
import socket as _socket
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ Implement a **sensing-only UI mode** that:
|
|||
- Breathing ring modulation when breathing-band power detected
|
||||
- Side panel with RSSI sparkline, feature meters, and classification badge
|
||||
|
||||
4. **Python WebSocket bridge** (`v1/src/sensing/ws_server.py`) that:
|
||||
4. **Python WebSocket bridge** (`archive/v1/src/sensing/ws_server.py`) that:
|
||||
- Auto-detects ESP32 UDP CSI stream on port 5005 (ADR-018 binary frames)
|
||||
- Falls back to `WindowsWifiCollector` → `SimulatedCollector`
|
||||
- Runs `RssiFeatureExtractor` → `PresenceClassifier` pipeline
|
||||
|
|
@ -80,7 +80,7 @@ Windows WiFi RSSI ───┘ │ │
|
|||
### Created
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `v1/src/sensing/ws_server.py` | Python asyncio WebSocket server with auto-detect collectors |
|
||||
| `archive/v1/src/sensing/ws_server.py` | Python asyncio WebSocket server with auto-detect collectors |
|
||||
| `ui/components/SensingTab.js` | Sensing tab UI with Three.js integration |
|
||||
| `ui/components/gaussian-splats.js` | Custom GLSL Gaussian splat renderer |
|
||||
| `ui/services/sensing.service.js` | WebSocket client with reconnect + simulation fallback |
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ Use the `wifi-densepose-nn` crate with `default-features = ["onnx"]` only. This
|
|||
|
||||
| Component | Rust Crate | Replaces Python |
|
||||
|-----------|-----------|-----------------|
|
||||
| CSI processing | `wifi-densepose-signal::csi_processor` | `v1/src/sensing/feature_extractor.py` |
|
||||
| Motion detection | `wifi-densepose-signal::motion` | `v1/src/sensing/classifier.py` |
|
||||
| CSI processing | `wifi-densepose-signal::csi_processor` | `archive/v1/src/sensing/feature_extractor.py` |
|
||||
| Motion detection | `wifi-densepose-signal::motion` | `archive/v1/src/sensing/classifier.py` |
|
||||
| BVP extraction | `wifi-densepose-signal::bvp` | N/A (new capability) |
|
||||
| Fresnel geometry | `wifi-densepose-signal::fresnel` | N/A (new capability) |
|
||||
| Subcarrier selection | `wifi-densepose-signal::subcarrier_selection` | N/A (new capability) |
|
||||
|
|
|
|||
|
|
@ -232,10 +232,10 @@ python scripts/provision.py --port COM7 \
|
|||
|
||||
| Component | File | Purpose |
|
||||
|-----------|------|---------|
|
||||
| Reference signal | `v1/data/proof/sample_csi_data.json` | 1,000 synthetic CSI frames, seed=42 |
|
||||
| Generator | `v1/data/proof/generate_reference_signal.py` | Deterministic multipath model |
|
||||
| Verifier | `v1/data/proof/verify.py` | SHA-256 hash comparison |
|
||||
| Expected hash | `v1/data/proof/expected_features.sha256` | `0b82bd45...` |
|
||||
| Reference signal | `archive/v1/data/proof/sample_csi_data.json` | 1,000 synthetic CSI frames, seed=42 |
|
||||
| Generator | `archive/v1/data/proof/generate_reference_signal.py` | Deterministic multipath model |
|
||||
| Verifier | `archive/v1/data/proof/verify.py` | SHA-256 hash comparison |
|
||||
| Expected hash | `archive/v1/data/proof/expected_features.sha256` | `0b82bd45...` |
|
||||
|
||||
**Audit-time result:** PASS. Hash regenerated with numpy 2.4.2 + scipy 1.17.1. Pipeline hash: `8c0680d7d285739ea9597715e84959d9c356c87ee3ad35b5f1e69a4ca41151c6`.
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ Remove duplicated platform-detection logic from `ws_server.py` and `install.sh`.
|
|||
|
||||
## Implementation Notes
|
||||
|
||||
1. Add `create_collector()` and `BaseCollector.is_available()` to `v1/src/sensing/rssi_collector.py`
|
||||
1. Add `create_collector()` and `BaseCollector.is_available()` to `archive/v1/src/sensing/rssi_collector.py`
|
||||
2. Refactor `ws_server.py` `_init_collector()` to call `create_collector()`
|
||||
3. Update `install.sh` `detect_wifi_hardware()` to use shared detection logic
|
||||
4. Add unit tests for each platform path (mock `/proc/net/wireless` presence/absence)
|
||||
|
|
|
|||
|
|
@ -17,19 +17,19 @@ Address the 15 prioritized issues from the QE analysis in three waves: P0 (immed
|
|||
|
||||
### 1. Rate Limiter Bypass (Security HIGH)
|
||||
|
||||
- **Location:** `v1/src/middleware/rate_limit.py:200-206`
|
||||
- **Location:** `archive/v1/src/middleware/rate_limit.py:200-206`
|
||||
- **Problem:** Trusts `X-Forwarded-For` without validation. Any client bypasses rate limits via header spoofing.
|
||||
- **Fix:** Validate forwarded headers against trusted proxy list, or use connection IP directly.
|
||||
|
||||
### 2. Exception Details Leaked in Responses (Security HIGH)
|
||||
|
||||
- **Location:** `v1/src/api/routers/pose.py:140`, `stream.py:297`, +5 endpoints
|
||||
- **Location:** `archive/v1/src/api/routers/pose.py:140`, `stream.py:297`, +5 endpoints
|
||||
- **Problem:** Stack traces visible regardless of environment.
|
||||
- **Fix:** Wrap with generic error responses in production; log details server-side only.
|
||||
|
||||
### 3. WebSocket JWT in URL (Security HIGH, CWE-598)
|
||||
|
||||
- **Location:** `v1/src/api/routers/stream.py:74`, `v1/src/middleware/auth.py:243`
|
||||
- **Location:** `archive/v1/src/api/routers/stream.py:74`, `archive/v1/src/middleware/auth.py:243`
|
||||
- **Problem:** Tokens in query strings visible in logs/proxies/browser history.
|
||||
- **Fix:** Use WebSocket subprotocol or first-message auth pattern.
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ This runs three phases:
|
|||
|
||||
1. **Environment checks** -- confirms Python, numpy, scipy, and proof files are present.
|
||||
2. **Proof pipeline replay** -- feeds a published reference signal through the full signal processing chain (noise filtering, Hamming windowing, amplitude normalization, FFT-based Doppler extraction, power spectral density via scipy.fft) and computes a SHA-256 hash of the output.
|
||||
3. **Production code integrity scan** -- scans `v1/src/` for `np.random.rand` / `np.random.randn` calls in production code (test helpers are excluded).
|
||||
3. **Production code integrity scan** -- scans `archive/v1/src/` for `np.random.rand` / `np.random.randn` calls in production code (test helpers are excluded).
|
||||
|
||||
Exit codes:
|
||||
- `0` PASS -- pipeline hash matches the published expected hash
|
||||
|
|
@ -51,7 +51,7 @@ make verify-audit
|
|||
If the expected hash file is missing, regenerate it:
|
||||
|
||||
```bash
|
||||
python3 v1/data/proof/verify.py --generate-hash
|
||||
python3 archive/v1/data/proof/verify.py --generate-hash
|
||||
```
|
||||
|
||||
### Minimal dependencies for verification only
|
||||
|
|
@ -63,7 +63,7 @@ pip install numpy==1.26.4 scipy==1.14.1
|
|||
Or install the pinned set that guarantees hash reproducibility:
|
||||
|
||||
```bash
|
||||
pip install -r v1/requirements-lock.txt
|
||||
pip install -r archive/v1/requirements-lock.txt
|
||||
```
|
||||
|
||||
The lock file pins: `numpy==1.26.4`, `scipy==1.14.1`, `pydantic==2.10.4`, `pydantic-settings==2.7.1`.
|
||||
|
|
@ -82,7 +82,7 @@ The Python pipeline lives under `v1/` and provides the full API server, signal p
|
|||
### Install (verification-only -- lightweight)
|
||||
|
||||
```bash
|
||||
pip install -r v1/requirements-lock.txt
|
||||
pip install -r archive/v1/requirements-lock.txt
|
||||
```
|
||||
|
||||
This installs only the four packages needed for deterministic pipeline verification.
|
||||
|
|
@ -98,7 +98,7 @@ This pulls in FastAPI, uvicorn, torch, OpenCV, SQLAlchemy, Redis client, and all
|
|||
### Verify the pipeline
|
||||
|
||||
```bash
|
||||
python3 v1/data/proof/verify.py
|
||||
python3 archive/v1/data/proof/verify.py
|
||||
```
|
||||
|
||||
Same as `./verify` but calls the Python script directly, skipping the bash wrapper's codebase scan phase.
|
||||
|
|
@ -124,7 +124,7 @@ uvicorn v1.src.api.main:app --host 0.0.0.0 --port 8000 --reload
|
|||
|
||||
### Run with commodity WiFi (RSSI sensing -- no custom hardware)
|
||||
|
||||
The commodity sensing module (`v1/src/sensing/`) extracts presence and motion features from standard Linux WiFi metrics (RSSI, noise floor, link quality) without any hardware modification. See [ADR-013](adr/ADR-013-feature-level-sensing-commodity-gear.md) for full design details.
|
||||
The commodity sensing module (`archive/v1/src/sensing/`) extracts presence and motion features from standard Linux WiFi metrics (RSSI, noise floor, link quality) without any hardware modification. See [ADR-013](adr/ADR-013-feature-level-sensing-commodity-gear.md) for full design details.
|
||||
|
||||
Requirements:
|
||||
- Any Linux machine with a WiFi interface (laptop, Raspberry Pi, etc.)
|
||||
|
|
@ -667,13 +667,13 @@ python3 -m http.server 3000 --directory ui
|
|||
|------|---------|
|
||||
| `./verify` | Trust kill switch -- one-command pipeline proof |
|
||||
| `Makefile` | `make verify`, `make verify-verbose`, `make verify-audit` |
|
||||
| `v1/requirements-lock.txt` | Pinned Python deps for hash reproducibility |
|
||||
| `archive/v1/requirements-lock.txt` | Pinned Python deps for hash reproducibility |
|
||||
| `requirements.txt` | Full Python deps (API server, torch, etc.) |
|
||||
| `v1/data/proof/verify.py` | Python verification script |
|
||||
| `v1/data/proof/sample_csi_data.json` | Deterministic reference signal |
|
||||
| `v1/data/proof/expected_features.sha256` | Published expected hash |
|
||||
| `v1/src/api/main.py` | FastAPI application entry point |
|
||||
| `v1/src/sensing/` | Commodity WiFi sensing module (RSSI) |
|
||||
| `archive/v1/data/proof/verify.py` | Python verification script |
|
||||
| `archive/v1/data/proof/sample_csi_data.json` | Deterministic reference signal |
|
||||
| `archive/v1/data/proof/expected_features.sha256` | Published expected hash |
|
||||
| `archive/v1/src/api/main.py` | FastAPI application entry point |
|
||||
| `archive/v1/src/sensing/` | Commodity WiFi sensing module (RSSI) |
|
||||
| `v2/Cargo.toml` | Rust workspace root |
|
||||
| `ui/viz.html` | Three.js 3D visualization |
|
||||
| `Dockerfile` | Multi-stage Docker build (dev/prod/test/security) |
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ The project implements WiFi-based human pose estimation using Channel State Info
|
|||
| Architecture Decision Records | Strong | 79 ADRs documented in `docs/adr/` |
|
||||
| CI/CD pipelines | Strong | 8 GitHub Actions workflows (CI, CD, security scan, firmware CI, QEMU, desktop release, verify pipeline, submodules) |
|
||||
| Security scanning | Strong | Dedicated `security-scan.yml` with Bandit, Semgrep, Safety; runs daily on schedule |
|
||||
| Deterministic verification | Strong | SHA-256 proof pipeline (`v1/data/proof/verify.py`) with witness bundles (ADR-028) |
|
||||
| Deterministic verification | Strong | SHA-256 proof pipeline (`archive/v1/data/proof/verify.py`) with witness bundles (ADR-028) |
|
||||
| Code formatting | Moderate | Black/Flake8 enforced for Python in CI; no `rustfmt.toml` found for Rust |
|
||||
| Type checking | Moderate | MyPy configured in CI for Python; Rust has native type safety |
|
||||
| Dependency management | Strong | Workspace-level Cargo.toml with pinned versions; `requirements.txt` for Python |
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ or macro-based approach would reduce this to a fraction of the code.
|
|||
| wifi-densepose-wifiscan | 75/100 | EASY | Platform-specific but well-abstracted |
|
||||
| wifi-densepose-sensing-server | 32/100 | VERY DIFFICULT | God object, coupled state, async |
|
||||
| wifi-densepose-wasm-edge | 55/100 | MODERATE | Repetitive but self-contained |
|
||||
| v1/src (Python) | 70/100 | MODERATE | Good DI, some tight coupling |
|
||||
| archive/v1/src (Python) | 70/100 | MODERATE | Good DI, some tight coupling |
|
||||
| firmware (C) | 40/100 | DIFFICULT | Hardware deps, global state |
|
||||
| ui/mobile (TypeScript) | 72/100 | MODERATE | Component isolation is good |
|
||||
|
||||
|
|
|
|||
|
|
@ -35,20 +35,20 @@ This security review examined all security-sensitive code across the wifi-densep
|
|||
**Severity:** HIGH
|
||||
**OWASP:** A07:2021 -- Identification and Authentication Failures
|
||||
**Files:**
|
||||
- `v1/src/api/routers/stream.py:74` (WebSocket `token` query parameter)
|
||||
- `v1/src/middleware/auth.py:243` (fallback to `request.query_params.get("token")`)
|
||||
- `v1/src/api/middleware/auth.py:173` (`request.query_params.get("token")`)
|
||||
- `archive/v1/src/api/routers/stream.py:74` (WebSocket `token` query parameter)
|
||||
- `archive/v1/src/middleware/auth.py:243` (fallback to `request.query_params.get("token")`)
|
||||
- `archive/v1/src/api/middleware/auth.py:173` (`request.query_params.get("token")`)
|
||||
|
||||
**Description:**
|
||||
JWT tokens are accepted via URL query parameters for WebSocket connections. URL parameters are logged in web server access logs, browser history, proxy logs, and HTTP Referer headers. This creates multiple credential leakage vectors.
|
||||
|
||||
```python
|
||||
# v1/src/api/routers/stream.py:74
|
||||
# archive/v1/src/api/routers/stream.py:74
|
||||
token: Optional[str] = Query(None, description="Authentication token")
|
||||
```
|
||||
|
||||
```python
|
||||
# v1/src/middleware/auth.py:243
|
||||
# archive/v1/src/middleware/auth.py:243
|
||||
if request.url.path.startswith("/ws"):
|
||||
token = request.query_params.get("token")
|
||||
```
|
||||
|
|
@ -66,13 +66,13 @@ if request.url.path.startswith("/ws"):
|
|||
|
||||
**Severity:** HIGH
|
||||
**OWASP:** A05:2021 -- Security Misconfiguration
|
||||
**File:** `v1/src/middleware/rate_limit.py:200-206`
|
||||
**File:** `archive/v1/src/middleware/rate_limit.py:200-206`
|
||||
|
||||
**Description:**
|
||||
The `_get_client_ip` method trusts the `X-Forwarded-For` header without any validation. An attacker can spoof this header to bypass IP-based rate limiting entirely by rotating forged IP addresses on each request.
|
||||
|
||||
```python
|
||||
# v1/src/middleware/rate_limit.py:200-206
|
||||
# archive/v1/src/middleware/rate_limit.py:200-206
|
||||
def _get_client_ip(self, request: Request) -> str:
|
||||
forwarded_for = request.headers.get("X-Forwarded-For")
|
||||
if forwarded_for:
|
||||
|
|
@ -99,17 +99,17 @@ def _get_client_ip(self, request: Request) -> str:
|
|||
**Severity:** HIGH
|
||||
**OWASP:** A09:2021 -- Security Logging and Monitoring Failures
|
||||
**Files:**
|
||||
- `v1/src/api/routers/pose.py:140-141` -- `detail=f"Pose estimation failed: {str(e)}"`
|
||||
- `v1/src/api/routers/pose.py:176-177` -- `detail=f"Pose analysis failed: {str(e)}"`
|
||||
- `v1/src/api/routers/stream.py:297` -- `detail=f"Failed to get stream status: {str(e)}"`
|
||||
- All exception handlers in `v1/src/api/routers/stream.py` (lines 326, 351, 404, 442, 463)
|
||||
- `v1/src/middleware/error_handler.py:101-104` -- traceback in development mode
|
||||
- `archive/v1/src/api/routers/pose.py:140-141` -- `detail=f"Pose estimation failed: {str(e)}"`
|
||||
- `archive/v1/src/api/routers/pose.py:176-177` -- `detail=f"Pose analysis failed: {str(e)}"`
|
||||
- `archive/v1/src/api/routers/stream.py:297` -- `detail=f"Failed to get stream status: {str(e)}"`
|
||||
- All exception handlers in `archive/v1/src/api/routers/stream.py` (lines 326, 351, 404, 442, 463)
|
||||
- `archive/v1/src/middleware/error_handler.py:101-104` -- traceback in development mode
|
||||
|
||||
**Description:**
|
||||
Multiple API endpoints directly interpolate Python exception messages into HTTP error responses. While the global error handler in `error_handler.py` correctly suppresses details in production, the per-endpoint `HTTPException` handlers bypass this and always expose `str(e)` regardless of environment.
|
||||
|
||||
```python
|
||||
# v1/src/api/routers/pose.py:140-141
|
||||
# archive/v1/src/api/routers/pose.py:140-141
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Pose estimation failed: {str(e)}"
|
||||
|
|
@ -130,14 +130,14 @@ raise HTTPException(
|
|||
**Severity:** MEDIUM
|
||||
**OWASP:** A05:2021 -- Security Misconfiguration
|
||||
**Files:**
|
||||
- `v1/src/config/settings.py:33-34` -- defaults: `cors_origins=["*"]`, `cors_allow_credentials=True`
|
||||
- `v1/src/middleware/cors.py:255-256` -- development config combines `allow_origins=["*"]` + `allow_credentials=True`
|
||||
- `archive/v1/src/config/settings.py:33-34` -- defaults: `cors_origins=["*"]`, `cors_allow_credentials=True`
|
||||
- `archive/v1/src/middleware/cors.py:255-256` -- development config combines `allow_origins=["*"]` + `allow_credentials=True`
|
||||
|
||||
**Description:**
|
||||
The default settings allow CORS from all origins (`*`) with credentials (`allow_credentials=True`). Per the CORS specification, `Access-Control-Allow-Origin: *` cannot be used with `Access-Control-Allow-Credentials: true`. However, the `CORSMiddleware` implementation echoes the requesting origin header verbatim, effectively granting credentialed access from any origin.
|
||||
|
||||
```python
|
||||
# v1/src/middleware/cors.py:255-256 (development_config)
|
||||
# archive/v1/src/middleware/cors.py:255-256 (development_config)
|
||||
"allow_origins": ["*"],
|
||||
"allow_credentials": True,
|
||||
```
|
||||
|
|
@ -158,8 +158,8 @@ The `validate_cors_config` function at line 354 correctly flags this combination
|
|||
**Severity:** MEDIUM
|
||||
**OWASP:** A04:2021 -- Insecure Design
|
||||
**Files:**
|
||||
- `v1/src/api/routers/stream.py:127-128` -- `message = await websocket.receive_text()` with no size limit
|
||||
- `v1/src/api/websocket/connection_manager.py` -- no `max_size` configuration
|
||||
- `archive/v1/src/api/routers/stream.py:127-128` -- `message = await websocket.receive_text()` with no size limit
|
||||
- `archive/v1/src/api/websocket/connection_manager.py` -- no `max_size` configuration
|
||||
|
||||
**Description:**
|
||||
WebSocket endpoints accept incoming messages of arbitrary size. The `receive_text()` call at `stream.py:127` has no size limit, allowing a client to send extremely large messages that consume server memory.
|
||||
|
|
@ -179,7 +179,7 @@ Additionally, the `ConnectionManager` does not enforce a maximum number of conne
|
|||
|
||||
**Severity:** MEDIUM
|
||||
**OWASP:** A07:2021 -- Identification and Authentication Failures
|
||||
**File:** `v1/src/api/middleware/auth.py:246-252`
|
||||
**File:** `archive/v1/src/api/middleware/auth.py:246-252`
|
||||
|
||||
**Description:**
|
||||
The `TokenBlacklist` class clears all blacklisted tokens every hour, regardless of their actual expiry time. This means:
|
||||
|
|
@ -187,7 +187,7 @@ The `TokenBlacklist` class clears all blacklisted tokens every hour, regardless
|
|||
2. Tokens revoked just before a clear cycle have nearly zero effective blacklist time.
|
||||
|
||||
```python
|
||||
# v1/src/api/middleware/auth.py:246-252
|
||||
# archive/v1/src/api/middleware/auth.py:246-252
|
||||
def _cleanup_if_needed(self):
|
||||
now = datetime.utcnow()
|
||||
if (now - self._last_cleanup).total_seconds() > self._cleanup_interval:
|
||||
|
|
@ -306,8 +306,8 @@ if (s_cfg.seed_token[0] != '\0') {
|
|||
**Severity:** MEDIUM
|
||||
**OWASP:** A04:2021 -- Insecure Design
|
||||
**Files:**
|
||||
- `v1/src/api/middleware/rate_limit.py:28-29` -- `self.request_counts = defaultdict(lambda: deque())`
|
||||
- `v1/src/middleware/rate_limit.py:132` -- `self._sliding_windows: Dict[str, SlidingWindowCounter] = {}`
|
||||
- `archive/v1/src/api/middleware/rate_limit.py:28-29` -- `self.request_counts = defaultdict(lambda: deque())`
|
||||
- `archive/v1/src/middleware/rate_limit.py:132` -- `self._sliding_windows: Dict[str, SlidingWindowCounter] = {}`
|
||||
|
||||
**Description:**
|
||||
Both rate limiter implementations store per-client sliding window data in unbounded in-memory dictionaries. An attacker sending requests from many spoofed IPs (see HIGH-002) can create millions of entries, each containing a `deque` of timestamps. The cleanup tasks run only periodically (every 5 minutes or on-demand) and cannot keep pace with a high-rate attack.
|
||||
|
|
@ -349,8 +349,8 @@ While marked with a comment indicating it should be changed, this file is checke
|
|||
**Severity:** LOW
|
||||
**OWASP:** A01:2021 -- Broken Access Control
|
||||
**Files:**
|
||||
- `v1/src/middleware/auth.py:298-299` -- `response.headers["X-User"] = user_info["username"]` and `response.headers["X-User-Roles"] = ",".join(user_info["roles"])`
|
||||
- `v1/src/api/middleware/auth.py:111` -- `response.headers["X-User-ID"] = request.state.user.get("id", "")`
|
||||
- `archive/v1/src/middleware/auth.py:298-299` -- `response.headers["X-User"] = user_info["username"]` and `response.headers["X-User-Roles"] = ",".join(user_info["roles"])`
|
||||
- `archive/v1/src/api/middleware/auth.py:111` -- `response.headers["X-User-ID"] = request.state.user.get("id", "")`
|
||||
|
||||
**Description:**
|
||||
Authenticated user information (username, roles, user ID) is included in HTTP response headers. These headers are visible to any intermediary (CDN, reverse proxy, browser extensions) and in browser developer tools.
|
||||
|
|
@ -380,7 +380,7 @@ Replace all instances of `datetime.utcnow()` with `datetime.now(datetime.timezon
|
|||
|
||||
**Severity:** LOW
|
||||
**OWASP:** A02:2021 -- Cryptographic Failures
|
||||
**File:** `v1/src/config/settings.py:30` -- `jwt_algorithm: str = Field(default="HS256")`
|
||||
**File:** `archive/v1/src/config/settings.py:30` -- `jwt_algorithm: str = Field(default="HS256")`
|
||||
|
||||
**Description:**
|
||||
The default JWT algorithm is HS256 (HMAC-SHA256), a symmetric algorithm. This means the same secret is used for both signing and verification, requiring the secret to be distributed to every service that needs to verify tokens. For multi-service architectures, asymmetric algorithms (RS256, ES256) are preferred.
|
||||
|
|
@ -398,7 +398,7 @@ Additionally, the `jwt_algorithm` setting is not validated against a safe algori
|
|||
|
||||
**Severity:** LOW
|
||||
**OWASP:** A07:2021 -- Identification and Authentication Failures
|
||||
**File:** `v1/src/middleware/auth.py:115` -- `create_user()` method
|
||||
**File:** `archive/v1/src/middleware/auth.py:115` -- `create_user()` method
|
||||
|
||||
**Description:**
|
||||
The `create_user()` method accepts any password without minimum length, complexity, or entropy requirements. Test credentials in `v1/test_auth_rate_limit.py:21-23` demonstrate weak passwords ("admin123", "user123").
|
||||
|
|
@ -460,7 +460,7 @@ This is a positive finding reflecting good security practices.
|
|||
| `paramiko>=3.0.0` | LOW -- SSH library. Ensure latest minor version for CVE patches. |
|
||||
| `fastapi>=0.95.0` | LOW -- Version floor is old. Pin to latest stable for security patches. |
|
||||
|
||||
**Recommendation:** Run `pip audit` or `safety check` against the locked dependency file (`v1/requirements-lock.txt`) to identify known CVEs.
|
||||
**Recommendation:** Run `pip audit` or `safety check` against the locked dependency file (`archive/v1/requirements-lock.txt`) to identify known CVEs.
|
||||
|
||||
### Rust Dependencies (`Cargo.toml`)
|
||||
|
||||
|
|
@ -484,11 +484,11 @@ The following areas demonstrate security-conscious design:
|
|||
|
||||
3. **RVF build hash validation** (`firmware/esp32-csi-node/main/rvf_parser.c:126-137`): SHA-256 hash of the WASM payload is verified against the manifest before loading, preventing tampered module execution.
|
||||
|
||||
4. **Password hashing with bcrypt** (`v1/src/middleware/auth.py:21`): Proper use of `passlib` with `bcrypt` scheme.
|
||||
4. **Password hashing with bcrypt** (`archive/v1/src/middleware/auth.py:21`): Proper use of `passlib` with `bcrypt` scheme.
|
||||
|
||||
5. **Protected user fields** (`v1/src/middleware/auth.py:139`): `update_user()` prevents modification of `username`, `created_at`, and `hashed_password`.
|
||||
5. **Protected user fields** (`archive/v1/src/middleware/auth.py:139`): `update_user()` prevents modification of `username`, `created_at`, and `hashed_password`.
|
||||
|
||||
6. **Production error suppression** (`v1/src/middleware/error_handler.py:214-218`): The centralized error handler correctly suppresses internal details in production mode.
|
||||
6. **Production error suppression** (`archive/v1/src/middleware/error_handler.py:214-218`): The centralized error handler correctly suppresses internal details in production mode.
|
||||
|
||||
7. **No hardcoded secrets in source** (verified via entropy-based search across entire repository): No API keys, passwords, or tokens found in source files (the test script placeholder at `test_auth_rate_limit.py:26` is marked as requiring replacement).
|
||||
|
||||
|
|
@ -502,20 +502,20 @@ The following areas demonstrate security-conscious design:
|
|||
|
||||
## Files Examined
|
||||
|
||||
### Python (v1/src/)
|
||||
- `v1/src/middleware/auth.py` (457 lines) -- JWT auth, user management, middleware
|
||||
- `v1/src/middleware/rate_limit.py` (465 lines) -- Rate limiting with sliding window
|
||||
- `v1/src/middleware/cors.py` (375 lines) -- CORS middleware and validation
|
||||
- `v1/src/middleware/error_handler.py` (505 lines) -- Error handling middleware
|
||||
- `v1/src/api/middleware/auth.py` (303 lines) -- API-layer JWT auth
|
||||
- `v1/src/api/middleware/rate_limit.py` (326 lines) -- API-layer rate limiting
|
||||
- `v1/src/api/websocket/connection_manager.py` (461 lines) -- WebSocket manager
|
||||
- `v1/src/api/websocket/pose_stream.py` (384 lines) -- Pose streaming handler
|
||||
- `v1/src/api/routers/pose.py` (420 lines) -- Pose API endpoints
|
||||
- `v1/src/api/routers/stream.py` (465 lines) -- Streaming API endpoints
|
||||
- `v1/src/config/settings.py` (436 lines) -- Application settings
|
||||
- `v1/src/sensing/rssi_collector.py` (partial) -- Subprocess usage review
|
||||
- `v1/src/tasks/backup.py` (partial) -- Subprocess command construction
|
||||
### Python (archive/v1/src/)
|
||||
- `archive/v1/src/middleware/auth.py` (457 lines) -- JWT auth, user management, middleware
|
||||
- `archive/v1/src/middleware/rate_limit.py` (465 lines) -- Rate limiting with sliding window
|
||||
- `archive/v1/src/middleware/cors.py` (375 lines) -- CORS middleware and validation
|
||||
- `archive/v1/src/middleware/error_handler.py` (505 lines) -- Error handling middleware
|
||||
- `archive/v1/src/api/middleware/auth.py` (303 lines) -- API-layer JWT auth
|
||||
- `archive/v1/src/api/middleware/rate_limit.py` (326 lines) -- API-layer rate limiting
|
||||
- `archive/v1/src/api/websocket/connection_manager.py` (461 lines) -- WebSocket manager
|
||||
- `archive/v1/src/api/websocket/pose_stream.py` (384 lines) -- Pose streaming handler
|
||||
- `archive/v1/src/api/routers/pose.py` (420 lines) -- Pose API endpoints
|
||||
- `archive/v1/src/api/routers/stream.py` (465 lines) -- Streaming API endpoints
|
||||
- `archive/v1/src/config/settings.py` (436 lines) -- Application settings
|
||||
- `archive/v1/src/sensing/rssi_collector.py` (partial) -- Subprocess usage review
|
||||
- `archive/v1/src/tasks/backup.py` (partial) -- Subprocess command construction
|
||||
- `v1/test_auth_rate_limit.py` (partial) -- Test credentials review
|
||||
|
||||
### Rust (v2/)
|
||||
|
|
|
|||
|
|
@ -352,16 +352,16 @@ pub fn run(&self, csi_input: &Tensor) -> NnResult<DensePoseOutput> {
|
|||
|
||||
| File | Lines | Role |
|
||||
|------|-------|------|
|
||||
| `v1/src/core/csi_processor.py` | 467 | CSI processing pipeline |
|
||||
| `v1/src/services/pose_service.py` | 200+ | Pose estimation service |
|
||||
| `v1/src/api/websocket/connection_manager.py` | 461 | WebSocket management |
|
||||
| `v1/src/sensing/feature_extractor.py` | 150+ | RSSI feature extraction |
|
||||
| `archive/v1/src/core/csi_processor.py` | 467 | CSI processing pipeline |
|
||||
| `archive/v1/src/services/pose_service.py` | 200+ | Pose estimation service |
|
||||
| `archive/v1/src/api/websocket/connection_manager.py` | 461 | WebSocket management |
|
||||
| `archive/v1/src/sensing/feature_extractor.py` | 150+ | RSSI feature extraction |
|
||||
|
||||
---
|
||||
|
||||
### FINDING PERF-PY01: Doppler Feature Extraction -- list() Conversion of deque [CRITICAL]
|
||||
|
||||
**File**: `v1/src/core/csi_processor.py`
|
||||
**File**: `archive/v1/src/core/csi_processor.py`
|
||||
**Lines**: 412-414
|
||||
|
||||
```python
|
||||
|
|
@ -391,7 +391,7 @@ class CircularBuffer:
|
|||
|
||||
### FINDING PERF-PY02: CSI Preprocessing Creates 3 New CSIData Objects per Frame [HIGH]
|
||||
|
||||
**File**: `v1/src/core/csi_processor.py`
|
||||
**File**: `archive/v1/src/core/csi_processor.py`
|
||||
**Lines**: 118-377
|
||||
|
||||
The preprocessing pipeline creates a new CSIData object at each step:
|
||||
|
|
@ -417,7 +417,7 @@ Each CSIData construction copies metadata via `{**csi_data.metadata, 'key': True
|
|||
|
||||
### FINDING PERF-PY03: Correlation Matrix -- Full np.corrcoef on Every Frame [MEDIUM]
|
||||
|
||||
**File**: `v1/src/core/csi_processor.py`
|
||||
**File**: `archive/v1/src/core/csi_processor.py`
|
||||
**Lines**: 391-395
|
||||
|
||||
```python
|
||||
|
|
@ -436,7 +436,7 @@ def _extract_correlation_features(self, csi_data: CSIData) -> np.ndarray:
|
|||
|
||||
### FINDING PERF-PY04: WebSocket Broadcast -- Sequential Send to All Clients [MEDIUM]
|
||||
|
||||
**File**: `v1/src/api/websocket/connection_manager.py`
|
||||
**File**: `archive/v1/src/api/websocket/connection_manager.py`
|
||||
**Lines**: 230-264
|
||||
|
||||
```python
|
||||
|
|
@ -461,7 +461,7 @@ results = await asyncio.gather(*tasks, return_exceptions=True)
|
|||
|
||||
### FINDING PERF-PY05: get_recent_history -- Copies Entire History [LOW]
|
||||
|
||||
**File**: `v1/src/core/csi_processor.py`
|
||||
**File**: `archive/v1/src/core/csi_processor.py`
|
||||
**Lines**: 284-297
|
||||
|
||||
```python
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ The wifi-densepose project contains **3,353 total test functions** across three
|
|||
| Stack | Test Functions | Files | Frameworks |
|
||||
|-------|---------------|-------|------------|
|
||||
| Rust (inline + integration) | 2,658 | 292 source files + 16 integration test files | `#[test]`, Rust built-in |
|
||||
| Python (v1/tests/) | 491 | 30 test files | pytest, pytest-asyncio |
|
||||
| Python (archive/v1/tests/) | 491 | 30 test files | pytest, pytest-asyncio |
|
||||
| Mobile (ui/mobile) | 204 | 25 test files | Jest, React Testing Library |
|
||||
| **Total** | **3,353** | **363** | |
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ The wifi-densepose project contains **3,353 total test functions** across three
|
|||
|
||||
---
|
||||
|
||||
## 1. Python Test Suite Analysis (v1/tests/)
|
||||
## 1. Python Test Suite Analysis (archive/v1/tests/)
|
||||
|
||||
### 1.1 Test Distribution
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ All 14 tests use `MockPoseModel` with `asyncio.sleep()` simulating inference tim
|
|||
|
||||
### 1.10 Test Infrastructure Quality
|
||||
|
||||
**Fixtures (`v1/tests/fixtures/csi_data.py`):**
|
||||
**Fixtures (`archive/v1/tests/fixtures/csi_data.py`):**
|
||||
|
||||
Well-designed `CSIDataGenerator` class (487 lines) with:
|
||||
- Multiple scenario generators (empty room, single person, multi-person)
|
||||
|
|
@ -238,7 +238,7 @@ Well-designed `CSIDataGenerator` class (487 lines) with:
|
|||
- Time series generation
|
||||
- Validation utilities (`validate_csi_sample`)
|
||||
|
||||
**Mocks (`v1/tests/mocks/hardware_mocks.py`):**
|
||||
**Mocks (`archive/v1/tests/mocks/hardware_mocks.py`):**
|
||||
|
||||
Comprehensive mock infrastructure (716 lines) including:
|
||||
- `MockWiFiRouter` with realistic CSI streaming
|
||||
|
|
@ -448,9 +448,9 @@ This is the best-tested service in the mobile suite.
|
|||
|
||||
**High maintenance cost files:**
|
||||
|
||||
1. `v1/tests/mocks/hardware_mocks.py` (716 lines) -- Complex mock infrastructure that must evolve with the production code. Any hardware interface change requires updating this file.
|
||||
1. `archive/v1/tests/mocks/hardware_mocks.py` (716 lines) -- Complex mock infrastructure that must evolve with the production code. Any hardware interface change requires updating this file.
|
||||
|
||||
2. `v1/tests/fixtures/csi_data.py` (487 lines) -- Rich data generation but duplicates some logic from the production `SimulatedCollector`.
|
||||
2. `archive/v1/tests/fixtures/csi_data.py` (487 lines) -- Rich data generation but duplicates some logic from the production `SimulatedCollector`.
|
||||
|
||||
3. The 5 CSI extractor test files collectively contain ~3,000 lines of test code for a single module. Merging to one file would reduce this to ~600 lines.
|
||||
|
||||
|
|
@ -468,8 +468,8 @@ This is the best-tested service in the mobile suite.
|
|||
|
||||
| File | Why It's Good |
|
||||
|------|---------------|
|
||||
| `v1/tests/unit/test_sensing.py` | 45 tests with mathematical rigor, known-signal validation, domain-specific edge cases, cross-receiver agreement, band isolation. No mocks for core logic. |
|
||||
| `v1/tests/unit/test_esp32_binary_parser.py` | Real UDP socket testing, struct-level binary validation, ADR-018 compliance. Tests actual I/Q to amplitude/phase math. |
|
||||
| `archive/v1/tests/unit/test_sensing.py` | 45 tests with mathematical rigor, known-signal validation, domain-specific edge cases, cross-receiver agreement, band isolation. No mocks for core logic. |
|
||||
| `archive/v1/tests/unit/test_esp32_binary_parser.py` | Real UDP socket testing, struct-level binary validation, ADR-018 compliance. Tests actual I/Q to amplitude/phase math. |
|
||||
| `v2/.../tests/validation_test.rs` | Physics-based validation (Doppler, phase unwrapping, spectral analysis). Tests prove algorithm correctness, not just non-failure. |
|
||||
| `v2/.../tests/test_losses.rs` | Deterministic data, feature-gated, tests mathematical properties (zero loss for identical inputs, non-zero for mismatched). |
|
||||
| `ui/mobile/.../utils/ringBuffer.test.ts` | Comprehensive boundary testing (NaN, Infinity, 0, negative, overflow). Tests copy semantics. |
|
||||
|
|
@ -478,10 +478,10 @@ This is the best-tested service in the mobile suite.
|
|||
|
||||
| File | Issues |
|
||||
|------|--------|
|
||||
| `v1/tests/performance/test_inference_speed.py` | Tests `asyncio.sleep()` accuracy, not model performance. `MockPoseModel` simulates inference with sleep. |
|
||||
| `v1/tests/e2e/test_healthcare_scenario.py` | Not a real E2E test -- defines its own mock classes. Test names contain stale "should_fail_initially" text. |
|
||||
| `v1/tests/unit/test_csi_processor_tdd.py` | 14/25 tests mock the SUT's own private methods. Tests verify mock calls, not behavior. |
|
||||
| `v1/tests/unit/test_phase_sanitizer_tdd.py` | 12/31 tests mock internal methods. Same anti-pattern as csi_processor_tdd. |
|
||||
| `archive/v1/tests/performance/test_inference_speed.py` | Tests `asyncio.sleep()` accuracy, not model performance. `MockPoseModel` simulates inference with sleep. |
|
||||
| `archive/v1/tests/e2e/test_healthcare_scenario.py` | Not a real E2E test -- defines its own mock classes. Test names contain stale "should_fail_initially" text. |
|
||||
| `archive/v1/tests/unit/test_csi_processor_tdd.py` | 14/25 tests mock the SUT's own private methods. Tests verify mock calls, not behavior. |
|
||||
| `archive/v1/tests/unit/test_phase_sanitizer_tdd.py` | 12/31 tests mock internal methods. Same anti-pattern as csi_processor_tdd. |
|
||||
| `ui/mobile/.../components/GaugeArc.test.tsx` | All 4 tests are `expect(toJSON()).not.toBeNull()` -- smoke tests with no behavioral verification. |
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -31,18 +31,18 @@ The WiFi-DensePose system demonstrates strong architectural foundations with a w
|
|||
### Key Findings
|
||||
|
||||
**Strengths:**
|
||||
- Comprehensive error handling middleware with structured error responses, request IDs, and environment-aware detail levels (`v1/src/middleware/error_handler.py`)
|
||||
- Comprehensive error handling middleware with structured error responses, request IDs, and environment-aware detail levels (`archive/v1/src/middleware/error_handler.py`)
|
||||
- Robust WebSocket reconnection with exponential backoff and automatic simulation fallback in the mobile app (`ui/mobile/src/services/ws.service.ts`)
|
||||
- Well-designed health check architecture with component-level status, readiness probes, and liveness endpoints (`v1/src/api/routers/health.py`)
|
||||
- Strong input validation on API models with Pydantic, including range constraints and clear field descriptions (`v1/src/api/routers/pose.py`)
|
||||
- Well-designed health check architecture with component-level status, readiness probes, and liveness endpoints (`archive/v1/src/api/routers/health.py`)
|
||||
- Strong input validation on API models with Pydantic, including range constraints and clear field descriptions (`archive/v1/src/api/routers/pose.py`)
|
||||
- Persistent settings with AsyncStorage in the mobile app, surviving app restarts (`ui/mobile/src/stores/settingsStore.ts`)
|
||||
- Server URL validation with test-before-save workflow in mobile settings (`ui/mobile/src/screens/SettingsScreen/ServerUrlInput.tsx`)
|
||||
|
||||
**Critical Issues:**
|
||||
- API documentation is disabled in production (`docs_url=None`, `redoc_url=None` when `is_production=True`), leaving production API consumers without discoverability (in `v1/src/api/main.py` line 146-148)
|
||||
- No user-facing progress indicator during calibration -- the calibration endpoint returns an estimated duration but there is no polling endpoint progress beyond percentage (`v1/src/api/routers/pose.py` lines 320-361)
|
||||
- Rate limit responses lack a human-readable `Retry-After` message body; the client receives a bare `"Rate limit exceeded"` string with retry information only in HTTP headers (`v1/src/middleware/rate_limit.py` line 323)
|
||||
- CLI `status` command uses emoji/Unicode characters that break in terminals without UTF-8 support (`v1/src/commands/status.py` lines 360-474)
|
||||
- API documentation is disabled in production (`docs_url=None`, `redoc_url=None` when `is_production=True`), leaving production API consumers without discoverability (in `archive/v1/src/api/main.py` line 146-148)
|
||||
- No user-facing progress indicator during calibration -- the calibration endpoint returns an estimated duration but there is no polling endpoint progress beyond percentage (`archive/v1/src/api/routers/pose.py` lines 320-361)
|
||||
- Rate limit responses lack a human-readable `Retry-After` message body; the client receives a bare `"Rate limit exceeded"` string with retry information only in HTTP headers (`archive/v1/src/middleware/rate_limit.py` line 323)
|
||||
- CLI `status` command uses emoji/Unicode characters that break in terminals without UTF-8 support (`archive/v1/src/commands/status.py` lines 360-474)
|
||||
- Mobile app `MainTabs.tsx` passes an inline arrow function as the `component` prop to `Tab.Screen` (line 130), causing unnecessary re-renders on every parent render cycle
|
||||
|
||||
**Top 3 Recommendations:**
|
||||
|
|
@ -166,7 +166,7 @@ WS /api/v1/stream/events - Event stream
|
|||
|
||||
### 4.2 Error Handling (Score: 85/100)
|
||||
|
||||
The `ErrorHandler` class in `v1/src/middleware/error_handler.py` is well-designed:
|
||||
The `ErrorHandler` class in `archive/v1/src/middleware/error_handler.py` is well-designed:
|
||||
|
||||
**Strengths:**
|
||||
- Structured error responses with consistent format: `{ "error": { "code": "...", "message": "...", "timestamp": "...", "request_id": "..." } }`
|
||||
|
|
@ -401,7 +401,7 @@ The `ServerUrlInput` component in the Settings screen provides:
|
|||
|
||||
**Strengths:**
|
||||
- Rust workspace has 1,031+ tests with a single command: `cargo test --workspace --no-default-features`
|
||||
- Deterministic proof verification via `python v1/data/proof/verify.py` with SHA-256 hash checking
|
||||
- Deterministic proof verification via `python archive/v1/data/proof/verify.py` with SHA-256 hash checking
|
||||
- Mobile app has comprehensive test coverage with tests for components, hooks, screens, services, stores, and utilities
|
||||
- Witness bundle verification with `VERIFY.sh` providing 7/7 pass/fail attestation
|
||||
|
||||
|
|
@ -706,20 +706,20 @@ The `provision.py` script in `firmware/esp32-csi-node/` handles WiFi credential
|
|||
This Quality Experience analysis was performed by examining source code across all touchpoints of the WiFi-DensePose system. Files analyzed include:
|
||||
|
||||
**API Layer (9 files):**
|
||||
- `v1/src/api/main.py` -- FastAPI application setup, middleware configuration, exception handlers
|
||||
- `v1/src/api/routers/health.py` -- Health check endpoints
|
||||
- `v1/src/api/routers/pose.py` -- Pose estimation endpoints
|
||||
- `v1/src/api/routers/stream.py` -- WebSocket streaming endpoints
|
||||
- `v1/src/api/websocket/connection_manager.py` -- WebSocket connection lifecycle
|
||||
- `v1/src/api/dependencies.py` -- Dependency injection, authentication, authorization
|
||||
- `v1/src/middleware/error_handler.py` -- Error handling middleware
|
||||
- `v1/src/middleware/rate_limit.py` -- Rate limiting middleware
|
||||
- `archive/v1/src/api/main.py` -- FastAPI application setup, middleware configuration, exception handlers
|
||||
- `archive/v1/src/api/routers/health.py` -- Health check endpoints
|
||||
- `archive/v1/src/api/routers/pose.py` -- Pose estimation endpoints
|
||||
- `archive/v1/src/api/routers/stream.py` -- WebSocket streaming endpoints
|
||||
- `archive/v1/src/api/websocket/connection_manager.py` -- WebSocket connection lifecycle
|
||||
- `archive/v1/src/api/dependencies.py` -- Dependency injection, authentication, authorization
|
||||
- `archive/v1/src/middleware/error_handler.py` -- Error handling middleware
|
||||
- `archive/v1/src/middleware/rate_limit.py` -- Rate limiting middleware
|
||||
|
||||
**CLI Layer (4 files):**
|
||||
- `v1/src/cli.py` -- Click CLI entry point
|
||||
- `v1/src/commands/start.py` -- Server start command
|
||||
- `v1/src/commands/stop.py` -- Server stop command
|
||||
- `v1/src/commands/status.py` -- Server status command
|
||||
- `archive/v1/src/cli.py` -- Click CLI entry point
|
||||
- `archive/v1/src/commands/start.py` -- Server start command
|
||||
- `archive/v1/src/commands/stop.py` -- Server stop command
|
||||
- `archive/v1/src/commands/status.py` -- Server status command
|
||||
|
||||
**Mobile Layer (15 files):**
|
||||
- `ui/mobile/src/screens/LiveScreen/index.tsx` -- Live visualization screen
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ The wifi-densepose project is an ambitious WiFi-based human pose estimation syst
|
|||
**Test Ideas:**
|
||||
| # | Priority | Test Idea | Automation |
|
||||
|---|----------|-----------|------------|
|
||||
| S-08 | P0 | Run `python v1/data/proof/verify.py` in CI on every PR that touches `v1/src/core/` or `v1/src/hardware/` to catch proof-breaking changes | CI |
|
||||
| S-08 | P0 | Run `python archive/v1/data/proof/verify.py` in CI on every PR that touches `archive/v1/src/core/` or `archive/v1/src/hardware/` to catch proof-breaking changes | CI |
|
||||
| S-09 | P2 | Pin numpy/scipy versions in requirements.txt and confirm `verify.py --generate-hash` produces the same hash across Python 3.10, 3.11, and 3.12 | Integration |
|
||||
|
||||
---
|
||||
|
|
@ -222,7 +222,7 @@ The Rust `Esp32CsiParser::parse_frame` takes raw bytes and returns structured `C
|
|||
|
||||
#### D3: Proof Data Integrity
|
||||
|
||||
**Finding:** The proof-of-reality system (`v1/data/proof/verify.py`) is a deterministic pipeline verification tool. It feeds 1,000 synthetic CSI frames through the production CSI processor, hashes the output with SHA-256, and compares against a published hash. This is a strong engineering practice.
|
||||
**Finding:** The proof-of-reality system (`archive/v1/data/proof/verify.py`) is a deterministic pipeline verification tool. It feeds 1,000 synthetic CSI frames through the production CSI processor, hashes the output with SHA-256, and compares against a published hash. This is a strong engineering practice.
|
||||
|
||||
**Risk: LOW**
|
||||
- The proof only exercises the Python v1 pipeline. The Rust port has no equivalent proof-of-reality check.
|
||||
|
|
@ -448,7 +448,7 @@ The ESP32-S3 is the primary sensing node. The mmWave sensors are auxiliary.
|
|||
**Test Ideas:**
|
||||
| # | Priority | Test Idea | Automation |
|
||||
|---|----------|-----------|------------|
|
||||
| O-06 | P0 | Run the complete developer setup workflow from a clean Ubuntu 22.04 VM: clone, install deps, `cargo test --workspace --no-default-features`, `python v1/data/proof/verify.py` -- measure total setup time and document any manual steps | Human Exploration |
|
||||
| O-06 | P0 | Run the complete developer setup workflow from a clean Ubuntu 22.04 VM: clone, install deps, `cargo test --workspace --no-default-features`, `python archive/v1/data/proof/verify.py` -- measure total setup time and document any manual steps | Human Exploration |
|
||||
| O-07 | P1 | Simulate a MAT scan with 5 survivors at varying signal strengths (strong, weak, borderline) and confirm the triage classification matches expected START protocol categories | Integration |
|
||||
|
||||
#### O4: Extreme Use
|
||||
|
|
|
|||
|
|
@ -287,22 +287,22 @@
|
|||
| 1 | `firmware/main/wasm_runtime.c` | Firmware | 867 | **Critical** | 0.98 | WASM execution on embedded device, untested attack surface |
|
||||
| 2 | `firmware/main/ota_update.c` | Firmware | 266 | **Critical** | 0.97 | OTA firmware update -- integrity/authentication critical |
|
||||
| 3 | `firmware/main/swarm_bridge.c` | Firmware | 327 | **Critical** | 0.96 | Multi-node mesh networking, untested protocol |
|
||||
| 4 | `v1/src/services/pose_service.py` | Python | 855 | **Critical** | 0.95 | Core production path, highest complexity, no unit tests |
|
||||
| 5 | `v1/src/middleware/auth.py` | Python | 456 | **Critical** | 0.94 | Authentication -- security-critical, no unit tests |
|
||||
| 6 | `v1/src/api/websocket/connection_manager.py` | Python | 460 | **Critical** | 0.93 | WebSocket lifecycle, connection state, no tests |
|
||||
| 4 | `archive/v1/src/services/pose_service.py` | Python | 855 | **Critical** | 0.95 | Core production path, highest complexity, no unit tests |
|
||||
| 5 | `archive/v1/src/middleware/auth.py` | Python | 456 | **Critical** | 0.94 | Authentication -- security-critical, no unit tests |
|
||||
| 6 | `archive/v1/src/api/websocket/connection_manager.py` | Python | 460 | **Critical** | 0.93 | WebSocket lifecycle, connection state, no tests |
|
||||
| 7 | `firmware/main/mmwave_sensor.c` | Firmware | 571 | **Critical** | 0.92 | 60GHz FMCW sensor driver, hardware-critical |
|
||||
| 8 | `firmware/main/wasm_upload.c` | Firmware | 432 | **Critical** | 0.91 | OTA WASM upload, code injection risk |
|
||||
| 9 | `v1/src/services/orchestrator.py` | Python | 394 | **Critical** | 0.90 | Service lifecycle management, no tests |
|
||||
| 10 | `v1/src/database/connection.py` | Python | 639 | **Critical** | 0.89 | DB + Redis connection management, pooling |
|
||||
| 11 | `v1/src/middleware/error_handler.py` | Python | 504 | **High** | 0.87 | Global error handler, affects all requests |
|
||||
| 12 | `v1/src/tasks/monitoring.py` | Python | 771 | **High** | 0.86 | System monitoring, DB queries, async tasks |
|
||||
| 13 | `v1/src/services/hardware_service.py` | Python | 481 | **High** | 0.85 | Hardware abstraction, device management |
|
||||
| 14 | `v1/src/middleware/rate_limit.py` | Python | 464 | **High** | 0.84 | Rate limiting -- DoS protection |
|
||||
| 15 | `v1/src/services/health_check.py` | Python | 464 | **High** | 0.83 | Health monitoring, dependency checks |
|
||||
| 16 | `v1/src/tasks/backup.py` | Python | 609 | **High** | 0.82 | Data backup operations |
|
||||
| 17 | `v1/src/tasks/cleanup.py` | Python | 597 | **High** | 0.81 | Data retention, cleanup logic |
|
||||
| 9 | `archive/v1/src/services/orchestrator.py` | Python | 394 | **Critical** | 0.90 | Service lifecycle management, no tests |
|
||||
| 10 | `archive/v1/src/database/connection.py` | Python | 639 | **Critical** | 0.89 | DB + Redis connection management, pooling |
|
||||
| 11 | `archive/v1/src/middleware/error_handler.py` | Python | 504 | **High** | 0.87 | Global error handler, affects all requests |
|
||||
| 12 | `archive/v1/src/tasks/monitoring.py` | Python | 771 | **High** | 0.86 | System monitoring, DB queries, async tasks |
|
||||
| 13 | `archive/v1/src/services/hardware_service.py` | Python | 481 | **High** | 0.85 | Hardware abstraction, device management |
|
||||
| 14 | `archive/v1/src/middleware/rate_limit.py` | Python | 464 | **High** | 0.84 | Rate limiting -- DoS protection |
|
||||
| 15 | `archive/v1/src/services/health_check.py` | Python | 464 | **High** | 0.83 | Health monitoring, dependency checks |
|
||||
| 16 | `archive/v1/src/tasks/backup.py` | Python | 609 | **High** | 0.82 | Data backup operations |
|
||||
| 17 | `archive/v1/src/tasks/cleanup.py` | Python | 597 | **High** | 0.81 | Data retention, cleanup logic |
|
||||
| 18 | `firmware/main/rvf_parser.c` | Firmware | 239 | **High** | 0.80 | Binary format parsing -- buffer overflow risk |
|
||||
| 19 | `v1/src/api/routers/pose.py` | Python | 419 | **High** | 0.79 | Pose API endpoint handlers |
|
||||
| 19 | `archive/v1/src/api/routers/pose.py` | Python | 419 | **High** | 0.79 | Pose API endpoint handlers |
|
||||
| 20 | `mobile/hooks/useWebViewBridge.ts` | Mobile | 30 | **High** | 0.78 | Native-WebView IPC bridge |
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
| # | Issue | File(s) | Impact |
|
||||
|---|-------|---------|--------|
|
||||
| 1 | **Rate limiter bypass** -- trusts `X-Forwarded-For` without validation | `v1/src/middleware/rate_limit.py:200-206` | Any client can bypass rate limits via header spoofing |
|
||||
| 2 | **Exception details leaked** in HTTP responses regardless of environment | `v1/src/api/routers/pose.py:140`, `stream.py:297`, +5 others | Stack traces visible to attackers |
|
||||
| 3 | **WebSocket JWT in URL** -- tokens visible in logs, browser history, proxies | `v1/src/api/routers/stream.py:74`, `v1/src/middleware/auth.py:243` | Token exposure (CWE-598) |
|
||||
| 1 | **Rate limiter bypass** -- trusts `X-Forwarded-For` without validation | `archive/v1/src/middleware/rate_limit.py:200-206` | Any client can bypass rate limits via header spoofing |
|
||||
| 2 | **Exception details leaked** in HTTP responses regardless of environment | `archive/v1/src/api/routers/pose.py:140`, `stream.py:297`, +5 others | Stack traces visible to attackers |
|
||||
| 3 | **WebSocket JWT in URL** -- tokens visible in logs, browser history, proxies | `archive/v1/src/api/routers/stream.py:74`, `archive/v1/src/middleware/auth.py:243` | Token exposure (CWE-598) |
|
||||
| 4 | **Rust tests not in CI** -- 2,618 tests in largest codebase never run in pipeline | No `cargo test` in any GitHub Actions workflow | Regressions ship undetected |
|
||||
| 5 | **WebSocket path mismatch** -- mobile app sends to wrong endpoint | `ui/mobile/src/services/ws.service.ts:104` vs `constants/websocket.ts:1` | Mobile WebSocket connections fail silently |
|
||||
|
||||
|
|
@ -39,16 +39,16 @@
|
|||
| 7 | **O(L*V) tomography voxel scan** per frame | `ruvsense/tomography.rs:345-383` | ~10ms wasted per frame; use DDA ray march for 5-10x speedup |
|
||||
| 8 | **Sequential neural inference** -- defeats GPU batching | `wifi-densepose-nn inference.rs:334-336` | 2-4x latency penalty |
|
||||
| 9 | **720 `.unwrap()` calls** in Rust production code | Across entire Rust workspace | Each is a potential panic in real-time/safety-critical paths |
|
||||
| 10 | **Python Doppler: 112KB alloc per frame** at 20Hz | `v1/src/core/csi_processor.py:412-414` | Converts deque -> list -> numpy every frame |
|
||||
| 10 | **Python Doppler: 112KB alloc per frame** at 20Hz | `archive/v1/src/core/csi_processor.py:412-414` | Converts deque -> list -> numpy every frame |
|
||||
|
||||
## P2 -- Fix This Quarter (Coverage + Safety)
|
||||
|
||||
| # | Issue | File(s) | Impact |
|
||||
|---|-------|---------|--------|
|
||||
| 11 | **11/12 Python modules untested** -- only CSI extraction has unit tests | `v1/src/services/`, `middleware/`, `database/`, `tasks/` | 12,280 LOC with zero unit tests |
|
||||
| 11 | **11/12 Python modules untested** -- only CSI extraction has unit tests | `archive/v1/src/services/`, `middleware/`, `database/`, `tasks/` | 12,280 LOC with zero unit tests |
|
||||
| 12 | **Firmware at 19% coverage** -- WASM runtime, OTA, swarm bridge untested | `firmware/esp32-csi-node/main/wasm_runtime.c` (867 LOC) | Security-critical code with no tests |
|
||||
| 13 | **MAT simulation fallback** -- disaster tool auto-falls back to simulated data | `ui/mobile/src/screens/MATScreen/index.tsx` | Risk of operators monitoring fake data during real incidents |
|
||||
| 14 | **Token blacklist never consulted** during auth | `v1/src/api/middleware/auth.py:246-252` | Revoked tokens remain valid |
|
||||
| 14 | **Token blacklist never consulted** during auth | `archive/v1/src/api/middleware/auth.py:246-252` | Revoked tokens remain valid |
|
||||
| 15 | **50ms frame budget never benchmarked** -- no latency CI gate | No benchmark harness exists | Real-time requirement is aspirational, not verified |
|
||||
|
||||
## P3 -- Technical Debt
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ Uses CoreWLAN via a Swift helper binary. macOS Sonoma 14.4+ redacts real BSSIDs;
|
|||
|
||||
```bash
|
||||
# Compile the Swift helper (once)
|
||||
swiftc -O v1/src/sensing/mac_wifi.swift -o mac_wifi
|
||||
swiftc -O archive/v1/src/sensing/mac_wifi.swift -o mac_wifi
|
||||
|
||||
# Run natively
|
||||
./target/release/sensing-server --source macos --http-port 3000 --ws-port 3001 --tick-ms 500
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue