Record ADRs 421 to 423, actual dependency integration, bounded input and evidence authority, duration evaluation, security regressions and measured receipts. Preserve negative predictive and caching results; no model promotion.
Preserve native source precision and exact pooled controls under the original
training and development split. Add an 18-configuration resolution ablation,
input provenance and artifact tests, and measured results retaining the
existing ACF model. Document unresolved semantic labels and confirmation limits.
Retain the stronger ACF model after an 18-configuration temporal ablation
regresses on development data. Add a pinned actual-library integrity probe,
strict bounded replay inspection, measured synthetic overhead, and CI tests.
Preserve source hashes and separate software integrity from sensing accuracy.
Integrate reviewed source PRs #2201-#2223, #2225-#2231, #2235-#2240, #2242 and #2243 (firmware README hunks remain in #2247). Regenerate one package manifest after integration, validate native Windows test execution, bound MTK listener startup, support official C6 release bundles, and retain stronger release metadata gates.
Both capture scripts decoded a header layout the firmware does not send.
csi_collector.c and esp32_parser.rs use: magic u32 @0, node_id @4,
n_antennas @5, n_subcarriers u16 @6, freq_mhz u32 @8, sequence u32 @12,
rssi i8 @16, noise_floor i8 @17, ppdu_type @18, flags @19, then
n_antennas * n_subcarriers int8 I/Q pairs from @20.
- collect-training-data.py read a 16-byte header and int16 I/Q, so its
length check rejected every real single-antenna frame. It now reads the
20-byte header and int8 pairs, records freq/channel/seq/ppdu/flags, and
lets the recorder stamp receive time (the header has no timestamp).
- record-csi-udp.py read rssi from byte 6 and channel from byte 7 (the
n_subcarriers bytes) and treated bytes 8-19 as I/Q, so a 64-subcarrier
frame came out as 70 subcarriers with header bytes in the first six
amplitudes. It now checks the magic, reads the real fields, and writes
only the I/Q block to iq_hex.
- Add scripts/tests/test_capture_adr018.py, which builds frames with the
esp32_parser.rs test layout and checks the decoded fields.
Co-Authored-By: claude-flow <ruv@ruv.net>
prove.sh looked only for `python`, so on macOS (python3 only) it skipped
the deterministic proof and still printed RESULT: PASS with exit 0.
- Pick $PYTHON, then python3, then python.
- Check numpy/scipy import before running verify.py and print the
lockfile install command when they are missing; warn when installed
versions differ from archive/v1/requirements-lock.txt.
- Run verify.py single-threaded, as CI does.
- Hard gates that cannot run (no cargo, no Python, missing deps) are
reported as [NOT RUN] and the run ends INCOMPLETE with exit 2.
Data/hardware-gated claims are unchanged.
- Tell people to stop any local server on UDP 5005 first (#2086).
Fixes#2095
Co-Authored-By: claude-flow <ruv@ruv.net>
- firmware/openwrt-wn586x3/: the patch set that made a Wavlink WL-WN586X3
Rev A (MT7981B + MT7976C) emit CSI on OpenWrt 24.10.8. It contains:
MediaTek's mt7915 CSI driver patch rebased onto the mt76 revision 24.10.8
pins (BSD-3-Clause-Clear, MediaTek author line kept); the Rev A board
patch (GPL-2.0); a buffer-overrun fix for `mt76-vendor dump csi`; and
an attribute-enum fix for MtkCSIdump. Each patch keeps the licence of
the code it modifies. There are no images, firmware blobs, or captures.
- docs/mediatek-router-csi.md: an operator guide covering supported
silicon, the image build route that was tested, arming CSI, the
bridge, `--source mediatek`, endpoints and provenance labels, what the
data is not, evidence, and troubleshooting. Every claim is tagged
MEASURED, CODE-DERIVED, CLAIMED, or SYNTHETIC.
- scripts/mediatek-csi-phase-stability.py: a read-only reproducer for
the one MEASURED offline result. On one MT7976C radio, the cross-chain
phase arg(H0*conj(H1)) moves 0.014-0.039 rad (p50) between adjacent
frames for well-sampled transmitters, against about 1.56 rad for raw
per-chain phase, which is what random phase gives. It never prints a
transmitter address. The captures it was run on are not in the tree.
- ADR-266 Amendment 1: vendor CSI exists on MT7981 through MediaTek's
public feed patch, demonstrated on one board model, and still
`mediatek:physical-unvalidated`. The hardware gates remain open.
- user-guide.md and the bridge README link to the guide.
Developed in whitsentry, a RuView-based project.
Co-Authored-By: claude-flow <ruv@ruv.net>
With authentication enabled, collect-ground-truth.py could not start a CSI
recording: it sent no bearer token. It also treated any HTTP 200 as success,
but the recording endpoints answer 200 with {"success": false, "error": ...}
for refusals such as "recording already in progress". Either way it went on
capturing camera keypoints with no paired CSI and only printed a warning.
- Read the token from --token-file, else RUVIEW_API_TOKEN, and send it as
Authorization: Bearer on start and stop.
- post_json() returns False when the body says success: false.
- Name the CSI recording gt_<timestamp> so it pairs with
keypoints_<timestamp>.jsonl.
- Exit with an error when the recording cannot start, unless
--allow-no-csi is given.
Tests: py_compile; scripts/tests (15 passed); a local smoke test against a
stub HTTP server checked the bearer header, the request id, the
success:false refusal, and token precedence (file, then env).
Co-Authored-By: claude-flow <ruv@ruv.net>