yggvault ratatoskr-space connected via regular web
Color theme
also available via yggdrasil mesh http://[203:b338:2a84:a18f:986:47ae:1a4:d8d3]/pkg/ruview/v0.6.5-esp32
vault / ruview / v0.6.5-esp32

ruview @ v0.6.5-esp32

integrity

size
52.7 MiB
downloaded
last checked
source https://github.com/ruvnet/RuView · available · github

release notes

v0.6.5-esp32 — Tmr Svc bootloop fix + OTA fail-closed visibility

Two real bugs uncovered while preparing this release on real hardware (ESP32-S3 8MB, COM7). Both regressions from earlier cleanup work that this release locks back down. Plus one security re-validation.

What changed

1. Fix bootloop on fresh builds — sdkconfig.defaults was missing the Tmr Svc stack bump

sdkconfig.defaults.template had CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=8192 (ADR-081: adaptive_controller emits feature_state from inside Timer Svc callbacks, exceeding the FreeRTOS 2 KiB default). The line was absent from sdkconfig.defaults (the file the build actually reads), so any fresh full-clean build on top of v0.6.4 reproduced:

***ERROR*** A stack overflow in task Tmr Svc has been detected.
Backtrace: 0x40375d41:0x3fcbe060 0x4037eac9:0x3fcbe080 …
Rebooting...

Cherry-picked the line into sdkconfig.defaults. Verified on hardware: 0 panics, 0 reboots in 30 s of operation with --edge-tier 2.

2. Fix invisible OTA fail-closed posture — _ex init path didn't load the PSK

PR #623 merged the RuView#596 audit fix: ota_check_auth() now fails closed when no PSK is provisioned, refusing all OTA uploads until provision.py --ota-psk <hex> writes the NVS key.

But main.c:230 calls ota_update_init_ex(), not ota_update_init(). Pre-this-release, only ota_update_init() loaded the PSK from NVS. So in production:

Extracted ota_load_psk_from_nvs() and call it from both _init() and _init_ex(). Verified on hardware:

W (3126) ota_update: NVS namespace 'security' not found —
OTA upload endpoint will REJECT all requests until provisioned. Fail-closed per RuView#596.

3. Confirms #438 (boot loop at edge-tier ≥ 1) is not reproducible

Issue #438 was filed against v0.4.3.1. v0.6.5 boots cleanly at --edge-tier 2 with full vitals + edge DSP active. Anyone hitting that bug should upgrade to this release.

Hardware validation matrix

Check Result
8MB binary builds 1,109,744 bytes (47% partition free)
4MB binary builds 893,792 bytes (53% partition free)
Flash 8MB to COM7 Hash verified, RC=0
Boot at edge-tier=2 Clean — Edge DSP task started on core 1 (tier=2)
30 s steady operation 0 panics, 0 reboots, 870 log lines, CSI streaming
OTA fail-closed warning Prints at boot 3.1 s after reset
Embedded version App version: 0.6.5
WiFi modem sleep Set ps type: 0 (RuView#521 — WIFI_PS_NONE active)
Adaptive calibration Completed: mean=6.76 sigma=4.93 threshold=21.54 over 1200 frames

Cumulative changes since v0.6.4-esp32

In firmware/esp32-csi-node/:

Upgrade notes

Breaking change for OTA users (from PR #623, now visible at boot): unprovisioned nodes refuse all OTA pushes. Before pushing firmware over the air to a fresh node, provision a PSK:

python firmware/esp32-csi-node/provision.py --port COM7 --ota-psk <64-hex-chars> --force-partial

The OTA HTTP server still starts so this provision.py (over USB-CDC) works without re-flashing.

Flashing

# 8MB variant
python -m esptool --chip esp32s3 --port COM7 --baud 460800 \
  write_flash --flash_mode dio --flash_size 8MB \
  0x0     bootloader.bin \
  0x8000  partition-table.bin \
  0xf000  ota_data_initial.bin \
  0x20000 esp32-csi-node.bin

# 4MB variant (use partition-table-4mb.bin + esp32-csi-node-4mb.bin)
python -m esptool --chip esp32s3 --port COM7 --baud 460800 \
  write_flash --flash_mode dio --flash_size 4MB \
  0x0     bootloader.bin \
  0x8000  partition-table-4mb.bin \
  0xf000  ota_data_initial.bin \
  0x20000 esp32-csi-node-4mb.bin

download

unix · zip
curl -fL -o v0.6.5-esp32.zip https://ratatoskr.space/pkg/ruview/v0.6.5-esp32.zip
                    printf '%s  %s\n' 'ba6be022f04f454ae77a4207c44260a938073617883e67ca552fff478effb762' 'v0.6.5-esp32.zip' | sha256sum -c -
windows · zip
$url = "https://ratatoskr.space/pkg/ruview/v0.6.5-esp32.zip"
$out = "v0.6.5-esp32.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "ba6be022f04f454ae77a4207c44260a938073617883e67ca552fff478effb762") { throw "sha256 mismatch" }
unix · tar.gz
curl -fL -o v0.6.5-esp32.tar.gz https://ratatoskr.space/pkg/ruview/v0.6.5-esp32.tar.gz
                    printf '%s  %s\n' 'c2d91b4f15e9e6642c4dbfab14fd858a577bf870a25abffd7d5b9f5e241e0326' 'v0.6.5-esp32.tar.gz' | sha256sum -c -
windows · tar.gz
$url = "https://ratatoskr.space/pkg/ruview/v0.6.5-esp32.tar.gz"
$out = "v0.6.5-esp32.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "c2d91b4f15e9e6642c4dbfab14fd858a577bf870a25abffd7d5b9f5e241e0326") { throw "sha256 mismatch" }
download via yggdrasil mesh
unix · zip
curl -fL -o v0.6.5-esp32.zip http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v0.6.5-esp32.zip
                    printf '%s  %s\n' 'ba6be022f04f454ae77a4207c44260a938073617883e67ca552fff478effb762' 'v0.6.5-esp32.zip' | sha256sum -c -
windows · zip
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v0.6.5-esp32.zip"
$out = "v0.6.5-esp32.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "ba6be022f04f454ae77a4207c44260a938073617883e67ca552fff478effb762") { throw "sha256 mismatch" }
unix · tar.gz
curl -fL -o v0.6.5-esp32.tar.gz http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v0.6.5-esp32.tar.gz
                    printf '%s  %s\n' 'c2d91b4f15e9e6642c4dbfab14fd858a577bf870a25abffd7d5b9f5e241e0326' 'v0.6.5-esp32.tar.gz' | sha256sum -c -
windows · tar.gz
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v0.6.5-esp32.tar.gz"
$out = "v0.6.5-esp32.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "c2d91b4f15e9e6642c4dbfab14fd858a577bf870a25abffd7d5b9f5e241e0326") { throw "sha256 mismatch" }
artifact format size hashes
v0.6.5-esp32.zip zip 52.6 MiB
blake3-24 94f7ee8e78c8a26d93b35f9e12d5034362ac7ca6f9cda975
sha256 ba6be022f04f454ae77a4207c44260a938073617883e67ca552fff478effb762
sha1 b81cc9e2e2d859f2c76c52ea7c3a52f5b0135c93
v0.6.5-esp32.tar.gz tar.gz 51.3 MiB
blake3-24 dee684dac6fd1bbe3a1cb4c594fc984bd10451c64b35dca8
sha256 c2d91b4f15e9e6642c4dbfab14fd858a577bf870a25abffd7d5b9f5e241e0326
sha1 75dcb42a5107e89f8d4007145fc2743383f41235

install

bazel
http_archive(
    name = "ruview",
    urls = ["https://ratatoskr.space/pkg/ruview/v0.6.5-esp32.tar.gz"],
    integrity = "sha256-wtkbTxXp5mQsTb+rFP2Fild7+HCiWr/9fVufXiQeAyY=",
    strip_prefix = "ruview-v0.6.5-esp32",
)
zig
.url = "https://ratatoskr.space/pkg/ruview/v0.6.5-esp32.tar.gz",
install via yggdrasil mesh
bazel
http_archive(
    name = "ruview",
    urls = ["http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v0.6.5-esp32.tar.gz"],
    integrity = "sha256-wtkbTxXp5mQsTb+rFP2Fild7+HCiWr/9fVufXiQeAyY=",
    strip_prefix = "ruview-v0.6.5-esp32",
)
zig
.url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v0.6.5-esp32.tar.gz",
← v0.6.6-esp32v0.8.0 →