Commit Graph

6 Commits

Author SHA1 Message Date
arsen 6ce25cec79 feat(adr-117): process hygiene + pose path honesty + audit sweep
Audit fix bundle (10 areas; details in ADR-117 + commit body below).

Server (main.rs / wiflow_v1.rs):
- UDP receiver filters loopback/multicast/unspecified before NODE_ADDRS
  registration. Defends against `cargo test` cross-talk that spawned
  250+ ping zombies on the production server's :5005 port.
- csi_keepalive_task pre-reaps `/sbin/ping -i 0.040` orphans at task
  entry. macOS doesn't propagate parent death, so killed servers used
  to leave init-parented pings running indefinitely.
- run_wiflow_inference stamps real classifier confidence onto every
  keypoint (was hardcoded 1.0) — reads 0.037 on live data, honest.
- run_wiflow_inference clones only the tail-20 frames inside the lock,
  not the full 600-deep VecDeque (~270 KB → ~9 KB per tick).
- wiflow_v1::build_input_from_history: zero-pad dead channel slots
  instead of duplicating subcarrier 0 across all of them. Comment said
  "zero the rest", prior code did the opposite.
- GET / now 308-redirects to /ui/index.html; API index moved to /api.

UI (ui/index.html, ui/components/LiveDemoTab.js):
- <section id="sensing"> gets a <div id="sensing-container"> child so
  app.js::SensingTab.mount has its mount point. Sensing tab was
  permanently blank.
- LiveDemoTab.fetchModels: only inject WiFlow into the dropdown if no
  RVF model is already active. Prevents silent flip back to WiFlow
  after every poll.

Tests (multi_node_test.rs):
- test_multi_node_udp_send probes 127.0.0.1:5005 first; if bind fails
  (e.g. a dev server is running), skip the send. Two-layer defense
  with the server-side filter above.

Docs (CHECKLIST.md, ADR-115, espectre-gap-analysis.md, ota-pipeline.md):
- CHECKLIST head sha + count refreshed (43→47 Done, head 0ec1e4b0,
  ADR range to 001-117 with ADR-111 noted as intentionally absent).
- ADR-115 typo fixes: "ADR-100" → "ADR-110" (TP-Link WISP),
  "ADR-111" → "ADR-109" (AP-MAC tracking actually lives there).
- gap-analysis "Still open" table: 8 shipped items annotated with
  commit hashes; remainder reclassified Deferred with reason.
- ota-pipeline.md: new "Operator REST endpoints" section listing
  /ota/recalibrate (ADR-109) and /ota/set-target (ADR-115) with
  unauthed + bearer-token curl examples.

Verified post-restart:
- exactly 2 ping children, both parented to current PID, one per real
  sensor IP, no 127.0.0.1.
- GET / → 308 → /ui/index.html.
- /api/v1/info: pose_estimation=true, version 0.3.0.
- /api/v1/pose/current: 17 COCO keypoints, confidence 0.037 (real).
- cargo test --workspace: 13 passed / 0 failed / 5 ignored.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 19:24:04 +07:00
arsen e4204595b0 docs: actualization sweep — close items shipped this session
Cross-referenced every ADR Open Items section + both reference docs
against the actual implementation state on the branch. Closed items
the session shipped, kept stale "will be done in ADR-X" forward-refs
honest:

ADR-100    NBVI port (ADR-102), RSSI parse fix (3393c1e8), idle-
            channel keepalive (ADR-106).  Tailscale-target still open.
ADR-101    per-sub baseline-drop / off-axis sit (both via ADR-104).
             CV saturation above ~30 % still open.
ADR-102    Step 3 FP-rate validation (ADR-104 D4).
ADR-103    all three open items closed (REST endpoint via ADR-107,
            per-sub comparison via ADR-104, auto-recalibrate via ADR-107).
ADR-106    FW-side µs timestamp via OTA (b787f40a).

espectre-techniques.md:
- NBVI: now "DONE (all 4 NBVI steps)" instead of "missing Step 3".
- Persisted calibration: split into "server (ADR-103) + FW NVS (ADR-108)"
  with intentional design note for NBVI staying server-side.

espectre-gap-analysis.md:
- NBVI Step 3, gain-lock NVS, baseline persistence, threshold
  persistence all flipped to  in the per-section comparison tables.
- Priority list restructured into " Done in this session" (10 items)
  + " Still open by impact" (14 items) with reality-checked
  estimates. Top 3 open: HA via MQTT, 2 000-packet test suite,
  per-sub delta sparkline in raw.html.

Verbatim Pace Part-2 article still informs the gap structure; nothing
was removed from his pipeline, only RuView's column updated.
2026-05-17 13:52:50 +07:00
arsen 274984d3a9 docs(refs): ota-pipeline.md — verbatim OTA reproduction recipe
Saves the comprehensive OTA pipeline reference written by another
agent so future sessions don't lose the diagnostic flowchart or the
"three FW prerequisites" causal chain.

Tested live against current FW (v0.6.4): port 8032 reachable on both
sensors, scripts/ota-deploy.sh round-trip works, both nodes
successfully switched partitions (ota_0 ↔ ota_1) without USB+BOOT
dance. OTA is the supported path for future FW changes from this
session — sensor µs timestamp (ADR-106 open item), NVS persistence
of gain-lock (gap-analysis #5), and any larger FW work.

Kept whole (329 lines, over the usual 200 line cap for docs) because
the flowchart and pitfall table lose meaning if split. The cap is a
guideline for new project ADRs; a verbatim recipe is justified by
diagnostic value.
2026-05-17 12:24:02 +07:00
arsen d28a1834d4 docs(refs): espectre-gap-analysis.md — full Part-2 gap structured by section
Catalogues, section-by-section against Pace's Part-2 article, every
ESPectre technique RuView has and does not have, plus a prioritized
roadmap (9 items, NVS persistence and FP-rate validation top of list).

Replaces the 8-item inline "open items" stub in espectre-techniques.md
with a 1-line forward link. Both files stay ≤ 200 lines per the docs
convention.
2026-05-17 10:51:32 +07:00
arsen 4d3ca49fba docs: ADR-101 / ADR-102 / ADR-103 — full session record
* ADR-101 raw-amplitude presence/motion classifier — per-node and
  cross-node fusion logic, hysteresis, per-node UI surface
  (`PerNodeFeatureInfo.classification` override).
* ADR-102 server-side NBVI subcarrier selection — formula, dead-zone
  gate, ESPectre Step-1 quiet-window finder, why we split FULL vs
  NBVI-subset broadband.
* ADR-103 persistent baseline + universal threshold normalization —
  JSON schema v2 at `v2/data/baseline.json`, FULL-broadband over
  NBVI for cross-restart stability, `norm_cv = cv / baseline_cv`
  with universal 3×/6× gates, recording script workflow.
* Updated espectre-techniques.md to reflect the DONE items (Steps
  1+2+4 of NBVI, baseline persistence, universal threshold) and the
  remaining open items in priority order.

Each ADR ≤ 200 lines per the operator's docs convention; deep detail
lives in `docs/references/espectre-techniques.md` (also ≤ 200) which
the ADRs link to. README.md and CLAUDE.md unchanged (no extra
content added; existing >200-line state pre-dates this session).
2026-05-17 10:46:36 +07:00
arsen 764388c0bf docs+fix: ESPectre technique reference + revert stale-amp UI fill
* docs/references/espectre-techniques.md — catalogues every Pace
  technique from Part-2 against what RuView has implemented, doesn't
  have, or has differently. Includes ranked open-items list.
* sensing-server: revert feature_state path to vec![] amplitudes.
  The previous fix made bars LOOK live by reissuing the last raw-CSI
  vector on every feature_state tick — operator reported this made
  the bars misleading (visually busy but unresponsive to movement).
  raw.html already skips empty-amp updates so bars now refresh only
  on actual fresh CSI, which is honest.
* raw.html: comment on the skip-empty branch for future-me.
2026-05-17 09:08:09 +07:00