diff --git a/.github/workflows/verify-pipeline.yml b/.github/workflows/verify-pipeline.yml index b46d4bd9..0ba4dbf7 100644 --- a/.github/workflows/verify-pipeline.yml +++ b/.github/workflows/verify-pipeline.yml @@ -4,16 +4,16 @@ on: push: branches: [ main, master, 'claude/**' ] paths: - - 'v1/src/core/**' - - 'v1/src/hardware/**' - - 'v1/data/proof/**' + - 'archive/v1/src/core/**' + - 'archive/v1/src/hardware/**' + - 'archive/v1/data/proof/**' - '.github/workflows/verify-pipeline.yml' pull_request: branches: [ main, master ] paths: - - 'v1/src/core/**' - - 'v1/src/hardware/**' - - 'v1/data/proof/**' + - 'archive/v1/src/core/**' + - 'archive/v1/src/hardware/**' + - 'archive/v1/data/proof/**' - '.github/workflows/verify-pipeline.yml' workflow_dispatch: @@ -37,19 +37,19 @@ jobs: - name: Install pinned dependencies run: | python -m pip install --upgrade pip - pip install -r v1/requirements-lock.txt + pip install -r archive/v1/requirements-lock.txt - name: Verify reference signal is reproducible run: | echo "=== Regenerating reference signal ===" - python v1/data/proof/generate_reference_signal.py + python archive/v1/data/proof/generate_reference_signal.py echo "" echo "=== Checking data file matches committed version ===" # The regenerated file should be identical to the committed one # (We compare the metadata file since data file is large) python -c " import json, hashlib - with open('v1/data/proof/sample_csi_meta.json') as f: + with open('archive/v1/data/proof/sample_csi_meta.json') as f: meta = json.load(f) assert meta['is_synthetic'] == True, 'Metadata must mark signal as synthetic' assert meta['numpy_seed'] == 42, 'Seed must be 42' @@ -76,7 +76,7 @@ jobs: echo "=== Scanning for unseeded np.random usage in production code ===" # Search for np.random calls without a seed in production code # Exclude test files, proof data generators, and known parser placeholders - VIOLATIONS=$(grep -rn "np\.random\." v1/src/ \ + VIOLATIONS=$(grep -rn "np\.random\." archive/v1/src/ \ --include="*.py" \ --exclude-dir="__pycache__" \ | grep -v "np\.random\.RandomState" \ diff --git a/CHANGELOG.md b/CHANGELOG.md index a6dc16ba..b0e48ad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -520,7 +520,7 @@ Major release: complete Rust sensing server, full DensePose training pipeline, R - `PresenceClassifier` — rule-based 3-state classification (ABSENT / PRESENT_STILL / ACTIVE) - Cross-receiver agreement scoring for multi-AP confidence boosting - WebSocket sensing server (`ws_server.py`) broadcasting JSON at 2 Hz -- Deterministic CSI proof bundles for reproducible verification (`v1/data/proof/`) +- Deterministic CSI proof bundles for reproducible verification (`archive/v1/data/proof/`) - Commodity sensing unit tests (`b391638`) ### Changed @@ -528,7 +528,7 @@ Major release: complete Rust sensing server, full DensePose training pipeline, R ### Fixed - Review fixes for end-to-end training pipeline (`45f0304`) -- Dockerfile paths updated from `src/` to `v1/src/` (`7872987`) +- Dockerfile paths updated from `src/` to `archive/v1/src/` (`7872987`) - IoT profile installer instructions updated for aggregator CLI (`f460097`) - `process.env` reference removed from browser ES module (`e320bc9`) diff --git a/CLAUDE.md b/CLAUDE.md index c0b225b7..31fb33f2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -91,10 +91,10 @@ cargo test --workspace --no-default-features cargo check -p wifi-densepose-train --no-default-features # Python — deterministic proof verification (SHA-256) -python v1/data/proof/verify.py +python archive/v1/data/proof/verify.py # Python — test suite -cd v1 && python -m pytest tests/ -x -q +cd archive/v1 && python -m pytest tests/ -x -q ``` ### ESP32 Firmware Build (Windows — Python subprocess required) @@ -156,7 +156,7 @@ cargo test --workspace --no-default-features # 2. Python proof — must print VERDICT: PASS cd .. -python v1/data/proof/verify.py +python archive/v1/data/proof/verify.py # 3. Generate witness bundle (includes both above + firmware hashes) bash scripts/generate-witness-bundle.sh @@ -169,8 +169,8 @@ bash VERIFY.sh **If the Python proof hash changes** (e.g., numpy/scipy version update): ```bash # Regenerate the expected hash, then verify it passes -python v1/data/proof/verify.py --generate-hash -python v1/data/proof/verify.py +python archive/v1/data/proof/verify.py --generate-hash +python archive/v1/data/proof/verify.py ``` **Witness bundle contents** (`dist/witness-bundle-ADR028-.tar.gz`): @@ -183,9 +183,9 @@ python v1/data/proof/verify.py - `VERIFY.sh` — One-command self-verification for recipients **Key proof artifacts:** -- `v1/data/proof/verify.py` — Trust Kill Switch: feeds reference signal through production pipeline, hashes output -- `v1/data/proof/expected_features.sha256` — Published expected hash -- `v1/data/proof/sample_csi_data.json` — 1,000 synthetic CSI frames (seed=42) +- `archive/v1/data/proof/verify.py` — Trust Kill Switch: feeds reference signal through production pipeline, hashes output +- `archive/v1/data/proof/expected_features.sha256` — Published expected hash +- `archive/v1/data/proof/sample_csi_data.json` — 1,000 synthetic CSI frames (seed=42) - `docs/WITNESS-LOG-028.md` — 11-step reproducible verification procedure - `docs/adr/ADR-028-esp32-capability-audit.md` — Complete audit record @@ -216,8 +216,8 @@ Active feature branch: `ruvsense-full-implementation` (PR #77) - `v2/crates/wifi-densepose-ruvector/src/viewpoint/` — Cross-viewpoint fusion (5 files) - `v2/crates/wifi-densepose-hardware/src/esp32/` — ESP32 TDM protocol - `firmware/esp32-csi-node/main/` — ESP32 C firmware (channel hopping, NVS config, TDM) -- `v1/src/` — Python source (core, hardware, services, api) -- `v1/data/proof/` — Deterministic CSI proof bundles +- `archive/v1/src/` — Python source (core, hardware, services, api) +- `archive/v1/data/proof/` — Deterministic CSI proof bundles - `.claude-flow/` — Claude Flow coordination state (committed for team sharing) - `.claude/` — Claude Code settings, agents, memory (committed for team sharing) @@ -243,7 +243,7 @@ Active feature branch: `ruvsense-full-implementation` (PR #77) Before merging any PR, verify each item applies and is addressed: 1. **Rust tests pass** — `cargo test --workspace --no-default-features` (1,031+ passed, 0 failed) -2. **Python proof passes** — `python v1/data/proof/verify.py` (VERDICT: PASS) +2. **Python proof passes** — `python archive/v1/data/proof/verify.py` (VERDICT: PASS) 3. **README.md** — Update platform tables, crate descriptions, hardware tables, feature summaries if scope changed 4. **CLAUDE.md** — Update crate table, ADR list, module tables, version if scope changed 5. **CHANGELOG.md** — Add entry under `[Unreleased]` with what was added/fixed/changed diff --git a/README.md b/README.md index bc76a86f..edf14ba2 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ node scripts/mincut-person-counter.js --port 5006 # Correct person counting > | **Research NIC** | Intel 5300 / Atheros AR9580 | ~$50-100 | Yes | Full CSI with 3x3 MIMO | > | **Any WiFi** | Windows, macOS, or Linux laptop | $0 | No | RSSI-only: coarse presence and motion | > -> No hardware? Verify the signal processing pipeline with the deterministic reference signal: `python v1/data/proof/verify.py` +> No hardware? Verify the signal processing pipeline with the deterministic reference signal: `python archive/v1/data/proof/verify.py` > --- @@ -1171,7 +1171,7 @@ Bundle verify: 7/7 checks PASS cd v2 && cargo test --workspace --no-default-features # Run the deterministic proof -python v1/data/proof/verify.py +python archive/v1/data/proof/verify.py # Generate + verify the witness bundle bash scripts/generate-witness-bundle.sh @@ -2164,7 +2164,7 @@ cargo test -p wifi-densepose-sensing-server ./target/release/sensing-server --benchmark # Python tests -python -m pytest v1/tests/ -v +python -m pytest archive/v1/tests/ -v # Pipeline verification (no hardware needed) ./verify diff --git a/archive/README.md b/archive/README.md new file mode 100644 index 00000000..ff9afb81 --- /dev/null +++ b/archive/README.md @@ -0,0 +1,74 @@ +# Archive + +Frozen, no-longer-active components of RuView preserved for historical +reference, reproducibility, and load-bearing legacy paths the active +codebase still depends on. + +## What lives here + +| Path | What it is | Why it's archived | Still load-bearing? | +|------|------------|-------------------|---------------------| +| `v1/` | Original Python implementation of RuView (CSI processing, hardware adapters, services, FastAPI) | Superseded by the Rust workspace at `v2/`; ~810× slower in benchmarks. Kept rather than deleted because the deterministic proof bundle (`v1/data/proof/`) is part of the pre-merge witness verification process per ADR-011 / ADR-028. | **Yes — for the proof bundle only.** Active code lives in `v2/`. | + +## What "archived" means + +- **Do not add new features here.** New work goes in `v2/`. +- **Do not refactor or modernize the archived code beyond what is + strictly necessary** to keep the load-bearing paths working. The + Python proof bundle is intentionally frozen so that its SHA-256 + reproducibility holds across releases (per ADR-028's witness + verification requirement). +- **Bug fixes inside archived code are allowed** when the bug affects a + still-load-bearing path (currently: only the Python proof). All + other "bugs" in archived code are out-of-scope — they are part of + the historical record and any fix would unnecessarily churn the + witness hashes. +- **CI continues to verify the load-bearing paths.** + `.github/workflows/verify-pipeline.yml` runs the Python proof on + every push and PR; if you change anything inside `archive/v1/src/` + or `archive/v1/data/proof/`, expect the determinism check to flag + it. + +## Quick reference for the load-bearing paths + +```bash +# Run the deterministic Python proof (must print VERDICT: PASS) +python archive/v1/data/proof/verify.py + +# Regenerate the expected hash (only if numpy/scipy version legitimately changed) +python archive/v1/data/proof/verify.py --generate-hash + +# Run the full Python test suite (legacy, still maintained) +cd archive/v1&& python -m pytest tests/ -x -q +``` + +## Why we keep `v1/` rather than delete it + +1. **Trust kill-switch.** The proof at `v1/data/proof/verify.py` feeds + a known reference signal through the full pipeline and hashes the + output. If the active code's behavior drifts, the hash changes and + CI fails. This is what stops accidental regression in the science + layer of the codebase. + +2. **Witness verification.** ADR-028's witness-bundle process bundles + the proof, the rust workspace test results, and firmware hashes + into a tarball recipients can self-verify. Removing v1 would break + that chain. + +3. **Historical reference.** ADR-011 documents the "no mocks in + production code" decision; the original violations and their fixes + live in this Python codebase. The ADRs reference these paths. + +If the time comes to retire the proof bundle (e.g., a Rust port of +the proof exists and the Python version is no longer canonical), the +right move is a single follow-up that simultaneously: ports the +witness-bundle process, updates `verify-pipeline.yml`, and either +deletes `archive/v1/` or moves it to a separate read-only repository. +That decision belongs in its own ADR. + +## See also + +- `docs/adr/ADR-011-python-proof-of-reality-mock-elimination.md` +- `docs/adr/ADR-028-esp32-capability-audit.md` +- `archive/v1/data/proof/README.md` (if present) +- `docs/WITNESS-LOG-028.md` diff --git a/v1/README.md b/archive/v1/README.md similarity index 100% rename from v1/README.md rename to archive/v1/README.md diff --git a/v1/__init__.py b/archive/v1/__init__.py similarity index 100% rename from v1/__init__.py rename to archive/v1/__init__.py diff --git a/v1/data/proof/expected_features.sha256 b/archive/v1/data/proof/expected_features.sha256 similarity index 100% rename from v1/data/proof/expected_features.sha256 rename to archive/v1/data/proof/expected_features.sha256 diff --git a/v1/data/proof/generate_reference_signal.py b/archive/v1/data/proof/generate_reference_signal.py similarity index 100% rename from v1/data/proof/generate_reference_signal.py rename to archive/v1/data/proof/generate_reference_signal.py diff --git a/v1/data/proof/sample_csi_data.json b/archive/v1/data/proof/sample_csi_data.json similarity index 100% rename from v1/data/proof/sample_csi_data.json rename to archive/v1/data/proof/sample_csi_data.json diff --git a/v1/data/proof/sample_csi_meta.json b/archive/v1/data/proof/sample_csi_meta.json similarity index 100% rename from v1/data/proof/sample_csi_meta.json rename to archive/v1/data/proof/sample_csi_meta.json diff --git a/v1/data/proof/verify.py b/archive/v1/data/proof/verify.py similarity index 100% rename from v1/data/proof/verify.py rename to archive/v1/data/proof/verify.py diff --git a/v1/data/test_wifi_densepose.db b/archive/v1/data/test_wifi_densepose.db similarity index 100% rename from v1/data/test_wifi_densepose.db rename to archive/v1/data/test_wifi_densepose.db diff --git a/v1/data/wifi_densepose_fallback.db b/archive/v1/data/wifi_densepose_fallback.db similarity index 100% rename from v1/data/wifi_densepose_fallback.db rename to archive/v1/data/wifi_densepose_fallback.db diff --git a/v1/docs/api-endpoints-summary.md b/archive/v1/docs/api-endpoints-summary.md similarity index 100% rename from v1/docs/api-endpoints-summary.md rename to archive/v1/docs/api-endpoints-summary.md diff --git a/v1/docs/api-test-results.md b/archive/v1/docs/api-test-results.md similarity index 100% rename from v1/docs/api-test-results.md rename to archive/v1/docs/api-test-results.md diff --git a/v1/docs/api/rest-endpoints.md b/archive/v1/docs/api/rest-endpoints.md similarity index 100% rename from v1/docs/api/rest-endpoints.md rename to archive/v1/docs/api/rest-endpoints.md diff --git a/v1/docs/api/websocket-api.md b/archive/v1/docs/api/websocket-api.md similarity index 100% rename from v1/docs/api/websocket-api.md rename to archive/v1/docs/api/websocket-api.md diff --git a/v1/docs/api_reference.md b/archive/v1/docs/api_reference.md similarity index 100% rename from v1/docs/api_reference.md rename to archive/v1/docs/api_reference.md diff --git a/v1/docs/deployment.md b/archive/v1/docs/deployment.md similarity index 100% rename from v1/docs/deployment.md rename to archive/v1/docs/deployment.md diff --git a/v1/docs/deployment/README.md b/archive/v1/docs/deployment/README.md similarity index 100% rename from v1/docs/deployment/README.md rename to archive/v1/docs/deployment/README.md diff --git a/v1/docs/developer/architecture-overview.md b/archive/v1/docs/developer/architecture-overview.md similarity index 100% rename from v1/docs/developer/architecture-overview.md rename to archive/v1/docs/developer/architecture-overview.md diff --git a/v1/docs/developer/contributing.md b/archive/v1/docs/developer/contributing.md similarity index 100% rename from v1/docs/developer/contributing.md rename to archive/v1/docs/developer/contributing.md diff --git a/v1/docs/developer/deployment-guide.md b/archive/v1/docs/developer/deployment-guide.md similarity index 100% rename from v1/docs/developer/deployment-guide.md rename to archive/v1/docs/developer/deployment-guide.md diff --git a/v1/docs/developer/testing-guide.md b/archive/v1/docs/developer/testing-guide.md similarity index 100% rename from v1/docs/developer/testing-guide.md rename to archive/v1/docs/developer/testing-guide.md diff --git a/v1/docs/implementation-plan.md b/archive/v1/docs/implementation-plan.md similarity index 100% rename from v1/docs/implementation-plan.md rename to archive/v1/docs/implementation-plan.md diff --git a/v1/docs/integration/README.md b/archive/v1/docs/integration/README.md similarity index 100% rename from v1/docs/integration/README.md rename to archive/v1/docs/integration/README.md diff --git a/v1/docs/review/comprehensive-system-review.md b/archive/v1/docs/review/comprehensive-system-review.md similarity index 100% rename from v1/docs/review/comprehensive-system-review.md rename to archive/v1/docs/review/comprehensive-system-review.md diff --git a/v1/docs/review/database-operations-findings.md b/archive/v1/docs/review/database-operations-findings.md similarity index 100% rename from v1/docs/review/database-operations-findings.md rename to archive/v1/docs/review/database-operations-findings.md diff --git a/v1/docs/review/hardware-integration-review.md b/archive/v1/docs/review/hardware-integration-review.md similarity index 100% rename from v1/docs/review/hardware-integration-review.md rename to archive/v1/docs/review/hardware-integration-review.md diff --git a/v1/docs/review/readme.md b/archive/v1/docs/review/readme.md similarity index 100% rename from v1/docs/review/readme.md rename to archive/v1/docs/review/readme.md diff --git a/v1/docs/security-features.md b/archive/v1/docs/security-features.md similarity index 100% rename from v1/docs/security-features.md rename to archive/v1/docs/security-features.md diff --git a/v1/docs/troubleshooting.md b/archive/v1/docs/troubleshooting.md similarity index 100% rename from v1/docs/troubleshooting.md rename to archive/v1/docs/troubleshooting.md diff --git a/v1/docs/user-guide/api-reference.md b/archive/v1/docs/user-guide/api-reference.md similarity index 100% rename from v1/docs/user-guide/api-reference.md rename to archive/v1/docs/user-guide/api-reference.md diff --git a/v1/docs/user-guide/configuration.md b/archive/v1/docs/user-guide/configuration.md similarity index 100% rename from v1/docs/user-guide/configuration.md rename to archive/v1/docs/user-guide/configuration.md diff --git a/v1/docs/user-guide/getting-started.md b/archive/v1/docs/user-guide/getting-started.md similarity index 100% rename from v1/docs/user-guide/getting-started.md rename to archive/v1/docs/user-guide/getting-started.md diff --git a/v1/docs/user-guide/troubleshooting.md b/archive/v1/docs/user-guide/troubleshooting.md similarity index 100% rename from v1/docs/user-guide/troubleshooting.md rename to archive/v1/docs/user-guide/troubleshooting.md diff --git a/v1/docs/user_guide.md b/archive/v1/docs/user_guide.md similarity index 100% rename from v1/docs/user_guide.md rename to archive/v1/docs/user_guide.md diff --git a/v1/requirements-lock.txt b/archive/v1/requirements-lock.txt similarity index 100% rename from v1/requirements-lock.txt rename to archive/v1/requirements-lock.txt diff --git a/v1/scripts/api_test_results_20250607_122720.json b/archive/v1/scripts/api_test_results_20250607_122720.json similarity index 100% rename from v1/scripts/api_test_results_20250607_122720.json rename to archive/v1/scripts/api_test_results_20250607_122720.json diff --git a/v1/scripts/api_test_results_20250607_122856.json b/archive/v1/scripts/api_test_results_20250607_122856.json similarity index 100% rename from v1/scripts/api_test_results_20250607_122856.json rename to archive/v1/scripts/api_test_results_20250607_122856.json diff --git a/v1/scripts/api_test_results_20250607_123111.json b/archive/v1/scripts/api_test_results_20250607_123111.json similarity index 100% rename from v1/scripts/api_test_results_20250607_123111.json rename to archive/v1/scripts/api_test_results_20250607_123111.json diff --git a/v1/scripts/api_test_results_20250609_161617.json b/archive/v1/scripts/api_test_results_20250609_161617.json similarity index 100% rename from v1/scripts/api_test_results_20250609_161617.json rename to archive/v1/scripts/api_test_results_20250609_161617.json diff --git a/v1/scripts/api_test_results_20250609_162928.json b/archive/v1/scripts/api_test_results_20250609_162928.json similarity index 100% rename from v1/scripts/api_test_results_20250609_162928.json rename to archive/v1/scripts/api_test_results_20250609_162928.json diff --git a/v1/scripts/test_api_endpoints.py b/archive/v1/scripts/test_api_endpoints.py similarity index 100% rename from v1/scripts/test_api_endpoints.py rename to archive/v1/scripts/test_api_endpoints.py diff --git a/v1/scripts/test_monitoring.py b/archive/v1/scripts/test_monitoring.py similarity index 100% rename from v1/scripts/test_monitoring.py rename to archive/v1/scripts/test_monitoring.py diff --git a/v1/scripts/test_websocket_streaming.py b/archive/v1/scripts/test_websocket_streaming.py similarity index 100% rename from v1/scripts/test_websocket_streaming.py rename to archive/v1/scripts/test_websocket_streaming.py diff --git a/v1/scripts/validate-deployment.sh b/archive/v1/scripts/validate-deployment.sh similarity index 100% rename from v1/scripts/validate-deployment.sh rename to archive/v1/scripts/validate-deployment.sh diff --git a/v1/scripts/validate-integration.sh b/archive/v1/scripts/validate-integration.sh similarity index 100% rename from v1/scripts/validate-integration.sh rename to archive/v1/scripts/validate-integration.sh diff --git a/v1/setup.py b/archive/v1/setup.py similarity index 100% rename from v1/setup.py rename to archive/v1/setup.py diff --git a/v1/src/__init__.py b/archive/v1/src/__init__.py similarity index 100% rename from v1/src/__init__.py rename to archive/v1/src/__init__.py diff --git a/v1/src/api/__init__.py b/archive/v1/src/api/__init__.py similarity index 100% rename from v1/src/api/__init__.py rename to archive/v1/src/api/__init__.py diff --git a/v1/src/api/dependencies.py b/archive/v1/src/api/dependencies.py similarity index 100% rename from v1/src/api/dependencies.py rename to archive/v1/src/api/dependencies.py diff --git a/v1/src/api/main.py b/archive/v1/src/api/main.py similarity index 100% rename from v1/src/api/main.py rename to archive/v1/src/api/main.py diff --git a/v1/src/api/middleware/__init__.py b/archive/v1/src/api/middleware/__init__.py similarity index 100% rename from v1/src/api/middleware/__init__.py rename to archive/v1/src/api/middleware/__init__.py diff --git a/v1/src/api/middleware/auth.py b/archive/v1/src/api/middleware/auth.py similarity index 100% rename from v1/src/api/middleware/auth.py rename to archive/v1/src/api/middleware/auth.py diff --git a/v1/src/api/middleware/rate_limit.py b/archive/v1/src/api/middleware/rate_limit.py similarity index 100% rename from v1/src/api/middleware/rate_limit.py rename to archive/v1/src/api/middleware/rate_limit.py diff --git a/v1/src/api/routers/__init__.py b/archive/v1/src/api/routers/__init__.py similarity index 100% rename from v1/src/api/routers/__init__.py rename to archive/v1/src/api/routers/__init__.py diff --git a/v1/src/api/routers/auth.py b/archive/v1/src/api/routers/auth.py similarity index 100% rename from v1/src/api/routers/auth.py rename to archive/v1/src/api/routers/auth.py diff --git a/v1/src/api/routers/health.py b/archive/v1/src/api/routers/health.py similarity index 100% rename from v1/src/api/routers/health.py rename to archive/v1/src/api/routers/health.py diff --git a/v1/src/api/routers/pose.py b/archive/v1/src/api/routers/pose.py similarity index 100% rename from v1/src/api/routers/pose.py rename to archive/v1/src/api/routers/pose.py diff --git a/v1/src/api/routers/stream.py b/archive/v1/src/api/routers/stream.py similarity index 100% rename from v1/src/api/routers/stream.py rename to archive/v1/src/api/routers/stream.py diff --git a/v1/src/api/websocket/__init__.py b/archive/v1/src/api/websocket/__init__.py similarity index 100% rename from v1/src/api/websocket/__init__.py rename to archive/v1/src/api/websocket/__init__.py diff --git a/v1/src/api/websocket/connection_manager.py b/archive/v1/src/api/websocket/connection_manager.py similarity index 100% rename from v1/src/api/websocket/connection_manager.py rename to archive/v1/src/api/websocket/connection_manager.py diff --git a/v1/src/api/websocket/pose_stream.py b/archive/v1/src/api/websocket/pose_stream.py similarity index 100% rename from v1/src/api/websocket/pose_stream.py rename to archive/v1/src/api/websocket/pose_stream.py diff --git a/v1/src/app.py b/archive/v1/src/app.py similarity index 100% rename from v1/src/app.py rename to archive/v1/src/app.py diff --git a/v1/src/cli.py b/archive/v1/src/cli.py similarity index 100% rename from v1/src/cli.py rename to archive/v1/src/cli.py diff --git a/v1/src/commands/start.py b/archive/v1/src/commands/start.py similarity index 100% rename from v1/src/commands/start.py rename to archive/v1/src/commands/start.py diff --git a/v1/src/commands/status.py b/archive/v1/src/commands/status.py similarity index 100% rename from v1/src/commands/status.py rename to archive/v1/src/commands/status.py diff --git a/v1/src/commands/stop.py b/archive/v1/src/commands/stop.py similarity index 100% rename from v1/src/commands/stop.py rename to archive/v1/src/commands/stop.py diff --git a/v1/src/config.py b/archive/v1/src/config.py similarity index 100% rename from v1/src/config.py rename to archive/v1/src/config.py diff --git a/v1/src/config/__init__.py b/archive/v1/src/config/__init__.py similarity index 100% rename from v1/src/config/__init__.py rename to archive/v1/src/config/__init__.py diff --git a/v1/src/config/domains.py b/archive/v1/src/config/domains.py similarity index 100% rename from v1/src/config/domains.py rename to archive/v1/src/config/domains.py diff --git a/v1/src/config/settings.py b/archive/v1/src/config/settings.py similarity index 100% rename from v1/src/config/settings.py rename to archive/v1/src/config/settings.py diff --git a/v1/src/core/__init__.py b/archive/v1/src/core/__init__.py similarity index 100% rename from v1/src/core/__init__.py rename to archive/v1/src/core/__init__.py diff --git a/v1/src/core/csi_processor.py b/archive/v1/src/core/csi_processor.py similarity index 100% rename from v1/src/core/csi_processor.py rename to archive/v1/src/core/csi_processor.py diff --git a/v1/src/core/phase_sanitizer.py b/archive/v1/src/core/phase_sanitizer.py similarity index 100% rename from v1/src/core/phase_sanitizer.py rename to archive/v1/src/core/phase_sanitizer.py diff --git a/v1/src/core/router_interface.py b/archive/v1/src/core/router_interface.py similarity index 100% rename from v1/src/core/router_interface.py rename to archive/v1/src/core/router_interface.py diff --git a/v1/src/database/connection.py b/archive/v1/src/database/connection.py similarity index 100% rename from v1/src/database/connection.py rename to archive/v1/src/database/connection.py diff --git a/v1/src/database/migrations/001_initial.py b/archive/v1/src/database/migrations/001_initial.py similarity index 100% rename from v1/src/database/migrations/001_initial.py rename to archive/v1/src/database/migrations/001_initial.py diff --git a/v1/src/database/migrations/env.py b/archive/v1/src/database/migrations/env.py similarity index 100% rename from v1/src/database/migrations/env.py rename to archive/v1/src/database/migrations/env.py diff --git a/v1/src/database/migrations/script.py.mako b/archive/v1/src/database/migrations/script.py.mako similarity index 100% rename from v1/src/database/migrations/script.py.mako rename to archive/v1/src/database/migrations/script.py.mako diff --git a/v1/src/database/model_types.py b/archive/v1/src/database/model_types.py similarity index 100% rename from v1/src/database/model_types.py rename to archive/v1/src/database/model_types.py diff --git a/v1/src/database/models.py b/archive/v1/src/database/models.py similarity index 100% rename from v1/src/database/models.py rename to archive/v1/src/database/models.py diff --git a/v1/src/hardware/__init__.py b/archive/v1/src/hardware/__init__.py similarity index 100% rename from v1/src/hardware/__init__.py rename to archive/v1/src/hardware/__init__.py diff --git a/v1/src/hardware/csi_extractor.py b/archive/v1/src/hardware/csi_extractor.py similarity index 100% rename from v1/src/hardware/csi_extractor.py rename to archive/v1/src/hardware/csi_extractor.py diff --git a/v1/src/hardware/router_interface.py b/archive/v1/src/hardware/router_interface.py similarity index 100% rename from v1/src/hardware/router_interface.py rename to archive/v1/src/hardware/router_interface.py diff --git a/v1/src/logger.py b/archive/v1/src/logger.py similarity index 100% rename from v1/src/logger.py rename to archive/v1/src/logger.py diff --git a/v1/src/main.py b/archive/v1/src/main.py similarity index 100% rename from v1/src/main.py rename to archive/v1/src/main.py diff --git a/v1/src/middleware/auth.py b/archive/v1/src/middleware/auth.py similarity index 100% rename from v1/src/middleware/auth.py rename to archive/v1/src/middleware/auth.py diff --git a/v1/src/middleware/cors.py b/archive/v1/src/middleware/cors.py similarity index 100% rename from v1/src/middleware/cors.py rename to archive/v1/src/middleware/cors.py diff --git a/v1/src/middleware/error_handler.py b/archive/v1/src/middleware/error_handler.py similarity index 100% rename from v1/src/middleware/error_handler.py rename to archive/v1/src/middleware/error_handler.py diff --git a/v1/src/middleware/rate_limit.py b/archive/v1/src/middleware/rate_limit.py similarity index 100% rename from v1/src/middleware/rate_limit.py rename to archive/v1/src/middleware/rate_limit.py diff --git a/v1/src/models/__init__.py b/archive/v1/src/models/__init__.py similarity index 100% rename from v1/src/models/__init__.py rename to archive/v1/src/models/__init__.py diff --git a/v1/src/models/densepose_head.py b/archive/v1/src/models/densepose_head.py similarity index 100% rename from v1/src/models/densepose_head.py rename to archive/v1/src/models/densepose_head.py diff --git a/v1/src/models/modality_translation.py b/archive/v1/src/models/modality_translation.py similarity index 100% rename from v1/src/models/modality_translation.py rename to archive/v1/src/models/modality_translation.py diff --git a/v1/src/sensing/__init__.py b/archive/v1/src/sensing/__init__.py similarity index 100% rename from v1/src/sensing/__init__.py rename to archive/v1/src/sensing/__init__.py diff --git a/v1/src/sensing/backend.py b/archive/v1/src/sensing/backend.py similarity index 100% rename from v1/src/sensing/backend.py rename to archive/v1/src/sensing/backend.py diff --git a/v1/src/sensing/classifier.py b/archive/v1/src/sensing/classifier.py similarity index 100% rename from v1/src/sensing/classifier.py rename to archive/v1/src/sensing/classifier.py diff --git a/v1/src/sensing/feature_extractor.py b/archive/v1/src/sensing/feature_extractor.py similarity index 100% rename from v1/src/sensing/feature_extractor.py rename to archive/v1/src/sensing/feature_extractor.py diff --git a/v1/src/sensing/mac_wifi.swift b/archive/v1/src/sensing/mac_wifi.swift similarity index 100% rename from v1/src/sensing/mac_wifi.swift rename to archive/v1/src/sensing/mac_wifi.swift diff --git a/v1/src/sensing/rssi_collector.py b/archive/v1/src/sensing/rssi_collector.py similarity index 100% rename from v1/src/sensing/rssi_collector.py rename to archive/v1/src/sensing/rssi_collector.py diff --git a/v1/src/sensing/ws_server.py b/archive/v1/src/sensing/ws_server.py similarity index 100% rename from v1/src/sensing/ws_server.py rename to archive/v1/src/sensing/ws_server.py diff --git a/v1/src/services/__init__.py b/archive/v1/src/services/__init__.py similarity index 100% rename from v1/src/services/__init__.py rename to archive/v1/src/services/__init__.py diff --git a/v1/src/services/hardware_service.py b/archive/v1/src/services/hardware_service.py similarity index 100% rename from v1/src/services/hardware_service.py rename to archive/v1/src/services/hardware_service.py diff --git a/v1/src/services/health_check.py b/archive/v1/src/services/health_check.py similarity index 100% rename from v1/src/services/health_check.py rename to archive/v1/src/services/health_check.py diff --git a/v1/src/services/metrics.py b/archive/v1/src/services/metrics.py similarity index 100% rename from v1/src/services/metrics.py rename to archive/v1/src/services/metrics.py diff --git a/v1/src/services/orchestrator.py b/archive/v1/src/services/orchestrator.py similarity index 100% rename from v1/src/services/orchestrator.py rename to archive/v1/src/services/orchestrator.py diff --git a/v1/src/services/pose_service.py b/archive/v1/src/services/pose_service.py similarity index 100% rename from v1/src/services/pose_service.py rename to archive/v1/src/services/pose_service.py diff --git a/v1/src/services/stream_service.py b/archive/v1/src/services/stream_service.py similarity index 100% rename from v1/src/services/stream_service.py rename to archive/v1/src/services/stream_service.py diff --git a/v1/src/tasks/backup.py b/archive/v1/src/tasks/backup.py similarity index 100% rename from v1/src/tasks/backup.py rename to archive/v1/src/tasks/backup.py diff --git a/v1/src/tasks/cleanup.py b/archive/v1/src/tasks/cleanup.py similarity index 100% rename from v1/src/tasks/cleanup.py rename to archive/v1/src/tasks/cleanup.py diff --git a/v1/src/tasks/monitoring.py b/archive/v1/src/tasks/monitoring.py similarity index 100% rename from v1/src/tasks/monitoring.py rename to archive/v1/src/tasks/monitoring.py diff --git a/v1/src/testing/__init__.py b/archive/v1/src/testing/__init__.py similarity index 100% rename from v1/src/testing/__init__.py rename to archive/v1/src/testing/__init__.py diff --git a/v1/src/testing/mock_csi_generator.py b/archive/v1/src/testing/mock_csi_generator.py similarity index 100% rename from v1/src/testing/mock_csi_generator.py rename to archive/v1/src/testing/mock_csi_generator.py diff --git a/v1/src/testing/mock_pose_generator.py b/archive/v1/src/testing/mock_pose_generator.py similarity index 100% rename from v1/src/testing/mock_pose_generator.py rename to archive/v1/src/testing/mock_pose_generator.py diff --git a/v1/test_application.py b/archive/v1/test_application.py similarity index 100% rename from v1/test_application.py rename to archive/v1/test_application.py diff --git a/v1/test_auth_rate_limit.py b/archive/v1/test_auth_rate_limit.py similarity index 100% rename from v1/test_auth_rate_limit.py rename to archive/v1/test_auth_rate_limit.py diff --git a/v1/tests/e2e/test_healthcare_scenario.py b/archive/v1/tests/e2e/test_healthcare_scenario.py similarity index 100% rename from v1/tests/e2e/test_healthcare_scenario.py rename to archive/v1/tests/e2e/test_healthcare_scenario.py diff --git a/v1/tests/fixtures/api_client.py b/archive/v1/tests/fixtures/api_client.py similarity index 100% rename from v1/tests/fixtures/api_client.py rename to archive/v1/tests/fixtures/api_client.py diff --git a/v1/tests/fixtures/csi_data.py b/archive/v1/tests/fixtures/csi_data.py similarity index 100% rename from v1/tests/fixtures/csi_data.py rename to archive/v1/tests/fixtures/csi_data.py diff --git a/v1/tests/integration/live_sense_monitor.py b/archive/v1/tests/integration/live_sense_monitor.py similarity index 100% rename from v1/tests/integration/live_sense_monitor.py rename to archive/v1/tests/integration/live_sense_monitor.py diff --git a/v1/tests/integration/test_api_endpoints.py b/archive/v1/tests/integration/test_api_endpoints.py similarity index 100% rename from v1/tests/integration/test_api_endpoints.py rename to archive/v1/tests/integration/test_api_endpoints.py diff --git a/v1/tests/integration/test_authentication.py b/archive/v1/tests/integration/test_authentication.py similarity index 100% rename from v1/tests/integration/test_authentication.py rename to archive/v1/tests/integration/test_authentication.py diff --git a/v1/tests/integration/test_csi_pipeline.py b/archive/v1/tests/integration/test_csi_pipeline.py similarity index 100% rename from v1/tests/integration/test_csi_pipeline.py rename to archive/v1/tests/integration/test_csi_pipeline.py diff --git a/v1/tests/integration/test_full_system_integration.py b/archive/v1/tests/integration/test_full_system_integration.py similarity index 100% rename from v1/tests/integration/test_full_system_integration.py rename to archive/v1/tests/integration/test_full_system_integration.py diff --git a/v1/tests/integration/test_hardware_integration.py b/archive/v1/tests/integration/test_hardware_integration.py similarity index 100% rename from v1/tests/integration/test_hardware_integration.py rename to archive/v1/tests/integration/test_hardware_integration.py diff --git a/v1/tests/integration/test_inference_pipeline.py b/archive/v1/tests/integration/test_inference_pipeline.py similarity index 100% rename from v1/tests/integration/test_inference_pipeline.py rename to archive/v1/tests/integration/test_inference_pipeline.py diff --git a/v1/tests/integration/test_pose_pipeline.py b/archive/v1/tests/integration/test_pose_pipeline.py similarity index 100% rename from v1/tests/integration/test_pose_pipeline.py rename to archive/v1/tests/integration/test_pose_pipeline.py diff --git a/v1/tests/integration/test_rate_limiting.py b/archive/v1/tests/integration/test_rate_limiting.py similarity index 100% rename from v1/tests/integration/test_rate_limiting.py rename to archive/v1/tests/integration/test_rate_limiting.py diff --git a/v1/tests/integration/test_streaming_pipeline.py b/archive/v1/tests/integration/test_streaming_pipeline.py similarity index 100% rename from v1/tests/integration/test_streaming_pipeline.py rename to archive/v1/tests/integration/test_streaming_pipeline.py diff --git a/v1/tests/integration/test_websocket_streaming.py b/archive/v1/tests/integration/test_websocket_streaming.py similarity index 100% rename from v1/tests/integration/test_websocket_streaming.py rename to archive/v1/tests/integration/test_websocket_streaming.py diff --git a/v1/tests/integration/test_windows_live_sensing.py b/archive/v1/tests/integration/test_windows_live_sensing.py similarity index 100% rename from v1/tests/integration/test_windows_live_sensing.py rename to archive/v1/tests/integration/test_windows_live_sensing.py diff --git a/v1/tests/mocks/hardware_mocks.py b/archive/v1/tests/mocks/hardware_mocks.py similarity index 100% rename from v1/tests/mocks/hardware_mocks.py rename to archive/v1/tests/mocks/hardware_mocks.py diff --git a/v1/tests/performance/test_api_throughput.py b/archive/v1/tests/performance/test_api_throughput.py similarity index 100% rename from v1/tests/performance/test_api_throughput.py rename to archive/v1/tests/performance/test_api_throughput.py diff --git a/v1/tests/performance/test_frame_budget.py b/archive/v1/tests/performance/test_frame_budget.py similarity index 100% rename from v1/tests/performance/test_frame_budget.py rename to archive/v1/tests/performance/test_frame_budget.py diff --git a/v1/tests/performance/test_inference_speed.py b/archive/v1/tests/performance/test_inference_speed.py similarity index 100% rename from v1/tests/performance/test_inference_speed.py rename to archive/v1/tests/performance/test_inference_speed.py diff --git a/v1/tests/unit/conftest.py b/archive/v1/tests/unit/conftest.py similarity index 100% rename from v1/tests/unit/conftest.py rename to archive/v1/tests/unit/conftest.py diff --git a/v1/tests/unit/test_auth_middleware.py b/archive/v1/tests/unit/test_auth_middleware.py similarity index 100% rename from v1/tests/unit/test_auth_middleware.py rename to archive/v1/tests/unit/test_auth_middleware.py diff --git a/v1/tests/unit/test_csi_extractor.py b/archive/v1/tests/unit/test_csi_extractor.py similarity index 100% rename from v1/tests/unit/test_csi_extractor.py rename to archive/v1/tests/unit/test_csi_extractor.py diff --git a/v1/tests/unit/test_csi_extractor_direct.py b/archive/v1/tests/unit/test_csi_extractor_direct.py similarity index 100% rename from v1/tests/unit/test_csi_extractor_direct.py rename to archive/v1/tests/unit/test_csi_extractor_direct.py diff --git a/v1/tests/unit/test_csi_extractor_tdd.py b/archive/v1/tests/unit/test_csi_extractor_tdd.py similarity index 100% rename from v1/tests/unit/test_csi_extractor_tdd.py rename to archive/v1/tests/unit/test_csi_extractor_tdd.py diff --git a/v1/tests/unit/test_csi_extractor_tdd_complete.py b/archive/v1/tests/unit/test_csi_extractor_tdd_complete.py similarity index 100% rename from v1/tests/unit/test_csi_extractor_tdd_complete.py rename to archive/v1/tests/unit/test_csi_extractor_tdd_complete.py diff --git a/v1/tests/unit/test_csi_processor.py b/archive/v1/tests/unit/test_csi_processor.py similarity index 100% rename from v1/tests/unit/test_csi_processor.py rename to archive/v1/tests/unit/test_csi_processor.py diff --git a/v1/tests/unit/test_csi_processor_tdd.py b/archive/v1/tests/unit/test_csi_processor_tdd.py similarity index 100% rename from v1/tests/unit/test_csi_processor_tdd.py rename to archive/v1/tests/unit/test_csi_processor_tdd.py diff --git a/v1/tests/unit/test_csi_standalone.py b/archive/v1/tests/unit/test_csi_standalone.py similarity index 100% rename from v1/tests/unit/test_csi_standalone.py rename to archive/v1/tests/unit/test_csi_standalone.py diff --git a/v1/tests/unit/test_densepose_head.py b/archive/v1/tests/unit/test_densepose_head.py similarity index 100% rename from v1/tests/unit/test_densepose_head.py rename to archive/v1/tests/unit/test_densepose_head.py diff --git a/v1/tests/unit/test_error_handler.py b/archive/v1/tests/unit/test_error_handler.py similarity index 100% rename from v1/tests/unit/test_error_handler.py rename to archive/v1/tests/unit/test_error_handler.py diff --git a/v1/tests/unit/test_esp32_binary_parser.py b/archive/v1/tests/unit/test_esp32_binary_parser.py similarity index 100% rename from v1/tests/unit/test_esp32_binary_parser.py rename to archive/v1/tests/unit/test_esp32_binary_parser.py diff --git a/v1/tests/unit/test_hardware_service.py b/archive/v1/tests/unit/test_hardware_service.py similarity index 100% rename from v1/tests/unit/test_hardware_service.py rename to archive/v1/tests/unit/test_hardware_service.py diff --git a/v1/tests/unit/test_health_check.py b/archive/v1/tests/unit/test_health_check.py similarity index 100% rename from v1/tests/unit/test_health_check.py rename to archive/v1/tests/unit/test_health_check.py diff --git a/v1/tests/unit/test_metrics.py b/archive/v1/tests/unit/test_metrics.py similarity index 100% rename from v1/tests/unit/test_metrics.py rename to archive/v1/tests/unit/test_metrics.py diff --git a/v1/tests/unit/test_modality_translation.py b/archive/v1/tests/unit/test_modality_translation.py similarity index 100% rename from v1/tests/unit/test_modality_translation.py rename to archive/v1/tests/unit/test_modality_translation.py diff --git a/v1/tests/unit/test_phase_sanitizer.py b/archive/v1/tests/unit/test_phase_sanitizer.py similarity index 100% rename from v1/tests/unit/test_phase_sanitizer.py rename to archive/v1/tests/unit/test_phase_sanitizer.py diff --git a/v1/tests/unit/test_phase_sanitizer_tdd.py b/archive/v1/tests/unit/test_phase_sanitizer_tdd.py similarity index 100% rename from v1/tests/unit/test_phase_sanitizer_tdd.py rename to archive/v1/tests/unit/test_phase_sanitizer_tdd.py diff --git a/v1/tests/unit/test_pose_service.py b/archive/v1/tests/unit/test_pose_service.py similarity index 100% rename from v1/tests/unit/test_pose_service.py rename to archive/v1/tests/unit/test_pose_service.py diff --git a/v1/tests/unit/test_rate_limit.py b/archive/v1/tests/unit/test_rate_limit.py similarity index 100% rename from v1/tests/unit/test_rate_limit.py rename to archive/v1/tests/unit/test_rate_limit.py diff --git a/v1/tests/unit/test_router_interface.py b/archive/v1/tests/unit/test_router_interface.py similarity index 100% rename from v1/tests/unit/test_router_interface.py rename to archive/v1/tests/unit/test_router_interface.py diff --git a/v1/tests/unit/test_router_interface_tdd.py b/archive/v1/tests/unit/test_router_interface_tdd.py similarity index 100% rename from v1/tests/unit/test_router_interface_tdd.py rename to archive/v1/tests/unit/test_router_interface_tdd.py diff --git a/v1/tests/unit/test_sensing.py b/archive/v1/tests/unit/test_sensing.py similarity index 100% rename from v1/tests/unit/test_sensing.py rename to archive/v1/tests/unit/test_sensing.py diff --git a/v1/tests/unit/test_stream_service.py b/archive/v1/tests/unit/test_stream_service.py similarity index 100% rename from v1/tests/unit/test_stream_service.py rename to archive/v1/tests/unit/test_stream_service.py diff --git a/docker/Dockerfile.python b/docker/Dockerfile.python index 7f7d88fd..b3059c62 100644 --- a/docker/Dockerfile.python +++ b/docker/Dockerfile.python @@ -10,16 +10,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Install Python dependencies -COPY v1/requirements-lock.txt /app/requirements.txt +COPY archive/v1/requirements-lock.txt /app/requirements.txt RUN pip install --no-cache-dir -r requirements.txt \ && pip install --no-cache-dir websockets uvicorn fastapi # Copy application code -COPY v1/ /app/v1/ +COPY archive/v1/ /app/v1/ COPY ui/ /app/ui/ # Copy sensing modules -COPY v1/src/sensing/ /app/v1/src/sensing/ +COPY archive/v1/src/sensing/ /app/v1/src/sensing/ EXPOSE 8765 EXPOSE 8080 diff --git a/docs/WITNESS-LOG-028.md b/docs/WITNESS-LOG-028.md index 64528fb9..a342f0a2 100644 --- a/docs/WITNESS-LOG-028.md +++ b/docs/WITNESS-LOG-028.md @@ -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`). diff --git a/docs/adr/ADR-011-python-proof-of-reality-mock-elimination.md b/docs/adr/ADR-011-python-proof-of-reality-mock-elimination.md index 2695477c..bf3f29e4 100644 --- a/docs/adr/ADR-011-python-proof-of-reality-mock-elimination.md +++ b/docs/adr/ADR-011-python-proof-of-reality-mock-elimination.md @@ -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 diff --git a/docs/adr/ADR-013-feature-level-sensing-commodity-gear.md b/docs/adr/ADR-013-feature-level-sensing-commodity-gear.md index 40a6ae28..4ec9870d 100644 --- a/docs/adr/ADR-013-feature-level-sensing-commodity-gear.md +++ b/docs/adr/ADR-013-feature-level-sensing-commodity-gear.md @@ -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) diff --git a/docs/adr/ADR-018-esp32-dev-implementation.md b/docs/adr/ADR-018-esp32-dev-implementation.md index 6cb70f3d..54c0ae10 100644 --- a/docs/adr/ADR-018-esp32-dev-implementation.md +++ b/docs/adr/ADR-018-esp32-dev-implementation.md @@ -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 diff --git a/docs/adr/ADR-019-sensing-only-ui-mode.md b/docs/adr/ADR-019-sensing-only-ui-mode.md index df782846..4d624ccd 100644 --- a/docs/adr/ADR-019-sensing-only-ui-mode.md +++ b/docs/adr/ADR-019-sensing-only-ui-mode.md @@ -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 | diff --git a/docs/adr/ADR-020-rust-ruvector-ai-model-migration.md b/docs/adr/ADR-020-rust-ruvector-ai-model-migration.md index 6485b45a..520fe957 100644 --- a/docs/adr/ADR-020-rust-ruvector-ai-model-migration.md +++ b/docs/adr/ADR-020-rust-ruvector-ai-model-migration.md @@ -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) | diff --git a/docs/adr/ADR-028-esp32-capability-audit.md b/docs/adr/ADR-028-esp32-capability-audit.md index 8836b7ef..02d037d3 100644 --- a/docs/adr/ADR-028-esp32-capability-audit.md +++ b/docs/adr/ADR-028-esp32-capability-audit.md @@ -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`. diff --git a/docs/adr/ADR-049-cross-platform-wifi-interface-detection.md b/docs/adr/ADR-049-cross-platform-wifi-interface-detection.md index f8003d4e..843e9f8d 100644 --- a/docs/adr/ADR-049-cross-platform-wifi-interface-detection.md +++ b/docs/adr/ADR-049-cross-platform-wifi-interface-detection.md @@ -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) diff --git a/docs/adr/ADR-080-qe-remediation-plan.md b/docs/adr/ADR-080-qe-remediation-plan.md index 402cfdc2..c0863c01 100644 --- a/docs/adr/ADR-080-qe-remediation-plan.md +++ b/docs/adr/ADR-080-qe-remediation-plan.md @@ -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. diff --git a/docs/build-guide.md b/docs/build-guide.md index 023d636a..cc943683 100644 --- a/docs/build-guide.md +++ b/docs/build-guide.md @@ -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) | diff --git a/docs/qe-reports/00-qe-queen-summary.md b/docs/qe-reports/00-qe-queen-summary.md index 422088ba..3b2a8d2f 100644 --- a/docs/qe-reports/00-qe-queen-summary.md +++ b/docs/qe-reports/00-qe-queen-summary.md @@ -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 | diff --git a/docs/qe-reports/01-code-quality-complexity.md b/docs/qe-reports/01-code-quality-complexity.md index 44b2f8d5..033d3765 100644 --- a/docs/qe-reports/01-code-quality-complexity.md +++ b/docs/qe-reports/01-code-quality-complexity.md @@ -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 | diff --git a/docs/qe-reports/02-security-review.md b/docs/qe-reports/02-security-review.md index ff2b7819..60cab4f2 100644 --- a/docs/qe-reports/02-security-review.md +++ b/docs/qe-reports/02-security-review.md @@ -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/) diff --git a/docs/qe-reports/03-performance-analysis.md b/docs/qe-reports/03-performance-analysis.md index 9f326c50..a10a9d0d 100644 --- a/docs/qe-reports/03-performance-analysis.md +++ b/docs/qe-reports/03-performance-analysis.md @@ -352,16 +352,16 @@ pub fn run(&self, csi_input: &Tensor) -> NnResult { | 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 diff --git a/docs/qe-reports/04-test-analysis.md b/docs/qe-reports/04-test-analysis.md index a0448d96..6c1f8c15 100644 --- a/docs/qe-reports/04-test-analysis.md +++ b/docs/qe-reports/04-test-analysis.md @@ -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. | --- diff --git a/docs/qe-reports/05-quality-experience.md b/docs/qe-reports/05-quality-experience.md index 47b795ca..26771563 100644 --- a/docs/qe-reports/05-quality-experience.md +++ b/docs/qe-reports/05-quality-experience.md @@ -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 diff --git a/docs/qe-reports/06-product-assessment-sfdipot.md b/docs/qe-reports/06-product-assessment-sfdipot.md index aba80cb5..3859cb53 100644 --- a/docs/qe-reports/06-product-assessment-sfdipot.md +++ b/docs/qe-reports/06-product-assessment-sfdipot.md @@ -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 diff --git a/docs/qe-reports/07-coverage-gaps.md b/docs/qe-reports/07-coverage-gaps.md index 66b88cd3..98f8ec9b 100644 --- a/docs/qe-reports/07-coverage-gaps.md +++ b/docs/qe-reports/07-coverage-gaps.md @@ -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 | --- diff --git a/docs/qe-reports/EXECUTIVE-SUMMARY.md b/docs/qe-reports/EXECUTIVE-SUMMARY.md index 79043c30..b020ae5b 100644 --- a/docs/qe-reports/EXECUTIVE-SUMMARY.md +++ b/docs/qe-reports/EXECUTIVE-SUMMARY.md @@ -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 diff --git a/docs/user-guide.md b/docs/user-guide.md index cb19427c..00e03329 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -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 diff --git a/v2/crates/wifi-densepose-wifiscan/src/adapter/macos_scanner.rs b/v2/crates/wifi-densepose-wifiscan/src/adapter/macos_scanner.rs index be3d045e..b339eed4 100644 --- a/v2/crates/wifi-densepose-wifiscan/src/adapter/macos_scanner.rs +++ b/v2/crates/wifi-densepose-wifiscan/src/adapter/macos_scanner.rs @@ -36,7 +36,7 @@ use crate::error::WifiScanError; /// Synchronous WiFi scanner that shells out to the `mac_wifi` Swift helper. /// -/// The helper binary must be compiled from `v1/src/sensing/mac_wifi.swift` and +/// The helper binary must be compiled from `archive/v1/src/sensing/mac_wifi.swift` and /// placed on `$PATH` or at a known location. The scanner invokes it with a /// `--scan-once` flag (single-shot mode) and parses the JSON output. ///