Version 2.1.0 validation
Validated October 23–24, 2026. Dependencies are pinned in platformio.ini.
Earlier release: 2.0.2. The
development capture records the live BLE observations.
Builds and release assets
| Environment |
Build |
Application bytes |
Physical validation this release |
xiao_s3 |
PASS |
1,220,416 |
One S3 and 60-pixel XIAO matrix |
xiao_c3 |
PASS |
1,361,776 |
Pending |
xiao_c6 |
PASS |
1,522,032 |
Pending |
xiao_c5 |
PASS |
1,575,072 |
Pending |
esp32 |
PASS |
1,307,600 |
Pending |
esp32_s2 |
PASS |
990,320 |
Pending; Wi-Fi only |
All six use the same detector, settings and light implementation. S2 has no BLE
hardware and disables the BLE spam default. C5 monitoring is 2.4 GHz only.
Every application fits the 3 MiB factory partition. tests/release_test.py
checks embedded version, chip family, bootloader offset, flash size, partition
and application bytes, and merged-image SHA-256. No old application was relabeled.
The flasher browser check loads ESP Web Tools, selects all six profiles,
downloads each 2.1.0 image and checks its checksum, verifies both Windows driver
links, and checks desktop/phone layout without page errors. The pinned installer
includes ESP32-C5 support. This does not substitute for a physical USB install on
every board.
Manifest and manual-download URLs include the release version so a browser's
cached older firmware cannot be reused across version updates.
Detection and output checks
Native tests pass for ordinary disconnects, duplicate retries, isolated bursts,
per-AP separation, repeated sampled bursts across channel changes, stale evidence,
stable BLE crowds, rotating addresses, changing pairing identities, ordinary
battery changes, clock wrap, malformed records and 100,000 fuzz inputs.
The actual light controller is compiled with host hardware stubs. Tests verify
exactly ten red or blue pulses, a 30-second cooldown after the four-second
sequence, independent cooldowns, sustained Axon presence, expiry, higher-priority
flood alerts, Axon resumption, silence and bounded manual output tests.
Live BLE pairing-spam detection was confirmed on the S3 development candidate
using the same classifier shipped here. Telemetry recorded sustained pairing
identity changes, alert activation and repetition after cooldown. The user
confirmed seeing the blue flashes. After the traffic stopped, the detector
returned to the nightlight and did not retrigger from stale evidence.
New live deauth confirmation remains pending. The previous capture exposed
missed repeated bursts; the revised per-AP history passes host fixtures, but that
is not an over-the-air confirmation. Axon behavior is host-tested; no physical
Axon camera or optional buzzer was available. No other board was flashed during
this release session. Signatures cannot establish intent or guarantee detection.
Nightlight and local web UI
All 22 modes pass bounded-rendering tests, including animated changes, static
modes, six palettes, timing extremes, wraparound, strobe edges and fade floors.
New modes are Strobe, Dim & brighten, Chase and Color tiles. Effect cycle,
minimum brightness and strobe duty are validated and persisted; legacy settings
exports remain accepted. The default remains the gentle two-minute spectrum.
An additional controller test verifies twenty consecutive 10 ms strobe pulses
at the shortest allowed cycle/duty, ensuring normal frame pacing cannot skip
these edges. The final six builds include this correction.
Mocked Chromium and WebKit tests pass at desktop and phone widths. Checks cover
animated previews, presets, save/import/export, alert rules, optional buzzer,
health diagnostics and escaped radio text. Actual S3 pages also pass in both
browser engines at phone width: all 22 choices, moving fade preview and strobe
controls, with no horizontal overflow or script errors.
tests/device_http.py passes against the S3: all 22 modes, seven alert patterns,
deauth/BLE output routes, 120 status requests, invalid settings and invalid-token
rejection, and restoration of the original settings. Manual output tests verify
routing, not RF sensitivity. The test's temporary silence was cleared by reboot;
all saved settings survived and detection was enabled afterward.
Android/Apple captive-portal responses, wildcard DNS and unknown-API handling
pass. Fast surveying previously interrupted AP joins. A 30-second startup hold
and 15-second hold for requests to join this AP now allow connection. Windows
joined successfully both immediately after boot and after idle surveying resumed;
the UI then loaded at http://192.168.4.1. Unrelated/wildcard probes do not hold
surveying. Connecting a client pins Wi-Fi reception to that channel; BLE continues.
Runtime measurements
The S3 application write was verified by esptool. The original full-flash backup
is retained privately; the application-only update preserved saved preferences.
The release image SHA-256 is
40078c1c07057d410adf27b634f85cf054d5fd3ff52f0bce37d7d0ebfb23e243.
HTTP stress ended at 115,252 bytes free heap (minimum 98,684) with no reset during
the test. It recorded 136 cumulative queue drops. Bounded queues preserve
responsiveness and cannot guarantee lossless reception. Per-queue counters are
visible in diagnostics. Raw radio logs and backups remain outside Git.
Before the final strobe-edge correction, a five-minute USB capture recorded
300 samples, uptime 264–564 seconds, steady free heap of 117,680 bytes, channels
1–11, no alert or reset, and no additional queue drops. Cumulative drops stayed
at 55 ordinary Wi-Fi, 284 BLE and zero disconnect records. These losses occurred
before the capture. HTTP/UI checks above used that candidate. The final image
was then flashed and verified to serve HTTP, preserve settings and run with
detection enabled.
The final image then completed a separate three-minute capture: 180 samples,
uptime 35–215 seconds, free heap between 117,376 and 117,732 bytes, all survey
channels visited, no unexpected reset or alert, no silence, and zero drops in
all three queues. This capture used the saved animated nightlight while passive
Wi-Fi and BLE monitoring ran.
Sanitized build, HTTP and runtime measurements are in
validation-results-2.1.0.json. A finite test does
not guarantee indefinite uptime, zero false alerts or field sensitivity.