From cd126fd9e3338c93ad2244298f2ecde666687fcd Mon Sep 17 00:00:00 2001 From: ruv Date: Sat, 16 May 2026 08:27:51 -0400 Subject: [PATCH 1/2] 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 --- firmware/esp32-csi-node/README.md | 21 +++++++++++++-------- firmware/esp32-csi-node/provision.py | 2 +- scripts/provision.py | 2 +- verify | 4 ++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/firmware/esp32-csi-node/README.md b/firmware/esp32-csi-node/README.md index a3cfe28d7e..c60e59fe59 100644 --- a/firmware/esp32-csi-node/README.md +++ b/firmware/esp32-csi-node/README.md @@ -37,18 +37,22 @@ MSYS_NO_PATHCONV=1 docker run --rm \ ### 2. Flash +Offsets must match `partitions_display.csv` (8 MB) or `partitions_4mb.csv` (4 MB): +`bootloader=0x0`, `partition-table=0x8000`, `otadata=0xf000`, `app (ota_0)=0x20000`. + ```bash python -m esptool --chip esp32s3 --port COM7 --baud 460800 \ write_flash --flash_mode dio --flash_size 8MB \ - 0x0 firmware/esp32-csi-node/build/bootloader/bootloader.bin \ - 0x8000 firmware/esp32-csi-node/build/partition_table/partition-table.bin \ - 0x10000 firmware/esp32-csi-node/build/esp32-csi-node.bin + 0x0 firmware/esp32-csi-node/build/bootloader/bootloader.bin \ + 0x8000 firmware/esp32-csi-node/build/partition_table/partition-table.bin \ + 0xf000 firmware/esp32-csi-node/build/ota_data_initial.bin \ + 0x20000 firmware/esp32-csi-node/build/esp32-csi-node.bin ``` ### 3. Provision WiFi credentials (no reflash needed) ```bash -python scripts/provision.py --port COM7 \ +python firmware/esp32-csi-node/provision.py --port COM7 \ --ssid "YourSSID" --password "YourPass" --target-ip 192.168.1.20 ``` @@ -254,9 +258,10 @@ Find your serial port: `COM7` on Windows, `/dev/ttyUSB0` on Linux, `/dev/cu.SLAB ```bash python -m esptool --chip esp32s3 --port COM7 --baud 460800 \ write_flash --flash_mode dio --flash_size 8MB \ - 0x0 firmware/esp32-csi-node/build/bootloader/bootloader.bin \ - 0x8000 firmware/esp32-csi-node/build/partition_table/partition-table.bin \ - 0x10000 firmware/esp32-csi-node/build/esp32-csi-node.bin + 0x0 firmware/esp32-csi-node/build/bootloader/bootloader.bin \ + 0x8000 firmware/esp32-csi-node/build/partition_table/partition-table.bin \ + 0xf000 firmware/esp32-csi-node/build/ota_data_initial.bin \ + 0x20000 firmware/esp32-csi-node/build/esp32-csi-node.bin ``` ### Serial Monitor @@ -285,7 +290,7 @@ All settings can be changed at runtime via Non-Volatile Storage (NVS) without re The easiest way to write NVS settings: ```bash -python scripts/provision.py --port COM7 \ +python firmware/esp32-csi-node/provision.py --port COM7 \ --ssid "MyWiFi" \ --password "MyPassword" \ --target-ip 192.168.1.20 diff --git a/firmware/esp32-csi-node/provision.py b/firmware/esp32-csi-node/provision.py index d6a0e2f0a2..b29e74638d 100644 --- a/firmware/esp32-csi-node/provision.py +++ b/firmware/esp32-csi-node/provision.py @@ -281,7 +281,7 @@ def main(): if args.ssid: print(f" WiFi SSID: {args.ssid}") if args.password is not None: - print(f" WiFi Password: {'*' * len(args.password)}") + print(f" WiFi Password: {'(set)' if args.password else '(empty)'}") if args.target_ip: print(f" Target IP: {args.target_ip}") if args.target_port: diff --git a/scripts/provision.py b/scripts/provision.py index f46f1543df..3222bf1017 100644 --- a/scripts/provision.py +++ b/scripts/provision.py @@ -213,7 +213,7 @@ def main(): if args.ssid: print(f" WiFi SSID: {args.ssid}") if args.password is not None: - print(f" WiFi Password: {'*' * len(args.password)}") + print(f" WiFi Password: {'(set)' if args.password else '(empty)'}") if args.target_ip: print(f" Target IP: {args.target_ip}") if args.target_port: diff --git a/verify b/verify index dd7eab57d6..1b868238c8 100755 --- a/verify +++ b/verify @@ -19,9 +19,9 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROOF_DIR="${SCRIPT_DIR}/v1/data/proof" +PROOF_DIR="${SCRIPT_DIR}/archive/v1/data/proof" VERIFY_PY="${PROOF_DIR}/verify.py" -V1_SRC="${SCRIPT_DIR}/v1/src" +V1_SRC="${SCRIPT_DIR}/archive/v1/src" # Colors (disabled if not a terminal) if [ -t 1 ]; then From 7c237199798adb1b94c9a7e992c67aa373ee05f1 Mon Sep 17 00:00:00 2001 From: ruv Date: Sat, 16 May 2026 08:34:17 -0400 Subject: [PATCH 2/2] 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 --- firmware/esp32-csi-node/test/stubs/esp_stubs.h | 7 +++++++ scripts/qemu_swarm.py | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/firmware/esp32-csi-node/test/stubs/esp_stubs.h b/firmware/esp32-csi-node/test/stubs/esp_stubs.h index 20b4f7b825..be96f68934 100644 --- a/firmware/esp32-csi-node/test/stubs/esp_stubs.h +++ b/firmware/esp32-csi-node/test/stubs/esp_stubs.h @@ -153,6 +153,13 @@ typedef struct { uint8_t primary; } wifi_ap_record_t; +typedef enum { + WIFI_PS_NONE = 0, + WIFI_PS_MIN_MODEM = 1, + WIFI_PS_MAX_MODEM = 2, +} wifi_ps_type_t; + +static inline esp_err_t esp_wifi_set_ps(wifi_ps_type_t type) { (void)type; return ESP_OK; } static inline esp_err_t esp_wifi_set_promiscuous(bool en) { (void)en; return ESP_OK; } static inline esp_err_t esp_wifi_set_promiscuous_rx_cb(void *cb) { (void)cb; return ESP_OK; } static inline esp_err_t esp_wifi_set_promiscuous_filter(wifi_promiscuous_filter_t *f) { (void)f; return ESP_OK; } diff --git a/scripts/qemu_swarm.py b/scripts/qemu_swarm.py index e5cf97c6c9..5b32ccf776 100644 --- a/scripts/qemu_swarm.py +++ b/scripts/qemu_swarm.py @@ -259,11 +259,16 @@ def provision_node( if stale.exists(): stale.unlink() - # Build provision.py arguments + # Build provision.py arguments. + # --force-partial: this is a per-node TDM/channel overlay; WiFi + # credentials live in the base flash image, not the per-node NVS slice. + # Without --force-partial, provision.py rejects calls missing the + # --ssid/--password/--target-ip trio (issue #391 guard). args = [ sys.executable, str(PROVISION_SCRIPT), "--port", "/dev/null", "--dry-run", + "--force-partial", "--node-id", str(node.node_id), "--tdm-slot", str(node.tdm_slot), "--tdm-total", str(n_total),