v0.6.1-esp32

google/comprehensive-rustv0.6.1-esp32Apr 16, 2026by ruvnet

AI Summary

Addresses a critical bug in multi-node deployments where the `node_id` was being clobbered, causing all nodes to report ID 1. Implements a defense-in-depth fix by capturing the ID locally at initialization.

Key Highlights

  • Fixes `node_id` clobbering in multi-node deployments
  • Defense-in-depth strategy capturing `node_id` into a module-local static at init
  • Clobber canary warning system to detect upstream memory corruption
  • Hardware validation confirms correct node ID transmission
  • Includes binaries for both 8MB and 4MB variants

New Features

  • Defensive node_id capture
  • Clobber canary warning
  • Multi-node stability fix

Full Release Notes

## ESP32-S3 CSI Firmware v0.6.1

### Critical fix: `node_id` clobber on multi-node deployments

Closes #232, #375, #385, #386, #390.

Users on multi-node deployments reported that every ESP32 node transmitted `node_id=1` in UDP frames, despite NVS provisioning showing the correct value. This made multi-node setups indistinguishable downstream.

### What changed

**Defense-in-depth fix** — the firmware now captures `node_id` into a module-local static at init time, isolating the UDP frame header from any memory corruption of `g_nvs_config`:

1. `csi_collector_init()` captures `g_nvs_config.node_id` into `static uint8_t s_node_id` **once** at init
2. `csi_serialize_frame()` writes `buf[4] = s_node_id` — bypasses the global entirely
3. All other consumers (`edge_processing.c`, `wasm_runtime.c`, `display_ui.c`, `swarm_bridge_init`) use the new `csi_collector_get_node_id()` accessor
4. **Clobber canary** logs `WARN` if `g_nvs_config.node_id` diverges from the captured value at init — helps isolate the upstream corruption path

### Hardware validation (ESP32-S3 on COM8)

| Check | Result |
|-------|--------|
| NVS `node_id` | `2` (provisioned) |
| Boot log `main:` | `Node ID: 2` |
| Defensive capture log | `Captured node_id=2 at init` |
| `csi_collector` init log | `node_id=2, channel=5` |
| UDP packets (15/15) | `byte[4] = 2` |
| Clobber canary | Quiet (no WARN) |
| App version | `0.6.1` |
| Binary size | 865 KB (54% flash free) |

### Binaries

| File | Flash size | Description |
|------|-----------|-------------|
| `esp32-csi-node.bin` | 8MB | Main firmware |
| `bootloader.bin` | 8MB | Bootloader |
| `partition-table.bin` | 8MB | Partition table (dual OTA) |
| `ota_data_initial.bin` | 8MB | OTA data |
| `esp32-csi-node-4mb.bin` | 4MB | Main firmware (SuperMini) |
| `partition-table-4mb.bin` | 4MB | Partition table (SuperMini) |

### Flash command

```bash
python -m esptool --chip esp32s3 -p COM8 -b 460800 \
  --before default_reset --after hard_reset \
  write_flash --flash_mode dio --flash_size 8MB --flash_freq 80m \
  0x0 bootloader.bin \
  0x8000 partition-table.bin \
  0xf000 ota_data_initial.bin \
  0x20000 esp32-csi-node.bin
```

For 4MB SuperMini boards, use `esp32-csi-node-4mb.bin` and `partition-table-4mb.bin` with `--flash_size 4MB`.

### SHA-256 hashes

```
7f943b26...88197f7  bootloader.bin
9e650bf1...54bd43   esp32-csi-node.bin
15c263f6...02b32    esp32-csi-node-4mb.bin
7d2c7ac4...82c62f   ota_data_initial.bin
4c2cc4ff...d81f0    partition-table.bin
4c2cc4ff...d81f0    partition-table-4mb.bin
```

### Who should upgrade

All users running multi-node ESP32-S3 deployments. Single-node users are unaffected but the upgrade is safe.