Commit Graph

2 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 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