Specialize repeater ACL session state, compact recent and flood records, stream Merkle proofs, and release cold OTA buffers safely. Preserve saved formats, stack sizes, table capacities, and OTA source limits. Account for lazy buffers when active and add compatibility, ARM alignment, allocation failure, and queued-response tests.
Validated six representative board/role builds, 1736 native test cases, sanitizer fixtures, and strict documentation. Document the preexisting Wio-E5 Mini flash overflow separately.
Distinguish OTA read failures from missing blocks and select unique raw-flash checkpoints by MID and target. Keep deferred CLI requests and replies bound to immutable command identity and full authenticated keys.
Gate radio mutations on their exact reply delivery, recover coding-rate restoration, and roll back failed Companion preference writes. Preserve accepted low duty cycles across reboot.
Retain partial network writes, cancel displaced client operations, and reject malformed or stalled framed input. Add regression and CI coverage, and size-optimize the RAK4631 Ethernet build without dropping features.
Preserve resumed nRF52 flash pages and keep filtered OTA catalogs incomplete until full pages arrive. Bound stuck radio preparation, report companion setting failures, retain safe rollback, and codify conservative advert penalties with regression tests.
Keep each deferred OTA response tied to the request's radio profile and generation. Separate requests from different radio sessions, discard stale queued responses, and retain the existing companion and infrastructure reply policies.
Reject staged captures with invalid file framing before adopting their state. Recover fixed internal-flash trailer bytes after interrupted checkpoints and handle small ESP32 delta trailers that share metadata sectors. Fail closed when install preflight cannot read a valid header, so hardware and automatic-update policy checks cannot be skipped.
Replace Companion preferences through verified file transactions and quarantine writes after incomplete loads on all platforms. Initialize serializer runtime fields before preferences snapshots copy them.
Add production-code fault regressions to CI for deferred routing, store recovery, install preflight, and preferences persistence. Validation: 1,510 native tests, 60 host checks, and six firmware targets across ESP32, nRF52, STM32, and RP2040.
Reject radio changes when receive mode cannot resume and restore the previous physical profile and power policy. Preserve selected folder OTA captures across disconnects and recoverable host I/O failures, while keeping corruption failures distinct. Validate OTA staging input before arithmetic or buffer writes and revoke published data before edits.
Commit companion channels through verified file replacement on ESP32, RP2040, and STM32, and quarantine incomplete startup reads. Recheck the last management connection during delayed wireless changes and prevent conflicting Bluetooth shutdowns. Detect complete OTA implementation sources rather than the shared inflater when configuring release builds.
Add fault-injection regressions and CI coverage for these paths, and document folder capture reconnect behavior.
Validation: 1,510 native tests; 55 host integration checks; build profile regressions; ESP32, nRF52, STM32, and RP2040 firmware builds.
Validate primary images before publishing their views, invalidate the shared source cache before reads that can partially overwrite it, and revoke self-serving references before replacing caller-owned buffers. Keep the CLI serving flag aligned with a surviving primary image after a rejected replacement.
Regression tests reproduce rejected replacements, partial source reads, and self-refresh allocation/read failures. Verify queued manifests, recovered payloads, Merkle proofs, and sanitizer-checked buffer lifetimes.
Drain received packets in single-profile radio fault backoff as well as
dual-profile mode. Share the normal channel-clear and bounded busy policy
with driver retries so a failed send cannot retry blindly or bypass the
existing single-retry limit.
Retain an unadmitted OTA request flight and count v2 fallback evidence only
after a sparse retry enters the transmit queue. Local queue congestion no
longer disables v2 before a request was sent or discards received fragments.
Include primary airtime when temporary RX-only radio2 crosses requests onto
that channel, keeping response allowances conservative on slower profiles.
Add six native regressions, including five failing-before cases, and document
the queue-admission and crossover timing behavior.
Validation: 1,502 native tests, 29 integration checks, and five firmware
builds passed across ESP32-S3, nRF52, and STM32.
Keep catalog, manifest and leaf requests pending when the local transmit
queue rejects them instead of spending their network retry allowance.
Keep the packet selected before CAD so work becoming due during sensing
cannot bypass its own channel or pacing checks. Retire cancelled radio
retries before waiting for BUSY hardware or their retry deadline.
Wait for active transmission completion before applying firmware. Stop
admitting new transmissions after the apply drain deadline so busy queues
cannot postpone reboot indefinitely, and keep those deadlines armed across
millis rollover. Retain the existing persistence-flush backoff.
Add failing-before/fixed-after regression coverage for all four issues,
including the production OTA apply and TX guards in CI.
Validation: 1,496 native tests, 42 Python integration tests, and five
firmware builds passed across ESP32-S3, nRF52, and STM32 targets.
Add get/set ota.speed and OTA CLI aliases for factors from 0.05 to 3,
defaulting to the existing pace. Persist the setting independently of the
OTA workspace and apply it to OTA packet pacing, relays, discovery and
adverts while retaining the configured airtime budget.
Preserve physical proof/retry allowances, account for both participating
radio profiles, keep optional deadlines armed across millis rollover, and
exclude intentional pacing from observer stale-packet age. Keep local
verification at its normal rate and retain a valid saved speed if backup
recovery cannot finish. Add documentation and CI regression coverage.
Validation: 1,491 native tests and 26 CLI/integration tests passed. Built
ESP32 full repeater, ESP32 full Companion, nRF52 full Companion and STM32
USB Companion successfully, including their memory/size checks.
Improve companion BLE delivery and idempotent remote CLI retries, make FPF7 persistence atomic with FPF6 migration, verify staged OTA data on resume, and clarify filter policy wildcard and BlackHole semantics.
Protocol: OTA_REQ and OTA_GET_MANIFEST now carry a want_mask bitmap, so a fetcher asks for specific fragments (all on the first request, only the still-missing holes on a retry) instead of a whole block/manifest window. The WANT_MANIFEST and FETCHING retry loops re-ask only on a no-progress tick, so a lost fragment costs one fragment to recover and a re-request can't collide with an in-flight multi-fragment burst on half-duplex radios.
Warm-start (motatool folder-capture only): new OTA_GET_LEAVES/OTA_LEAVES let `ota pull <#> folder validate` bulk-fetch the target's merkle leaves, authenticate them against the manifest root, diff a similar seed build already staged in the destination, and pull DATA over LoRa only for the blocks that differ. Leaves are bitmap-fragmented + no-progress retry-gated like the manifest, capped at OTA_DIFF_MAX_BLOCKS so the want_mask stays a fixed uint16, and the diff runs a bounded batch per loop tick so it never starves the mesh loop. motatool `serve --seed <build.mota>` injects the seed payload into the destination .part on OP_BEGIN.
If an `ota pull <#> folder` block-write fails mid-transfer (the motatool seeder
link dropped), the fetch enters a new PAUSED state instead of failing or falling
back to RAM/flash: progress stays on the host, the manager stops requesting, and
loop()/stall-detection leave it untouched (it waits indefinitely). On reconnect
the ESP32 seeder re-registers the folder destination and, if PAUSED, calls
resumeStaged(): OP_STAT re-attaches the host's partial, the leaves are re-read,
and only the missing blocks are re-requested (a brand-new/absent file restarts
from 0). `ota status` reports the paused state.