Skip to content

fix: provision.py esptool v5 + refuse partial NVS flashes (#391)#392

Merged
ruvnet merged 2 commits intomainfrom
fix/issue-391-provision-py
Apr 15, 2026
Merged

fix: provision.py esptool v5 + refuse partial NVS flashes (#391)#392
ruvnet merged 2 commits intomainfrom
fix/issue-391-provision-py

Conversation

@ruvnet
Copy link
Copy Markdown
Owner

@ruvnet ruvnet commented Apr 15, 2026

Summary

Fixes two bugs in firmware/esp32-csi-node/provision.py reported in #391.

Bug 1 — esptool v5 syntax: write_flash -> write-flash (hyphenated) for esptool >= 5.x. The actual flash command was already fixed; the dry-run manual-flash hint still printed the old syntax.

Bug 2 — Silent NVS wipe on partial invocations: provision.py writes a fresh NVS binary at offset 0x9000, replacing the entire csi_cfg namespace. Any key not passed on the CLI was silently erased. A user running provision.py --port COM8 --target-port 5005 would wipe their WiFi credentials and see the node stuck in Retrying WiFi connection (10/10).

Fix

  • Refuse invocations missing --ssid, --password, or --target-ip by default.
  • Add --force-partial flag for users who intentionally want to wipe keys (prints a warning listing which keys will be erased).
  • Update docstring with the full-replace warning.

Validation

  • Dry-run (happy path): --ssid X --password Y --target-ip Z --target-port 5005 --dry-run builds 24576-byte binary, prints correct write-flash command.
  • Safety check: --port COM8 --target-port 5005 is rejected with a clear message pointing to --force-partial.
  • Warning path: --force-partial --target-port 5005 prints which NVS keys will be wiped before proceeding.
  • Hardware: non-destructive esptool v5.1.0 read-flash 0x9000 0x100 against attached ESP32-S3 (COM8) succeeded. NVS preserved across the esptool-triggered reset: device reconnected to WiFi and resumed CSI streaming at 192.168.1.104 with node_id=2 intact.

Did not perform a destructive write-flash test because that would wipe the working device's WiFi credentials — the exact failure mode this patch prevents.

Out of scope

Bug 3 from #391 (~11% UDP frame loss on channel-hop boundaries) is a firmware-side issue, not provision.py. Tracking separately.

Closes #391
Closes #367

Test plan

  • Dry-run produces correct binary
  • Partial invocation is rejected
  • --force-partial prints warning with wiped keys
  • esptool v5 hyphenated syntax works on attached hardware
  • Non-destructive: NVS and WiFi config preserved through test cycle

🤖 Generated with claude-flow

ruvnet added 2 commits April 15, 2026 11:39
Bug 1: `write_flash` -> `write-flash` for esptool v5.x compat
  - Actual flash command (flash_nvs, line 153) was already fixed
  - Dry-run manual-flash hint (line 301) still printed old syntax

Bug 2: Refuse partial invocations that would silently wipe NVS
  - provision.py flashes a fresh NVS binary at offset 0x9000, which
    REPLACES the entire csi_cfg namespace. Any key not passed on the
    CLI is erased.
  - Previously: `provision.py --port COM8 --target-port 5005` would
    silently wipe ssid, password, target_ip, node_id, etc., causing
    "Retrying WiFi connection (10/10)" in the field.
  - Now: refuse unless all of --ssid/--password/--target-ip provided,
    or --force-partial is set (prints warning listing wiped keys).

Validation:
  - Dry-run: binary generates to 24576 bytes, hint uses write-flash
  - Safety check: partial invocation rejected with clear message
  - Force-partial: warning lists keys that will be wiped
  - Hardware: esptool v5.1.0 `read-flash 0x9000 0x100` works on
    attached ESP32-S3 (COM8); NVS preserved, device reconnected at
    192.168.1.104 with node_id=2 intact after reset.

Co-Authored-By: claude-flow <ruv@ruv.net>
The changelog was stale at v0.5.4 — three releases were cut without
updating it. Added full entries for each, plus an [Unreleased] block
for the #391 provision.py fixes.

version.txt correctly stays at 0.6.0 — v0.7.0 was a model/pipeline
release, not a new firmware binary. Latest firmware is v0.6.0-esp32.

Closes #367

Co-Authored-By: claude-flow <ruv@ruv.net>
@ruvnet ruvnet added the bug Something isn't working label Apr 15, 2026
@ruvnet ruvnet merged commit 6e015c4 into main Apr 15, 2026
11 of 12 checks passed
@ruvnet ruvnet deleted the fix/issue-391-provision-py branch April 15, 2026 17:12
AntwerpDesignsIonity pushed a commit to AntwerpDesignsIonity/AEDI-SIGHT-IO-with-RuView that referenced this pull request Apr 19, 2026
ruvnet#392)

* fix: provision.py esptool v5 syntax + refuse partial NVS flashes (ruvnet#391)

Bug 1: `write_flash` -> `write-flash` for esptool v5.x compat
  - Actual flash command (flash_nvs, line 153) was already fixed
  - Dry-run manual-flash hint (line 301) still printed old syntax

Bug 2: Refuse partial invocations that would silently wipe NVS
  - provision.py flashes a fresh NVS binary at offset 0x9000, which
    REPLACES the entire csi_cfg namespace. Any key not passed on the
    CLI is erased.
  - Previously: `provision.py --port COM8 --target-port 5005` would
    silently wipe ssid, password, target_ip, node_id, etc., causing
    "Retrying WiFi connection (10/10)" in the field.
  - Now: refuse unless all of --ssid/--password/--target-ip provided,
    or --force-partial is set (prints warning listing wiped keys).

Validation:
  - Dry-run: binary generates to 24576 bytes, hint uses write-flash
  - Safety check: partial invocation rejected with clear message
  - Force-partial: warning lists keys that will be wiped
  - Hardware: esptool v5.1.0 `read-flash 0x9000 0x100` works on
    attached ESP32-S3 (COM8); NVS preserved, device reconnected at
    192.168.1.104 with node_id=2 intact after reset.

Co-Authored-By: claude-flow <ruv@ruv.net>

* docs: CHANGELOG catch-up for v0.5.5, v0.6.0, v0.7.0 (ruvnet#367)

The changelog was stale at v0.5.4 — three releases were cut without
updating it. Added full entries for each, plus an [Unreleased] block
for the ruvnet#391 provision.py fixes.

version.txt correctly stays at 0.6.0 — v0.7.0 was a model/pipeline
release, not a new firmware binary. Latest firmware is v0.6.0-esp32.

Closes ruvnet#367

Co-Authored-By: claude-flow <ruv@ruv.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

provision.py: esptool v5 incompat + NVS partition wipes existing keys when partial update 0.7.0 release inconsistencies

1 participant