Updated: 2026-10-08
This roadmap assumes one primary maintainer with occasional testers. Target windows express order and intent, not promises. The v0.6.0 field beta was released with open hardware gates; a phase is complete only when its exit gate passes on hardware.
Make Tab5 OS the fastest portable way to connect, discover, inspect, control, log, and recover a 3.3 V embedded or IoT target.
Tab5 OS should complement calibrated bench instruments, not imitate them. Version 1.0 is successful when a user can bring up a typical sensor or controller, capture useful evidence, export it, and safely recover the tablet without needing a laptop.
- Connect safely to wired, BLE, Wi-Fi, and USB devices.
- Discover addresses, services, peers, and protocol settings.
- Inspect live signals, registers, packets, and device state.
- Control pins and send transactions with explicit safeguards.
- Log timestamped sessions to user-owned storage and export them.
- Recover from bad settings, storage faults, and failed updates.
- No desktop-style OS, package manager, or native app store.
- No general-purpose scripting runtime before stable tool operations exist.
- No cloud account requirement; cloud-backed features remain optional.
- No promise of calibrated, protected, or 5 V-safe measurements without validated external hardware.
- No new one-off BLE product app until the generic BLE path is usable.
- AI, weather, browser, and ebook features stay maintained, but they do not outrank the electronics and IoT core.
The published v0.6.0 field beta is the tagged baseline. It includes the wired, BLE, Wi-Fi, capture, and Servo tools shipped with that release. The release notes and hardware smoke checklist identify the measured coverage and open gates.
Unreleased development on main adds nine apps: Electronics, Byte Lab, Subnet Lab, Resistor Lab, Modbus TCP, RTU Frames, NTP Lab, Wake-on-LAN, and UDP Console. It also adds a Network launcher tile, the shared byte clipboard and saved serial log inspection, and improves Serial/SPI/I2C/BLE workflows, Wi-Fi/HTTP input and resource cleanup. The LVGL PSRAM pool and SDK-scoped executable-pointer workaround address the recorded memory and worker-exit failures. None of these additions are included in v0.6.0.
Host checks and the single-job firmware build pass for the documented changes; ST7121 device coverage is limited to the named cases and image identities in the checklist. The prepared speaker startup change is built but unflashed. The 2026-09-30 USB brownout follow-up, remaining HTTP checks, external peripherals, OTA/fault/soak work and the second display family remain open.
Phase 0 software work is implemented and builds cleanly:
- Servo owns LEDC timer 1/channel 2 and releases its outputs safely without touching the backlight.
- Govee, Ring, and KICKR Bluetooth activity is off at boot and requires an explicit user toggle.
- GPIO, Scope, Servo, and external I2C share the app-exit release path; app switching waits for Scope teardown before reusing the pins.
- External 5 V remains off at boot and has no implicit enable path.
- OTA blocks active writers, capture, BLE sessions, and outputs; navigation stays locked during install.
- OTA rollback validation waits for a 30-second healthy LVGL window, and NVS failures preserve settings instead of erasing them.
- The internal partition and runtime both use SPIFFS; only provably blank storage auto-initializes, while damaged data requires explicit confirmation.
- Push/PR verification, release separation, artifact scoping, and a two-panel hardware checklist are present.
- ST7121 hardware boots through the launcher with SDIO Wi-Fi/BLE, touch, SD, System diagnostics, and stable heap; unused LVGL rotation/PPA paths are disabled.
- Firmware builds reject stale configurations that do not use the fixed Tab5 ESP32-C6 SDIO pin map.
- ST7121 completed a corrected 100-transition run across ten safe apps after app-entry scroll reset was added: the launcher returned to row zero, the USB boot stayed continuous, internal heap remained 70 KB free/65 KB minimum, and PSRAM remained 23516 KB free before and after.
- Forgetting a saved Wi-Fi network now requires an unchanged second tap within five seconds; the control is disabled when no profile is saved.
- Run the hardware matrix on both display/touch families, including OTA rollback and missing-peripheral cases.
- Repeat the transition/pin test on ILI9881C hardware and complete the eight-hour soak.
- Land the software as reviewable commits and publish v0.6.0 with its tested scope and outstanding hardware gates stated in the release notes.
Phase 1 software progress is also underway:
- Scope and I2C capture cleanup no longer retries publication after a rejected write or failed I2C flush/sync. I2C releases recording ownership on known SD failure; both writers preserve the first cause through close and report once. All 35 original native writer/storage cases pass; the callbacks preceding the writer fix fail 16 controls. Exact CSV/TMP bytes, Scope filename collision, pre-flush timing and 25 independent failure/success cycles per writer are checked with closed handles. UI, data, time, mount and fault boundaries are controlled; ADC/drivers and physical SD/panel remain separate gates. Linux CI retains source hashes and logs.
- Ebook library listings confirm regular-file metadata before accepting
.txtentries and report directory setup/open/read/stat/close errors, entry capacity and skipped long paths. Failed listings no longer claim an empty library; the first failure survives close. All 28 native existing-directory/file cases pass, including unchanged bytes, callback path ownership, first-error checks and 25 reopen cycles with closed handles. The previous callback fails 18 controls. UI, timer, mount, download and error boundaries are controlled; welcome creation and physical SD/panel checks remain separate. Linux CI retains source hashes and logs. - First-run ebook welcome creation checks fresh open/write errors and stream flags, preserves the first cause through cleanup, and shows a creation warning without an empty-library hint. All 55 native library cases pass: 28 existing listing controls plus 27 welcome controls; the preceding callback fails 25 welcome controls. Exact final/TMP bytes, retained collisions, commit faults and 25 failure/recreation/reopen cycles are checked with closed file/directory handles. Existing directories do not retry or rewrite the welcome file. UI, timer, mount and faults are controlled; physical SD/panel and power cuts remain open. CI retains the complete compiled storage helper and source hashes.
- UART/RS-485 logging retries only filename collisions, reports the first preparation/write/sync failure, and retains rejected headers as unpublished TMPs. All 82 native start/write/Stop and storage cases pass; the previous functions fail 42 controls. Exact bytes, ten-name limits, tick wrap and 25 failure/restart pairs per link are checked with unchanged retained TMPs and closed handles. UI, clock, mount and faults are controlled; drivers and physical SD/panel remain separate checks. Linux CI retains source hashes and logs.
- Scope and I2C capture constructors stop on preparation/stream-creation failures and preserve fresh first errors through cleanup. The capture suite now passes 78 native cases: 35 writer cases plus 43 constructor cases; the previous constructors fail 14 controls. Both 100-name limits, existing bytes, empty/partial TMP recovery and 25 header-failure/restart pairs per constructor are checked with closed handles and guarded I2C watch ownership. Paths, UI, clocks, data and faults are controlled; physical SD/panel and drivers remain separate checks.
- System reports the firmware/commit, reset reason, uptime, panel, heap, storage capacity, current OTA state, and persistent last OTA result.
- Notes and ride summaries use recoverable backup replacement; rides publish only after durable sync, and health logs repair incomplete final rows.
- Notes loads complete files up to 65,535 bytes, replacing a silent 2,047-byte prefix. Recovery/read/close errors, oversized files and NUL data disable Save; byte-length and SD checks run before storage changes. Its launcher leave hook clears editor ownership. Four preceding-source controls reproduce full-note truncation; 36 native file/fault cases and five real LVGL cases pass, including maximum ASCII/UTF-8 notes and 25 reopens without retained resources in the unchanged 96 KiB pool. Linux and Windows CI retain separate source-bound evidence. Physical SD/panel and power cuts remain open.
- Notes confirms directory/TMP preparation before opening a writer and preserves each load/write failure through cleanup. Missing errno uses EIO; a failed open cannot become an empty editable note, and a stream-flagged positive write cannot publish. All 63 native file/fault cases and 12 real LVGL cases pass; the preceding callbacks fail 18 and six controls respectively. Exact final/backup/TMP bytes, blocked stale Save events, accepted existing-directory/missing-TMP responses and 25 failure/retry pairs are checked with closed resources and unchanged LVGL allocation counts. Logical directory/mount responses, faults and PSRAM APIs are controlled. CI retains source hashes and logs; physical SD/panel and power cuts remain open.
- Ride history reports recovery/open/read/close errors as unavailable instead of showing zero or partial totals. Summary appends check SD availability and preparation errors, reject failed read chunks before copying, and retain the first error through cleanup. All 50 native file/fault cases pass; the preceding callbacks fail 24 controls. Exact final/backup/temporary bytes and 25 reopens are checked with closed modeled handles. Linux CI retains source hashes and logs, and the unflashed firmware builds with unchanged configuration. Physical SD/panel and power cuts remain open.
- Default ebook downloads capture their first write error independently of ignored SDK callback returns, stop later file writes and reject publication after failed chunks. Probe/TMP preparation failures preserve existing bytes; missing errno uses EIO and cleanup cannot replace the first cause. All 58 native callback/storage cases pass; the preceding callbacks fail 32 controls. All three default profiles, status/installation boundaries, retained TMPs, init/transport/status cleanup failures and 25 failure/retry/installed-recheck cycles are checked with closed controlled clients and native streams. Linux CI retains source hashes and logs. The unflashed firmware builds with the actual SDK; worker/timer scheduling, Wi-Fi/TLS, physical SD/panel and power cuts remain open.
- Default-book installation probes require regular-file metadata before their size check. Directories and other nonregular paths stop downloads before a writer/client or TMP change, with EISDIR/EINVAL retained for reporting. All 79 download cases pass, including twenty-one preceding-source failures across all three profiles and 25 conflict-resolution/retry/recheck pairs per profile. Native directories/files are checked; directory sizes, nonregular metadata and HTTP/I/O faults are controlled. All 55 library and 42 worker regressions pass. Physical FAT/SD, Wi-Fi/TLS and panels remain unchecked for this change.
- Default-book workers bound their initial Wi-Fi wait to 30 seconds, stop later attempts on known SD/Wi-Fi loss, claim admission atomically and publish completion before releasing busy ownership. They use the SDK's caps-aware task deletion and request no output handle, avoiding stale handles after immediate completion. All 42 controlled worker/restart cases pass; the preceding source fails 37 controls. Both 100/1,000 Hz clocks, tick wrap, interleaved admission, creation failure, timer handoff and 25 timeout/retry pairs are checked. All 55 library and 58 download regressions pass, and the actual SDK firmware builds unflashed. CI retains sources and logs; real scheduling, task-memory recovery, Wi-Fi/TLS and physical SD remain open.
- Ride history and summary writers now isolate errno at every I/O boundary. Failed opens cannot become empty history or replace an existing index; flagged positive-count reads/writes stop before later parsing, writes or publication, preserving the first cause through cleanup. All 95 history and 41 recording cases pass; the preceding history callbacks fail 32 controls and the Stop flow fails one additional missing-errno source-open control. Exact generations, retained TMPs, four 25-pair failure/retry paths and successful reloads are checked with closed resources. A published ride remains saved when its index update fails, and the failure is reported separately. Logical directory/mount responses, UI, BLE data, time and faults are controlled. The unflashed firmware builds; physical SD/panel and power cuts remain open.
- Ride Start checks both directories, stops on noncollision creation errors and preserves their first cause. Rejected headers/rows, periodic sync failures and known SD loss retain the named TMP and clear recording ownership without retrying publication. All 39 native recording/history/storage cases pass; the preceding source fails 27 controls. Exact CSV/index/backup bytes, 100-name limits, tick wrap and 25 same-second restart pairs are checked with closed streams/descriptors. Linux CI retains source hashes and logs. Physical SD, BLE, panel and power cuts remain open.
- Ring logging commits its saved timestamp only after tail recovery and a complete, successfully closed read. Failed loads retain queued samples and defer history requests until a successful retry; known SD unavailability also blocks a cached checkpoint. Appends check directory errors and preserve the first seek/tell/header/row error through close and repair. All 59 native file/queue/fault cases pass; the preceding callbacks fail 32 controls. Checks verify exact bytes, retry/deduplication, timeout handling while blocked and 25 checkpoint reopens with closed modeled handles. Linux CI retains source hashes and logs. Physical SD, BLE, panel and power cuts remain open.
- Ebook page reads publish their text and byte positions only after read/close success. Failed navigation retains the previous page for retry, including zero-byte and full-count read errors. Initial navigation is disabled until a page loads; callbacks reject disabled/offscreen actions and invalid positions. All 44 native file/state/fault checks pass, including 25 navigation cycles with one reused buffer and closed handles. Thirty-one preceding-callback controls fail; three new unsafe-boundary guards are tested only with the new callbacks. Linux CI retains source hashes, initialization source and logs. Physical SD/panel and power behavior remain open.
- Recognized Scope/I2C and saved serial CSV loads require a successful close before showing a graph or row-copy controls. Failed or empty capture loads release their row buffer immediately. All 36 real LVGL/native-file checks pass; the preceding viewers fail 15 controls. Checks cover both row limits, I2C gaps, read/seek/close and allocation faults, unchanged file/clipboard bytes and 25 success/error/reopen cycles per viewer with stable memory in the unchanged 96 KiB pool. Existing serial-copy/inspector checks pass. Windows CI retains complete viewer/parser sources and logs; physical SD/panel behavior remains open.
- Files text previews require a successful read and close before showing their existing 4,095-byte prefix. Failed operations show the first error, using EIO when errno is absent; SD-path failures reach the existing error callback. All 36 native file/fault cases pass with unchanged bytes and closed handles, including read/close errors, retry, routing and 25 cycles. The preceding callback fails 29 controls: 23 reproduce ignored read/close failures or retry cycles, and six concern open-error details/reporting. UI, CSV probes and logical mount paths are controlled; Linux CI retains source hashes and logs. Physical storage/panel checks remain open.
- Files directory browsing reports open/read/close errors, marks interrupted listings incomplete, and discloses its entry cap and skipped long paths. Fresh errno checks distinguish normal EOF from read errors and preserve the first failure through close. All 31 native directory/file cases pass with unchanged bytes, valid callback path ownership and closed handles, including 25 success/error/reopen cycles. The previous callback fails 21 controls: 14 concern silent read/close errors or recovery, three disclose limits and four add open-error details/reporting. UI, mount paths and faults are controlled; Linux CI retains source hashes and logs. SDK mounts, physical SD and panel checks remain open.
- Shared CSV tail recovery now scans backwards in 512-byte blocks. Eight previous-source controls exceed stdio seek budgets; a 64 KiB partial tail drops from 65,538 seeks to 130 with the same retained prefix. All 32 native byte/boundary/fault cases, original storage checks and five MQTT/HTTP logging cases pass with closed modeled handles. The unflashed firmware builds with unchanged configuration. Linux CI retains source hashes and compilation/result logs; physical SD timing and power cuts remain open.
- Shared storage sync/publication/recovery now uses fresh errors at each I/O boundary, falls back to EIO and preserves the first cause through cleanup/rollback. Failed probes cannot authorize publication or recovery; CSV repair rejects scalar/full-count reads with stream errors before truncation. All 57 native storage fault cases and the expanded 52 CSV tail cases pass; the preceding helper fails 21 and 17 controls respectively. Exact temporary/final/backup bytes, consumed stream ownership and 25 recovery/republish pairs are checked. Linux CI retains complete helper source, hashes and logs. Physical SD timing, removal and power cuts remain open.
- HTTP/MQTT metadata appenders capture fresh errors at preparation, positioning, every write and close. Rejected writes and positive-count stream errors stop remaining fields and explicit sync; cleanup preserves the first cause. All 192 native metadata cases pass (116 HTTP, 76 MQTT); the preceding appenders fail 80 controls. Exact metadata/redaction/quoted bytes, partial-header/row repair and 25 failure/retry pairs per app are checked with closed handles. Linux CI retains actual functions, metadata types, shared helper, hashes and logs. Clock/SDK types/faults are controlled; real UI/client suites and physical SD/TLS validation remain separate gates.
- Built-in SD paths, timestamps, units, 8.3-safe collision names,
.TMP, and.BAKbehavior are documented. - Persisted brightness choices, a dimmed two-minute screen, and configurable 5/10/30-minute or Never screen-off behavior are implemented.
- ST7121 UI and boot logs verify 100/75/50/25% brightness persistence plus the two-minute dim, five-minute off, and first-tap-only wake path without a watchdog or panic.
- Source-built complete flashing, app-only flashing, destructive clean recovery, and post-recovery checks are documented.
- USB Serial/JTAG is the build-enforced sole console; COM7 flashing, ROM-to-launcher logs, Wi-Fi startup, and remote desktop pass on ST7121, leaving hardware UARTs available to tools.
- Validate SD removal/full-card behavior, ten representative power cuts, display wake behavior, and energy impact on hardware.
- Launcher metadata now lives in one static app table; Scope and Settings use explicit leave hooks, and other cleanup moves only when each app is materially touched.
The first Phase 2 workflow is implemented in software:
-
Serial separates TX format from transcript display, adds explicit ASCII line endings and clipboard paste, rejects invalid/overlong drafts without shortening them, and recalls the last eight accepted sends with exact bytes and suffixes. The Stop drain bound covers the slowest framing. Pure checks, real LVGL/UART-adapter checks, and 100 lifecycle cycles pass; physical UART/RS-485 and panel validation remain open.
-
Serial and Byte Lab coalesce bulk-paste display updates to prevent per-nibble button animations exhausting the fixed LVGL heap. Send/copy still validate synchronously; exit cancels pending UI work. Maximum Hex paste and lifecycle regressions cover both apps.
-
Serial adds an explicit 128-byte RX capture/freeze/copy window across driver reads, preserving source settings through Home. Overflow and read/drain failures cannot replace the clipboard with a partial copy. A native RTU Frames -> Serial -> RTU Frames/Byte Lab round trip, capture fault cases and eight lifecycle cycles pass in the single-job quick check. The single-job firmware build and ST7121 empty capture/retention checks pass; populated physical receive windows remain open. This does not detect timed protocol frames.
-
Saved serial logs expose a page-local record selector and COPY ROW for original byte payloads up to 128 bytes. Selection remains correct across filters, pages and Hex/ASCII views; oversized records preserve the clipboard. Real-file/LVGL checks cover inspector handoff, both allocation failures, the 512-record cap and eight reopen cycles without heap loss. The firmware build passes; physical SD and panel validation for record copying remain pending.
-
Resistor Lab decodes four/five color bands and numeric/R-decimal/EIA-96 SMD markings offline, with a numbered band drawing, explicit tolerance ranges where encoded, separate in-memory drafts, and no hardware resources. Known-value/invalid-input checks, 1,056 independent EIA-96 references, and 100 real LVGL lifecycle cycles pass. Physical panel/touch and device heap checks remain open.
-
Electronics provides offline Ohm's law, divider, LED resistor, and RC low-pass/timing calculations. Byte Lab decodes hex/ASCII, computes checksums, and interprets or encodes signed/unsigned integers and IEEE 754 Float32 in either byte order. Number encoding includes explicit Hex-draft handoff, bounded retained inputs, and independent exact-rounding references. Host parser/math/reference tests, real LVGL lifecycle checks, and the firmware build pass; physical UI checks remain open.
-
External I2C supports 100/400 kHz byte reads, a 1 Hz watch, five-second two-tap raw writes, and durable timestamped SD capture without retaining the bus between samples.
-
I2C supports explicit reads of 1-32 bytes after an 8-bit register pointer and copies complete saved reads into Byte Lab with source identity retained through Home. READ ONCE stops the one-byte Watch/CSV workflow, while writes remain gated single-byte operations. Failed reads (including transaction cleanup) and confirmed writes invalidate saved reads. Failed device/bus removals retain ownership for retry; shared-pin apps and restart/OTA cannot proceed while the bus is retained. Entry no longer auto-scans. Native checks cover 192 read combinations, transaction/cleanup faults, byte/Float32 handoff and eight panel reopen cycles without heap loss; cached target syntax checks pass. The firmware build and ST7121 empty-bus failures, length selection/retention, Watch-to-read transition and popup teardown pass; known-device, CSV fault and electrical checks remain pending.
-
On ST7121 hardware, the no-pull-up bus reports timeout safely; the speed control, write-confirmation expiry, watch start/stop, Home teardown, and heap baseline pass over USB.
-
Validate known and stuck devices, successful transfers at both speeds, capture recovery, and repeated G53/G54 transitions on hardware.
-
UART1 uses the documented G47 TX/G48 RX 3.3 V pin pair with baud/parity/stop controls, ASCII/hex receive and send, timestamps, send history, durable SD logging, and deterministic high-impedance teardown; its unrouted internal loopback passes on ST7121 hardware.
-
Validate UART with a physical G47/G48 loopback and external 3.3 V target across representative line settings.
-
The same serial terminal supports the onboard SIT3088 RS-485 path on G20/G21/G34 with automatic half-duplex direction, physical-termination guidance, durable logging, and receive-safe teardown; disconnected receive-only Start/Stop passes on ST7121 hardware without regressing UART loopback.
-
Validate bidirectional RS-485 traffic, polarity, turnaround, termination, and fault recovery with an external transceiver fixture.
-
USB keyboard and a general CDC/VCP terminal remain future work. The combined ESP-IDF 5.4.2 image now boots with the Ender 3 USB host path. A reproduced re-entry abort was fixed by draining USB events before uninstalling the host and retaining ownership through cleanup. ST7121 passed 16 empty-port Ender/Home cycles with continuous boot and recovered heap on 2026-09-29; live peripheral disconnect/reconnect, motion and electrical checks remain open.
-
SPI2 master uses the documented M5-Bus MOSI G18, MISO G19, SCK G5, and explicit CS G45 pins with modes 0-3, 100 kHz-10 MHz clocks, 32-byte full-duplex transfers, and deterministic high-impedance teardown.
-
SPI saves its transmit draft and the last completed transfer with original TX/RX bytes and mode/clock through Stop/Home. Its hex keyboard, independent CLEAR TX, and retained invalid/Unicode/excess-length drafts keep editing separate from transfer. COPY RX sends 1-32 raw received bytes to Byte Lab without bus activity; driver failures clear the saved result and preserve the clipboard. Cached, single-job native checks cover the actual keyboard, no-send Done/Cancel, receive bytes differing from transmit bytes, bounds, clear/fault behavior, the real Byte Lab handoff, and eight reopen cycles without heap loss. The firmware build and ST7121 keyboard, one-byte disconnected transfer, original-setting retention and RX-to-Byte-Lab handoff pass. Real-peripheral, electrical and second-panel checks remain pending.
-
Validate SPI with a physical G18/G19 loopback and target device across all modes and representative clocks; verify CS timing and shared Scope/GPIO transitions with a logic analyzer.
- ST7121, 2026-08-09: the compact launcher, SPI page, mode 1/5 MHz selection, disconnected Start/Stop, and Home teardown pass over USB without transmitting. Electrical release and loopback remain open.
-
Signal Generator uses M5-Bus G6 and isolated LEDC timer 2/channel 3 for 50 Hz-50 kHz PWM, 10-90% duty, bounded 10 us-10 ms single pulses, five-minute automatic stop, and high-impedance teardown.
-
Measure every PWM frequency/duty and pulse width, automatic timeout, backlight isolation, and GPIO transitions on both hardware families before treating the output as characterized.
- ST7121, 2026-08-10: all five LEDC frequency configurations and all five duty choices were accepted, with the driver reporting each exact requested frequency. All four pulse actions, Home/re-entry, and the verified five-minute automatic-stop path completed over USB. Electrical timing, actual high-impedance release, backlight isolation, pin transitions, and the other panel family remain open.
-
Scope reports frequency and duty from complete rising-edge spans, applies bounded persistent scale/offset per input after ESP-IDF calibration, resets to neutral, and atomically publishes the visible 300-point chart to SD.
-
Validate Scope timing across known frequencies/duties and sample rates, calibrate every input against physical references, and exercise full-card/removal capture failures.
- ST7121, 2026-08-10: disconnected G16 correctly showed timing unavailable; +10 mV/102.5% survived app re-entry and a hard reset, neutral reset saved, and a final CSV with the documented calibrated 5 kS/s rows was browsable on SD.
Phase 3 software progress has begun:
-
RTU Frames builds bounded read-only Modbus frames with CRC and decodes complete pasted replies, sharing the existing TCP PDU/value decoder and Byte Lab CRC helper. Request copy prepares Serial's Hex draft without starting a port. Strict pure checks, native UI checks and eight lifecycle cycles pass. The single-job firmware build, ST7121 example decode and request handoff into stopped Serial pass. Broader panel and wired-fixture checks remain open; an automatic timed RTU transport remains separate work.
-
Byte Lab, UDP Console, and SPI Console share a bounded RAM byte clipboard. It carries encoded payloads into explicit send/transfer drafts and complete UDP replies back to Byte Lab. Invalid, oversized, or truncated data cannot silently replace a valid copy; paste never transmits. SPI also rejects invalid or overlong drafts without filtering them into different bytes. Native UI/network/SPI-adapter checks and firmware build pass; physical panels and bus/network measurements remain open.
-
Modbus TCP provides explicit connection tests and confirmed function 01-04 reads, with cancellation and OTA blocking through socket cleanup. Saved replies support raw 16-bit words and unsigned/signed/Float32 register pairs in four byte orders without extra traffic. Reference/native checks, the firmware build and ST7121 Wi-Fi fixture tests pass for all four functions, single-byte fragmentation, saved views, exceptions, timeout and cancellation; physical device maps, further network faults and the second panel family remain open.
-
Modbus TCP captures its five-second deadline at request acceptance, includes scheduling time in the displayed duration and rejects already expired workers before socket creation. All 24 actual app/LVGL/loopback scenarios pass, including seven delayed-start controls that fail against the preceding source and 25 timeout/retry pairs with stable handles and LVGL memory. Delayed reads/probes, remaining budgets, stale admission and Stop/Home ownership are checked with controlled native startup/clock boundaries. CI retains exact compiled sources, hashes, logs and peer request bytes. Physical ESP-IDF scheduling, lwIP/Wi-Fi timing and both panels remain open.
-
Subnet Lab and the new device/network apps share strict decimal IPv4 parsing. Address/numeric fields retain invalid characters, line breaks, and excess length for rejection through Home/re-entry, with host tests proving no worker or traffic for invalid network input. Physical input paths remain unverified.
-
UDP Console sends one confirmed 0-128-byte hex/ASCII datagram to a selected IPv4 endpoint, filters replies to that peer, and displays an explicitly bounded 512-byte preview. A three-second deadline, cancellation, source-port controls, immutable request/result identity, and OTA blocking cover its lifecycle. Native checks, firmware build and ST7121 Wi-Fi tests pass for 25 repeated echoes, reply copy, timeout, cancellation and 0/512/513-byte replies after fixing SDK task cleanup; broader network faults and the second panel family remain open.
-
NTP Lab, Wake-on-LAN and UDP Console count worker scheduling inside their ten-, two- and three-second request budgets and displayed duration. Expired requests create no socket; NTP clock-step checks retain their measurement reference. All 56 actual-app/LVGL/loopback scenarios pass, including seventeen preceding-source regression controls and 25 timeout/retry pairs per app with stable allocation/handle counts. CI retains the source and peer evidence. Physical scheduler/Wi-Fi timing and both panels remain unchecked for this change.
-
Subnet Lab calculates IPv4 networks, netmasks, broadcast and host ranges, and optional peer membership entirely offline, including /0 counts, /31 point-to-point links, and /32 host routes. All 33 prefixes match independent host reference checks; real LVGL input/lifecycle checks and the firmware build pass. Physical touch and both panel families remain open.
-
Settings scans report Wi-Fi channel and RSSI; Network Diagnostics reports link addressing, performs DNS lookup and four bounded ICMP echo probes, and enumerates up to eight standard DNS-SD mDNS service types without blocking LVGL or OTA restart safety.
-
Network Diagnostics ping uses nonblocking I/O, absolute one-second probe waits and a six-second cooperative budget after DNS; unrelated traffic cannot restart a timeout. Complete replies must match the target, valid framing/checksums and a fresh echoed payload. The 120 deterministic cases across IPv4-only/IPv6 builds check filtering, deadlines, cancellation, faults and socket closure. See Network Diagnostics; physical IPv6/traffic validation remains open.
-
On ST7121 hardware,
example.comresolved and returned four of four pings; mDNS found five real service types, off-screen operations rendered after re-entry, System reported a USB reset rather than panic, and internal heap remained 55 KB free/53 KB minimum after mDNS startup. -
Validate disconnected, unresolvable, partial-loss, empty-mDNS, and second-panel cases before calling the network-diagnosis slice complete.
-
HTTP Console performs GET/POST/PUT/DELETE requests with bounded input buffers and a per-I/O timeout, verifies HTTPS with the certificate bundle, refuses automatic redirects, caps textual response previews at 4 KiB, validates up to four custom headers, and requires a matching second tap within five seconds before sending plain HTTP.
-
HTTP SD logging is explicitly enabled per session and records only timestamp, method, query-free URL, status, response size, duration, and outcome; request headers/bodies and response content are never exported.
-
On ST7121 hardware, two
https://example.com/GETs returned HTTP 200 with 559-byte bodies in 885-922 ms; the metadata CSV was browsable, an active request completed safely off-screen and rendered after re-entry, System still reportedReset: USB, and internal heap was 48 KB free/35 KB minimum after TLS use. -
Validate POST/PUT/DELETE with a disposable endpoint, custom authorization without persistence, query/fragment redaction, redirect and over-4-KiB responses, timeout/DNS/TLS failures, the plain-HTTP confirmation/expiry path, SD faults, and the second panel family.
-
HTTP Console applies a 15-second request budget around its transport calls and cooperative Cancel/Home, retains partial body previews, validates response headers within 8 KiB, and releases its request task after cleanup. Native checks use the actual pinned SDK HTTP client/parser, real LVGL and loopback sockets, including trickled headers/body and allocation accounting. The budget remains cooperative around SDK operations; observed Wi-Fi/TLS latency is still a hardware gate. See HTTP Console.
-
HTTP Console waits for the final response after informational replies, validates and discards bounded chunked trailers without leaking SDK values, distinguishes real EOF from a timeout, and handles bodyless 204/304 correctly. Native framing/cancellation/deadline and allocation checks cover these paths; PC fixtures expose informational and trailer waits for the remaining hardware gate.
-
HTTP Console reports metadata success/failure for every network outcome and turns logging off after storage errors. Eighteen real-file checks use the actual repair/sync implementation to verify opt-in, exact/redacted CSV rows, partial-write recovery, file failures, pending-error consumption by SEND/CLEAR and busy ownership through Home during blocked sync. Physical FAT/SD faults remain open.
-
HTTP results identify the original method and query/fragment-free endpoint after form edits or Home during a request. An accepted SEND clears the previous preview. Native checks compare the displayed source with the two actual peer exchanges and cover re-entry during transport cancellation and SD sync.
-
HTTP CLEAR consumes a finished result waiting for the UI instead of letting the next timer restore it, preserves pending storage-failure reporting, and disarms plain-HTTP confirmation. A stale WORKING tap shows the waiting result before accepting another SEND. Native race checks cover both actions and active SD ownership during CLEAR.
-
HTTP resolves hostnames asynchronously on the lwIP TCP/IP thread and connects ESP-TLS to a numeric peer while retaining the original HTTP Host, certificate name and SNI. Lookup IDs isolate late replies and queued work from freed or subsequent requests. Fourteen host scenarios cover cached/delayed/failed lookups, allocation/queue errors, cancellation, timeout/budget checks, stale callbacks during the next lookup, TLS-name preservation and IPv6 formatting. These synthetic resolver cases and the firmware build do not validate physical DNS or TLS.
-
A loopback-default PC DNS fixture supplies bounded UDP answers/delays/drops/NXDOMAIN/SERVFAIL under
fixture.test, with redacted logs and a hardware late-reply/recovery procedure. Fourteen independent socket/wire checks cover its framing, EDNS, limits, malformed input, queue/shutdown behavior and an HTTP echo exchange; the release workflow includes them. Physical resolver/TLS validation remains open. -
Network Diagnostics shares HTTP's cancellable asynchronous resolver, bounds its DNS wait to ten seconds from the accepted action, stops ping cooperatively on Cancel/Home, and releases each operation's task after cleanup. Its five controls fit the existing action row, overlong inputs are retained/rejected, and results keep their original target. Sixty-eight native worker/resolver/LVGL checks cover one-address and four-address configurations, late/concurrent callbacks and mDNS ownership through cleanup; 120 raw-ping checks cover packet/deadline/cancellation paths. The full 79-case HTTP suite passes with the shared resolver. Physical cancellation latency, resolver-table recovery and both panels remain open.
-
Shared resolver core dispatch enforces each caller's captured deadline before starting DNS, including while the caller has not resumed after posting. All sixteen controlled dispatch/copy/slot cases pass at one-address and four-address capacities; the preceding resolver fails ten controls. Expired/live lookup isolation and 25 timeout/fresh-retry pairs per capacity are checked, and CI retains full input snapshots and logs. The model executes no SDK scheduler or DNS traffic; physical scheduling/network timing and both panels remain open.
-
Hardware-validate HTTP deadline/cancellation, verified TLS and hostname/SNI through the guarded transport, DNS failure/cancellation latency, SD outcomes, repeated cleanup and both panel families. Measure the cooperative budget on real Wi-Fi before claiming a strict whole-request wall-clock limit.
-
Resolve the 2026-09-30 brownout resets observed during USB boot verification, confirm a stable connection/power source, and validate the prepared speaker-off startup/alarm sequence before resuming hardware tests. The captured log and image identities are recorded in the hardware checklist.
-
MQTT Console supports
mqtts/wsswith certificate-bundle verification, gates cleartextmqtt/wsbehind an unchanged five-second confirmation, and exposes one bounded topic/filter, QoS 0/1/2, retain state, an eight-message receive ring, and capped display history. -
A TLS/WSS broker profile can be saved explicitly as one validated, versioned NVS blob and removed with a five-second two-tap action. Cleartext profiles remain memory-only; developer settings flash is disclosed as unencrypted; SD exports never contain the username, password, or payload.
-
MQTT SD logging is opt-in per session and records only timestamp, direction, topic, QoS, retain state, payload byte count, and outcome; credentials and payloads are never exported. Disconnect and Home teardown run off the LVGL thread while remaining visible to the OTA restart blocker.
-
MQTT teardown now holds busy ownership through pending SD writes, file close, buffer release and error reporting. Stale actions and delayed SDK events cannot start work or re-enable Subscribe/Publish while stopping; failed cleanup logging stops at its first error and reports unconfirmed persistence. Twenty-six native app/LVGL/storage scenarios reproduce the old early-release bug and verify the fix, pending completion, metadata privacy, action-row bounds and 25 stable sessions. See MQTT lifecycle; real SDK network timing, SD faults and both panels remain open.
-
MQTT Subscribe and Publish enqueue run on the existing worker with one captured action at a time. Pending actions precede cleanup under the same lock, preserving client lifetime during SDK waits and coalesced notifications. QoS 0 now requests outbox storage and accepts zero as success; 512-byte UTF-8 payloads and 127-byte ASCII topics retain/reject excess input. The expanded 43 native scenarios cover SDK thread routing/stalls, original form identity, action backpressure, queued cancellation, errors, bounds, metadata privacy, 50 stable actions and 25 stable sessions. Real broker delivery, action/Home latency, SD timing and both panels remain open.
-
MQTT's existing worker now owns every metadata filesystem call. A bounded eight-entry metadata queue, independent of history previews, captures the log choice at completed receive/publish acceptance, reports overflow and stops at the first storage failure. Home/Disconnect and UI updates continue during modeled active sync/close/error-callback waits, while OTA ownership remains held. Immediate reconnect restores buffers and clears old pending status before starting a client. The expanded 57 native scenarios reproduce the previous UI filesystem path, verify metadata capture without UI draining, queue pressure and error recovery, and retain stable memory/handles through logged and unlogged 25-session soaks. Real Wi-Fi/SD timing and both panels remain open.
-
MQTT receive assembly preserves the first topic through an empty first payload fragment, validates contiguous offsets and stable metadata, and records each completed assembly once. Binary payload and changed/shortened topic views are explicitly labeled; metadata retains the complete payload size without its contents. The expanded 69 native scenarios reproduce the lost-topic regression and cover empty, fragmented, capped and malformed messages, interruption, Home completion and 50 stable fragmented receives. Real SDK packet parsing, broker traffic, SD faults and both panels remain open.
-
On ST7121 hardware, Tab5 connected to the public TLS test broker on port 8886 and exchanged an 18-byte QoS 1 retained message on its device-specific loopback topic. The metadata-only CSV contained matching TX/RX rows, Home returned to the launcher within 0.82 seconds while cleanup continued, System showed 64 KB free/62 KB minimum heap after the exchange, and a fresh boot of the same image reported
Reset: USB. -
MQTT broker settings use the pinned SDK URI parser plus explicit port/IPv6/path rules, retain excess endpoint/credential input and reject oversized raw byte counts before Connect or Save Profile. Connected status follows the captured transport; fatal errors remain visible through disconnect, ordinary acknowledgments and concurrent storage/drop warnings, while a refused subscription stays distinguishable from success. The expanded 85 native scenarios reproduce six previous connection regressions and preserve earlier worker/receive/storage/resource checks. Physical broker/TLS/WSS behavior, SD faults and both panels remain open.
-
MQTT profile loading checks the 515-byte v1 length twice, preserves exact masked credentials and retains explicit recovery for malformed/wrong-type/read-error values. Failed save/delete reports unconfirmed persistence; confirmation handoffs and stale disabled callbacks protect profile actions. The expanded 109 native scenarios include 24 retained-RAM profile cases, thirteen malformed blobs, seven previous-source regressions and 25 stable reload/delete/save cycles. Firmware builds; actual NVS flash, cold reboot, power loss and both panels remain open.
-
MQTT cleartext confirmation now cancels on URI/username/password value changes, including edits restored to their original text, and retains the five-second second-tap limit. Four native regressions reproduce changed settings with identical old fingerprints and unfocused edit/restore sequences against the preceding source. All 113 scenarios and the firmware build pass, with stable native resources after Home. Physical touch/keyboard, broker traffic and both panels remain open.
-
Configure Windows LVGL/MQTT CI with a 3.9 MB pinned-source artifact from the firmware build, fresh Debug library compilation, full offline/SPI/MQTT checks and retained failure logs/source metadata. Release publication requires its success. A clean local rehearsal passed all 113 MQTT scenarios and the offline/SPI suite without SDK export or cached libraries; version/marker rejection and first-suite failure propagation passed.
-
The 2026-10-06 hosted run built firmware, transferred the pinned source artifact to Windows and passed all 201 MQTT cases plus nine offline/SPI checks. Downloaded source hashes, broker transcripts and metadata rows match the retained evidence; local/hosted SDK inputs differ only in line endings. The separate Linux checks exposed a GCC warning in the UART test fixture, corrected by explicitly narrowing the formatted value to one byte.
-
Verify artifact retention after a failing Windows test and the tag-release failure gate in GitHub. The successful native run does not establish these failure paths.
-
Extend the native CI job with all 79 HTTP Console and 68 Network Diagnostics scenarios, reusing its pinned source bundle and Debug LVGL library. Its 30-file SDK bundle rejects absent HTTP sources before packaging/CMake. Early terminating errors are written to the current suite log, and a private HTTP failure probe verifies that Diagnostics stays skipped and temporary environment settings are restored. The expanded hosted run passes all three jobs and all 357 native checks; downloaded evidence verifies the SDK hashes, every HTTP/Diagnostics case and 21 metadata-only HTTP rows in 16 files.
-
MQTT transport failures preserve supplied ESP, signed TLS-stack, certificate-bitmask and socket codes in the bounded status, omit
ESP_OKand identify missing SDK details. Six previous-source regressions cover individual/combined/empty reports and integer boundaries; all 119 native scenarios and the pinned firmware build pass. Actual broker/TLS faults, physical status wrapping and both panels remain open. -
Native MQTT checks compile the pinned SDK 3.1.1 packet codec and compare captured actions with independent bytes. Thirteen packet cases cover empty/UTF-8/binary data, QoS/retain flags, topic-filled first buffers, fragmented/capped receives, Home, fixed-header and length boundaries. Codec mutations fail, and real decoded bytes reproduce the archived empty-first-fragment bug. The expanded pinned-source CI rehearsal passes all 132 MQTT app/codec cases and offline/SPI checks without developer caches or SDK export; missing codec inputs fail before packaging/compilation. These app cases model the full client; the standalone client fixture and remaining integration/hardware checks are described below.
-
A separate 16-case native broker fixture runs the pinned SDK MQTT client, receive/dispatch loop, outbox and transport dispatch unchanged over loopback TCP. Independent bytes verify authentication/subscription refusal, retained/empty/UTF-8 publishes, binary/fragmented receives, a topic-filled first buffer, both directions of QoS acknowledgment exchanges and malformed/incomplete packets. Twenty-five combined sessions release every tracked allocation/socket/task and preserve handle counts after warm-up. Pinned-source CI includes these cases alongside offline/SPI and the expanded app/codec suite; hosted execution passes, while board scheduling, TLS/WSS and both panels remain open.
-
Thirty-one complete-client console cases run actual LVGL actions, previews and native metadata files against the real SDK and broker fixture. They cover QoS 0/1/2, empty/binary/capped receives, a topic-filled first buffer, refusal and Home during blocked receive completion/abandonment. The 25-session app soak preserves LVGL memory and native handles. Four early broker-ACK regressions reproduce a status race against the previous source; the worker now preserves newer event statuses when an SDK action returns. The unflashed firmware builds with unchanged board configuration. Clean source-bundle CI includes all 201 MQTT cases and retains console CSVs; device timing, TLS/WSS, physical SD faults and both panels remain open.
-
Nine complete-client storage cases verify continued SDK receives/acknowledgments during native sync/close waits, prompt Home/re-entry, cancellation of queued publishes and exact eight-slot metadata overflow order with 13 omissions. One-shot open/flush/sync/close faults report unconfirmed persistence once and stop later appends; held error callbacks preserve busy ownership through Home and shutdown buffer release. Every error case reconnects and logs successfully with stable LVGL/native resources. Native boundary effects do not verify physical SD/FAT or power-loss behavior.
-
MQTT COPY RX shares the latest complete 0-128 raw bytes with Byte Lab without SDK or SD activity. Original topic/QoS/retain/length survive draft edits, transmit and Home; partial or oversized receives cannot replace the clipboard. Clear removes queued history and the saved receive while preserving accepted metadata. Twelve native copy scenarios include every 0-128-byte length, exact binary/fragmented data, Byte Lab paste, confirmation/error retention and 25 stable cycles. Four complete-client broker cases and three rejected private mutations verify raw-byte fidelity, incomplete rejection and Clear behavior. Physical touch/panel validation remains open.
-
MQTT PASTE BYTES prepares a separate 0-128-byte publish draft from Byte Lab, including empty payloads. Explicit Text/Bytes selection preserves the current text field; queued requests retain captured bytes/topic/QoS/retain through later edits and Home. Paste/mode changes never send or log, cleanup rejects stale taps, and profiles/metadata exclude the body. Ten native scenarios cover every length, pending/active ownership, errors and 25 stable cycles. Four actual Byte Lab/SDK/broker round trips cover QoS 0/1/2 and empty data; three private mutations are rejected. The built firmware remains unflashed; physical validation is open.
-
Validate authenticated TLS and WSS brokers, saved-profile reboot/overwrite/delete/corruption recovery, cleartext confirmation/expiry, QoS 0/2, wildcard subscriptions, fragmentation and receive-ring overflow, failed auth/DNS/TLS/timeout paths, SD full/removal, and the second panel family. NVS encryption remains part of the opt-in hardened-device profile.
-
BLE GATT Explorer reuses the shared NimBLE scanner but never starts it or connects automatically. It caps results at eight devices, 16 services, and 32 characteristics; requires product-specific BLE profiles to be off; exposes UUIDs, handles, and properties; supports explicit reads and one notification/indication subscription; gates 1-64-byte raw writes behind an unchanged five-second confirmation; and atomically exports the bounded evidence snapshot to SD only after an explicit tap.
-
BLE evidence never publishes after a rejected header/row write, retains the named TMP and preserves the first cause through close/error reporting. Creation stops on noncollision directory/probe/open/stream errors and reports
EEXISTafter all ten names are occupied. All 50 native callback/formatter/storage cases pass; the previous callback fails 28 controls, including eight rejected writes incorrectly published. Exact bytes, cache isolation/capacity, admission gates and 25 failure/restart pairs are checked with closed streams/descriptors and balanced modeled locks. Linux CI retains source hashes and logs; physical SD, live BLE, panel and power cuts remain open. -
BLE COPY LATEST VALUE copies a complete 0-64-byte received payload and disarms write confirmation without BLE traffic. It uses the original value handle, rejects truncated or failed buffer copies, and preserves the shared clipboard through disconnect. A read returns one ATT response, not an assembled long attribute. On-device startup tests cover all lengths 0-64, a 65-byte rejection, chained/short buffers, read errors, notify/indicate, stale connections and disconnect. Live GATT copy and evidence-export checks remain open.
-
On ST7121 hardware, an explicit scan filled the eight-device cap and found the owned
KICKR CORE 4816. Read-only discovery reported 12 services and the disclosed 32-characteristic cap; Manufacturer Name returnedWahooFitness; Indoor Bike Data0x2AD2subscribed, delivered an 8-byte notification, and unsubscribed. The published CSV contained eight advertisements, 32 characteristic rows, and the correctly labeled notification row. Home released the live connection, immediate re-entry was idle, System reportedReset: USB, and internal heap remained 62 KB free/60 KB minimum. -
Validate no-target and overflowing scans, connection cancel/failure, pairing/authentication errors, indications and fragmented/over-64-byte values, the raw-write confirmation/expiry path on a disposable target, SD full/removal and retained-temp behavior, interaction with each optional product profile, and the second panel family.
Phase 4 release hardening has started in software:
- Root CMake rejects a missing or mismatched SDK export before configuration regeneration, then requires the Tab5 P4/C6 SDIO profile. Twenty portable fixture checks run in the release workflow. Real pinned-SDK checks verified rejection without
sdkconfigmutation and a passing configure/build with the correct export; existing compile-time pin checks remain in force. - Stable OTA now consumes a bounded schema-1 manifest and rejects the wrong hardware/channel, invalid or non-newer versions, unsupported predecessors, oversized images, and URLs outside the immutable tagged-release path.
- OTA validates the complete response length and exactly eight flat schema fields, rejecting duplicate/extra members, raw or escaped NULs, non-JSON whitespace and nesting before cJSON recursion. Image sizes fit the P4's 32-bit representation, and malformed parsed output is cleared. The actual fetch/check functions and pinned cJSON pass 372 native checks with released clients/allocations and four rejected private mutations. The
44594dbhosted run passes all three jobs and 729 native checks; downloaded artifacts verify all 33 SDK hashes and manifest results. - The updater streams SHA-256 over the exact downloaded
.bin, verifies byte count, HTTP length when available, and embedded application version, and aborts before boot selection on any mismatch. Tag CI publishes the binary, manifest, andSHA256SUMS; prerelease tags are excluded from the stable channel. - OTA hashes only HTTP 200 image bytes, fixing a reproduced SDK redirect-body failure. A Windows fixture compiles actual SDK OTA/HTTP/software SHA-256 sources and passes 27 image cases with RAM partitions, including matching-digest length mismatches, write/finalization/boot-selection faults and 25 installs after warm-up with stable resources. Four private guard mutations are rejected; the shared HTTP adapter passes all 79 cases. The
8882b1fhosted run passes all three jobs and 756 native checks; downloaded artifacts verify the 51-file SDK bundle and image evidence. Physical flash/boot/rollback/TLS validation remains open. - OTA manifest fetches exclude redirect data and require complete fixed-length/chunked framing before JSON parsing, fixing four real SDK regressions involving early disconnects and large/chained redirects. Header presence avoids signed-length ambiguity while valid close-delimited transfers remain supported. The
016d3aahosted run passes all three jobs and 774 native checks, including 374 parser checks, 27 images and 16 SDK fetches. Downloaded artifacts verify all 51 SDK hashes and the complete fetch evidence. Four private fetch controls and source-bundle/missing-header checks pass. - Manifest retrieval reuses the guarded HTTP transport with bounded metadata and a cooperative 15-second total budget across DNS, connection, redirects and body. It fixes reproduced resource-check failures for partial headers/trailers and false rejection after informational replies. Response framing resets on new/reused connections. Native checks pass 379 parser cases, 27 image plus 27 fetch cases, three real-time wait/trickle deadlines, allocation faults and repeated informational/trailer fetches with stable resources. The hosted source-only bundle passes all 54 SDK cases in a separate checkout; all 79 HTTP Console cases still pass. The
cf3831ahosted run passes all three jobs and 790 native checks; downloaded artifacts verify all seven suites and all 51 SDK hashes. Physical TLS/timing/flash validation remains open. - Image downloads use the guarded transport and a cooperative five-minute budget through redirects, metadata and body, checked around SDK writes and before finalization. Raw Content-Length validation precedes description reads and avoids the SDK's integer narrowing. Sixteen new image cases cover informational/trailer cleanup, malformed/oversized headers, aliased lengths, allocation faults, repeated metadata and trickles during headers/description/body. A 20x host-only clock exercises the unchanged production budget in about 15 seconds; timeout releases resources, aborts an active RAM write and never finalizes/selects a boot partition. Previous-source probes reproduce metadata failures and invalid length reads. All 70 SDK cases pass from both the local SDK and hosted source-only bundle; all 379 parser checks and 79 HTTP Console cases pass, and the unflashed firmware builds with unchanged board configuration. The
9dffe34hosted run passes all three jobs and 806 native checks; downloaded artifacts verify all seven suites and all 51 SDK hashes. Physical TLS/timing/flash validation remains open. - Length-unknown image streams abort after the first SDK download/write call that exceeds the manifest size. Three prior-executable probes read/write all 32 KiB against an 8 KiB manifest, including a full-body matching digest. The new guard stops at 9 KiB with the configured 1 KiB reader, aborts the RAM image and never finalizes/selects a boot partition. All 73 SDK cases pass with released resources from the local SDK and hosted source-only bundle; all 379 parser checks pass and the unflashed firmware builds with unchanged configuration. The
6d6a42ahosted run passes all three jobs and 809 native checks; downloaded artifacts verify all seven suites, all 51 SDK hashes and the stream bounds. The SDK may write the current buffer before the updater observes the excess count. Physical flash validation remains open. - Recorded SHA update failures and size overruns in cached description data now abort before the next SDK perform call. Controlled SHA API errors against
6d6a42astill write all 8 KiB; the new check prevents writes after the first-update failure and stops a later failure at 2 KiB, including its current buffer. A chunked image against a 512-byte manifest now avoids the previous 1 KiB cached write. Initialization/digest-completion failure controls also abort without finalization/boot selection. All 78 SDK cases and 379 parser checks pass with released resources; a source-only bundle rehearsal runs the actual final suite with six preceding suites stubbed, and the unflashed firmware builds with unchanged configuration. The native SHA target forwards normal calls to the unchanged pinned implementation and injects API errors only for four modes. Thea9788d7hosted run passes all three jobs and 814 native checks; downloaded artifacts verify all seven suites, all 51 SDK hashes and the verification-error cases. Physical crypto/flash validation remains open. - Image deadline checks now run before and after each SDK perform call, including the first cached description write. Advancing the native clock by five minutes after 1 KiB of description data makes the
a9788d7executable begin/write 1 KiB before returning timeout; the new check returns timeout with zero partition starts/writes, no finalization/boot selection and released resources. All 79 SDK cases and 379 parser checks pass; the source-only bundle rehearsal passes with six preceding suites stubbed, and the unflashed firmware builds with unchanged configuration. The0f4a54ehosted run passes all three jobs and 815 native checks; downloaded artifacts verify all seven suites, all 51 SDK hashes and the expiry-before-write case. Physical scheduling/flash latency checks remain open. - OTA result reconciliation records a matching pending version as installed only after a successful
VALIDstate read. Failed or unconfirmed states retain pending metadata without writable NVS operations and show their uncertainty in System. Nine regressions against the0f4a54efunctions reproduce false installation/pending deletion, including loss of later reconciliation. All 30 portable result cases pass locally with closed modeled handles, including state/read/storage faults, preserved rollback/non-activation behavior, recovery and maximum-version status lengths. The unflashed firmware builds with unchanged configuration. Linux checks run the fixture and retain its function source/metadata/logs; downloaded GCC failure evidence exposed a pending-health message needing up to 65 bytes in a 64-byte buffer. Its shorter replacement fits all 31-byte versions, with both pending states checked. Physical NVS/boot/rollback faults remain open. - At the health window, an already
VALIDimage now reconciles retained OTA metadata after a boot-time read error or earlier pending/unconfirmed status. Four previous-callback regressions reproduce stale status and a retained record despite successful validation-state reads. The expanded portable fixture compiles all five result/health functions and passes 50 cases locally, including 20 callback cases for recovery, NVS/internal-storage barriers, validation/state/storage faults and maximum-version installation. Every callback deletes its modeled timer once, marks the window elapsed and leaves handles closed; known-valid reconciliation never calls SDK validation. The unflashed firmware builds with unchanged configuration. Physical timer scheduling, NVS flash and boot/rollback remain open. - OTA completion now publishes through atomic signals before failure releases busy ownership, and the UI waits for that release before consuming a failure. Health processing defers during active updates, retaining its timer at 250 ms after the window and resuming once idle even with System closed. Ten previous-function controls reproduce premature handoff and deletion of newly saved pending metadata during the restart delay. The eight-function portable fixture passes 70 cases locally, including 20 ownership cases and 25 retained-worker retries; the unflashed firmware builds with unchanged configuration. Downloaded
bd28f02andb1ba688artifacts verify all seven native suites, 815 checks per run and all 51 SDK hashes; separate Linux artifacts verify the preceding 30/50 result cases. Physical task/timer scheduling, NVS flash and boot/rollback remain open. - The successful updater records the manifest version already verified against the image, avoiding a second fallible boot/description read. Four previous-worker controls reproduce stale, absent or changed pending metadata despite successful installation. All 80 portable cases pass locally, including ten new version-identity/storage/reboot controls and zero additional metadata reads after success. The
0bba799hosted run passes all three jobs; downloaded artifacts verify seven native suites, 815 checks, all 51 SDK hashes and the separate 70-case Linux callback fixture. Physical NVS persistence and boot/rollback remain open. - System's OTA diagnostics refresh after idle health processing and post-window storage recovery, replacing a stale opening snapshot. Six previous-callback controls reproduce old displayed state/results despite successful validation or reconciliation. Eleven actual functions pass 88 portable cases locally, including eight diagnostics cases with the storage confirmation callback, maximum versions, read/validation faults, busy deferral and offscreen protection. The unflashed firmware builds with unchanged configuration. Downloaded
5c8bddeartifacts verify all three green jobs, 815 native checks, 51 SDK hashes and the separate 80-case Linux fixture. Physical rendering, formatting, NVS persistence and boot remain open. - Tag CI also publishes a native ESP-IDF 16 MiB merged factory/recovery image, Apache and LVGL license/notice files, and the pinned dependency lock. App-only, complete-source, and destructive factory paths plus the current partition/NVS/filesystem migration contract are documented.
- Architecture, troubleshooting, privacy, contribution, security-reporting/support, conduct, compatibility, installation/recovery, data-format, and pin-safety contracts are now repository-owned documentation.
- Add independent release signing and verify the signature with an embedded public key; HTTPS/GitHub control remains the trust root until then.
- Exercise valid, malformed, incompatible, downgrade, truncated, wrong-size, wrong-version, and wrong-hash manifests plus rollback on hardware before calling the manifest path hardware validated.
- Verify the released factory image from checksums on a clean Windows machine, recover a fully erased Tab5, and confirm both display families plus deliberate NVS/SPIFFS erasure before calling distribution complete.
Current strengths:
- A working ESP-IDF/LVGL product rather than a scaffold.
- Pinned dependencies and a reproducible release container.
- Dual 6 MB OTA slots with substantial image headroom.
- HTTPS transport, revocable relay credentials, and OTA rollback support.
- Small parser/math self-checks plus relay and desktop-tool checks.
Current constraints and risks:
- Nearly all firmware lives in one roughly 7,000-line
main/main.c. - The static launcher/lifecycle table exists, but most legacy app timers, pins, and UI pointers still use the shared manual cleanup path until those apps are touched.
- G53/G54 remain shared by GPIO, ADC, and external I2C; Servo uses G0 for PWM and G54 for its LED, so their software release paths still need hardware transition testing.
- OTA metadata and image hashes are verified through a versioned stable manifest, but the manifest is not yet independently signed; GitHub repository control and Web PKI remain trusted.
- SD writers now preserve or repair incomplete data, but removable/full-card behavior and retained-temp recovery still need field validation.
- Reverse-engineered wearable work is excluded from release inputs but still needs a provenance decision before publication.
- The stable-release process still depends on manually completing the hardware gate before a tag is pushed.
- The factory BSP remains pinned to ESP-IDF 5.4.2; the published support matrix lists the 5.4 line as end-of-life on 2027-07-05.
| Target window | Release | Outcome |
|---|---|---|
| Aug-Sep 2026 | v0.6 | Field beta released; hardware exit gates remain open |
| Oct-Dec 2026 | v0.7 | Establish reliability, CI, recovery, and shared capture conventions |
| Jan-Apr 2027 | v0.8 | Deliver the core wired electronics bench |
| May-Aug 2027 | v0.9 | Add generic IoT commissioning and complete the IDF migration |
| Sep-Dec 2027 | v1.0 | Ship a documented, signed, field-ready stable release |
| 2028 | v1.x | Add repeatable projects, profiles, USB workflows, and optional hardware expansion |
Target: v0.6, Aug-Sep 2026
Outcome: preserve the new capability while removing the immediate hardware and release hazards.
- Land the current I2C, BLE sensor, cycling, ring, and servo work as separate reviewable changes.
- Move the servo to a timer/channel that cannot alter the display backlight.
- Make BLE scanning and connection user-controlled; never connect to a KICKR or ring merely because it is nearby.
- Give G53/G54 and other shared outputs one deterministic acquire/release path. Leaving an app must restore safe input/high-impedance or explicitly off state.
- Stop enabling external 5 V by default; keep it unavailable until an explicit UI control and signal-level guidance are implemented.
- Block OTA and shutdown while a capture, SD writer, microphone, ADC sampler, BLE control session, or external output is active; graceful quiescing can follow later.
- Delay OTA validation until display, storage, settings, and the main event loop have remained healthy for a meaningful window.
- Stop silently erasing all NVS settings on a recoverable initialization fault; surface recovery and preserve credentials where possible.
- Resolve the
littlefspartition versus SPIFFS mount mismatch and choose one internal filesystem before storing user data there. - Add push/PR CI for a clean firmware build, relay tests, Python checks,
git diff --check, and image-size reporting. - Keep stock/patched wearable binaries and uncertain decompiled material out of release artifacts pending provenance review.
- Record a manual hardware smoke checklist covering both panel/touch variants, SD present/absent, Wi-Fi offline/online, BLE absent/present, and every launcher transition.
- A clean clone builds and produces the same release inputs as CI.
- Both display variants pass cold boot, touch, storage, Wi-Fi, and OTA recovery checks.
- One hundred mixed app enter/exit transitions leave no pin driven, timer repurposed, or material heap loss.
- An empty I2C bus, missing SD card, absent BLE devices, and offline Wi-Fi all fail safely.
- An eight-hour idle/mixed-use soak completes without reset.
- The release contains no vendor wearable firmware.
Target: v0.7, Oct-Dec 2026
Outcome: make every existing tool predictable before adding another protocol surface.
- Show firmware version/commit, reset reason, uptime, panel type, free/minimum heap, storage state, and last OTA result in System.
- Use temp-file-plus-rename writes for notes, captures, ride summaries, and health logs where the filesystem supports it.
- Standardize session paths, timestamps, CSV headers, units, and filename collision handling.
- Add brightness, screen timeout, and conservative idle behavior; measure battery impact of Wi-Fi and continuous BLE scanning.
- Make SD removal/full-card errors visible and prevent partial files from appearing successful.
- Add a documented factory-flash and recovery path alongside app-only flashing.
- Introduce one static app table with name, icon, enter, and leave callbacks, then migrate apps into it only as they are touched. One lifecycle path should replace the growing app-specific cleanup list.
- Extract code from
main.conly when it is being changed: new apps get their own source file; shared hardware code appears only after a second real consumer. - Keep stable releases milestone-based. Add candidate/prerelease tags only when there are external testers; do not create release-channel machinery before then.
- Ten power interruptions during representative writes leave previous data readable and no corrupt file reported as complete.
- Ten OTA install/rollback cycles preserve settings and user data.
- A repeated 100-cycle launcher soak stays within an agreed heap baseline recorded in the release notes.
- Every hardware app documents pins, voltage limits, power state, and exit behavior on-screen.
Target: v0.8, Jan-Apr 2027
Outcome: bring up a common sensor or microcontroller entirely offline.
- I2C register read, write, watch, bus-speed selection, and CSV capture. Raw writes require an explicit confirmation.
- UART terminal with safe pin choices, baud/parity/stop settings, ASCII/hex views, timestamps, send history, and SD logging.
- RS-485 terminal using the onboard transceiver, with documented direction and termination behavior.
- USB keyboard input and CDC/VCP serial host after the existing USB host path passes disconnect/reconnect testing.
- SPI master transaction console with explicit chip-select and bounded transfer sizes.
- General PWM/frequency/duty/pulse output built from the proven servo work without sharing display resources.
- Frequency and duty-cycle measurement plus ADC offset/scale calibration and scope CSV export.
A multi-channel logic capture is a feasibility experiment, not a promise. It enters the release only if measured sample rate, channel count, memory use, and signal integrity are useful and honestly documented.
- A loopback fixture verifies UART, RS-485, SPI, PWM, and frequency measurement.
- A user can identify an unknown I2C device, inspect a register, watch a controller's boot log, exercise an output, and export a timestamped capture without a PC.
- All tools return pins and peripherals to a safe state when stopped, navigated away from, disconnected, or timed out.
- Calibration values are visible, persistent, bounded, and resettable.
Target: v0.9, May-Aug 2027
Outcome: commission common BLE and network devices without compiling a custom app for each product.
- Replace product-driven background BLE behavior with a generic scanner and GATT explorer: advertisements, services, characteristics, read/write, notifications, and explicit connection controls.
- Keep Govee, Ring, and KICKR as optional views or data profiles over shared BLE machinery.
- Add Wi-Fi channel/RSSI survey, address details, DNS lookup, ping, and mDNS discovery.
- Add a bounded HTTP request console and MQTT publish/subscribe with TLS, retained-message visibility, and timestamped logs.
- Store credentials in NVS; exported project/session files exclude secrets by default.
- Start an ESP-IDF migration spike no later than Jan 2027 and complete migration by May 2027, leaving time before the 5.4 support deadline. Select the newest line that passes Tab5 display, ESP-Hosted Wi-Fi/BLE, OTA, audio, and USB tests; do not upgrade solely for a version number.
- Keep the old toolchain branch only for time-bounded critical fixes after migration.
- The hardware matrix passes on a supported ESP-IDF line with no display or wireless regression.
- A user can discover and subscribe to a generic BLE characteristic, diagnose a network path, publish and receive an MQTT message, and export the evidence.
- Offline operation remains intact; cloud or broker outages do not block wired tools.
Target: v1.0, Sep-Dec 2027
Outcome: define a stable product and recovery contract.
- Replace direct
latestOTA consumption with a versioned manifest containing version, hardware compatibility, size, SHA-256, URL, release channel, and minimum supported predecessor. - Sign release images and verify signatures during OTA while preserving normal developer builds. Offer a separately documented hardened-device profile before enabling irreversible secure-boot or flash-encryption eFuses.
- Publish app-only and factory/recovery images, checksums, LICENSE, third-party notices, and useful release notes.
- Document partition, NVS, settings, and SD-format compatibility plus migration policy.
- Add installation, recovery, pin-safety, architecture, troubleshooting, privacy, contribution, and security-reporting documentation.
- Protect stable releases with CI and a hardware sign-off checklist. Add branch protection when contribution volume makes it useful.
- Freeze only the user-visible data formats and operations proven by v0.8/v0.9; do not freeze a plugin ABI.
- Both panel variants, battery/no-battery operation, SD absent/present/full, Wi-Fi offline/online, and BLE absent/present pass the published matrix.
- An eight-hour mixed-workload soak and one hundred app transitions produce no crash, unsafe output, or material memory regression.
- A bad candidate image rolls back; a good image is not marked valid until the health window passes.
- Factory recovery works from documented steps on a clean Windows machine and the CI container build is reproducible.
- Five canonical workflows pass end-to-end: I2C inspection, UART/RS-485 capture, signal generation/measurement, BLE GATT subscription, and MQTT commissioning.
Target: v1.x through 2028
Outcome: turn isolated measurements into reusable field projects without creating a second operating system inside the firmware.
- SD project folders containing notes, non-secret connection profiles, pin assignments, captures, and exports.
- A small USB/remote CLI for screenshots, logs, file transfer, and starting/stopping existing captures.
- Declarative device profiles for I2C registers, BLE characteristics, MQTT topics, and simple decoders.
- Constrained recipes using existing operations such as read, write, wait, assert, and log. No arbitrary native code or general-purpose interpreter.
- Camera-assisted QR/barcode provisioning, IMU logging, USB mass-storage workflows, and supported LoRa/cellular modules.
- Thread/Zigbee only when the ESP32-C6 hosted transport and upstream support are stable enough to test and maintain.
- A protected companion board with level shifting, buffered logic inputs, and improved analog front ends only after repeated users establish real voltage, bandwidth, accuracy, and connector requirements.
A profile/recipe format becomes stable only after at least three materially different devices use it without firmware-specific exceptions. A new shared abstraction follows the same rule.
- Keep ESP-IDF, FreeRTOS, LVGL, NVS, SPIFFS, and ordinary files. Do not rewrite the working product.
- New substantial apps live in their own source files. Existing apps move only when being materially changed.
- Use one owner at a time for each pin, bus, LEDC timer/channel, ADC unit, BLE connection, and storage writer.
- Every app or service has a deterministic stop path; background work cannot retain deleted LVGL objects.
- Keep NVS for small settings, SPIFFS for built-in state, and microSD for user logs. Do not add a database until file formats measurably fail.
- Keep the smallest on-device self-check for pure parsers and calculations.
- Add host tests when logic can run without ESP-IDF; do not mock the entire board.
- Run clean firmware builds and existing relay/tool tests before merge, not first on a tag.
- Maintain a manual hardware matrix until at least three repeatable fixtures justify automated hardware-in-loop testing.
- Record firmware size, minimum internal heap, PSRAM use, boot time, and soak results for each stable release. Regressions need an explicit reason, not an arbitrary universal limit.
- Keep API keys off the tablet and repository; use independently revocable per-device relay tokens.
- Apply size/rate limits at network boundaries and avoid exporting secrets.
- Use HTTPS plus signed OTA images before 1.0. Secure boot, flash encryption, anti-rollback eFuses, and locked debug interfaces belong to an opt-in production profile because they permanently change a development device.
- Publish a security contact and support window with 1.0.
Work enters a milestone only if it materially improves one of the six core jobs: connect, discover, inspect, control, log, or recover. Within a milestone, order work by:
- Prevent hardware damage or data/credential loss.
- Restore build, boot, update, or recovery reliability.
- Complete an end-to-end field workflow.
- Remove repeated maintenance cost proven in at least two places.
- Add optional polish.
- Run the checked smoke matrix on both display/touch families, including backlight/Servo and every G53/G54 transition.
- Complete the eight-hour mixed-use soak; the corrected ST7121 100-transition resource/heap test passes, while ILI9881C remains part of the two-panel matrix.
- Exercise ten OTA install/rollback cycles while preserving NVS and SD data.
- Close the v0.6.0 hardware gaps and document migration from the legacy factory/4 MiB OTA layout.
- Validate Phase 1 atomic writes, display wake, and SD full/removal behavior on hardware.
- Migrate each legacy app's cleanup into the static lifecycle table only when that app is materially changed.
- Hardware-validate the completed I2C inspect/control/capture workflow, including retained
.TMPrecovery. - Hardware-validate UART1 and the implemented onboard RS-485 path with external loop fixtures.
- Hardware-validate the SPI master console, CS timing, transfer bound, and G18/G19 shared-pin teardown.
- Hardware-characterize the G6 PWM/pulse generator across its full range and verify timer/backlight isolation.
- Hardware-characterize Scope frequency/duty, per-input calibration, CSV publication, and storage-fault behavior.
- Begin the supported-IDF migration spike by Jan 2027.