The original `verify` script (220 LOC) only validated the v1 Python
signal-processing pipeline. After v0.9.0 (ADR-125) and v0.10.0/v0.11.0
(HOMECORE), the stack has six more proof boundaries that an operator
should be able to verify in one command.
New `verify` (~290 LOC) runs nine phases:
1. Python pipeline SHA-256 (existing — replays v1 proof)
2. Production-code mock scan (existing — np.random.rand/randn)
3. Rust workspace tests — cargo test --workspace --no-default-features
4. PyO3 BFLD binding — cargo check -p wifi-densepose-py
5. ADR-125 §2.1.d invariant — identity_risk_score = None in scripts
6. crates.io publishes — verifies 12 published crates
7. npm publishes — verifies @ruvnet/rvagent
8. Docker Hub multi-arch — verifies amd64 + arm64 manifests
9. HOMECORE binary in image — runs homecore-server --help inside the image
Flags:
--quick skip slow phases (3 + 8 + 9)
--rust-only just Phase 3
--docker-only just Phases 8 + 9
--verbose, --audit, --generate-hash pass through to verify.py
Per-phase result is PASS / FAIL / SKIP; SKIP is the honest verdict
when an optional tool (cargo, docker, curl) is absent — no false
green. Final exit is 0 only if every phase that RAN reported PASS.
Empirical (--quick, just now on HEAD 358ca6190):
PASS Phase 2: no random generators in production code
PASS Phase 4: wifi-densepose-py compiles cleanly
PASS Phase 5: identity_risk_score=None at every gateway script
PASS Phase 6: 12/12 crates on crates.io
(core 0.3.0, signal 0.3.1, sensing-server 0.3.1, hardware 0.3.0,
nn 0.3.0, bfld 0.3.0, vitals 0.3.0, wifiscan 0.3.0, train 0.3.1,
cog-ha-matter 0.3.0, cog-person-count 0.3.0, cog-pose-estimation 0.3.0)
PASS Phase 7: @ruvnet/rvagent v0.1.0 on npm
SKIP Phase 9: docker not on this Windows shell PATH
FAIL Phase 1: v1 pipeline hash mismatch (pre-existing — needs
`verify --generate-hash` after the latest numpy/scipy bump)
The verify script does its job: Phase 1's FAIL is the proof that the
v1 numerical pipeline has drifted from its last published hash and
needs explicit operator action to regenerate. That is the whole
point of a Trust Kill Switch — fail loud, not silently green.
Co-Authored-By: claude-flow <ruv@ruv.net>
* fix: bug triage from issues #559, #561, #588
- verify: point at archive/v1/ proof paths (v1/ was removed) (#559)
- firmware README: app flash offset 0x10000 -> 0x20000, include
ota_data_initial.bin at 0xf000, correct provision.py path from
scripts/ to firmware/esp32-csi-node/ (#561)
- provision.py: drop password-length leak in console output; print
(set)/(empty) instead of len(password) asterisks (#588)
Co-Authored-By: claude-flow <ruv@ruv.net>
* ci: fix Fuzz Testing + Swarm Test (ADR-062) workflow regressions
Both have been red on main for ~5 weeks; root-causing them so PR #590
can land green rather than merging on top of pre-existing breakage.
- esp_stubs.h: add wifi_ps_type_t enum (WIFI_PS_NONE/MIN/MAX) and
esp_wifi_set_ps() stub. csi_collector.c:346 added a real
esp_wifi_set_ps(WIFI_PS_NONE) call to disable modem sleep
(RuView#521 fix); the host-native fuzz target couldn't link.
- scripts/qemu_swarm.py: pass --force-partial to provision.py.
The per-node TDM/channel overlay intentionally omits WiFi
credentials (those live in the base flash image), but the
issue #391 wifi-trio guard now rejects calls missing the
--ssid/--password trio. --force-partial is exactly the opt-in
for this case.
Co-Authored-By: claude-flow <ruv@ruv.net>
Optimization:
- Cache mean phase per frame in ring buffer for O(1) Doppler access
- Sliding window (last 64 frames) instead of full history traversal
- Doppler FFT: 253.9us -> 44.9us per frame (5.7x faster)
- Full pipeline: 719.2us -> 254.2us per frame (2.8x faster)
Trust kill switch:
- ./verify: one-command proof replay with SHA-256 hash verification
- Enhanced verify.py with source provenance, feature inspection, --audit
- Makefile with verify/verify-verbose/verify-audit targets
- New hash: 0b82bd45e836e5a99db0494cda7795832dda0bb0a88dac65a2bab0e949950ee0
Benchmark fix:
- NN inference_bench.rs uses MockBackend instead of calling forward()
which now correctly errors when no weights are loaded
https://claude.ai/code/session_01Ki7pvEZtJDvqJkmyn6B714