Repository navigation
Releases
nightly per-target images
Rolling nightly builds - see each artifact's NOTES.md. New-hardware flashing only; fleet boards update over mesh OTA.
nightly — the platform at fd7cca7
Prebuilt ESP32-C3 images from main @ fd7cca7.
Prerelease — for USB-flashing a new or bare board. The first proper versioned release (sigil-named,
full tools/repro_build ceremony) is not this.
🔴 Read before flashing
These binaries carry PLACEHOLDER credentials. They cannot join a WiFi network or any real fleet.
They are built from a clean checkout provisioned by tools/ci_provision.sh, whose whole job is
"throwaway values good enough to COMPILE and never good enough to ship". Specifically:
WIFI_NETWORK,MQTT_USER,MQTT_PASS— the published example placeholders, byte-identical.GROUP_KEY— a random throwaway generated at provisioning time, not any real fleet key.
Note the consequence: it is baked into a public binary, so it is public. Two boards flashed from
this same download share an extractable mesh key. Treat it as a demo key, never a fleet key.
So a board flashed with this boots, drives the OLED, runs the menu, Snake and the sensors — and
will not associate, will not reach a broker, and will not talk to an existing mesh. To join a
network you must rebuild with your own rust/clock/src/secrets.rs (start from
secrets.rs.example); see docs/BUILDING.md.
(smol/ota/staged, ed25519 over build|size|sha256), never from a GitHub download. These images
are deliberately stamped v345+dev.fd7cca7 — SMOL_RELEASE was not set, so the identity is a
dev identity by construction and cannot outrank a real release on the fleet's build ratchet. That
is a safety property, not an oversight.
Artifacts
| file | tier | features | what it is |
|---|---|---|---|
smol-esp32c3-fleet.bin |
canonical fleet | espnow,cast,io |
merged flashable image (bootloader + OTA partition table + app), 4 MiB. App occupies 1,032,688 / 2,031,616 B of the OTA slot (50.83%). |
smol-esp32c3-fleet.elf |
canonical fleet | espnow,cast,io |
the same build's ELF, for probe-rs, readelf, symbol work |
smol-esp32c3-default.elf |
default |
none (no radio) | ELF only — see below |
espnow,cast,io is the canonical tier of record: tools/build-matrix.toml canonical_tier = "fleet",
matching REPRO_FLEET_FEATURES in tools/repro_build.sh.
Why there is no default .bin
espflash save-image (4.5.0) refuses it: the ESP-IDF application descriptor is missing. The
esp_bootloader_esp_idf::esp_app_desc!() macro is wifi-gated in main.rs, so the no-radio
default build does not emit one, and espflash 4.5 hard-requires it — with or without a partition
table. The ELF is attached for completeness, but the no-radio tier is not packageable as a
flashable image today. Filed as a follow-up rather than papered over.
sha256
1e88e27271b4534dfa3af7467f603c513a9a9f7aceee0eaa2ab0731dc30ee0b7 smol-esp32c3-fleet.bin
0241ceaa159291136c5665bb7389d4547b8d312fa65fe95b4cad55f7eec6e472 smol-esp32c3-fleet.elf
d8560d63aa32b68b73939745e5ab59bceac04fed212b64a448502e3edc14ce4a smol-esp32c3-default.elf
SHA256SUMS is attached; verify with sha256sum -c SHA256SUMS.
Flashing (per docs/BUILDING.md)
# If this board has EVER taken an OTA, clear otadata first. After an OTA the board runs from
# ota_1; a USB flash writes ota_0 and would SILENTLY never run. This spares `nvs`, so a
# provisioned node id survives.
espflash erase-region --port /dev/ttyACM0 0xf000 0x2000
# Then flash the merged image.
espflash write-bin --port /dev/ttyACM0 0x0 smol-esp32c3-fleet.binCheck the Loaded app from offset line after every flash. It names the slot that actually ran
and it is the only cheap confirmation you flashed the thing you are about to debug. (That line cost
an hour on 2026-07-28 while it lived only in operator memory.)
To flash from the ELF instead — espflash flash --port /dev/ttyACM0 smol-esp32c3-fleet.elf — note
this repo's .cargo/config.toml runner passes --partition-table partitions-ota.csv, which the
merged .bin already embeds.
Build identity — stated plainly
Built on the familiar build host from a clean git archive of fd7cca7, which has no .git,
so build.rs would normally fall back to a placeholder stamp. It did not: build.rs's documented
archive seam was used —
SMOL_GIT_HASH=fd7cca7 # SMOL_BUILD_NUMBER left unset → read from rust/clock/version.txt = 345
# SMOL_RELEASE deliberately unset → dev identity
— giving the baked identity v345+dev.fd7cca7, verified present in the ELF rather than assumed.
build.rs's own docs describe this env path as existing "exactly so archive builds are
reproducible".
These are content-built from fd7cca7: the source tree is that commit's tracked content, plus
ci_provision.sh's placeholder board.rs/secrets.rs (git-ignored by design, since the repo is
public). They have not been through the tools/repro_build reproducibility ceremony, which is
what a real versioned release requires.
Not verified
Not flashed. No board, broker, or serial port was touched producing this release. The images
compile, link, and package; nothing here is evidence that they boot.