Commit Graph
1508 Commits
Author SHA1 Message Date
github-actions[bot] 75c2921d06 chore: update vendor submodules to latest upstream 2026-10-06 06:27:03 +00:00
rUv 0b15c0ebc9 Merge pull request #2163 from ruvnet/release/aepod-integration
release: integrate aepod PRs #2100-#2157 (38 PRs, review fixes, validated)
v3060
2026-10-05 13:52:42 -07:00
ruv 682a6f4538 docs(changelog): community batch PRs #2100-#2157
Co-Authored-By: claude-flow <ruv@ruv.net>
2026-10-05 12:21:07 -04:00
ruv a72174c571 fix: review findings and cross-PR integration fixes for aepod release set
- mediatek: cap per-device maps at 64 with oldest-first eviction; clamp --csi-ring
- training: mark live-buffer fallback runs degraded (data_source/degraded) instead of plain "completed"
- multistatic: skip CIR blend when any frame in the cohort has a placeholder phase
- groundtruth: median count baseline; radar labels carry evidence=CLAIMED
- spatial-evidence: default proof CODE; MEASURED requires a reproducer
- scripts: collect-ground-truth guards non-JSON replies and unreadable token files
- docker: entrypoint accepts 1/true/yes/on for RUVIEW_UDP_INSECURE_LAN
- adaptive model: untrack v2/data/adaptive_model.json (#2135)
- docs: ADR-379 evidence tags, RUNBOOK/README OTA wording, NOTICE for vendored MediaTek patch
- tests: fresh timestamps for privacy tests (#2119 staleness), plan_source Result handling,
  drop obsolete qualcomm-binds-nothing test (#2126), ignore slow live-binary test (#2157)

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-10-05 12:08:21 -04:00
ruv fd323e483e Merge PR #2128 (aepod) into release integration
# Conflicts:
#	.github/workflows/ci.yml
2026-10-05 11:48:40 -04:00
ruv 9f0821cf69 Merge PR #2104 (aepod) into release integration 2026-10-05 11:48:25 -04:00
ruv 69fc9efff7 Merge PR #2145 (aepod) into release integration 2026-10-05 11:48:25 -04:00
ruv 20386cf313 Merge PR #2141 (aepod) into release integration
# Conflicts:
#	docs/adr/README.md
2026-10-05 11:48:24 -04:00
ruv c4fd6d9b36 Merge PR #2101 (aepod) into release integration
# Conflicts:
#	v2/crates/wifi-densepose-sensing-server/src/training_api.rs
2026-10-05 11:48:16 -04:00
ruv e223d86ba2 Merge PR #2144 (aepod) into release integration 2026-10-05 11:47:35 -04:00
ruv 52e5ebefbd Merge PR #2143 (aepod) into release integration 2026-10-05 11:47:35 -04:00
ruv ca44cd1a7b Merge PR #2117 (aepod) into release integration
# Conflicts:
#	docs/integrations/home-assistant.md
#	v2/crates/wifi-densepose-sensing-server/src/main.rs
2026-10-05 11:47:34 -04:00
ruv 5fe0a6a48d Merge PR #2105 (aepod) into release integration
# Conflicts:
#	v2/crates/wifi-densepose-sensing-server/src/main.rs
2026-10-05 11:46:33 -04:00
ruv da1ef6a17d Merge PR #2102 (aepod) into release integration
# Conflicts:
#	docs/adr/README.md
2026-10-05 11:46:15 -04:00
ruv b6c2fb5b7d Merge PR #2116 (aepod) into release integration 2026-10-05 11:46:08 -04:00
ruv b8b70b7df7 Merge PR #2115 (aepod) into release integration 2026-10-05 11:46:07 -04:00
ruv bb5d903724 Merge PR #2114 (aepod) into release integration
# Conflicts:
#	v2/crates/wifi-densepose-sensing-server/src/main.rs
2026-10-05 11:46:07 -04:00
ruv 1e2348abef Merge PR #2113 (aepod) into release integration
# Conflicts:
#	v2/crates/wifi-densepose-sensing-server/src/main.rs
2026-10-05 11:45:52 -04:00
ruv 2493185ab8 Merge PR #2112 (aepod) into release integration 2026-10-05 11:45:33 -04:00
ruv 678f63f4f3 Merge PR #2125 (aepod) into release integration
# Conflicts:
#	v2/crates/wifi-densepose-sensing-server/src/cli.rs
#	v2/crates/wifi-densepose-sensing-server/src/main.rs
2026-10-05 11:45:26 -04:00
ruv 0aba0fc467 Merge PR #2127 (aepod) into release integration
# Conflicts:
#	v2/crates/wifi-densepose-sensing-server/src/main.rs
2026-10-05 11:44:53 -04:00
ruv 6f550c39ed Merge PR #2157 (aepod) into release integration 2026-10-05 11:44:34 -04:00
ruv e9d0cef610 Merge PR #2133 (aepod) into release integration 2026-10-05 11:44:34 -04:00
ruv bb22f1b185 Merge PR #2109 (aepod) into release integration 2026-10-05 11:44:33 -04:00
ruv 7bc5fe1a53 Merge PR #2103 (aepod) into release integration 2026-10-05 11:44:33 -04:00
ruv 51e1788c7e Merge PR #2129 (aepod) into release integration 2026-10-05 11:44:32 -04:00
ruv 7b62297f3e Merge PR #2126 (aepod) into release integration 2026-10-05 11:44:31 -04:00
ruv 890e521a3a Merge PR #2132 (aepod) into release integration 2026-10-05 11:44:31 -04:00
ruv 444184f9ef Merge PR #2119 (aepod) into release integration 2026-10-05 11:44:30 -04:00
ruv 7955af5bc0 Merge PR #2107 (aepod) into release integration 2026-10-05 11:44:29 -04:00
ruv 273a2a8536 Merge PR #2108 (aepod) into release integration 2026-10-05 11:44:29 -04:00
ruv add0755958 Merge PR #2134 (aepod) into release integration 2026-10-05 11:44:28 -04:00
ruv de5f7edd16 Merge PR #2100 (aepod) into release integration 2026-10-05 11:44:22 -04:00
ruv 69e0729c61 Merge PR #2156 (aepod) into release integration 2026-10-05 11:44:22 -04:00
ruv 9baaf8434f Merge PR #2155 (aepod) into release integration 2026-10-05 11:44:21 -04:00
ruv 27eefb6a7f Merge PR #2140 (aepod) into release integration 2026-10-05 11:44:20 -04:00
ruv c6f7e8ca0d Merge PR #2120 (aepod) into release integration 2026-10-05 11:44:20 -04:00
ruv 474f1a904e Merge PR #2118 (aepod) into release integration 2026-10-05 11:44:19 -04:00
ruv ddaa54eba0 Merge PR #2110 (aepod) into release integration 2026-10-05 11:44:19 -04:00
ruv b3d31510ee Merge PR #2130 (aepod) into release integration 2026-10-05 11:44:18 -04:00
ruv bce512cb8d Merge PR #2131 (aepod) into release integration 2026-10-05 11:44:18 -04:00
ruv 9950ecc340 fix(provision): refuse to write credentials through a symlink with a clear error
Co-Authored-By: claude-flow <ruv@ruv.net>
2026-10-05 11:44:17 -04:00
ruv e0c4207bd5 Merge PR #2152 (aepod) into release integration
# Conflicts:
#	firmware/esp32-csi-node/provision.py
2026-10-05 11:43:47 -04:00
ruv 044a41d2de Merge PR #2153 (aepod) into release integration 2026-10-05 11:43:14 -04:00
ruv 8d243a67f4 Merge PR #2111 (aepod) into release integration 2026-10-05 11:43:13 -04:00
Mathew Beaneandclaude-flow ee6717f035 fix(sensing-server): lock the CSI grid gate on the majority grid and report a stalled pipeline on /health (#1894)
The per-node grid gate locked onto the densest CSI grid a node had ever
sent and rejected every other grid. Real ESP32-S3 nodes interleave
several grids: one node sent 192 bins on 88% of frames and 306 on 6%, so
the gate locked onto the 306 minority and dropped about 90% of that
node's frames. A node whose radio moved to a sparser grid for good was
rejected forever; when every node did this, `tick` froze while /health
still reported ok.

The gate now votes over each node's last 64 frames and locks onto the
grid the node sends most. A challenger must outnumber the active grid
3:2 to take over, so interleaved grids don't flap the lock. A switch
clears the window as before. On an ESP32-C6 the HE-SU majority still
wins and the HT minority is still rejected.

/health keeps `status: "ok"` (the UI's server probe keys on it) and adds
a `processing` block: a live/stalled/no_input/idle state, the age of the
last published update, and lock-free UDP counters (datagrams, age of the
last datagram, datagrams dropped by the source allowlist). A frozen
pipeline can now be told apart from input that stopped arriving.
Allowlist drops also log a warning on the 1st, 2nd, 4th, 8th... drop
instead of only at debug level.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-10-04 17:31:47 -04:00
Mathew Beaneandclaude-flow f5a36666fc fix(hardware): accept ESP32 frames up to the firmware buffer size
Esp32CsiParser capped n_subcarriers at 256. Real ESP32-S3 nodes on
firmware 0.8.12 send 1-antenna frames with 306 subcarriers (612 I/Q
bytes), so the parser dropped about a third of live frames. Pointcloud
started hitting that cap once it switched to this parser.

The bound now comes from the firmware: frames are serialized into
CSI_MAX_FRAME_SIZE = 20 + 4 * 256 * 2 bytes, so a frame carries at most
1024 I/Q pairs across all antennas. The check is n_antennas *
n_subcarriers <= 1024.

HT/legacy bandwidth no longer maps subcarrier counts above 128 to 80 or
160 MHz. ESP32 radios use 20/40 MHz channels, and the larger counts
(192, 306) come from merged LLTF/HT-LTF buffers, so anything above 64
is reported as 40 MHz.

The pointcloud UDP receive buffer grows from 2048 to 4096 bytes so the
largest legal frame (2068 bytes) is not truncated.

Refs #1348

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-10-04 16:52:10 -04:00
Mathew Beaneandclaude-flow d78a221607 feat(provision): read the WiFi password from a file or a prompt
--password puts the WiFi password in argv, where ps and shell history can
see it (#1754). This adds two ways to give it without that:

- --password-file PATH reads it from a file, dropping one trailing newline
  (\n or \r\n). The file must exist and not be empty. If group or others can
  read it, the script refuses and suggests chmod 600.
  --allow-insecure-password-file accepts such a file with a warning, for
  read-only mounts such as 0444 secrets.
- When --ssid is given with no password flag and stdin is a terminal, the
  script asks with getpass. It reuses a saved password only if it was saved
  for the same SSID. Without a terminal (scripts, CI) nothing is asked and
  the existing missing-credentials check applies.

--password still works, but now prints a one-line warning on stderr that
points at --password-file. The two flags are mutually exclusive. The
firmware README examples now use --password-file.

Tests: 10 new tests in tests/test_provision_secrets.py, with placeholder
credentials and getpass and the flasher stubbed. 8 fail on the previous
commit; the other 2 check that nothing is asked without a terminal or when a
saved password matches the SSID. The suite goes from 25 to 35 passing.

Refs #1754

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-10-04 16:50:43 -04:00
Mathew Beaneandclaude-flow db81dce7ba fix(multistatic): gate phase combining on a declared shared reference
The sensing-server bridge builds every node frame with a zero phase
placeholder and the fuser combined those phases across nodes as if they
were measured against one reference. ESP32 nodes each run an independent
crystal with a random PLL phase after reset; mesh time sync aligns frames,
not RF phase, so there is nothing to combine.

- Add PhaseReference (Unavailable / NodeLocal / Shared{id}) to
  MultiBandCsiFrame. The server bridge declares Unavailable.
- MultistaticFuser combines phase only when every frame declares the same
  Shared id. Otherwise fused_phase is empty and FusedSensingFrame carries
  PhaseFusion::AmplitudeOnly(reason). Amplitude fusion is unchanged.
- The ADR-134 CIR blend is skipped when the phase is a placeholder.
- TrustedOutput and /health/ready (trust.phase_fusion) report the mode
  and reason.
- ADR-029 status note updated.

Refs #1752, #1710, #1750.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-10-04 16:42:03 -04:00
Mathew Beaneandclaude-flow 3a8ec8139e fix(pointcloud): parse ESP32 CSI frames with the reference ADR-018 parser
The pointcloud parser read channel from byte 8, RSSI from byte 9, noise
floor from byte 10 and a "timestamp" from bytes 16..19. The firmware
(csi_serialize_frame) writes freq_mhz as u32 at 8..11, sequence at
12..15, RSSI at 16, noise floor at 17 and PPDU type/flags at 18..19. So
RSSI came out as the high byte of the frequency (+9 for 2437 MHz), and
the tomography attenuation was built from it.

parse_adr018 now delegates to wifi_densepose_hardware::Esp32CsiParser,
the same parser the rest of the workspace uses, and only reshapes its
output. CsiFrame.channel/timestamp_us become freq_mhz/sequence, which
are what the header actually carries. ADR-081 feature-state packets
(0xC5110006) are no longer decoded as CSI frames.

build_test_frame (used by csi-test) now emits the real layout. Golden
byte-by-byte tests cover single and two-antenna frames, truncation and
the feature-state packet; a cross-check test compares against the
reference parser.

Refs #1348

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-10-04 16:30:45 -04:00