Files
ESP32_Serial_Swiss_Army_Knife/docs/roadmap.md
T

377 lines
32 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Implementation roadmap
This document tracks the implementation and hardware-validation plan for the ESP32 Serial Swiss Army Knife. It describes intended sequencing rather than a release schedule. A phase is complete only when its implementation, documentation, build validation, and relevant hardware tests have passed.
## Status legend
- **Complete** — implemented and validated on the target hardware.
- **In progress** — implementation or validation is actively underway, but the overall phase is not complete.
- **Implemented; validation pending** — code is present and builds, but the current implementation still needs the listed hardware checks.
- **Planned** — accepted project direction, not yet implemented.
- **Under evaluation** — useful candidate whose feasibility, security, or resource cost must be measured before it becomes a commitment.
## Project-wide design constraints
These constraints apply across all phases:
- UART0 remains the trusted physical administration and recovery console.
- UART1 and the MAX3243 provide the single physical RS-232 data port.
- All serial transports use the central session broker: one writer, multiple observers.
- A slow or failed client must not block UART reception or unrelated clients.
- Serial data paths remain binary-transparent; transports must not reserve in-band control sequences.
- Network serial access must be authenticated and encrypted. No unauthenticated plaintext TCP serial service is planned.
- Secrets must not be exposed by routine status output, command completion, or logs.
- Resource use must remain bounded and observable on the ESP32-S3 N16R8 target.
- New work must preserve USB CDC and UART0 recovery when Wi-Fi or a network service fails.
- Project code remains `GPL-3.0-only`; third-party license notices and compatibility must be preserved.
## Phase overview
| Phase | Scope | Status |
|---|---|---|
| 0 | RS-232 hardware characterization and diagnostics | **Complete** |
| 1 | Persistent UART1 serial-service foundation | **Complete** |
| 2 | Transport-neutral session broker | **Complete** |
| 3 | Native USB CDC-ACM serial transport | **Complete** |
| 4 | Wi-Fi station/AP foundation and network diagnostics | **Complete** |
| 5A | Authenticated HTTPS administration foundation | **Complete** |
| 5B | Offline xterm.js WebSocket serial terminal | **Complete** |
| 6 | Authenticated SSH serial transport | **Complete** |
| 7 | Local display and button interface | **In progress (7E validation)** |
| 8 | Role-based users and administrative access | **In progress (8A validation)** |
| 9 | Security and production hardening | **Planned** |
| 10 | Authenticated, rollback-capable OTA | **Planned** |
| 11 | BLE serial transport and provisioning evaluation | **Planned** |
| 12 | Advanced network integration | **Under evaluation** |
| 13 | Optional filesystem-backed features | **Under evaluation** |
## Completed foundation
### Phase 0 — RS-232 hardware characterization
Implemented and hardware-validated:
- Central board pin profile for the ESP32-S3 N16R8 and MAX3243 breakout.
- MAX3243 enable, static driver, receiver, valid-voltage, and modem-signal checks.
- UART loopback across supported framing and baud-rate combinations.
- Hardware CTS transmit gating and RTS receive-backpressure tests.
- Exclusive RS-232 port ownership and fault-safe cleanup.
- RGB status indication for diagnostic state.
- Potentially disruptive tests isolated under the `debug` CLI submenu; top-level `status` retained.
Detailed procedures are in [Electrical tests](electrical_tests.md) and [Hardware wiring](wiring.md).
### Phase 1 — Serial-service foundation
Implemented and hardware-validated:
- Persistent, versioned UART configuration with safe defaults.
- UART1 lifecycle management and exclusive ownership.
- Nonblocking RX and TX software streams.
- Baud rate, data bits, parity, stop bits, RTS/CTS, DTR policy, and RTS threshold controls.
- Runtime counters and safe restart after working-configuration changes.
- Explicit save/load/default/reset behavior; edits are not silently persisted.
### Phase 2 — Session broker
Implemented and hardware-validated:
- Up to eight generation-safe broker clients.
- Exactly one writer lease with multiple observers.
- Bounded per-client output and event queues.
- Slow-observer isolation and drop accounting.
- Writer grant, release, denial, revocation, and forced administrative reassignment.
- DTR `on-connect` integration.
- Partial-transfer and retryable no-progress semantics for transports.
- Broker payload storage placed preferentially in PSRAM while FreeRTOS control structures remain in internal RAM.
### Phase 3 — Native USB CDC-ACM
Implemented and hardware-validated:
- Native ESP32-S3 USB CDC-ACM serial transport.
- Automatic broker connection when the host opens the port with DTR asserted.
- Opportunistic writer acquisition with observer fallback.
- Binary-transparent bidirectional serial data.
- Supported host line-coding application while USB owns the writer lease.
- Disconnect cleanup, bounded buffering, counters, and UART0 lifecycle controls.
### Phase 4 — Wi-Fi foundation
Implemented and hardware-validated:
- Four persistent station profiles with priority ordering.
- WPA2/WPA3 mixed mode and WPA3-SAE-required mode.
- Explicit no-echo secret entry through UART0.
- AP policies `off`, `fallback`, and `always`.
- Random persistent fallback-AP password and MAC-derived default SSID.
- Bounded profile attempts, DHCP deadlines, failover, and retry backoff.
- Root and `wifi` aliases for `ping`, `nslookup`, and `traceroute`.
- Wi-Fi/lwIP payload allocation configured to prefer PSRAM with capacities pinned in `sdkconfig.defaults`.
A WPA3-required profile correctly rejects an AP that does not advertise the required Protected Management Frame capability; mixed mode is the compatible choice for such an AP.
### Phase 5A — Authenticated HTTPS foundation
Implemented and hardware-validated:
- HTTPS-only service on TCP port 443 using ESP-IDF mbedTLS.
- Persistent random shared `admin` credential.
- Persistent device-specific ECDSA P-256 certificate and private key.
- Physical-console credential retrieval, rotation, certificate inspection, rotation, and recovery.
- Explicit failure behavior that preserves UART0, USB, serial, and Wi-Fi recovery paths.
- Credential rotation revocation hooks shared with WebSocket and SSH sessions.
### Phase 5B — Offline browser terminal
Implemented and hardware-validated:
- Vendored xterm.js and FitAddon assets; no Internet or CDN dependency.
- CSP-compatible page structure with scripts served as separate resources.
- Authenticated status and one-time WebSocket-ticket APIs.
- Binary WebSocket serial frames and broker writer/observer integration.
- Two bounded browser-terminal sessions.
- Writer request/release controls and role indication.
- Bounded TLS/socket behavior and slow-observer isolation.
- Viewport-constrained terminal fitting without recursive page growth.
- Validation with multiple clients, ANSI colors, advanced escape sequences, and full-screen terminal software.
## Latest completed phase
### Phase 6 — Authenticated SSH serial transport
The SSH implementation is complete and hardware-validated. It provides:
- wolfSSH on TCP port 22 while HTTPS remains on mbedTLS.
- Password authentication using the shared `admin` credential.
- A separate persistent ECDSA P-256 SSH host key and OpenSSH-compatible fingerprint.
- Interactive shell/PTY channels only.
- No `exec`, subsystem, SFTP, SCP, agent forwarding, or TCP forwarding.
- Two fixed session/handshake slots.
- Three password attempts and a 15-second handshake deadline.
- No broker client before successful authentication and shell negotiation.
- Binary-transparent serial forwarding with no in-band writer-control protocol.
- Opportunistic writer acquisition and observer behavior through the common broker.
- Credential-rotation revocation and UART0 session/host-key administration.
- A single bounded wolfSSH owner task pinned to CPU 1.
- wolfSSL/wolfSSH allocations that prefer PSRAM with internal-memory fallback.
- A per-call wolfSSH receive budget to prevent pipelined input from monopolizing the owner task.
- Bounded broker and WebSocket work bursts that guarantee scheduler/idle progress during sustained serial traffic.
- Software AES for PSRAM-backed mbedTLS records plus software wolfCrypt AES/SHA, preventing mbedTLS and wolfSSL from independently reconfiguring shared ESP32 crypto hardware.
- Internal task stacks retained for safety during flash/NVS cache-disable windows.
- Heap and SSH stack telemetry through `memory` and `ssh status`.
SSH login, host-key verification, serial traffic, Web Serial coexistence, and USB CDC coexistence have been validated. During concurrency testing, the previously failing three-client arrangement used USB CDC and SSH as writer in turn while the remaining transports observed.
Early runs showed healthy heap values but CPU 0 idle-task watchdog timeouts, disproving the initial memory-pressure hypothesis. One trace exposed an unbounded broker scheduling path. A later, decisive trace repeatedly stopped inside mbedTLS's external-RAM hardware-AES DMA wait while HTTPD encrypted a WebSocket record. The broker and WebSocket producer now use bounded active bursts, mbedTLS software AES avoids the hanging PSRAM DMA path, and wolfSSL AES/SHA hardware acceleration is disabled because its private locks do not coordinate with ESP-IDF's crypto lock.
#### Phase 6 hardware validation
The final target-hardware retest covered:
1. USB CDC, one WebSocket terminal, and one SSH terminal connected concurrently.
2. SSH as writer with USB CDC and WebSocket observing.
3. USB CDC as writer with SSH and WebSocket observing.
4. Serial traffic with active readers and writer-token release/reassignment.
5. Continued HTTPS/WebSocket, SSH, USB CDC, serial-service, and UART0 responsiveness.
The software-crypto build no longer reproduces the HTTPD watchdog stall. This validates that the failure was a shared hardware-crypto/PSRAM DMA problem rather than heap exhaustion. Phase 6 is complete; these concurrent arrangements remain regression tests for future transport, TLS, memory-placement, and ESP-IDF changes.
## Current and planned phases
The order below is the current plan. Phase 7 is in progress, Phase 8A is implemented and awaiting target-hardware validation, and later work remains planned or under evaluation. Detailed requirements should be finalized at the start of each phase, and optional features must not weaken the completed serial and recovery paths.
### Phase 7 — Local display and buttons
Add a standalone local status/control interface without making it a dependency of the serial core. The planning baseline uses a 128×64 dual-color monochrome I²C OLED sold with an SSD1315 controller. Phase 7A confirmed SSD1306-compatible operation, 7-bit I²C address `0x3c`, orientation, column mapping, contrast/inversion behavior, button inputs, and the physical color geometry on the selected hardware.
Phase 7A diagnostics and target-hardware electrical validation are complete. Phases 7B, 7C, and 7D are complete. Phase 7E is implemented and awaiting target-hardware fault and persistence validation.
#### Hardware baseline
- Wire OLED `VCC` to `3V3` and OLED `GND` to `GND`. The OLED must use 3.3 V because module-mounted I²C pull-ups may connect SDA and SCL to `VCC`.
- Wire OLED `SDA` to GPIO11 and OLED `SCL` to GPIO12. These pins are currently unused and sit in the available GPIO1014 block on the DevKit header.
- Wire three active-low buttons between their GPIO and `GND`, using the ESP32 internal pull-ups: GPIO10 for previous/back, GPIO13 for select/confirm, and GPIO14 for next.
- Use short left/right presses for page or item navigation, short select for entry, a long left press for back/home, and an explicit select hold for disruptive confirmation.
- Verify whether the module provides suitable SDA/SCL pull-ups and that every external pull-up is tied to 3.3 V, not 5 V; add external pull-ups to 3.3 V if the module does not provide them.
- Hardware verification established yellow rows 015 and blue rows 1663. A narrow physical black divider separates the two regions even though row 15 is the final yellow addressable row and row 16 the first blue addressable row.
- Keep assignments centralized in the board profile rather than scattering display or button GPIO assumptions through UI code.
![Phase 7C icon status-page mockup](phase7c_icon_mockup.svg)
The persistent yellow strip uses fixed-position serial, Wi-Fi-strength, USB, WebSocket, SSH, broker-client, and alert icons. Active icons are solid with a compact value below; inactive icon slots remain blank and show no value. The blue 128×48 content panel begins at row 16 and rotates through overview, RS-232, broker-client, and network/service pages; the physical black divider remains visually clear. No password, Wi-Fi secret, private-key material, or routine credential data may appear on the display.
#### Implementation sequence
1. **Phase 7A — Electrical bring-up and diagnostics — Complete**
- Bounded low-level display and button diagnostics are available under the existing `debug` submenu.
- The selected module acknowledged at 7-bit `0x3c` (8-bit `0x78` write / `0x79` read). A guarded full scan is retained for the dedicated local-UI bus; an absent display remains nonfatal and does not make the serial core dependent on the OLED.
- Hardware validation passed for geometry, orientation, row/column addressing, contrast, inversion, button pull-ups/debounce/short-press/long-press/stuck behavior, and the color geometry: yellow rows 015, blue rows 1663, with a physical black separator between the regions.
2. **Phase 7B — Display driver — Complete**
- The `local_display` service owns the local I²C bus, SSD1315-compatible panel, and framebuffer. It uses a static 1 KiB 128×64 framebuffer, a compact 5×7 upper/lowercase, digit, and punctuation renderer, and an internal mutex; do not add LVGL for this fixed monochrome UI.
- Rendering treats the yellow 128×16 status panel (rows 015) and blue 128×48 content panel (rows 1663) as separate panels so the physical divider remains clear.
- Frame commits refresh only dirty 8-pixel pages. I²C runs at 100 kHz with bounded transactions.
- The display bus initializes at boot; a known display is automatically initialized and cleared. A missing or unresponsive display is nonfatal and does not make the serial core dependent on it.
- Target-hardware validation passed for initialization, all display diagnostic patterns, the rendered panel layout and physical divider, row 15/16 boundary, contrast, inversion, display-off/reinitialization, and button diagnostics. Observed contrast control has a useful brightness range of 1255.
3. **Phase 7C — Read-only status UI — Complete**
- The low-priority `local_status_ui` owner task builds display state from copied public serial, Wi-Fi, broker, USB, WebSocket, HTTPS, and SSH snapshots. It does not parse CLI output, reach into transport internals, or become a broker client.
- Previous/back and next short presses navigate overview, RS-232/modem, broker-client/writer, and network/service pages. Select has no state-changing action in this read-only phase.
- The task polls and debounces the existing active-low button inputs and refreshes at 4 Hz maximum. It collects service snapshots before beginning a display frame, so no service or broker lock is held across an I²C transaction.
- The yellow panel is page-independent and uses fixed icon slots. Wi-Fi strength is shown by segmented Wi-Fi bars; the USB glyph is derived from Pictogrammers Material Design Icons. Page text uses lowercase where appropriate, separates labels and values with colons, and shows the active station or AP SSID plus channel.
- To reduce OLED aging, inactivity dims contrast to `1` after five minutes and switches the panel off after ten minutes. The first debounced button press restores contrast `127` and wakes without navigating.
- A missing/unresponsive display is nonfatal; the task remains read-only and never acquires serial writer ownership.
- Target-hardware validation passed for the four pages, fixed active-only status icons, lowercase layout, diagnostics hold, dim/off/wake behavior, all available concurrent client interfaces, UART0 recovery, and serial traffic from 9600 through 230400 baud.
4. **Phase 7D — Local controls — Complete**
- A shallow local `Controls` menu directly invokes public serial-service, Wi-Fi, HTTPS, SSH, broker, display, and restart APIs; it never parses or injects CLI text.
- The menu provides serial start/stop, Wi-Fi start/stop/reconnect/next-profile, HTTPS start/stop, SSH start/stop, emergency current-writer revocation, display off, and reboot. `WiFi:next profile` queues a rotation to the enabled profile after the currently active one in priority order, wrapping safely; profile configuration and credentials remain unavailable to the UI. The menu deliberately excludes serial configuration editing, Wi-Fi profile/AP changes, host-key/certificate changes, I²C scans, and assignment of the writer to another client.
- A visible confirmation screen and one continuous two-second Select hold are required for service stops, Wi-Fi reconnect, Wi-Fi next-profile, writer revocation, and reboot. The confirmation times out after 30 seconds; previous/back cancels. A wake press is consumed and cannot navigate or confirm an action.
- Wi-Fi lifecycle results report a queued request rather than falsely claiming an asynchronous transition has completed. HTTPS/SSH start requests require a connected station or active AP. The current writer is only ever force-released to no writer; the UI is not a broker client and cannot acquire or assign a writer lease.
- Target-hardware validation passed for menu navigation and timeout behavior, controls and asynchronous results, two-second confirmations and cancellation, Wi-Fi next-profile progression/wrap, chord rejection, wake-press suppression, and preservation of UART0 plus transport recovery.
5. **Phase 7E — Reliability, persistence, and documentation — Implemented; validation pending**
- At startup, a bounded five-second OLED-only identity animation renders a compact monochrome, right-oriented derivative of the project logo in the blue panel: its upright `>_` terminal remains readable, while both USB and serial cable ends enter from the left. The full device name scrolls through the yellow panel. A missing or failing OLED skips the animation without delaying recovery services further.
- A versioned `local_ui` NVS configuration makes the dim and display-off inactivity delays independently configurable from 0 through 86400 seconds. Zero disables a transition; defaults remain 300/600 seconds. UART0 `display` commands provide status, RAM edits, save/load, defaults, and atomic reset behavior.
- A button held for ten seconds is quarantined until its debounced release, after which it rearms. Quarantined inputs no longer keep a chord latched or block the other controls. A confirmation hold can execute at most once.
- Dim/off wake and missing-display recovery now occur only on a new debounced press edge. A held or stuck input cannot continuously probe an absent OLED, flood logs, or indefinitely refresh the inactivity timer; the wake gesture remains consumed.
- Dirty framebuffer commits have a 500 ms scheduling budget in addition to each bounded 250 ms I²C transaction. A failed frame marks the panel unavailable, while serial, broker, network, USB, and UART0 services remain independent. Safely reconnecting the OLED and pressing a button requests one bounded reprobe.
- Wi-Fi manager queue drops now activate the persistent yellow alert slot and remain observable through Wi-Fi counters. Local action errors continue to be reported directly without blocking queue insertion.
- Pending target-hardware validation: configuration persistence/disable semantics, absent and reattached display behavior, I²C NACK/timeout handling, each stuck button and rearm path, repeated actions/queue-error indication, and concurrent USB CDC, WebSocket, SSH, serial, and UART0 operation during faults.
Completion requires electrical validation on the selected module, correct operation with all current transports, bounded display/button failure behavior, safe action confirmation, no unexplained serial or broker loss, and documented UART0 recovery.
### Phase 8 — Role-based users and administrative access
Replace the single shared network credential with a bounded, persistent user system. Accounts have one of two authorization roles: `user` receives the currently implemented authenticated serial/status experience, while `admin` additionally receives administrative command and user-management capabilities. UART0 remains the physical recovery and bootstrap authority.
Implementation sequence:
1. **Phase 8A — User database and UART0 administration — Implemented; validation pending**
- A versioned `user_db` NVS blob holds at most eight accounts with unique lowercase usernames, `user`/`admin` roles, random account IDs, per-account authentication generations, and fixed storage bounds. The final administrator cannot be deleted or demoted.
- Passwords use random 16-byte salts and PBKDF2-HMAC-SHA256 verifiers rather than recoverable plaintext. UART0 provides bounded no-echo entry, confirmation, and one-time 24-character generated passwords for bootstrap, create, and password-change operations. Valid authentication attempts perform one real or dummy PBKDF2 outside the database mutex and revalidate the account generation before returning a principal.
- Each account accepts up to three bounded OpenSSH public keys. Initial import supports Ed25519 and ECDSA P-256, validates key structure and P-256 points, rejects a key already assigned to any account, and exposes only key type plus SHA-256 fingerprint in snapshots and status output.
- On first boot after upgrade, the existing shared `admin` network credential is transactionally imported as a role-`user` account; it is never silently elevated. `user bootstrap` sets a new password and promotes that account to `admin`. Until bootstrap, legacy web credential rotation/reset synchronizes the imported verifier and boot reconciliation repairs an interrupted second NVS commit. After bootstrap, Phase 8A deliberately leaves the legacy HTTPS/SSH credential separate until Phase 8B switches network authentication to the common database.
- `user recover --force` remains registered even when a malformed or incompatible user blob prevents normal initialization. From physical UART0 it explicitly replaces only the user-database blob with a role-`user` account derived from the current legacy network credential; it never automatically erases shared NVS.
- NVS remains unencrypted. Verifiers improve password-at-rest handling, but offline guessing remains possible and append-oriented flash may retain historical plaintext legacy credentials until the partition or flash is physically erased.
- Pending target-hardware validation covers migration and reboot persistence, CRUD/capacity/final-admin invariants, hidden and generated passwords, malformed/duplicate/capacity-limited key imports, legacy-rotation reconciliation, explicit recovery, NVS failures, and regression of existing HTTPS/SSH access.
2. **Phase 8B — Role-aware HTTPS and SSH authentication — Planned**
- Authenticate HTTPS and SSH passwords through the common user database and retain a secret-free principal containing account ID, role, authentication method, and credential generation.
- Add SSH public-key authentication while retaining password authentication. wolfSSH authorizes the stored username/key pair and remains responsible for cryptographic signature verification; unsigned key probes never count as completed authentication.
- Bind WebSocket tickets and active SSH/WebSocket sessions to account generations so password, role, key, disable, or delete operations can revoke only the affected account.
- Preserve the current serial terminal, status, writer/observer behavior, and hidden administrative controls for normal `user` accounts.
3. **Phase 8C — SSH administrative shell — Planned**
- Route authenticated `admin` SSH shell sessions to the same registered administrative command set as UART0, without creating a broker client. Normal users continue to receive the existing broker-backed serial stream.
- Serialize command parsing safely because ESP-IDF console internals are process-global. Use bounded per-session input/output queues and a separate command worker; only the SSH owner task may call wolfSSH APIs.
- Keep SFTP, SCP, `exec`, forwarding, subsystems, and unauthenticated shells disabled.
4. **Phase 8D — Web user administration — Planned**
- Add an admin-only user-management interface and typed, bounded APIs for account CRUD, roles, password generation/change, SSH-key management, and revocation. Never expose a generic HTTP endpoint that executes arbitrary CLI text.
- Hide administrative navigation and controls for normal users, and enforce every authorization decision server-side so hidden UI is not treated as a security boundary.
- Preserve the existing normal terminal interface. Use strict origin/CSRF protections for mutations, secret-safe JSON encoding, one-time display of generated passwords, and no-store responses for administrative material.
Completion requires migration and power-loss recovery tests, final-admin protection, malformed credential/key rejection, password and key login for both roles, targeted session revocation, concurrent normal/admin SSH operation, hidden and server-rejected user-level web administration, and continued UART0 recovery.
### Phase 9 — Security and production hardening
Harden stored credentials, boot integrity, update trust, failure diagnostics, and dependency maintenance. This phase must be staged carefully because some ESP32 eFuse operations are irreversible.
Planned work:
- Define development, test, and production security profiles.
- Enable and validate NVS encryption for Wi-Fi, HTTPS, and SSH material.
- Evaluate flash encryption and PSRAM encryption for the target hardware and threat model.
- Enable secure boot with a documented signing-key and recovery process.
- Define secret-safe core-dump handling; do not expose credentials or session material in diagnostics.
- Audit key and session-material zeroization across application, mbedTLS, wolfSSL, and wolfSSH allocations.
- Add authentication throttling, lockout/backoff, and security-event counters where appropriate.
- Review TLS/SSH algorithms, certificate policy, password policy, and browser security headers.
- Review current wolfSSL/wolfSSH and ESP-IDF security releases instead of treating integration versions as permanent pins.
- Recheck all third-party licenses and preserve source/license notices.
- Document provisioning, key rotation, factory reset, backup, recovery, and device decommissioning.
Security features must be validated first on expendable hardware before any irreversible production configuration is recommended.
### Phase 10 — Authenticated OTA and rollback
Use the existing dual 4 MiB application slots and `otadata` partition to add safe firmware updates.
Planned work:
- Accept only authenticated, integrity-checked firmware images compatible with the selected secure-boot policy.
- Support an update path that does not expose a plaintext management endpoint.
- Stream downloads with bounded RAM use and explicit progress/error reporting.
- Preserve serial, Wi-Fi, HTTPS, and SSH configuration across successful updates.
- Mark new firmware pending until a post-boot health check succeeds.
- Roll back automatically after failed boot or health confirmation.
- Define power-loss behavior for every update stage.
- Keep UART0 recovery and wired re-flashing documented and functional.
- Add version/compatibility checks and reject accidental downgrade unless an explicit policy allows it.
OTA is complete only after successful update, interrupted-update, invalid-image, rollback, and configuration-persistence tests on hardware.
### Phase 11 — BLE
Evaluate and, if resource limits permit, add BLE as another bounded transport or provisioning path.
Planned work:
- Decide whether BLE is primarily a serial transport, a provisioning interface, or both.
- Require authenticated pairing/bonding appropriate to the device threat model.
- Integrate serial access through the existing broker rather than bypassing writer ownership.
- Preserve binary transparency through explicit framing and MTU-aware partial transfers.
- Bound connections, queues, retries, and advertising behavior.
- Measure coexistence with 2.4 GHz Wi-Fi, HTTPS, WebSocket, SSH, USB CDC, and UART service.
- Store bond/provisioning data under the hardened secret-storage policy.
- Provide UART0 controls and a physical recovery path for clearing BLE state.
BLE remains subordinate to stable Wi-Fi and serial operation; it should be omitted if coexistence or memory costs cannot be bounded acceptably.
### Phase 12 — Advanced network integration
These features are candidates, not current commitments:
- mDNS advertisement for the certificates device-specific `.local` name and selected services.
- Enterprise Wi-Fi support, subject to credential-storage and certificate-validation design.
- IPv6 behavior and diagnostics beyond the current basic support.
- WireGuard feasibility evaluation, including RAM, CPU, licensing, key storage, routing, and recovery impact.
The device is not intended to become a general-purpose router. Captive-portal interception, unauthenticated DNS redirection, NAPT, and a plaintext serial listener remain out of scope unless the project requirements are explicitly revised.
### Phase 13 — Optional filesystem-backed features
The `storage` partition is reserved but not currently mounted. Possible uses must be justified individually:
- LittleFS-backed web assets to decouple large static files from the application image.
- Bounded diagnostic logs with explicit retention and secret-redaction rules.
- Import/export of non-secret configuration.
- Optional user files needed by later administration features.
Before enabling storage, define corruption recovery, wear limits, quotas, atomic update behavior, compatibility across OTA slots, and whether encryption is required. Serial operation and recovery must not depend on a mountable filesystem.
## Cross-phase release gates
Every phase should satisfy the following before being marked complete:
1. A clean release build for the ESP32-S3 N16R8 target.
2. No new compiler or project diagnostics attributable to the change.
3. Focused automated tests where practical and documented hardware tests where hardware behavior is involved.
4. UART0, native USB CDC, and previously completed network transports still operate.
5. Broker writer/observer semantics and binary transparency remain intact.
6. Failure, disconnect, stop/start, reboot, and stale-session cleanup paths are exercised.
7. Runtime memory, stack, socket, and queue bounds are measured under maximum supported concurrency.
8. Secrets remain absent from ordinary status output and logs.
9. [Command reference](command_reference.md), [Hardware wiring](wiring.md), electrical tests, and this roadmap are updated as applicable.
10. New dependencies receive security, maintenance, and GPL-3.0 compatibility review.
## Explicitly deferred work
The following are not implemented merely because flash partitions or library support exist:
- NVS, flash, or PSRAM encryption.
- Secure boot or production eFuse provisioning.
- OTA download, image confirmation, or rollback policy.
- Core-dump collection or secret-safe core-dump processing.
- Filesystem mounting.
- SFTP, SCP, SSH `exec`, forwarding, or subsystems.
- General routing, NAPT, captive-portal interception, or unauthenticated serial access.
Deferring these features is intentional: each changes the security model, recovery behavior, or bounded-resource assumptions and therefore requires its own design and validation gate.