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.