fix: provision.py esptool v5 + refuse partial NVS flashes (#391)#392
Merged
fix: provision.py esptool v5 + refuse partial NVS flashes (#391)#392
Conversation
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>
This was referenced Apr 15, 2026
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes two bugs in
firmware/esp32-csi-node/provision.pyreported 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.pywrites a fresh NVS binary at offset0x9000, replacing the entirecsi_cfgnamespace. Any key not passed on the CLI was silently erased. A user runningprovision.py --port COM8 --target-port 5005would wipe their WiFi credentials and see the node stuck inRetrying WiFi connection (10/10).Fix
--ssid,--password, or--target-ipby default.--force-partialflag for users who intentionally want to wipe keys (prints a warning listing which keys will be erased).Validation
--ssid X --password Y --target-ip Z --target-port 5005 --dry-runbuilds 24576-byte binary, prints correctwrite-flashcommand.--port COM8 --target-port 5005is rejected with a clear message pointing to--force-partial.--force-partial --target-port 5005prints which NVS keys will be wiped before proceeding.read-flash 0x9000 0x100against 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 withnode_id=2intact.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
--force-partialprints warning with wiped keys🤖 Generated with claude-flow