Compare commits
2
Commits
archive/phase-9
...
devel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f628a4098 | ||
|
|
b9653426e4 |
@@ -14,7 +14,7 @@ ESP32-S3 firmware for a secure, multi-transport RS-232 adapter. It operates one
|
|||||||
|
|
||||||
## Development status
|
## Development status
|
||||||
|
|
||||||
Hardware characterization, serial/USB/Wi-Fi/HTTPS/SSH and local display/control are implemented and hardware-validated. **Phase 8 role-based users and administration is complete:** 8A–8C were target-hardware validated and the user explicitly signed off tested firmware at **8D.22 (2026-09-13)**. See the [roadmap](docs/roadmap.md#phase-8--role-based-users-and-administrative-access--complete) and [acceptance evidence](docs/web_administration_acceptance.md). Very low internal/DMA lifetime minima remain a nonblocking headroom follow-up, not an approved reserve. Phase 9 hardening begins only on a separate request.
|
Hardware characterization, serial/USB/Wi-Fi/HTTPS/SSH and local display/control are implemented and hardware-validated. **Phase 8 role-based users and administration is complete:** 8A–8C were target-hardware validated and the user explicitly signed off tested firmware at **8D.22 (2026-09-13)**. See the [roadmap](docs/roadmap.md#phase-8--role-based-users-and-administrative-access--complete) and its [consolidated acceptance evidence](docs/roadmap.md#phase8-acceptance-evidence). Very low internal/DMA lifetime minima remain a nonblocking headroom follow-up, not an approved reserve. The reduced Phase 9 focuses on intermittent trusted-network use, standard no-dump/silent-panic defaults and a short [operational checklist](docs/security_operations.md), without dependency patches or upgrades. **The reduced Phase 9 is complete by user sign-off on 2026-09-18.** The user waived a new device check based on prior Phase 8 validation; application code is unchanged, but crash-diagnostic defaults changed. No new hardware or panic-test pass is claimed.
|
||||||
|
|
||||||
### Browser administration
|
### Browser administration
|
||||||
|
|
||||||
@@ -31,7 +31,8 @@ Keep UART0 ready for administrative recovery and native USB for network-independ
|
|||||||
- [Hardware wiring](docs/wiring.md): hardware profile, GPIO assignments, connector guidance, and safety notes.
|
- [Hardware wiring](docs/wiring.md): hardware profile, GPIO assignments, connector guidance, and safety notes.
|
||||||
- [Electrical tests](docs/electrical_tests.md): OLED/buttons, MAX3243, UART loopback, and session-broker verification procedures.
|
- [Electrical tests](docs/electrical_tests.md): OLED/buttons, MAX3243, UART loopback, and session-broker verification procedures.
|
||||||
- [Role-based user database and UART0 administration](docs/user_administration_tests.md): user provisioning and administration, HTTPS/SSH authentication, session revocation, and reusable integrated web-administration regression procedures (not execution evidence).
|
- [Role-based user database and UART0 administration](docs/user_administration_tests.md): user provisioning and administration, HTTPS/SSH authentication, session revocation, and reusable integrated web-administration regression procedures (not execution evidence).
|
||||||
- [Web administration](docs/web_administration.md): current bounded API/owner and recovery contracts; [acceptance evidence](docs/web_administration_acceptance.md) records sign-off and telemetry limits.
|
- [Web administration](docs/web_administration.md): current bounded API/owner and recovery contracts; [roadmap acceptance evidence](docs/roadmap.md#phase8-acceptance-evidence) records sign-off and telemetry limits.
|
||||||
|
- [Security operations](docs/security_operations.md): trusted-network use, credentials, identity verification, shutdown and recovery; physical-extraction limits and lightweight upstream maintenance.
|
||||||
- [Command reference](docs/command_reference.md): UART0/admin-SSH administration, serial, broker, USB, Wi-Fi, mDNS, web, SSH, and diagnostic commands.
|
- [Command reference](docs/command_reference.md): UART0/admin-SSH administration, serial, broker, USB, Wi-Fi, mDNS, web, SSH, and diagnostic commands.
|
||||||
|
|
||||||
## Flash partition layout
|
## Flash partition layout
|
||||||
@@ -71,6 +72,8 @@ This removes saved serial configuration and all other flash contents. The firmwa
|
|||||||
pio run
|
pio run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The small Phase 9 sets `CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y` and `CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT=y` in `sdkconfig.defaults`. An existing generated `sdkconfig.esp32-s3-devkitc-1-n16r8` can retain earlier selections: check its resolved values after configuration, or change them using `pio run --target menuconfig`. Defaults alone do not enforce existing configurations. Silent panic reboot removes panic register/backtrace output; ordinary logs remain. No existing flash contents are erased, and stored secrets remain unencrypted.
|
||||||
|
|
||||||
## Upload and monitor
|
## Upload and monitor
|
||||||
|
|
||||||
Connect the board's **USB-to-UART** port for firmware upload and the UART0 development console, then run:
|
Connect the board's **USB-to-UART** port for firmware upload and the UART0 development console, then run:
|
||||||
@@ -88,7 +91,7 @@ Serial, Wi-Fi, and mDNS hostname edits remain in RAM until explicitly saved with
|
|||||||
|
|
||||||
## Security notes
|
## Security notes
|
||||||
|
|
||||||
The HTTPS interface uses a device-specific self-signed certificate and a same-origin login page with bounded server-side cookie sessions; HTTP Basic is no longer accepted. Open `/` or `/login`, sign in with a user-database password, and use **Sign out** before switching accounts. Four sessions have a one-hour absolute lifetime, including active serial connections; logout closes only that session's serial access. Login is globally limited to five credential verifications per 60 seconds, with explicit capacity/backoff errors. Direct-IP and mDNS access use separate host-only Secure/HttpOnly/SameSite=Strict cookies. Non-browser clients also require cookies, strict Origin and CSRF for mutations rather than Basic credentials. There is no plaintext HTTP or TCP serial listener. SSH accepts role-based passwords and authorized Ed25519/ECDSA P-256 public keys. User passwords are stored as salted PBKDF2-HMAC-SHA256 verifiers, but the HTTPS private key, SSH private key, and Wi-Fi credentials remain recoverable from unencrypted application-owned NVS blobs. Offline password guessing and stale append-oriented flash copies also remain possible. The reserved `nvs_key` partition does not enable encryption. Do not treat this firmware as resistant to physical flash or RAM extraction until the planned hardening work is complete.
|
The HTTPS interface uses a device-specific self-signed certificate and a same-origin login page with bounded server-side cookie sessions; HTTP Basic is no longer accepted. Open `/` or `/login`, sign in with a user-database password, and use **Sign out** before switching accounts. Four sessions have a one-hour absolute lifetime, including active serial connections; logout closes only that session's serial access. Login is globally limited to five credential verifications per 60 seconds, with explicit capacity/backoff errors. Direct-IP and mDNS access use separate host-only Secure/HttpOnly/SameSite=Strict cookies. Non-browser clients also require cookies, strict Origin and CSRF for mutations rather than Basic credentials. There is no plaintext HTTP or TCP serial listener. SSH accepts role-based passwords and authorized Ed25519/ECDSA P-256 public keys. User passwords are stored as salted PBKDF2-HMAC-SHA256 verifiers, but the HTTPS private key, SSH private key, and Wi-Fi credentials remain recoverable from unencrypted application-owned NVS blobs. Offline password guessing and stale append-oriented flash copies also remain possible. The reserved `nvs_key` partition does not enable encryption. This firmware is not resistant to physical flash or RAM extraction; the completed reduced Phase 9 deliberately does not add that protection.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
@@ -98,4 +101,4 @@ This project is licensed under the [GNU General Public License version 3 only](L
|
|||||||
|
|
||||||
Missing user storage is persisted as an empty database; no shared credential is imported or synchronized. Existing valid v1 user records retain their accounts, roles, IDs, verifiers and keys without a schema change. HTTPS `web_sec/material` upgrades valid 1,392-byte v1 storage to 1,340-byte TLS-only v2, retaining exact certificate/key DER, fingerprint and generation, and committing before publication. Invalid records or migration failures fail closed rather than triggering fallback replacement. `web certificate rotate --force` remains available; `web reset --force` replaces TLS identity only, not users.
|
Missing user storage is persisted as an empty database; no shared credential is imported or synchronized. Existing valid v1 user records retain their accounts, roles, IDs, verifiers and keys without a schema change. HTTPS `web_sec/material` upgrades valid 1,392-byte v1 storage to 1,340-byte TLS-only v2, retaining exact certificate/key DER, fingerprint and generation, and committing before publication. Invalid records or migration failures fail closed rather than triggering fallback replacement. `web certificate rotate --force` remains available; `web reset --force` replaces TLS identity only, not users.
|
||||||
|
|
||||||
**Downgrade warning:** older v1-only firmware cannot read v2 HTTPS material. Logical NVS replacement is not a secure flash wipe; historical plaintext credentials can remain in flash. This cleanup requires no factory/partition erase. See [implementation and evidence limits](docs/legacy_credential_removal.md); final integration build evidence is pending.
|
**Downgrade warning:** older v1-only firmware cannot read v2 HTTPS material. Logical NVS replacement is not a secure flash wipe; historical plaintext credentials can remain in flash. This cleanup requires no factory/partition erase. See [consolidated compatibility and evidence limits](docs/roadmap.md#phase8-legacy-credential-compatibility); Phase 8 acceptance is recorded there.
|
||||||
|
|||||||
@@ -231,4 +231,4 @@ Hardware diagnostics are synchronous console commands. RS-232 tests own the phys
|
|||||||
|
|
||||||
`user_database_init(load_result)` has no credential input. Missing storage is persisted empty; `user_database_recover_empty()` is the unavailable-only destructive recovery API. Valid v1 user bytes load without rewriting or account changes. The private `v1_admin_marker` retains its byte position and is derived from administrator count during mutations; it is not a public bootstrap state, new role or schema change. No user migration/bootstrap/synchronization API remains.
|
`user_database_init(load_result)` has no credential input. Missing storage is persisted empty; `user_database_recover_empty()` is the unavailable-only destructive recovery API. Valid v1 user bytes load without rewriting or account changes. The private `v1_admin_marker` retains its byte position and is derived from administrator count during mutations; it is not a public bootstrap state, new role or schema change. No user migration/bootstrap/synchronization API remains.
|
||||||
|
|
||||||
`web_security` owns TLS only. A private reader validates 1,392-byte v1 `web_sec/material`, copies exact key/certificate DER, fingerprint and generation into 1,340-byte v2, commits, then publishes. Temporary v1 credential-bearing input is wiped; no public legacy credential type/getter/rotation remains. Malformed/unknown records and read/validation/commit failures fail closed, with no fallback regeneration or overwrite of rejected records. Missing material may be generated; explicit reset replaces TLS only. Downgrade to v1-only firmware is incompatible. Logical NVS replacement is not secure flash erasure. Contracts/evidence: [legacy compatibility](../legacy_credential_removal.md).
|
`web_security` owns TLS only. A private reader validates 1,392-byte v1 `web_sec/material`, copies exact key/certificate DER, fingerprint and generation into 1,340-byte v2, commits, then publishes. Temporary v1 credential-bearing input is wiped; no public legacy credential type/getter/rotation remains. Malformed/unknown records and read/validation/commit failures fail closed, with no fallback regeneration or overwrite of rejected records. Missing material may be generated; explicit reset replaces TLS only. Downgrade to v1-only firmware is incompatible. Logical NVS replacement is not secure flash erasure. Contracts/evidence: [legacy compatibility](../roadmap.md#phase8-legacy-credential-compatibility).
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ This is a semantic map, not a complete file inventory. Start here, then read the
|
|||||||
- Dependencies: every subsystem initializer
|
- Dependencies: every subsystem initializer
|
||||||
- Lifecycle constraint: optional display/network failures should not remove UART0 administrative recovery or USB UART1 access; the custom administration frontend starts only after command registration.
|
- Lifecycle constraint: optional display/network failures should not remove UART0 administrative recovery or USB UART1 access; the custom administration frontend starts only after command registration.
|
||||||
|
|
||||||
|
## Small Phase 9 operating baseline
|
||||||
|
|
||||||
|
- `sdkconfig.defaults` explicitly selects no core dumps and silent panic reboot; existing generated configs can override defaults. README documents verification. No dependency overlays, custom crypto policy or version changes are part of this phase.
|
||||||
|
- User accepted the reduced Phase 9 on 2026-09-18 and waived a new hardware check; this is not a claim of a new hardware-test pass.
|
||||||
|
- [Operational checklist](../security_operations.md) and [scope/acceptance](../roadmap.md#phase-9--security-and-production-hardening): intermittent trusted-network use, unchanged authentication/recovery, no physical-extraction protection. Keep upgrades separate and do not restore the abandoned extensive patchset.
|
||||||
|
|
||||||
## Secure randomness
|
## Secure randomness
|
||||||
|
|
||||||
**Responsibility:** provide the sole project-owned, mutex-serialized application DRBG, seeded before Wi-Fi/radio use.
|
**Responsibility:** provide the sole project-owned, mutex-serialized application DRBG, seeded before Wi-Fi/radio use.
|
||||||
@@ -64,7 +70,7 @@ This is a semantic map, not a complete file inventory. Start here, then read the
|
|||||||
- Files: `src/web_server.{h,c}`, `src/web_serial_transport.{h,c}`, `src/web_ui.{h,c}`, `src/web_console.{h,c}`
|
- Files: `src/web_server.{h,c}`, `src/web_serial_transport.{h,c}`, `src/web_ui.{h,c}`, `src/web_console.{h,c}`
|
||||||
- Ordinary HTTPS idle cleanup: `src/web_httpd_idle.{c,h}`, owner sweep in `web_httpd_adapter.{c,h}`, lifecycle/TLS composition in `web_server.c`; `tests/web_httpd_idle/run.py`. Independent of diagnostics/optional transports: 15-second observed idle, one-second timer/one queued probe, six rows, actual WS/async/pending exemptions, safe current-owner shutdown and stop/restart fencing. No LRU/socket/timeout/stack increase. SDK queue/owner-delay and regression contract: `docs/https_idle_cleanup.md`.
|
- Ordinary HTTPS idle cleanup: `src/web_httpd_idle.{c,h}`, owner sweep in `web_httpd_adapter.{c,h}`, lifecycle/TLS composition in `web_server.c`; `tests/web_httpd_idle/run.py`. Independent of diagnostics/optional transports: 15-second observed idle, one-second timer/one queued probe, six rows, actual WS/async/pending exemptions, safe current-owner shutdown and stop/restart fencing. No LRU/socket/timeout/stack increase. SDK queue/owner-delay and regression contract: `docs/https_idle_cleanup.md`.
|
||||||
- Independent throughput diagnostics: `web_serial_transport.{c,h}` owns two fixed per-slot binary-TX aggregates and epoch fences; `web_console.c` exposes default-disabled `web performance enable|disable|show|clear`. Queue-entry/callback-entry, synchronous-send and completion/drain-return estimates, not peer receipt or scheduler-only latency. `tests/web_serial_performance/run.py`; resource/evidence limits and UART0 paired capture: `docs/web_throughput_diagnostics.md`.
|
- Independent throughput diagnostics: `web_serial_transport.{c,h}` owns two fixed per-slot binary-TX aggregates and epoch fences; `web_console.c` exposes default-disabled `web performance enable|disable|show|clear`. Queue-entry/callback-entry, synchronous-send and completion/drain-return estimates, not peer receipt or scheduler-only latency. `tests/web_serial_performance/run.py`; resource/evidence limits and UART0 paired capture: `docs/web_throughput_diagnostics.md`.
|
||||||
- Storage compatibility: `user_database` persists missing storage empty and preserves valid v1 user bytes; private derived `v1_admin_marker`, no public bootstrap/migration/sync APIs. `web_security` privately migrates v1 1392-byte material to TLS-only v2 1340-byte material, exact identity/generation retained, commit before publish, fail closed without fallback overwrite. Credential commands removed; user generated passwords and TLS rotation remain. Contracts, downgrade and evidence limits: `docs/legacy_credential_removal.md`.
|
- Storage compatibility: `user_database` persists missing storage empty and preserves valid v1 user bytes; private derived `v1_admin_marker`, no public bootstrap/migration/sync APIs. `web_security` privately migrates v1 1392-byte material to TLS-only v2 1340-byte material, exact identity/generation retained, commit before publish, fail closed without fallback overwrite. Credential commands removed; user generated passwords and TLS rotation remain. Contracts, downgrade and evidence limits: [legacy compatibility](../roadmap.md#phase8-legacy-credential-compatibility).
|
||||||
- Security files: `src/web_security.{h,c}`, `src/web_cookie_auth.{h,c}`, `src/web_session_store.{h,c}`, `src/web_auth_parse.{h,c}`. Private IDF boundary: `src/web_httpd_adapter.{h,c}`.
|
- Security files: `src/web_security.{h,c}`, `src/web_cookie_auth.{h,c}`, `src/web_session_store.{h,c}`, `src/web_auth_parse.{h,c}`. Private IDF boundary: `src/web_httpd_adapter.{h,c}`.
|
||||||
- HTTP policy/UI: `web_cookie_auth` + `web_auth_parse` enforce bounded cookie/Origin/CSRF/admin admission; `web_login_ui.{c,h}` serves login, `web_ui.c` owns session-fenced Serial/Admin/Settings and shared quick controllers. Tests: `tests/web_cookie_auth/run.py` (domain variants), `tests/web_auth_parse/run.py`, `tests/web_login_ui/run.py`, `tests/web_ui_session/run.py`.
|
- HTTP policy/UI: `web_cookie_auth` + `web_auth_parse` enforce bounded cookie/Origin/CSRF/admin admission; `web_login_ui.{c,h}` serves login, `web_ui.c` owns session-fenced Serial/Admin/Settings and shared quick controllers. Tests: `tests/web_cookie_auth/run.py` (domain variants), `tests/web_auth_parse/run.py`, `tests/web_login_ui/run.py`, `tests/web_ui_session/run.py`.
|
||||||
- Admission diagnostics: `web_diagnostics.{c,h}`, `tests/web_diagnostics/run.py`; six post-TLS records/32-event opt-in ring, no HTTPD off-owner inspection. [Contract](../web_admission_diagnostics.md).
|
- Admission diagnostics: `web_diagnostics.{c,h}`, `tests/web_diagnostics/run.py`; six post-TLS records/32-event opt-in ring, no HTTPD off-owner inspection. [Contract](../web_admission_diagnostics.md).
|
||||||
|
|||||||
+21
-34
@@ -1,44 +1,31 @@
|
|||||||
# Current project state
|
# Current project state
|
||||||
|
|
||||||
Working memory, not an implementation timeline. Source is authoritative; begin with [code map](code-map.md), then [architecture](architecture.md) and [decisions](design-decisions.md).
|
Working memory, not an implementation timeline. Source is authoritative; begin with [code map](code-map.md), [architecture](architecture.md) and [decisions](design-decisions.md).
|
||||||
|
|
||||||
## Web popup cosmetics — 2026-09-14
|
## Phase 10 plan — simplified by user, 2026-09-18
|
||||||
|
|
||||||
- `src/web_ui.c`: contextual buttons now occupy entire status cards; bounded grid columns and clipped/ellipsized values prevent narrow-window overflow. Quick panels preserve the visible terminal title, admin toolbar and selected-view indication; full-page promotion retains drafts and restores Settings presentation.
|
- Plan only: admin HTTPS file picker/upload for a locally built ESP32-S3 application firmware.bin, existing auth/same-origin/CSRF, standard ESP-IDF OTA APIs and bounded streaming into inactive4MiBslot, SDK image/target/size validation before boot selection and controlled reboot.
|
||||||
- Quick panels hide full-page explanations and duplicate detail readouts while preserving live status, errors and operation results. Wi-Fi exposes configured profile selection/enabled state and AP policy, plus Apply/Save/Refresh/Result; empty profile slots and advanced editors remain full-page-only. Profile selection is an editing target, not a direct-connect command; existing backend operations are unchanged.
|
- Preserve NVS and all other data partitions; only inactiveapp/otadata writes. No wholeflash/bootloader/partitiontable uploads or erase. Storage bytes preserved, but user-selected firmware must remain schema-compatible. Wired USB-to-UART recovery if a valid image is nonfunctional.
|
||||||
- Validation: all 161 UI behavior groups and C/HTML checks PASS; 36 Chromium geometry fixtures PASS at 320/600/900/1200px. `pio run` PASS (94,212 B linked RAM / 1,830,329 B flash). No generated-asset regeneration, upload, erase or hardware validation. Updated regression coverage in `tests/web_ui_session/`.
|
- Explicitly no signature/key infrastructure, antirollback/version rules, automatic rollback/healthconfirmation, remote downloadservice or dependency patches. This replaces the old broader OTA plan, not an implementation authorization. [Roadmap](../roadmap.md#phase-10--simple-admin-web-firmware-upload) is authoritative.
|
||||||
|
|
||||||
## Focused cleanup / PSRAM review — 2026-09-13
|
## Accepted state — 2026-09-18
|
||||||
|
|
||||||
- User-authorized post-acceptance code review: removed superseded `admin_ssh_console_open()` SSH-only wrapper; production already uses available-slot admission. Updated adapter regression to actual production entry. Wrapper was already linker-discarded: no binary saving attributed to removal.
|
- **Reduced Phase 9 complete by explicit user sign-off.** User waived a new whole-phase device check based on prior Phase 8 validation. Application code was unchanged, but no-core-dump/silent-panic defaults changed. Do not record the waived check as executed or claim a new panic/hardware pass.
|
||||||
- Moved ping queue payload4,200 B and public user snapshot2,156 B to lazy PSRAM-only lifetime allocations, no fallback. Queue control/internal locks unchanged; allocation failure affects only ping or status/list/show, not UART0 registration/mutations/recovery. Snapshot fully wiped on success/error. No serial hot-path, stacks, CPU, queue bounds or external-BSS config changes.
|
- Small scope: standard `sdkconfig.defaults` options, source-reviewed [operational checklist](../security_operations.md), README/roadmap guidance. No dependency patches, crypto policy replacement, allocator hooks, SDK migration, encryption, eFuse or partition changes. User abandoned the extensive earlier Phase 9 and restored baseline `f40c09c`; do not resurrect it.
|
||||||
- Baseline pio PASS23.79s100,556 RAM/1,828,573 flash. Final parent pio PASS22.11s **94,212 RAM/1,828,809 flash: −6,344 B linked internal RAM/+236 B flash**. Requested lazy PSRAM6,356 B plus allocator overhead; target pointer sizes4 B, controls84 B verified. This is not measured runtime-minimum improvement. CPU160 retained.
|
- Last actual build: normal `pio run` PASS on PlatformIO6.12.0 / IDF5.5.0 / original20241119 toolchains, **94,196 B linked RAM / 1,828,565 B flash**. Generated configuration confirmed no dumps/silent panic; compilation inputs had no abandoned overlays/crypto guard. Existing generated config already selected these options. Defaults do not override saved sdkconfig; README explains verification. No new build is implied by this documentation consolidation.
|
||||||
- Focused ping allocation/callback/end-capacity and accounts allocation/full-wipe/failure/retry tests PASS; console boundary/lifecycle/policy and SSH management/runtime suites PASS. Independent review found no actionable bugs and reran ping/accounts/boundary/diff PASS. Sanitizer linking unavailable (missing host runtimes), no sanitizer or hardware pass. No upload/erase/commit. Next target check: ping/user list/show repeatedly alongside NVS writes and full mix230400, collect serial/broker counters and memory before/after first allocations.
|
- **Phase 8 complete:** 8A–C target validated; explicit 8D.22 user acceptance on 2026-09-13. Completion/telemetry and legacy compatibility now live in [roadmap acceptance](../roadmap.md#phase8-acceptance-evidence) and [storage compatibility](../roadmap.md#phase8-legacy-credential-compatibility). Separate acceptance/legacy history documents removed; active [web contracts](../web_administration.md) and [regression procedures](../user_administration_tests.md) retained.
|
||||||
- Further audited opportunities, not implemented: OLED framebuffer1,024 B (internal I2C staging retained), local/remote completion scratch1,024 B each, optional web diagnostic ring2,816 B, remote console output payload8,192 B. Console rings need explicit secret-output wiping/lifecycle and admission-failure isolation; do not relocate mixed state wholesale. Leave authoritative user database, driver/DMA buffers, locks and task stacks internal. Global external-BSS enable is not surgical: it also changes SDK library placement.
|
- Post-acceptance baseline includes PSRAM-only ping payload/user snapshot allocations and refined web quick panels. Prior focused host/geometry/build checks passed; those are not additional hardware claims. Preserve lazy-allocation failure isolation and unchanged serial hot path.
|
||||||
|
|
||||||
## Accepted state — 2026-09-13
|
## Evidence limits and follow-ups
|
||||||
|
|
||||||
- **8D.22 explicitly signed off by the user:** “Yep, I tested the firmware thats a 8d.22 signoff.” The retained Phase 8D scope is complete; earlier per-slice pending target/review/integration gates are superseded. Roadmap already records 8A/B/C as complete and target-hardware validated, so **Phase 8 is complete**. Acceptance does not manufacture individual unreported test passes.
|
- Previously accepted combined binary WS send: CPU160MHz / 230400 baud full mix including browser admin. Latest recorded telemetry has very low internal/DMA lifetime minima (2,052/460 B); these are nonblocking headroom follow-ups, not approved reserves or proof of simultaneous allocation failure. Full table, capture workload and counter limits are preserved in the roadmap.
|
||||||
- [Roadmap](../roadmap.md#phase-8--role-based-users-and-administrative-access--complete) holds the completed-phase gist; [web administration](../web_administration.md) holds current API/owner/recovery contracts; [acceptance evidence](../web_administration_acceptance.md) holds the latest report and limits. The old plan/baseline/per-slice histories are consolidated, not archived as another timeline. Test READMEs now link directly to current contracts and evidence; obsolete forwarding notes were removed too.
|
- TLS `-0x004C` means generic NET_RECV_FAILED, not OOM. Historical authentication/admission symptoms do not establish a cause. Do not invent fault, soak, timing or power-loss passes.
|
||||||
- Final prior production build **PASS: 100,556 B linked RAM / 1,828,573 B flash, CPU 160 MHz**. No build/test/device execution is implied by this documentation update. The prior combined binary WebSocket-send fix was separately user-accepted at **160 MHz / 230400 baud with full mix including browser admin**; preserve combined send and bounded failed-send isolation.
|
- Credentials remain unencrypted; old flash contents are not erased. Intermittent trusted-network operation reduces exposure, not physical-extraction risk. Upstream upgrades are separate deliberate tasks, not an endless local backport programme.
|
||||||
- Latest loaded capture: two serial WS, USB, two SSH roles with SSH serial writer; browser admin used then closed, not active in the capture. Internal/DMA/PSRAM free **31,508 / 23,752 / 8,136,624 B**, minima **2,052 / 460 / 8,065,972 B**, largest **18,432 / 18,432 / 7,995,392 B**; SSH minimum-free stack **15,028 B**. Full boot/loaded table is in acceptance evidence. Web send/queue/protocol and SSH IO errors zero; one SSH handshake failure/session revocation. Missing latest broker/serial counters prohibit an exact zero-drop inference.
|
- Phase 10 is planned, not automatically authorized by acceptance. No device operations, branch/reset, commits or dependency upgrades are part of this documentation task.
|
||||||
|
|
||||||
## Follow-ups, not acceptance blockers
|
## Contracts to preserve
|
||||||
|
|
||||||
- Extremely low internal/DMA lifetime minima warrant correlated transient-headroom investigation; overlapping capability pools and conservative/non-simultaneous region minima do not prove allocation failure. Numeric reserves, HTTPD/dispatcher stack margins, peak correlation and detailed soak/fault evidence remain unapproved/unreported. Do not reopen functional sign-off or invent a reserve threshold.
|
- One UART1 writer, isolated observers and binary transparency. UART0 is administrative recovery; native USB is network-independent UART1, not administration or uninterrupted reboot.
|
||||||
- SDK TLS `-0x004C` is generic NET_RECV_FAILED, not OOM. Two boot auth failures plausibly involve stale cookies, but causation is unconfirmed. Prior intermittent web admission issues and accepted idle cleanup do not justify claiming every admission failure fixed.
|
- Typed operations carry original-login IDs to the existing dispatcher. Owner-reserved generations fence stale/ABA changes; revocation/timeout does not cancel already admitted work. HTTPS commits before stop/restart; SSH stops before commit/restart; committed identity is not rolled back on lifecycle failure. Lost acknowledgement means uncertainty, not automatic replay.
|
||||||
- Real DNS/reannouncement, NVS power-loss, browser geometry/accessibility, individual fault cases and exact duration claims require explicit evidence if investigated; retained [regression procedures](../user_administration_tests.md) are not execution records.
|
- Preserve private IDF HTTPD version guards, one outstanding owner-work reservation through failed destruction, SSH context lifetime until slots retire, bounded queues/buffers and secret-free metadata. Canonical recovery survives conditional-token exhaustion.
|
||||||
- **Next: Phase 9 security/production hardening only if requested.** No source, configuration, test implementation, build, upload, erase, branch or commit is authorized by documentation consolidation.
|
- Removed Phase 8 scope stays removed: dedicated typed network diagnostics and ordinary browser-session/USB controls. No implicit browser-shell parity or browser identity reset/recovery/export.
|
||||||
|
|
||||||
## Scope and safety to retain
|
|
||||||
|
|
||||||
- 8D.15 dedicated typed network diagnostics was removed; shell diagnostics remain subject to frontend policy. Unimplemented 8D.19 ordinary browser-session/native-USB controls were removed; SSH settings remain. No implicit full browser-shell parity or browser identity reset/recovery/export.
|
|
||||||
- One UART1 broker writer, isolated observers and binary transparency. UART0 is administrative recovery; native USB is network-independent UART1, not administration or uninterrupted reboot.
|
|
||||||
- Typed operations carry original-login IDs to the existing dispatcher. Owner-reserved generations fence stale/ABA changes; later revocation/timeout does not cancel admitted work. HTTPS commits before stop/restart; SSH stops before commit/restart; committed identity never rolls back on lifecycle failure. Lost ACK/result means uncertainty, never automatic replay.
|
|
||||||
- Preserve private IDF HTTPD version guards, at-most-one owner-work reservations through failed destruction, retained SSH context until all slots retire, bounded queues/buffers and secret-free metadata. Canonical recovery survives conditional-token exhaustion.
|
|
||||||
|
|
||||||
## Previous documentation consolidation handoff
|
|
||||||
|
|
||||||
Initial Git status was clean. This task changes root `README.md`, `docs/` and five test-directory READMEs; executable source/tests/config/generated assets remain untouched. Independent documentation review checked acceptance scope, owner contracts and local links. It restored explicit pointer-backed HTTPD response-header lifetime and same-version SDK-patch audit warnings, updated test README links, and removed obsolete forwarding notes without reopening sign-off.
|
|
||||||
|
|
||||||
Validation completed: independent Python local-link/anchor audit PASS across 29 authored Markdown files (122 local links, 53 Markdown fragments); 213 authored source/test/document files checked with zero obsolete Phase 8D filename references. Earlier path audit resolved127 expanded navigation references. GPT logs, vendored/generated trees and remote URL fetching excluded. Twenty obsolete phase documents removed, with no forwarding stubs/archive dump. Git diff/scope checks confirm documentation-only changes. No firmware tests/build/device commands run.
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ Only constraints supported by implementation or current project documentation be
|
|||||||
|
|
||||||
**Rationale/evidence:** Serial, Wi-Fi, local UI, web security, users, and SSH security each validate schema/size and own their namespace. User/security mutations build and validate candidate state before committing it; security modules avoid silently replacing an established identity. The live user database remains internal while its 5,360-byte candidate is a persistent PSRAM-preferred allocation with internal fallback and is wiped after every transaction.
|
**Rationale/evidence:** Serial, Wi-Fi, local UI, web security, users, and SSH security each validate schema/size and own their namespace. User/security mutations build and validate candidate state before committing it; security modules avoid silently replacing an established identity. The live user database remains internal while its 5,360-byte candidate is a persistent PSRAM-preferred allocation with internal fallback and is wiped after every transaction.
|
||||||
|
|
||||||
**Consequence for future changes:** Add schema versions and transactional candidate validation. Do not overwrite unknown records automatically; provide explicit migration/reset behavior. Preserve the distinct persistence contracts: explicit save/load/default/reset for working configuration and per-blob commit-before-live-install for user and identity mutation. Keep candidate ownership mutex-local and wipe/free it on initialization or recovery failure. Recheck external-buffer staging in the flash/NVS implementation when upgrading from the pinned ESP-IDF 5.5 baseline. Legacy credential synchronization and reconciliation are removed. Missing user storage commits empty; valid user v1 bytes remain compatible, with private `v1_admin_marker` derived from admin count, not a public bootstrap contract. HTTPS v1 (1,392 bytes) migrates through a private validated reader to TLS-only v2 (1,340 bytes), preserving exact DER/fingerprint/generation and committing before publication. Failures fail closed without fallback regeneration or overwriting rejected records. See [legacy compatibility](../legacy_credential_removal.md).
|
**Consequence for future changes:** Add schema versions and transactional candidate validation. Do not overwrite unknown records automatically; provide explicit migration/reset behavior. Preserve the distinct persistence contracts: explicit save/load/default/reset for working configuration and per-blob commit-before-live-install for user and identity mutation. Keep candidate ownership mutex-local and wipe/free it on initialization or recovery failure. Recheck external-buffer staging in the flash/NVS implementation when upgrading from the pinned ESP-IDF 5.5 baseline. Legacy credential synchronization and reconciliation are removed. Missing user storage commits empty; valid user v1 bytes remain compatible, with private `v1_admin_marker` derived from admin count, not a public bootstrap contract. HTTPS v1 (1,392 bytes) migrates through a private validated reader to TLS-only v2 (1,340 bytes), preserving exact DER/fingerprint/generation and committing before publication. Failures fail closed without fallback regeneration or overwriting rejected records. See [legacy compatibility](../roadmap.md#phase8-legacy-credential-compatibility).
|
||||||
|
|
||||||
**Relevant files:** `src/serial_config.c`, `src/wifi_config.c`, `src/mdns_config.c`, `src/mdns_service.c`, `src/local_ui_config.c`, `src/web_security.c`, `src/user_database.c`, `src/ssh_security.c`
|
**Relevant files:** `src/serial_config.c`, `src/wifi_config.c`, `src/mdns_config.c`, `src/mdns_service.c`, `src/local_ui_config.c`, `src/web_security.c`, `src/user_database.c`, `src/ssh_security.c`
|
||||||
|
|
||||||
|
|||||||
@@ -189,4 +189,4 @@ UART0 and admin SSH use shared whole-line Tab completion. A unique/common prefix
|
|||||||
|
|
||||||
Follow the exact wiring in [Electrical tests](electrical_tests.md) before invoking diagnostics. The OLED must be powered from 3.3 V because module I²C pull-ups may connect to `VCC`; verify that all external pull-ups also terminate at 3.3 V. Display diagnostics probe the standard SSD1315-compatible 7-bit `0x3c`/`0x3d` addresses. The currently tested module acknowledges at `0x3c`, whose 8-bit write/read forms are `0x78`/`0x79`; an explicit `scan --force` is available only for the dedicated local-UI bus. Diagnostics initially run at 100 kHz and treat an absent display as nonfatal. RS-232 diagnostics that require UART1 refuse to use it until `serial stop` releases it. The RGB LED shows test state: blue idle, yellow/orange running, green passed, red failed.
|
Follow the exact wiring in [Electrical tests](electrical_tests.md) before invoking diagnostics. The OLED must be powered from 3.3 V because module I²C pull-ups may connect to `VCC`; verify that all external pull-ups also terminate at 3.3 V. Display diagnostics probe the standard SSD1315-compatible 7-bit `0x3c`/`0x3d` addresses. The currently tested module acknowledges at `0x3c`, whose 8-bit write/read forms are `0x78`/`0x79`; an explicit `scan --force` is available only for the dedicated local-UI bus. Diagnostics initially run at 100 kHz and treat an absent display as nonfatal. RS-232 diagnostics that require UART1 refuse to use it until `serial stop` releases it. The RGB LED shows test state: blue idle, yellow/orange running, green passed, red failed.
|
||||||
|
|
||||||
HTTPS storage migration preserves the exact TLS identity and commits TLS-only v2 before publication. Older v1-only firmware cannot read v2. Logical NVS replacement is not secure flash erasure; no factory erase is required. See [legacy removal](legacy_credential_removal.md).
|
HTTPS storage migration preserves the exact TLS identity and commits TLS-only v2 before publication. Older v1-only firmware cannot read v2. Logical NVS replacement is not secure flash erasure; no factory erase is required. See [legacy removal](roadmap.md#phase8-legacy-credential-compatibility).
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Bounded ordinary HTTPS idle retention
|
# Bounded ordinary HTTPS idle retention
|
||||||
|
|
||||||
Current owner/SDK contract. The user accepted idle cleanup as working; [overall acceptance](web_administration_acceptance.md) records current status and evidence limits. No individual unreported soak, fault or reserve result is inferred.
|
Current owner/SDK contract. The user accepted idle cleanup as working; [overall acceptance](roadmap.md#phase8-acceptance-evidence) records current status and evidence limits. No individual unreported soak, fault or reserve result is inferred.
|
||||||
|
|
||||||
## Evidence and scope
|
## Evidence and scope
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ Detach first prevents submissions, then waits at most one second for any submitt
|
|||||||
|
|
||||||
`tests/web_httpd_idle/run.py` exercises production lifecycle/sweep paths, installed SDK request cleanup, host socketpair/readiness/shutdown/fd reuse and deterministic TLS/timer/queue doubles. `tests/web_admin_transport/server_lifecycle.py` checks server composition. Historical host validation passed; these references do not claim a new run or real target scheduler/TLS timing.
|
`tests/web_httpd_idle/run.py` exercises production lifecycle/sweep paths, installed SDK request cleanup, host socketpair/readiness/shutdown/fd reuse and deterministic TLS/timer/queue doubles. `tests/web_admin_transport/server_lifecycle.py` checks server composition. Historical host validation passed; these references do not claim a new run or real target scheduler/TLS timing.
|
||||||
|
|
||||||
Bounded storage: six observation rows (144 bytes), one persistent timer (installed non-profiled layout 32 bytes before allocator overhead), lifecycle/generation flags and one reserved probe. SDK control UDP/mailbox allocation is transient and separate. No per-connection payload/task/stack/socket growth. Actual HTTPD/timer margins and runtime overhead/reserve floors require target measurement, not host sizes. See [latest firmware resources](web_administration_acceptance.md#latest-firmware-evidence).
|
Bounded storage: six observation rows (144 bytes), one persistent timer (installed non-profiled layout 32 bytes before allocator overhead), lifecycle/generation flags and one reserved probe. SDK control UDP/mailbox allocation is transient and separate. No per-connection payload/task/stack/socket growth. Actual HTTPD/timer margins and runtime overhead/reserve floors require target measurement, not host sizes. See [latest firmware resources](roadmap.md#phase8-acceptance-evidence).
|
||||||
|
|
||||||
## Regression procedure — not execution evidence
|
## Regression procedure — not execution evidence
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
# Legacy credential removal and storage compatibility
|
|
||||||
|
|
||||||
Current storage/recovery contract. The user accepted cleanup on 2026-09-08, confirming the certificate fingerprint was unchanged and preexisting test users remained usable. [Overall acceptance and evidence limits](web_administration_acceptance.md) supersede the old per-slice handoff; no unreported provisioning, recovery, power-loss or all-key tests are implied.
|
|
||||||
|
|
||||||
## User database
|
|
||||||
|
|
||||||
- `user_database_init(load_result)` takes no legacy credential. Missing `user_db/database` storage is committed as an empty v1 database; no account/password is imported.
|
|
||||||
- Create the first administrator on physical UART0 with `user add <username> admin`, optionally `--generate`. Entered passwords use hidden confirmation; generated passwords are shown once. There is no reserved bootstrap account or public bootstrap state.
|
|
||||||
- `user recover --force` is UART0-only, calls `user_database_recover_empty()`, and destructively rebuilds only an unavailable database empty. It refuses a healthy initialized database, including an empty one. Follow with normal `user add`; unrelated configuration and TLS/SSH identities are untouched.
|
|
||||||
- Valid existing v1 database bytes load without rewriting or changing accounts, roles, IDs, authentication generations, verifiers or authorized keys. Previously migrated role-`user` accounts are not automatically promoted. The private `v1_admin_marker` preserves the old wire byte and is derived from administrator count during mutations; it is not a new role, public bootstrap field or schema change.
|
|
||||||
- No public bootstrap, legacy user migration or synchronization API remains. Final-admin protection, conditional mutations, copied principal currentness and target-only revocation remain the canonical account contracts.
|
|
||||||
|
|
||||||
## HTTPS identity storage
|
|
||||||
|
|
||||||
`web_security` owns only TLS material. At the unchanged `web_sec/material` key, a private byte-oriented reader validates the shipped **1,392-byte v1** layout and builds **1,340-byte TLS-only v2**. It retains the **exact private-key DER, certificate DER, SHA-256 fingerprint and material generation**: this migration is not certificate rotation.
|
|
||||||
|
|
||||||
The v2 candidate is validated and committed before live publication. Temporary credential-bearing v1 input is wiped. No public legacy credential reader/type, display, rotation or authentication path remains. Unknown/malformed material, read failures, invalid cryptographic identity and migration write/commit failures fail closed; they do not trigger fallback regeneration or overwrite of rejected material. Truly missing material may be generated and saved normally.
|
|
||||||
|
|
||||||
`web credentials show`, `web credentials rotate --force` and `user bootstrap` (including its generated form) are removed. `web certificate info` and `web certificate rotate --force` remain subject to existing frontend policy. `web reset --force` explicitly replaces TLS certificate/private key only; it does not reset passwords, import accounts or synchronize verifiers. TLS replacement/restart can close browser sessions and requires renewed certificate trust/login, without changing user credentials or revoking unrelated SSH sessions.
|
|
||||||
|
|
||||||
## Compatibility and physical-security limits
|
|
||||||
|
|
||||||
**Older v1-only firmware cannot read v2 HTTPS storage.** Do not assume a downgrade preserves usable HTTPS or restores removed credentials. Existing user database v1 compatibility is separate from this HTTPS downgrade incompatibility.
|
|
||||||
|
|
||||||
Replacing an NVS blob logically removes credential fields from the current record; it is **not secure flash wiping**. Append-oriented historical copies may retain plaintext legacy credentials, and current Wi-Fi secrets/TLS/SSH private keys remain unencrypted. PBKDF2 verifiers remain subject to offline guessing. No factory/partition erase is required or authorized by this cleanup.
|
|
||||||
|
|
||||||
## Regression references
|
|
||||||
|
|
||||||
Use `tests/web_security/run.py`, `tests/admin_console_boundary/accounts.py`, `tests/admin_ssh_policy/run.py` and [current legacy-removal procedures](user_administration_tests.md#current-legacy-removal-regression-procedure). Prior host tests used NVS fault doubles and a generated identity wrapped in the historical TLS layout, not an independently captured old-device fixture; they do not prove flash durability or power-loss behavior. Procedures are not claims of execution.
|
|
||||||
+68
-41
@@ -1,10 +1,10 @@
|
|||||||
# Implementation roadmap
|
# 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.
|
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. Completion requires implementation, documentation and build validation, plus relevant hardware tests or an explicitly recorded user waiver. A waiver is not a hardware-test pass.
|
||||||
|
|
||||||
## Status legend
|
## Status legend
|
||||||
|
|
||||||
- **Complete** — implemented and validated on the target hardware.
|
- **Complete** — implemented and accepted, with target-hardware validation or an explicit phase-specific user waiver recorded below.
|
||||||
- **In progress** — implementation or validation is actively underway, but the overall phase is not complete.
|
- **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.
|
- **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.
|
- **Planned** — accepted project direction, not yet implemented.
|
||||||
@@ -38,9 +38,9 @@ These constraints apply across all phases:
|
|||||||
| 5B | Offline xterm.js WebSocket serial terminal | **Complete** |
|
| 5B | Offline xterm.js WebSocket serial terminal | **Complete** |
|
||||||
| 6 | Authenticated SSH serial transport | **Complete** |
|
| 6 | Authenticated SSH serial transport | **Complete** |
|
||||||
| 7 | Local display and button interface | **Complete** |
|
| 7 | Local display and button interface | **Complete** |
|
||||||
| 8 | Role-based users and administrative access | **In progress (8A–8C complete; integrated web administration 8D planned)** |
|
| 8 | Role-based users and administrative access | **Complete** |
|
||||||
| 9 | Security and production hardening | **Planned** |
|
| 9 | Small intermittent-use security baseline | **Complete (user signoff 2026-09-18; new hardware check waived)** |
|
||||||
| 10 | Authenticated, rollback-capable OTA | **Planned** |
|
| 10 | Simple admin web firmware upload | **Planned** |
|
||||||
| 11 | BLE serial transport and provisioning evaluation | **Planned** |
|
| 11 | BLE serial transport and provisioning evaluation | **Planned** |
|
||||||
| 12 | Advanced network integration | **Under evaluation** |
|
| 12 | Advanced network integration | **Under evaluation** |
|
||||||
| 13 | Optional filesystem-backed features | **Under evaluation** |
|
| 13 | Optional filesystem-backed features | **Under evaluation** |
|
||||||
@@ -200,50 +200,77 @@ Completed implementation (8A–8C target-hardware validated; 8D explicitly accep
|
|||||||
- Typed Serial, Accounts/password/authorized-key, Network/Wi-Fi/mDNS, Display, Broker and SSH settings; confirmed HTTPS stop/restart/reboot and HTTPS/SSH identity rotation. Canonical owners compare reserved service/identity/target generations, preserve commit/failure semantics and expose no stored secrets. Admitted work is not cancelled by later logout/timeout; uncertain mutations are never automatically replayed.
|
- Typed Serial, Accounts/password/authorized-key, Network/Wi-Fi/mDNS, Display, Broker and SSH settings; confirmed HTTPS stop/restart/reboot and HTTPS/SSH identity rotation. Canonical owners compare reserved service/identity/target generations, preserve commit/failure semantics and expose no stored secrets. Admitted work is not cancelled by later logout/timeout; uncertain mutations are never automatically replayed.
|
||||||
- Accessible Serial/Wi-Fi/client/writer contextual controls reuse existing controllers. Writer transfer is explicit and generation-safe; one writer, isolated observers, binary transparency, UART0 administrative recovery and network-independent native USB UART1 remain invariants.
|
- Accessible Serial/Wi-Fi/client/writer contextual controls reuse existing controllers. Writer transfer is explicit and generation-safe; one writer, isolated observers, binary transparency, UART0 administrative recovery and network-independent native USB UART1 remain invariants.
|
||||||
- Scope removed by user: **8D.15** dedicated typed network diagnostics (shell diagnostics retained) and the unimplemented **8D.19** ordinary browser-session/native-USB controls (SSH controls retained). Browser identity reset/recovery/export is excluded; canonical recovery remains available.
|
- Scope removed by user: **8D.15** dedicated typed network diagnostics (shell diagnostics retained) and the unimplemented **8D.19** ordinary browser-session/native-USB controls (SSH controls retained). Browser identity reset/recovery/export is excluded; canonical recovery remains available.
|
||||||
- Prior final build PASS: **100,556 B linked RAM / 1,828,573 B flash, CPU 160 MHz**. Earlier combined binary WebSocket-send fix was explicitly accepted at **160 MHz / 230400 baud with full client mix including browser admin**. Latest overall sign-off does not invent individual fault/soak/duration results or a latest exact zero-drop comparison.
|
- Acceptance evidence and legacy storage compatibility are condensed below. [Web administration](web_administration.md) retains current API/owner/recovery contracts; [regression procedures](user_administration_tests.md#integrated-web-administration-regression-procedure) retain practical checks, not claims of execution.
|
||||||
- Latest loaded internal/DMA minima **2,052 / 460 B** remain a conservative transient-headroom follow-up, not a blocker reopening acceptance or an approved reserve. See [acceptance and telemetry](web_administration_acceptance.md), [current contracts](web_administration.md), [regression procedures](user_administration_tests.md#integrated-web-administration-regression-procedure) and [legacy compatibility](legacy_credential_removal.md).
|
|
||||||
|
|
||||||
## Current and planned phases
|
#### Phase8 acceptance evidence
|
||||||
|
|
||||||
Phase 8 is complete for its accepted scope. Phase 9 is next **only on a separate user request**; later work remains planned or under evaluation. Optional features must not weaken completed serial and recovery paths. General release gates below remain guidance for future work, not claims that every listed fault, soak or reserve measurement was individually performed for 8D.
|
**8D.22 signoff, 2026-09-13:** the user explicitly accepted the tested firmware, superseding earlier per-slice target, review and integration gates for the retained scope above. Earlier scoped acceptance covered browser login/logout, shared administration, Serial/account/Network presentation and legacy cleanup. Prior host regression suites and independent reviews were reported passing; this consolidation asserts no new build or test execution.
|
||||||
|
|
||||||
|
Prior final Phase 8 build: **PASS, 100,556 B linked RAM / 1,828,573 B flash, CPU 160 MHz**. The combined binary WebSocket-send fix was separately accepted at **160 MHz / 230400 baud with the full client mix including browser admin**; retain combined send and bounded failed-send isolation, not the earlier frequency-only experiment. Ordinary HTTPS idle cleanup was accepted, not every possible admission failure or owner delay.
|
||||||
|
|
||||||
|
Latest reported Phase 8 telemetry (bytes):
|
||||||
|
|
||||||
|
| Sample / capability | Free | Minimum free | Largest block |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| Boot internal 8-bit | 59,808 | 58,840 | 31,744 |
|
||||||
|
| Boot internal DMA | 52,052 | 51,084 | 31,744 |
|
||||||
|
| Boot PSRAM | 8,196,968 | 8,183,972 | 8,126,464 |
|
||||||
|
| Loaded after burst, internal 8-bit | 31,508 | 2,052 | 18,432 |
|
||||||
|
| Loaded after burst, internal DMA | 23,752 | 460 | 18,432 |
|
||||||
|
| Loaded after burst, PSRAM | 8,136,624 | 8,065,972 | 7,995,392 |
|
||||||
|
|
||||||
|
Loaded SSH minimum-free stack: **15,028 B**. This sample had two SSH sessions (serial/admin), two serial WebSockets and USB, with SSH as writer. Browser admin had been used then closed; it was **not active in this capture**. Web send/queue/protocol and SSH IO errors were zero; one SSH handshake failure and one session revocation were reported without an established cause.
|
||||||
|
|
||||||
|
**Limits, not reopened acceptance gates:** missing latest broker/serial counters prevent an exact zero-drop or byte-integrity inference. No latest browser-admin-active full-mix, individual fault-injection, exact duration, soak, cleanup-cycle or reserve-floor result is inferred. Internal/DMA lifetime minima remain a nonblocking transient-headroom follow-up, not approved reserves or proof of allocation failure: capability pools overlap and per-region minima may be non-simultaneous, so do not sum them. HTTPD/dispatcher stack margins, correlated peaks and allocation-reserve policy remain unmeasured/unapproved here. SDK TLS `-0x004C` means NET_RECV_FAILED, not an OOM diagnosis; stale cookies as the cause of two boot authentication failures remain unconfirmed.
|
||||||
|
|
||||||
|
#### Phase8 legacy credential compatibility
|
||||||
|
|
||||||
|
Cleanup was accepted **2026-09-08**, with unchanged certificate fingerprint and usable preexisting test users. This is not an unreported provisioning, recovery, power-loss or all-key pass.
|
||||||
|
|
||||||
|
- **Users:** missing `user_db/database` is committed as an empty v1 database, with no legacy account/password import. First-admin provisioning is physical UART0 `user add <username> admin` (optional `--generate`); entered passwords use hidden confirmation and generated passwords appear once. UART0-only `user recover --force` rebuilds only an unavailable database empty, refuses healthy databases (including empty ones), and leaves other configuration and TLS/SSH identities untouched; follow with normal `user add`.
|
||||||
|
- Valid existing v1 user bytes load without rewrite or changes to accounts, roles, IDs, authentication generations, verifiers or authorized keys; migrated `user` accounts are not promoted. Private `v1_admin_marker` preserves the old wire byte and is derived from admin count on mutation, not a new role/schema/public bootstrap state. Public bootstrap and legacy migration/synchronization APIs are removed; final-admin protection, conditional mutations, principal currentness and targeted revocation remain.
|
||||||
|
- **TLS:** at unchanged `web_sec/material`, a private reader validates the **1,392-byte v1** layout and migrates to **1,340-byte TLS-only v2**, preserving exact private-key DER, certificate DER, SHA-256 fingerprint and material generation—not rotating identity. The candidate is validated and committed before publication; temporary credential-bearing input is wiped. Malformed/unknown material, read/crypto failures and migration write/commit failures fail closed without regeneration or overwrite; truly missing material may be generated normally.
|
||||||
|
- `web credentials show`, `web credentials rotate --force` and `user bootstrap` are removed. `web certificate info` / `web certificate rotate --force` retain frontend policy. `web reset --force` replaces TLS identity only, not accounts/passwords/verifiers; replacement/restart may close browser sessions and require renewed certificate trust/login, without revoking unrelated SSH sessions. No public legacy credential reader, display, rotation or authentication path remains.
|
||||||
|
- **Downgrade/security:** older v1-only firmware cannot read v2 HTTPS storage; user-database v1 compatibility does not make HTTPS downgrade safe or restore removed credentials. Logical NVS replacement is **not secure flash wiping**: historical plaintext legacy credentials may remain, Wi-Fi secrets and TLS/SSH private keys remain unencrypted, and PBKDF2 verifiers permit offline guessing. No erase is required or authorized by cleanup.
|
||||||
|
- Prior host tests used NVS fault doubles and a generated identity wrapped in the historical layout, **not an independently captured old-device fixture**; they do not prove flash durability or power-loss behavior. Focused runners: `tests/web_security/run.py`, `tests/admin_console_boundary/accounts.py`, `tests/admin_ssh_policy/run.py`. See [legacy-removal regressions](user_administration_tests.md#current-legacy-removal-regression-procedure).
|
||||||
|
|
||||||
### Phase 9 — Security and production hardening
|
### 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.
|
**Complete — user signoff 2026-09-18; new hardware check explicitly waived.** Reduced scope: an intermittently powered wireless serial cable on a trusted network, not a permanently exposed Internet service. The earlier extensive Phase 9 implementation was abandoned in favor of the accepted pre-Phase-9 baseline. Short exposure reduces risk; it does not make upstream defects harmless or certify this firmware secure.
|
||||||
|
|
||||||
|
Small implementation:
|
||||||
|
|
||||||
|
- Keep the baseline PlatformIO/ESP-IDF and managed-library versions and upstream sources. No generated dependency patches, custom SSH state machine, crypto-policy replacement, allocator hooks, or SDK migration in this phase.
|
||||||
|
- Explicitly disable core dumps and select silent panic reboot through standard `sdkconfig.defaults` options. Keep ordinary logging; reduced crash diagnostics are a deliberate trade-off. Existing generated configurations must be checked because defaults do not override saved selections.
|
||||||
|
- Follow the [operational checklist](security_operations.md): unique credentials, trusted identity verification, no Internet forwarding, networking off/power off after use, and existing rotation/recovery procedures.
|
||||||
|
- Review upstream maintenance releases occasionally and before planned upgrades. Evaluate reachable issues against actual use; any stock dependency upgrade is a separate build/device-tested task, not a reason to accumulate local backports. Preserve existing license notices.
|
||||||
|
|
||||||
|
**Excluded:** secure boot, NVS/flash/PSRAM encryption, eFuse changes, partition changes, exhaustive CVE/zeroization audits, new authentication throttling, and production certification. Existing authentication, session isolation and recovery behavior remain unchanged. There is no protection against physical extraction or replacement of firmware. Phase 10 uses administrator-selected firmware, without a separate image-signing system.
|
||||||
|
|
||||||
|
**Host/build evidence (2026-09-18):** normal `pio run` passed on PlatformIO 6.12.0 / ESP-IDF 5.5.0 with the original 20241119 toolchains: **94,196 B linked RAM / 1,828,565 B flash**. Generated configuration confirms no dumps and silent panic reboot; compilation inputs contain none of the abandoned Phase 9 source overlays or wolf crypto guards. No device operation or target validation was performed.
|
||||||
|
|
||||||
|
**Acceptance (2026-09-18):** the user signed off this small Phase 9 and explicitly waived a new whole-phase hardware check of boot, UART0 recovery, native USB serial, HTTPS/SSH login and normal serial sharing. Application code is unchanged, **but crash-diagnostic defaults changed**; this is a waiver, not evidence of target or panic-path validation. The prior build/configuration evidence above remains the validation record; no new hardware test was performed. A separately controlled panic check with synthetic secrets remains optional, not a completion gate; do not add a production panic endpoint or erase flash. Disabling dumps does not erase old contents.
|
||||||
|
|
||||||
|
## Current and planned phases
|
||||||
|
|
||||||
|
**Phases 8 and 9 are complete** for their accepted scopes; Phase 9 completion includes the explicit new-hardware-check waiver above. Phase 10 is planned, not implemented; later work remains planned or under evaluation. Optional features must not weaken completed serial and recovery paths. General release gates below guide future work, not claims that every fault, soak or reserve measurement was performed for Phase 8 or that Phase 9 received new target validation.
|
||||||
|
|
||||||
|
### Phase 10 — Simple admin web firmware upload
|
||||||
|
|
||||||
|
**Plan only.** Add a file picker and upload button in the existing admin web interface. The owner builds the firmware locally and chooses the application `firmware.bin`; there is no release server, automatic download or update service. Treat an authenticated administrator as authorized to replace the application, as the physical owner can through wired flashing.
|
||||||
|
|
||||||
Planned work:
|
Planned work:
|
||||||
|
|
||||||
- Define development, test, and production security profiles.
|
- Reuse existing HTTPS admin authentication, same-origin and CSRF protections; ordinary `user` accounts cannot upload firmware. Require an explicit upload/reboot confirmation and show progress, success or an actionable error. Never automatically retry a possibly completed update.
|
||||||
- Enable and validate NVS encryption for Wi-Fi, HTTPS, and SSH material.
|
- Use standard ESP-IDF OTA APIs (`esp_ota_begin`, `esp_ota_write`, `esp_ota_end`, `esp_ota_set_boot_partition`) to stream one upload at a time through a bounded buffer into the inactive application slot. Use the existing two 4 MiB slots and `otadata`; no custom flash protocol or whole-image RAM buffer.
|
||||||
- Evaluate flash encryption and PSRAM encryption for the target hardware and threat model.
|
- Accept an ESP32-S3 application binary for this board/layout, not an ELF, ZIP, merged full-flash image, bootloader or partition-table image. Check nonempty/complete upload, target/header compatibility and actual destination capacity; use SDK image validation before selecting the new boot partition. A `.bin` filename alone is not validation. Basic format/integrity checks do not prove authenticity or that the application will work.
|
||||||
- Enable secure boot with a documented signing-key and recovery process.
|
- On interrupted, invalid or failed uploads, abort the OTA operation and leave the current boot selection unchanged. Select the new slot only after successful final validation, report completion and reboot in a controlled way. Upload may disrupt network/serial activity; reboot interrupts every transport, so do not promise uninterrupted operation.
|
||||||
- Define secret-safe core-dump handling; do not expose credentials or session material in diagnostics.
|
- **Preserve NVS:** write only the inactive application slot and the OTA selection metadata. Do not erase the chip, rewrite the partition table/bootloader, or touch `nvs`, `nvs_key`, PHY, storage or other data partitions. Existing users, passwords, Wi-Fi/serial settings and HTTPS/SSH identities remain stored, as with an application-only wired update without erase. This preserves stored bytes; the uploaded firmware must still understand the existing schemas and must not itself erase/migrate them incompatibly.
|
||||||
- Audit key and session-material zeroization across application, mbedTLS, wolfSSL, and wolfSSH allocations.
|
- Keep wired USB-to-UART flashing documented as recovery if the uploaded application does not boot or no longer serves the web UI. Basic image validation cannot prevent a valid but broken application from requiring wired recovery.
|
||||||
- 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.
|
**Not in scope:** secure boot, image signatures/signing-key management, anti-rollback/version-downgrade enforcement, automatic rollback/post-boot health-confirmation machinery, remote release discovery, partition migration or NVS backup/restore. Use upstream OTA support without dependency patches. The administrator is responsible for selecting trusted, compatible firmware, including when deliberately installing an older build.
|
||||||
|
|
||||||
### Phase 10 — Authenticated OTA and rollback
|
**Acceptance:** test a successful application upload/reboot, invalid/wrong-target/oversized and interrupted uploads, authorization rejection, and retained configuration/identities after update. Confirm wired recovery remains possible. These are future tests, not execution claims; no new cryptographic certification or exhaustive fault campaign is required.
|
||||||
|
|
||||||
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
|
### Phase 11 — BLE
|
||||||
|
|
||||||
@@ -286,7 +313,7 @@ Before enabling storage, define corruption recovery, wear limits, quotas, atomic
|
|||||||
|
|
||||||
## Cross-phase release gates
|
## Cross-phase release gates
|
||||||
|
|
||||||
Every phase should satisfy the following before being marked complete:
|
Every phase should satisfy the following before being marked complete, with any user-waived check explicitly recorded in that phase rather than reported as passed:
|
||||||
|
|
||||||
1. A clean release build for the ESP32-S3 N16R8 target.
|
1. A clean release build for the ESP32-S3 N16R8 target.
|
||||||
2. No new compiler or project diagnostics attributable to the change.
|
2. No new compiler or project diagnostics attributable to the change.
|
||||||
@@ -305,7 +332,7 @@ The following are not implemented merely because flash partitions or library sup
|
|||||||
|
|
||||||
- NVS, flash, or PSRAM encryption.
|
- NVS, flash, or PSRAM encryption.
|
||||||
- Secure boot or production eFuse provisioning.
|
- Secure boot or production eFuse provisioning.
|
||||||
- OTA download, image confirmation, or rollback policy.
|
- Automatic OTA downloads, image signing, post-boot health confirmation and automatic rollback. The simple admin upload is planned in Phase 10.
|
||||||
- Core-dump collection or secret-safe core-dump processing.
|
- Core-dump collection or secret-safe core-dump processing.
|
||||||
- Filesystem mounting.
|
- Filesystem mounting.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
# Security operations — intermittent hobby use
|
||||||
|
|
||||||
|
This checklist is for a wireless serial cable used occasionally on a trusted network,
|
||||||
|
not an Internet-facing appliance or a production-security certification.
|
||||||
|
It covers existing firmware operations only: no dependency patches, crypto upgrades,
|
||||||
|
secure-boot, encrypted-NVS, or eFuse changes are part of this scope.
|
||||||
|
|
||||||
|
## Provision once, locally
|
||||||
|
|
||||||
|
- Use the physical **UART0 administration console** on a trusted computer.
|
||||||
|
Native USB CDC is a separate UART1 serial-data path, not the admin console.
|
||||||
|
- Create the first administrator with `user add <username> admin`.
|
||||||
|
Use a unique password; the prompt accepts 12–64 printable ASCII characters.
|
||||||
|
Add a separate `user` account for ordinary serial use, especially over SSH:
|
||||||
|
SSH `admin` opens administration, whereas SSH `user` opens UART1.
|
||||||
|
- Use unique Wi-Fi credentials, not passwords reused from other services.
|
||||||
|
Configure station profiles using the [Wi-Fi command reference](command_reference.md#wi-fi);
|
||||||
|
enter their passwords with `wifi profile secret <slot>`.
|
||||||
|
If using the device AP, set its password with `wifi ap secret`.
|
||||||
|
If the AP is unnecessary, select `wifi ap policy off`.
|
||||||
|
Run `wifi save` to persist working Wi-Fi settings.
|
||||||
|
- Before entering network credentials into a client, check device identity locally:
|
||||||
|
run `web certificate info` and `ssh host-key info` on trusted UART0.
|
||||||
|
Compare the SHA-256 certificate fingerprint in the browser certificate viewer
|
||||||
|
and the SSH host-key fingerprint in the SSH client with those local values.
|
||||||
|
Record the verified fingerprints; do not blindly dismiss certificate or changed-key warnings.
|
||||||
|
- Keep passwords in a password manager. Generated account passwords (`--generate`)
|
||||||
|
are displayed once; avoid terminal recording or sharing that output.
|
||||||
|
|
||||||
|
## Each use
|
||||||
|
|
||||||
|
- Use only a trusted LAN or the device's password-protected AP.
|
||||||
|
Do not configure router port forwarding or otherwise expose HTTPS/SSH to the Internet.
|
||||||
|
A trusted network reduces exposure; it does not make every attached client trustworthy.
|
||||||
|
- Check unexpected identity warnings against UART0 before logging in.
|
||||||
|
Keep UART0, native USB, and the connected RS-232 equipment physically controlled:
|
||||||
|
local serial access is not protected by network account authentication.
|
||||||
|
- When finished, sign out of the browser and close SSH clients.
|
||||||
|
Browser serial **Disconnect** alone is not sign-out.
|
||||||
|
- Prefer powering the device off when unused. If it must remain powered for USB
|
||||||
|
serial use, run `wifi stop` from UART0 and check `wifi status` after the queued
|
||||||
|
operation completes. This stops network access, not native USB UART1 access.
|
||||||
|
To keep Wi-Fi disabled at the next boot, follow with `wifi save`.
|
||||||
|
`wifi start` enables it again in RAM; save again only if that boot policy is wanted.
|
||||||
|
Do not rely on a temporary stop surviving reboot without saving.
|
||||||
|
|
||||||
|
## Change credentials or identity when needed
|
||||||
|
|
||||||
|
Use trusted UART0 for these operations to avoid losing a remote session mid-change.
|
||||||
|
Rotate after suspected disclosure, a lost client key, or a change of owner/access;
|
||||||
|
there is no need for a calendar-driven rotation ritual for this use case.
|
||||||
|
|
||||||
|
| What changed | Built-in operation |
|
||||||
|
|---|---|
|
||||||
|
| Account password | `user password <username>` (no-echo prompt). |
|
||||||
|
| Authorized SSH client key | `user show <username>` to identify its index; `user key delete <username> <0..2> --force`, then `user key add <username>` to enter the replacement public key. |
|
||||||
|
| Account no longer needed | `user delete <username> --force`; the final administrator is protected. |
|
||||||
|
| Wi-Fi password | Change the router credential as appropriate, then `wifi profile secret <slot>`; for the device AP use `wifi ap secret`. Finish with `wifi save`. |
|
||||||
|
| HTTPS device identity | `web certificate rotate --force`. |
|
||||||
|
| SSH device identity | `ssh host-key rotate --force`. |
|
||||||
|
|
||||||
|
Account changes invalidate that account's network sessions; identity replacement
|
||||||
|
interrupts the affected service. Check command results, then verify new fingerprints
|
||||||
|
through UART0 before updating browser trust or SSH known-host entries and reconnecting.
|
||||||
|
Changing a password does not remove authorized SSH keys; review both after compromise.
|
||||||
|
Identity rotation is not an account-password change. If an acknowledgement is lost,
|
||||||
|
inspect current state on UART0 rather than blindly repeating the operation.
|
||||||
|
|
||||||
|
## Recovery and backup limits
|
||||||
|
|
||||||
|
- Keep UART0 available for forgotten passwords, Wi-Fi mistakes, and network-service
|
||||||
|
recovery. Native USB can still carry UART1 data when networking fails, but cannot
|
||||||
|
repair accounts or identities; neither path promises uninterrupted service through reboot.
|
||||||
|
- For a healthy database, use normal UART0 account commands to repair access.
|
||||||
|
`user recover --force` is **only** for an unavailable user database: it destroys
|
||||||
|
that database's contents and rebuilds it empty, refuses a healthy database, and
|
||||||
|
requires creating a new administrator afterward. It is not a forgotten-password reset.
|
||||||
|
- `web reset --force` replaces HTTPS certificate/private-key material only;
|
||||||
|
`ssh reset --force` replaces SSH host-key material. Neither resets accounts or Wi-Fi.
|
||||||
|
These are scoped recovery operations, not a whole-device factory reset.
|
||||||
|
- No supported configuration/credential/identity backup-export command was found
|
||||||
|
in the application console. Keep a private reprovisioning record of settings,
|
||||||
|
account names/roles, client public keys, and verified fingerprints; store passwords
|
||||||
|
separately in a password manager. Do not expect status output to recover secrets
|
||||||
|
or private keys. Reprovisioning may require accepting a newly verified device identity.
|
||||||
|
- Physical extraction or firmware replacement is **not protected by this checklist**.
|
||||||
|
Treat a lost device or a raw flash copy as potentially exposing stored Wi-Fi secrets,
|
||||||
|
private identities, and password verifiers. Rotation is not a secure flash-erasure claim.
|
||||||
|
|
||||||
|
## Lightweight maintenance
|
||||||
|
|
||||||
|
Occasionally, and before a planned firmware update, review relevant ESP-IDF,
|
||||||
|
wolfSSL/wolfSSH, and bundled web-library upstream release/security notes.
|
||||||
|
If a relevant issue appears, stop network use until a separate upgrade decision is made;
|
||||||
|
USB serial remains an option. Dependency upgrades and their validation are separate work,
|
||||||
|
not an endless CVE audit or an implied promise that this firmware is vulnerability-free.
|
||||||
|
|
||||||
|
Commands and limits were checked against application sources and the [command reference](command_reference.md) at `f40c09c`.
|
||||||
|
This is source-reviewed operating guidance, not a build, hardware test, security audit,
|
||||||
|
or verification of any individual device's flash/eFuse configuration.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# User administration and authentication tests
|
# User administration and authentication tests
|
||||||
|
|
||||||
Reusable procedures, **not execution evidence**. [Phase 8 is accepted](web_administration_acceptance.md); overall 8D.22 user sign-off does not assert that every checklist item below ran. Historical 8A/B sections describe their original baselines only; current cookie authentication, removed bootstrap/credentials and UART0-only recovery override them. Use current contracts and the integrated regression section for present behavior. Never log generated/entered passwords, cookies/tickets or private/verifier material.
|
Reusable procedures, **not execution evidence**. [Phase 8 is accepted](roadmap.md#phase8-acceptance-evidence); overall 8D.22 user sign-off does not assert that every checklist item below ran. Historical 8A/B sections describe their original baselines only; current cookie authentication, removed bootstrap/credentials and UART0-only recovery override them. Use current contracts and the integrated regression section for present behavior. Never log generated/entered passwords, cookies/tickets or private/verifier material.
|
||||||
|
|
||||||
## Current Broker management regression procedure — 8D.16
|
## Current Broker management regression procedure — 8D.16
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ The [Network contract](web_administration.md#network) defines the current byte c
|
|||||||
|
|
||||||
## Current legacy-removal regression procedure
|
## Current legacy-removal regression procedure
|
||||||
|
|
||||||
The legacy bootstrap/credential/reconciliation instructions in the phase baselines below are **historical only**, superseded by [legacy credential removal](legacy_credential_removal.md) and the current [command reference](command_reference.md). Basic authentication is also historical; current HTTPS uses cookie login. The current overrides apply to later Phase 8C/browser procedures too: no `user bootstrap` or `web credentials` command remains, first-admin creation uses normal UART0 `user add`, and recovery rebuilds empty. Never treat the checklist below as evidence of execution.
|
The legacy bootstrap/credential/reconciliation instructions in the phase baselines below are **historical only**, superseded by [legacy credential removal](roadmap.md#phase8-legacy-credential-compatibility) and the current [command reference](command_reference.md). Basic authentication is also historical; current HTTPS uses cookie login. The current overrides apply to later Phase 8C/browser procedures too: no `user bootstrap` or `web credentials` command remains, first-admin creation uses normal UART0 `user add`, and recovery rebuilds empty. Never treat the checklist below as evidence of execution.
|
||||||
|
|
||||||
1. On a disposable controlled NVS image with only `user_db/database` missing, boot and confirm an empty database is persisted with zero accounts/admins and no imported credential. Reboot and confirm it remains empty. Keep physical UART0 attached; do not factory-erase the device for this test.
|
1. On a disposable controlled NVS image with only `user_db/database` missing, boot and confirm an empty database is persisted with zero accounts/admins and no imported credential. Reboot and confirm it remains empty. Keep physical UART0 attached; do not factory-erase the device for this test.
|
||||||
2. Run `user add maint admin` on UART0, check hidden password confirmation and cancellation, then confirm account/password persistence after reboot. Separately exercise `user add operator user --generate` and secure one-time display. Final-administrator delete/demotion must still fail. Existing SSH own-password generation restrictions and typed browser generated-password support remain unchanged.
|
2. Run `user add maint admin` on UART0, check hidden password confirmation and cancellation, then confirm account/password persistence after reboot. Separately exercise `user add operator user --generate` and secure one-time display. Final-administrator delete/demotion must still fail. Existing SSH own-password generation restrictions and typed browser generated-password support remain unchanged.
|
||||||
@@ -36,7 +36,7 @@ The legacy bootstrap/credential/reconciliation instructions in the phase baselin
|
|||||||
6. Confirm help/completion/status expose no legacy credential/bootstrap operation or secret. Removed commands must reject without mutation. Exercise retained user generation and `web certificate rotate --force` through supported frontends. `web reset --force` must change TLS only, require new certificate trust/login after HTTPS restart, leave user credentials/generations unchanged, and not revoke unrelated SSH sessions.
|
6. Confirm help/completion/status expose no legacy credential/bootstrap operation or secret. Removed commands must reject without mutation. Exercise retained user generation and `web certificate rotate --force` through supported frontends. `web reset --force` must change TLS only, require new certificate trust/login after HTTPS restart, leave user credentials/generations unchanged, and not revoke unrelated SSH sessions.
|
||||||
7. Recheck UART0/native USB availability and broker one-writer/isolated-observer behavior with network authentication unavailable. Record only nonsecret counters and telemetry. Older v1-only firmware cannot read HTTPS v2; logical NVS replacement is not secure flash erasure and no factory erase is required.
|
7. Recheck UART0/native USB availability and broker one-writer/isolated-observer behavior with network authentication unavailable. Record only nonsecret counters and telemetry. Older v1-only firmware cannot read HTTPS v2; logical NVS replacement is not secure flash erasure and no factory erase is required.
|
||||||
|
|
||||||
Acceptance and prior evidence limits are recorded in [legacy compatibility](legacy_credential_removal.md) and [overall acceptance](web_administration_acceptance.md); the preceding procedure is not an execution log.
|
Acceptance and prior evidence limits are recorded in [legacy compatibility](roadmap.md#phase8-legacy-credential-compatibility) and [overall acceptance](roadmap.md#phase8-acceptance-evidence); the preceding procedure is not an execution log.
|
||||||
|
|
||||||
## Historical Phase 8A baseline — role-based database and UART0 administration
|
## Historical Phase 8A baseline — role-based database and UART0 administration
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ Finally, issue commands concurrently from UART0 and admin SSH, including `user l
|
|||||||
|
|
||||||
## Integrated web administration regression procedure
|
## Integrated web administration regression procedure
|
||||||
|
|
||||||
Current retained-scope checks for future changes. [8D.22 sign-off](web_administration_acceptance.md) closes the phase; these are **not additional acceptance conditions or claims of individual execution**. Record exact revision, workload/client mix, duration, counters and heap/stack evidence for any new run. Do not treat host doubles as target timing/power-loss proof or reserve approval. Prepare UART0 recovery/native USB before disruptive tests and do not erase persisted data without explicit approval.
|
Current retained-scope checks for future changes. [8D.22 sign-off](roadmap.md#phase8-acceptance-evidence) closes the phase; these are **not additional acceptance conditions or claims of individual execution**. Record exact revision, workload/client mix, duration, counters and heap/stack evidence for any new run. Do not treat host doubles as target timing/power-loss proof or reserve approval. Prepare UART0 recovery/native USB before disruptive tests and do not erase persisted data without explicit approval.
|
||||||
|
|
||||||
### 1. Integrated login and authorization
|
### 1. Integrated login and authorization
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Web administration contracts
|
# Web administration contracts
|
||||||
|
|
||||||
Current, accepted firmware behavior. Phase status and executed-evidence limits belong in the [roadmap](roadmap.md#phase-8--role-based-users-and-administrative-access--complete) and [acceptance record](web_administration_acceptance.md), not in implementation timelines. [Regression procedures](user_administration_tests.md#integrated-web-administration-regression-procedure) describe checks, not results. Source is authoritative; start with the [code map](agent/code-map.md).
|
Current, accepted firmware behavior. Phase status and executed-evidence limits belong in the [roadmap](roadmap.md#phase-8--role-based-users-and-administrative-access--complete) and [acceptance record](roadmap.md#phase8-acceptance-evidence), not in implementation timelines. [Regression procedures](user_administration_tests.md#integrated-web-administration-regression-procedure) describe checks, not results. Source is authoritative; start with the [code map](agent/code-map.md).
|
||||||
|
|
||||||
## Authentication and admission
|
## Authentication and admission
|
||||||
|
|
||||||
@@ -123,6 +123,6 @@ SSH changes leave invoking HTTPS available, so they use the ordinary ID-dispatch
|
|||||||
|
|
||||||
## Diagnostics, recovery and scope boundaries
|
## Diagnostics, recovery and scope boundaries
|
||||||
|
|
||||||
See [admission diagnostics](web_admission_diagnostics.md), [ordinary HTTPS idle cleanup](https_idle_cleanup.md), [throughput diagnostics](web_throughput_diagnostics.md) and [legacy storage compatibility](legacy_credential_removal.md). Broker read means transport handoff, not peer receipt; capture non-consuming counters before disconnect. TLS `-0x004C` is generic NET_RECV_FAILED, not evidence of OOM. Resource minima and counter observations require attribution, not inferred causes.
|
See [admission diagnostics](web_admission_diagnostics.md), [ordinary HTTPS idle cleanup](https_idle_cleanup.md), [throughput diagnostics](web_throughput_diagnostics.md) and [legacy storage compatibility](roadmap.md#phase8-legacy-credential-compatibility). Broker read means transport handoff, not peer receipt; capture non-consuming counters before disconnect. TLS `-0x004C` is generic NET_RECV_FAILED, not evidence of OOM. Resource minima and counter observations require attribution, not inferred causes.
|
||||||
|
|
||||||
Phase 8D.15's dedicated typed network-diagnostics UI/API was removed: diagnostics remain shell-based, subject to frontend policy. The unimplemented 8D.19 ordinary browser-session/native-USB control expansion was removed; existing SSH controls remain. No full shell parity, browser identity recovery/reset/export, encryption, secure boot or OTA is implied by acceptance. UART0 is the administrative recovery authority; native USB is binary-transparent, network-independent UART1 access. Neither permits bypassing the broker's single writer or recalling already-admitted work.
|
Phase 8D.15's dedicated typed network-diagnostics UI/API was removed: diagnostics remain shell-based, subject to frontend policy. The unimplemented 8D.19 ordinary browser-session/native-USB control expansion was removed; existing SSH controls remain. No full shell parity, browser identity recovery/reset/export, encryption, secure boot or OTA is implied by acceptance. UART0 is the administrative recovery authority; native USB is binary-transparent, network-independent UART1 access. Neither permits bypassing the broker's single writer or recalling already-admitted work.
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
# Web administration acceptance
|
|
||||||
|
|
||||||
## Phase 8D.22 sign-off — 2026-09-13
|
|
||||||
|
|
||||||
The user explicitly accepted the tested firmware: **“Yep, I tested the firmware thats a 8d.22 signoff.”** Phase 8D is complete for its retained scope. This supersedes earlier per-slice target-pending, parent-review and integration-acceptance gates; it does not require additional testing to establish the user's sign-off. Phase 8A/B/C were already recorded as complete and target-hardware validated in the roadmap, so [Phase 8 is complete](roadmap.md#phase-8--role-based-users-and-administrative-access--complete).
|
|
||||||
|
|
||||||
Accepted functionality comprises cookie authentication, isolated browser serial/admin terminals, typed Serial/Accounts/authorized-key/Network/Display/Broker/SSH/HTTPS settings, contextual controls, confirmed generation-safe writer/service/identity actions and retained UART0/native-USB recovery. [Current contracts](web_administration.md) define actual permissions, bounded failures and partial effects; acceptance is not a claim of unrestricted browser-shell parity.
|
|
||||||
|
|
||||||
Scope decisions remain effective: 8D.15 dedicated typed network diagnostics was removed (shell diagnostics retained); the unimplemented 8D.19 ordinary browser-session/native-USB control remainder was removed (SSH controls retained). Browser identity Reset/recovery/export was not added. Phase 9 security/production hardening is next only on a separate user request.
|
|
||||||
|
|
||||||
## Latest firmware evidence
|
|
||||||
|
|
||||||
The **prior final firmware build passed**, reporting **100,556 bytes linked RAM / 1,828,573 bytes flash**, at **160 MHz**. This is recorded prior build evidence, not a build run during documentation consolidation. Host regression suites and independent implementation reviews were previously reported passing; no new host/runtime test pass is asserted here.
|
|
||||||
|
|
||||||
Latest user telemetry, bytes:
|
|
||||||
|
|
||||||
| Sample / memory capability | Free | Minimum free | Largest block |
|
|
||||||
|---|---:|---:|---:|
|
|
||||||
| Boot internal 8-bit | 59,808 | 58,840 | 31,744 |
|
|
||||||
| Boot internal DMA | 52,052 | 51,084 | 31,744 |
|
|
||||||
| Boot PSRAM | 8,196,968 | 8,183,972 | 8,126,464 |
|
|
||||||
| Loaded after burst, internal 8-bit | 31,508 | 2,052 | 18,432 |
|
|
||||||
| Loaded after burst, internal DMA | 23,752 | 460 | 18,432 |
|
|
||||||
| Loaded after burst, PSRAM | 8,136,624 | 8,065,972 | 7,995,392 |
|
|
||||||
|
|
||||||
Loaded SSH minimum-free stack was **15,028 bytes**. The capture had two active SSH sessions across the serial/admin roles, two serial WebSockets and USB, with SSH holding the serial writer. Browser admin had been used and then closed; it was **not active in the captured loaded sample**. Web send/queue/protocol error counters were zero; SSH IO errors were zero, with one handshake failure and one session revocation retained without attributing a cause.
|
|
||||||
|
|
||||||
Latest broker/serial counters were not supplied, so these transport counters do **not** establish an exact latest zero-drop or byte-integrity result. No latest full-mix-with-browser-admin-active, individual fault-injection, exact duration, soak, cleanup-cycle or reserve-floor result is inferred. Generic SDK TLS `-0x004C` / NET_RECV_FAILED is not an OOM diagnosis. Two boot authentication failures could plausibly involve stale browser cookies, but that explanation is unconfirmed.
|
|
||||||
|
|
||||||
## Earlier acceptance retained without replaying the timeline
|
|
||||||
|
|
||||||
- M1 browser login/logout and M2 shared browser administration were explicitly accepted by the user; later Serial/account/Network presentation and legacy-credential cleanup also received scoped acceptance.
|
|
||||||
- The user explicitly accepted the combined binary WebSocket-send fix at **160 MHz, 230400 baud with the full client mix, including browser admin**. That prior acceptance stands independently of the latest capture's closed browser-admin socket. It does not imply an unreported latest exact counter comparison or soak duration. Keep the combined send and bounded failed-send isolation, not the earlier frequency-only experiment.
|
|
||||||
- Ordinary HTTPS idle cleanup was accepted as working; that is not a guarantee against all future admission failures or owner delays.
|
|
||||||
|
|
||||||
## Nonblocking follow-ups and evidence limits
|
|
||||||
|
|
||||||
The extremely low internal/DMA lifetime minima remain an unresolved transient-headroom follow-up, **not a blocker reopening 8D sign-off and not an approved reserve**. Capability pools overlap; summed per-region lifetime minima can be conservative/non-simultaneous and do not prove an allocation failure. Do not add internal and DMA numbers together or attribute an error to memory pressure without correlated evidence. HTTPD/dispatcher stack margins, peak correlation, allocation reserve policy and long-run cleanup/soak evidence remain distinct future measurements.
|
|
||||||
|
|
||||||
[Regression procedures](user_administration_tests.md#integrated-web-administration-regression-procedure) and focused test runners remain available for future changes; listing them is not evidence they all ran on hardware. Documentation-only consolidation changes no firmware, configuration, generated assets or test implementation and performs no build/upload/erase/commit. No new Phase 9 work is authorized by this acceptance.
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Web admission diagnostics
|
# Web admission diagnostics
|
||||||
|
|
||||||
Current default-disabled instrumentation, not an admission fix or an allocation-failure detector. `src/web_diagnostics.{c,h}` observes public synchronous HTTPS create/close callbacks and the four serial/admin ticket/upgrade handlers. It adds no owner task, queued probe or socket-capacity change. See [ordinary idle cleanup](https_idle_cleanup.md) for the independent cleanup policy and [acceptance evidence](web_administration_acceptance.md) for user reports.
|
Current default-disabled instrumentation, not an admission fix or an allocation-failure detector. `src/web_diagnostics.{c,h}` observes public synchronous HTTPS create/close callbacks and the four serial/admin ticket/upgrade handlers. It adds no owner task, queued probe or socket-capacity change. See [ordinary idle cleanup](https_idle_cleanup.md) for the independent cleanup policy and [acceptance evidence](roadmap.md#phase8-acceptance-evidence) for user reports.
|
||||||
|
|
||||||
## Usage and interpretation
|
## Usage and interpretation
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Current contract and accepted fix
|
## Current contract and accepted fix
|
||||||
|
|
||||||
Default-disabled instrumentation measures broker fan-out and binary WebSocket TX, not CPU usage, peer receipt or pure scheduler latency. The user separately accepted the combined binary header/payload-send fix at **160 MHz / 230400 baud with full mix including browser admin**. [Acceptance evidence](web_administration_acceptance.md) distinguishes that report from the latest capture and unmeasured reserves. The old frequency-only experiment is not the retained solution.
|
Default-disabled instrumentation measures broker fan-out and binary WebSocket TX, not CPU usage, peer receipt or pure scheduler latency. The user separately accepted the combined binary header/payload-send fix at **160 MHz / 230400 baud with full mix including browser admin**. [Acceptance evidence](roadmap.md#phase8-acceptance-evidence) distinguishes that report from the latest capture and unmeasured reserves. The old frequency-only experiment is not the retained solution.
|
||||||
|
|
||||||
`web_httpd_ws_send_binary` is an IDF-5.5.0-pinned owner-only session-override send with a bounded 516-byte header/payload scratch copy and 512-byte payload. Generation validation and one outstanding item per slot remain. A non-full send installs a reject-only override before close/shutdown, preventing SDK automatic PONG/CLOSE from reentering TLS with different arguments after incomplete output, even if shutdown fails. No retry/replay; HTTPD owns TLS destruction. Text/control/admin retain the SDK sender. One API call does not promise one TLS record/packet or peer receipt. Keep CPU160, priorities, scheduling and 4096-byte broker/512-byte web payload bounds unless separately changing them with evidence.
|
`web_httpd_ws_send_binary` is an IDF-5.5.0-pinned owner-only session-override send with a bounded 516-byte header/payload scratch copy and 512-byte payload. Generation validation and one outstanding item per slot remain. A non-full send installs a reject-only override before close/shutdown, preventing SDK automatic PONG/CLOSE from reentering TLS with different arguments after incomplete output, even if shutdown fails. No retry/replay; HTTPD owns TLS destruction. Text/control/admin retain the SDK sender. One API call does not promise one TLS record/packet or peer receipt. Keep CPU160, priorities, scheduling and 4096-byte broker/512-byte web payload bounds unless separately changing them with evidence.
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -16,7 +16,7 @@ CONFIG_ESP_WIFI_RX_BA_WIN=6
|
|||||||
CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4
|
CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4
|
||||||
|
|
||||||
# Keep concurrent HTTPS handshakes from exhausting scarce internal DRAM.
|
# Keep concurrent HTTPS handshakes from exhausting scarce internal DRAM.
|
||||||
# Active TLS material remains unencrypted in PSRAM until the hardening phase.
|
# Active TLS material remains unencrypted in PSRAM; physical extraction is outside scope.
|
||||||
CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y
|
CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y
|
||||||
# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC is not set
|
# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC is not set
|
||||||
# Hardware AES can hang in the PSRAM DMA path and cannot be shared safely with
|
# Hardware AES can hang in the PSRAM DMA path and cannot be shared safely with
|
||||||
@@ -72,3 +72,8 @@ CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y
|
|||||||
|
|
||||||
# Keep diagnostic and interactive-console logging concise but useful.
|
# Keep diagnostic and interactive-console logging concise but useful.
|
||||||
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
|
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
|
||||||
|
|
||||||
|
# Intermittent-use baseline: avoid secret-bearing crash dumps/register output.
|
||||||
|
# Ordinary logging remains enabled; this is not physical-memory protection.
|
||||||
|
CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y
|
||||||
|
CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT=y
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ No firmware build, network access or device operation is performed.
|
|||||||
|
|
||||||
Implementer reports `run.py --tickets` PASS **25 transport / 12 ticket groups**, including certificate owner routing, currentness rejection and commit → stop → start short-circuit/error behavior. The owner's `dispatcher_actions` mask selects the existing 12 KiB dispatcher, not the 4 KiB control task. `tests/admin_console_boundary/run.py` (including `certificate.c`) separately covers typed deferred handoff/pending gate/executing reservation; `lifecycle.py` covers canonical handlers and unchanged SSH/UART0 behavior. Policy, server lifecycle **11**, cookie `--admin` and store `--serial` also pass as reported. Independent review has no actionable findings; sanitizer validation is unavailable due to missing libasan/libubsan. No hardware validation is claimed or performed by this documentation update.
|
Implementer reports `run.py --tickets` PASS **25 transport / 12 ticket groups**, including certificate owner routing, currentness rejection and commit → stop → start short-circuit/error behavior. The owner's `dispatcher_actions` mask selects the existing 12 KiB dispatcher, not the 4 KiB control task. `tests/admin_console_boundary/run.py` (including `certificate.c`) separately covers typed deferred handoff/pending gate/executing reservation; `lifecycle.py` covers canonical handlers and unchanged SSH/UART0 behavior. Policy, server lifecycle **11**, cookie `--admin` and store `--serial` also pass as reported. Independent review has no actionable findings; sanitizer validation is unavailable due to missing libasan/libubsan. No hardware validation is claimed or performed by this documentation update.
|
||||||
|
|
||||||
Current [browser-shell policy](../../docs/web_administration.md#browser-shell-policy) permits selected other-account mutations as well as exact parsed `web status`, `web stop`, `web certificate rotate --force`, and `reboot`/self-close; network mutations and restricted SSH lifecycle/key mutations remain blocked in the shell. Typed Settings permissions are separate. Certificate drain/acknowledgement bounds do not bound queued execution or prove browser receipt. [Acceptance evidence](../../docs/web_administration_acceptance.md) records M2 and the later 8D.22 signoff; earlier pending gates below are historical, not current acceptance blockers.
|
Current [browser-shell policy](../../docs/web_administration.md#browser-shell-policy) permits selected other-account mutations as well as exact parsed `web status`, `web stop`, `web certificate rotate --force`, and `reboot`/self-close; network mutations and restricted SSH lifecycle/key mutations remain blocked in the shell. Typed Settings permissions are separate. Certificate drain/acknowledgement bounds do not bound queued execution or prove browser receipt. [Acceptance evidence](../../docs/roadmap.md#phase8-acceptance-evidence) records M2 and the later 8D.22 signoff; earlier pending gates below are historical, not current acceptance blockers.
|
||||||
|
|
||||||
## Earlier results recorded 2026-09-06
|
## Earlier results recorded 2026-09-06
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ below. Final admin closure uses direct HTTPD-owned `shutdown`, not queued IDF
|
|||||||
session-close work. Parent reports the sequential final firmware build after this
|
session-close work. Parent reports the sequential final firmware build after this
|
||||||
fix passed in **23.55 s**, at **95,580 B RAM / 1,637,273 B flash**, and the final
|
fix passed in **23.55 s**, at **95,580 B RAM / 1,637,273 B flash**, and the final
|
||||||
independent security integration review found no actionable findings. See
|
independent security integration review found no actionable findings. See
|
||||||
[terminal ownership](../../docs/web_administration.md#terminal-and-console-ownership) and [acceptance evidence](../../docs/web_administration_acceptance.md) for current contracts and signoff limits.
|
[terminal ownership](../../docs/web_administration.md#terminal-and-console-ownership) and [acceptance evidence](../../docs/roadmap.md#phase8-acceptance-evidence) for current contracts and signoff limits.
|
||||||
|
|
||||||
After the production empty-frame, input-deadline and timer-generation fixes:
|
After the production empty-frame, input-deadline and timer-generation fixes:
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Coverage includes challenge reuse/consumption/expiry, capacities without evictio
|
|||||||
|
|
||||||
This is **not** the full IDF parser/dispatcher, real handshake/TLS/socket, browser, multicore task or hardware test. The private struct doubles do not prove binary layout; firmware compilation uses the actual pinned headers, and the version guard requires a new audit on SDK changes. Handshake sending and transport revocation are doubled. Actual on-wire pre-101 rejection, frame routing, pipelining/early bytes, cookie/CSP/browser recovery and loaded expiry latency require real-target evidence beyond this harness; M1 and the retained Phase 8D scope have since been accepted. No sanitizer or runtime memory-reserve result is implied.
|
This is **not** the full IDF parser/dispatcher, real handshake/TLS/socket, browser, multicore task or hardware test. The private struct doubles do not prove binary layout; firmware compilation uses the actual pinned headers, and the version guard requires a new audit on SDK changes. Handshake sending and transport revocation are doubled. Actual on-wire pre-101 rejection, frame routing, pipelining/early bytes, cookie/CSP/browser recovery and loaded expiry latency require real-target evidence beyond this harness; M1 and the retained Phase 8D scope have since been accepted. No sanitizer or runtime memory-reserve result is implied.
|
||||||
|
|
||||||
See [authentication contracts](../../docs/web_administration.md#authentication-and-admission), [acceptance evidence and limits](../../docs/web_administration_acceptance.md), and [regression procedures](../../docs/user_administration_tests.md#integrated-web-administration-regression-procedure).
|
See [authentication contracts](../../docs/web_administration.md#authentication-and-admission), [acceptance evidence and limits](../../docs/roadmap.md#phase8-acceptance-evidence), and [regression procedures](../../docs/user_administration_tests.md#integrated-web-administration-regression-procedure).
|
||||||
|
|
||||||
## Accounts (8D.10)
|
## Accounts (8D.10)
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ The second command separately exercises production conditional database mutation
|
|||||||
and zero-wait list bodies with NVS/RTOS doubles, including last-admin protection,
|
and zero-wait list bodies with NVS/RTOS doubles, including last-admin protection,
|
||||||
target generation/recreation checks and commit-failure cleanup. It retains the
|
target generation/recreation checks and commit-failure cleanup. It retains the
|
||||||
canonical CLI account tests. These are not end-to-end RTOS/flash/TLS tests.
|
canonical CLI account tests. These are not end-to-end RTOS/flash/TLS tests.
|
||||||
See [Accounts contracts](../../docs/web_administration.md#accounts-and-authorized-keys) and [acceptance evidence](../../docs/web_administration_acceptance.md). Timer doubles do not prove hard cleanup latency.
|
See [Accounts contracts](../../docs/web_administration.md#accounts-and-authorized-keys) and [acceptance evidence](../../docs/roadmap.md#phase8-acceptance-evidence). Timer doubles do not prove hard cleanup latency.
|
||||||
|
|
||||||
## Read-only Serial Settings
|
## Read-only Serial Settings
|
||||||
|
|
||||||
@@ -62,4 +62,4 @@ registration. No SDK files are modified. Lifecycle registration/optional failure
|
|||||||
orchestration is separately tested by `tests/web_admin_transport/server_lifecycle.py`.
|
orchestration is separately tested by `tests/web_admin_transport/server_lifecycle.py`.
|
||||||
|
|
||||||
This does not run the full serial task/UART driver, TLS/network dispatcher or a real
|
This does not run the full serial task/UART driver, TLS/network dispatcher or a real
|
||||||
browser. See [typed Settings contracts](../../docs/web_administration.md#typed-settings-api-and-operation-lifetime) and [Serial semantics](../../docs/web_administration.md#serial-and-display). [Acceptance evidence](../../docs/web_administration_acceptance.md) records the 8D.22 signoff without inferring individual target comparisons or runtime memory/stack margins.
|
browser. See [typed Settings contracts](../../docs/web_administration.md#typed-settings-api-and-operation-lifetime) and [Serial semantics](../../docs/web_administration.md#serial-and-display). [Acceptance evidence](../../docs/roadmap.md#phase8-acceptance-evidence) records the 8D.22 signoff without inferring individual target comparisons or runtime memory/stack margins.
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ survives until its owner releases it after service stop/start.
|
|||||||
`python3 tests/web_admin_transport/server_lifecycle.py` additionally links real
|
`python3 tests/web_admin_transport/server_lifecycle.py` additionally links real
|
||||||
production security and mbedTLS to the production HTTPS owner, with NVS/HTTPD doubles,
|
production security and mbedTLS to the production HTTPS owner, with NVS/HTTPD doubles,
|
||||||
for unchanged identity/storage before commit and no rollback after stop/start failure.
|
for unchanged identity/storage before commit and no rollback after stop/start failure.
|
||||||
See [HTTPS identity contracts](../../docs/web_administration.md#service-lifecycle-and-identity-rotation) and [acceptance evidence and limits](../../docs/web_administration_acceptance.md).
|
See [HTTPS identity contracts](../../docs/web_administration.md#service-lifecycle-and-identity-rotation) and [acceptance evidence and limits](../../docs/roadmap.md#phase8-acceptance-evidence).
|
||||||
|
|
||||||
Removed: two credential functions (`show_credentials`, `rotate_credentials`),
|
Removed: two credential functions (`show_credentials`, `rotate_credentials`),
|
||||||
one credential struct type, three username/password capacity/length constants,
|
one credential struct type, three username/password capacity/length constants,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ and inline asset-failure script, not a separately maintained implementation.
|
|||||||
|
|
||||||
Historical 8D.17 run: **126 behavior groups**, plus production renderer/HTML/CSP checks. Seven new quick groups cover mouse/focus/touch activation, single DOM ownership, focused-editor hover stability, Escape/outside dismissal, late reads/expiry, terminal input/drain isolation, full-page draft/promotion preservation, explicit Apply/Save and pending non-replay, Network secret exclusion/strict schema/401. `Element` focus/containment/hover and events are doubles, not browser event-dispatch proof.
|
Historical 8D.17 run: **126 behavior groups**, plus production renderer/HTML/CSP checks. Seven new quick groups cover mouse/focus/touch activation, single DOM ownership, focused-editor hover stability, Escape/outside dismissal, late reads/expiry, terminal input/drain isolation, full-page draft/promotion preservation, explicit Apply/Save and pending non-replay, Network secret exclusion/strict schema/401. `Element` focus/containment/hover and events are doubles, not browser event-dispatch proof.
|
||||||
|
|
||||||
Optional geometry: `WEB_UI_CHROMIUM=/usr/bin/chromium-browser python3 tests/web_ui_session/run.py`. The fixture covers 36 cases at 320/600/900/1200px: full settings and quick panels plus dashboard card hit-testing, overflow/ellipsis, compact controls, status visibility, and full-page restoration. Quick panels use height 360px. The 2026-09-14 cosmetic update passed these Chromium fixtures and all 161 browser behavior groups; fixtures are not live-device validation. See [contextual-control contracts](../../docs/web_administration.md#broker-and-contextual-controls), [acceptance evidence and limits](../../docs/web_administration_acceptance.md), and [regression procedures](../../docs/user_administration_tests.md#integrated-web-administration-regression-procedure).
|
Optional geometry: `WEB_UI_CHROMIUM=/usr/bin/chromium-browser python3 tests/web_ui_session/run.py`. The fixture covers 36 cases at 320/600/900/1200px: full settings and quick panels plus dashboard card hit-testing, overflow/ellipsis, compact controls, status visibility, and full-page restoration. Quick panels use height 360px. The 2026-09-14 cosmetic update passed these Chromium fixtures and all 161 browser behavior groups; fixtures are not live-device validation. See [contextual-control contracts](../../docs/web_administration.md#broker-and-contextual-controls), [acceptance evidence and limits](../../docs/roadmap.md#phase8-acceptance-evidence), and [regression procedures](../../docs/user_administration_tests.md#integrated-web-administration-regression-procedure).
|
||||||
|
|
||||||
Coverage:
|
Coverage:
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ These tests model DOM, timers, fetch cancellation and WebSocket events. They do
|
|||||||
not prove real-browser CSP enforcement, script-loading errors, TLS/HTTPD behavior,
|
not prove real-browser CSP enforcement, script-loading errors, TLS/HTTPD behavior,
|
||||||
actual bfcache policy, cookie expiry, server revocation, or hardware serial byte
|
actual bfcache policy, cookie expiry, server revocation, or hardware serial byte
|
||||||
integrity, actual xterm escape parsing, hidden prompts, or desktop/mobile layout.
|
integrity, actual xterm escape parsing, hidden prompts, or desktop/mobile layout.
|
||||||
See [Accounts contracts](../../docs/web_administration.md#accounts-and-authorized-keys) and [acceptance evidence](../../docs/web_administration_acceptance.md). The following are historical 8D.10 slice 2 reports, not current totals: parent build PASS 25.61 s, 95,908 B RAM / 1,694,237 B flash.
|
See [Accounts contracts](../../docs/web_administration.md#accounts-and-authorized-keys) and [acceptance evidence](../../docs/roadmap.md#phase8-acceptance-evidence). The following are historical 8D.10 slice 2 reports, not current totals: parent build PASS 25.61 s, 95,908 B RAM / 1,694,237 B flash.
|
||||||
The generated endpoint is independently optionally registered (23 handlers), with
|
The generated endpoint is independently optionally registered (23 handlers), with
|
||||||
route-agent lifecycle 15 PASS for failure isolation/restart. UI 57/CSP and lifecycle
|
route-agent lifecycle 15 PASS for failure isolation/restart. UI 57/CSP and lifecycle
|
||||||
15 results are agent-attributed, not claims of the parent's additional reruns.
|
15 results are agent-attributed, not claims of the parent's additional reruns.
|
||||||
|
|||||||
Reference in New Issue
Block a user