Updated memory baselines
This commit is contained in:
+118
-19
@@ -1,6 +1,6 @@
|
|||||||
# Phase 8D.0 — Baseline and M1 browser contract
|
# Phase 8D.0 — Baseline and M1 browser contract
|
||||||
|
|
||||||
Status: **documentation/source audit, baseline build and user-provided runtime memory baseline recorded; remaining target validation and numeric runtime budgets pending.** This is a plan for M1, not implemented authentication. Stop at 8D.0; do not start 8D.1 without the missing evidence or an explicit user decision. See [execution plan](phase8d_plan.md) and [acceptance matrix](user_administration_tests.md#planned-phase-8d-integrated-web-administration).
|
Status: **documentation/source audit, baseline build and user-provided runtime memory baseline recorded; remaining target validation and numeric runtime budgets pending.** The M1 browser contract below remains planned, not implemented authentication. The user explicitly requested 8D.1 with remaining reserve gates pending; its internal-primitives results are recorded below. See [execution plan](phase8d_plan.md) and [acceptance matrix](user_administration_tests.md#planned-phase-8d-integrated-web-administration).
|
||||||
|
|
||||||
## Reproducible build baseline
|
## Reproducible build baseline
|
||||||
|
|
||||||
@@ -120,29 +120,116 @@ Five new handlers mean **14 route slots total** at cutover if using these exact
|
|||||||
|
|
||||||
## Runtime measurements, reserve gates and exact target checklist
|
## Runtime measurements, reserve gates and exact target checklist
|
||||||
|
|
||||||
**The user-provided concurrent-session sample below is the runtime memory baseline. Other workload measurements remain pending, not zero.** `memory` reports free/minimum-free/largest-block for internal 8-bit, internal DMA and PSRAM. Record all nine values at every point. DMA overlaps internal heap: do not sum them. Minimum-free is the conservative sum of per-region lifetime minima, not a synchronized low-water sample. Only SSH currently exposes stack minimum-free via `ssh status`; HTTPD/web/broker/admin/UART task margins lack instrumentation and remain pending (no telemetry changes in 8D.0).
|
**The user-provided settled-boot and concurrent-session samples below form the 8D.0 runtime memory baseline. Other workload measurements remain pending, not zero.** `memory` reports free/minimum-free/largest-block for internal 8-bit, internal DMA and PSRAM. Record all nine values at every point. DMA overlaps internal heap: do not sum them. Minimum-free is the conservative sum of per-region lifetime minima, not a synchronized low-water sample. Only SSH currently exposes stack minimum-free via `ssh status`; HTTPD/web/broker/admin/UART task margins lack instrumentation and remain pending (no telemetry changes in 8D.0).
|
||||||
|
|
||||||
| Workload point | Internal free/min/largest | DMA free/min/largest | PSRAM free/min/largest | SSH stack minimum-free |
|
| Workload point | Internal free/min/largest | DMA free/min/largest | PSRAM free/min/largest | SSH stack minimum-free |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| Settled boot, 60 seconds, network services up | Pending | Pending | Pending | Pending |
|
| **Settled clean boot, ~60 seconds, Wi-Fi STA connected, mDNS running (8D.0, user-provided)** | **68,036 / 67,192 / 31,744 B** | **60,280 / 59,436 / 31,744 B** | **8,198,508 / 8,188,800 / 8,126,464 B** | **18,464 B** |
|
||||||
| Basic-authenticated browser/status, serial explicitly disconnected | Pending | Pending | Pending | Pending |
|
| **Basic-authenticated browser/status, browser serial explicitly disconnected, UART service running; fresh settled boot (user-provided)** | **65,340 / 60,088 / 31,744 B** | **57,584 / 52,332 / 31,744 B** | **8,212,812 / 8,158,868 / 8,126,464 B** | **18,464 B** |
|
||||||
| **Baseline: one browser serial + user SSH + admin SSH (user-provided)** | **39,668 / 13,876 / 18,432 B** | **31,912 / 6,120 / 18,432 B** | **8,138,380 / 8,107,324 / 7,995,392 B** | Pending |
|
| **Basic-authenticated browser/status, browser serial explicitly disconnected, UART service stopped (user-provided)** | **69,988 / 60,280 / 31,744 B** | **62,232 / 52,524 / 31,744 B** | **8,223,088 / 8,158,832 / 8,126,464 B** | **18,464 B** |
|
||||||
| Two browser serial + USB DTR + user SSH + admin SSH | Pending | Pending | Pending | Pending |
|
| **Browser/status sample: one active browser serial writer, no SSH sessions (user-provided; disconnected label unconfirmed)** | **60,980 / 55,880 / 31,744 B** | **53,224 / 48,124 / 31,744 B** | **8,163,616 / 8,109,644 / 7,995,392 B** | **18,464 B** |
|
||||||
| After five serial disconnect/reconnect cycles | Pending | Pending | Pending | Pending |
|
| **Updated baseline: one browser serial + user SSH + admin SSH (user-provided)** | **44,552 / 17,812 / 31,744 B** | **36,796 / 10,056 / 31,744 B** | **8,187,416 / 8,176,688 / 8,126,464 B** | **16,288 B** |
|
||||||
| After 15-minute concurrent soak, then 60-second settled cleanup | Pending | Pending | Pending | Pending |
|
| **Baseline follow-up: two browser serial + USB + user SSH + admin SSH (user-provided)** | **42,056 / 17,812 / 29,696 B** | **34,300 / 10,056 / 29,696 B** | **8,162,828 / 8,126,736 / 7,995,392 B** | **16,288 B** |
|
||||||
|
| **After five browser serial disconnect/reconnect cycles, ending connected as user writer (user-provided)** | **60,776 / 59,792 / 31,744 B** | **53,020 / 52,036 / 31,744 B** | **8,163,656 / 8,153,968 / 8,126,464 B** | **18,464 B** |
|
||||||
|
| **After 15-minute concurrent soak, clients disconnected, then 60-second settled cleanup; UART running (user-provided)** | **65,040 / 17,812 / 31,744 B** | **57,284 / 10,056 / 31,744 B** | **8,212,596 / 8,126,736 / 8,126,464 B** | **16,288 B** |
|
||||||
| Cookie login/logout and browser admin connected | Not implemented | Not implemented | Not implemented | Not implemented |
|
| Cookie login/logout and browser admin connected | Not implemented | Not implemented | Not implemented | Not implemented |
|
||||||
|
|
||||||
### Runtime baseline provenance and observed workload
|
### Settled clean-boot sample (8D.0 firmware)
|
||||||
|
|
||||||
Recorded from the user's administrative SSH transcript supplied on 2026-09-05, at the user's request to use it as the memory baseline. Commands were `broker clients`, `ssh sessions`, `web status`, then `memory`; these are sequential snapshots, not an atomic sample or an agent-executed test.
|
The user supplied this transcript on 2026-09-05 after 8D.1 work had begun, explicitly identifying the measured firmware as based on **8D.0**, not 8D.1. Conditions reported: clean boot, settled after approximately 60 seconds, Wi-Fi STA connected and mDNS running. Commands were `memory`, `ssh sessions`, `broker clients`, `ssh counters`, `web counters`, `web status`, then `mdns status`; these are sequential user-provided snapshots, not an atomic sample or an agent-executed test.
|
||||||
|
|
||||||
- HTTPS initialized/running on port 443, `last-error=ESP_OK`, HTTP Basic via the user database (four users, two admins).
|
- SSH sessions **0/2**; no broker clients connected. HTTPS initialized/running, not transitioning, port 443, `last-error=ESP_OK`; HTTP Basic via the user database, four users and two admins. Web serial attached, sessions **0/2**, zero tickets. Endpoints reported: `GET /`, `GET /api/status`, `POST /api/ws-ticket`, `WSS /ws/serial`.
|
||||||
- One of two web serial slots active, zero outstanding tickets: role-`user` password-authenticated browser, broker client **8**, **writer**; no pending TX or closing state reported.
|
- mDNS initialized and announced, hostname `sak-1024.local`, suffix `1024`, `last-error=ESP_OK`. This records announcement status, not an independently verified hostname-resolution test.
|
||||||
- Both SSH slots active, public-key authenticated: role-`user` SSH session **5**, broker client **9**, **observer**; role-`admin` SSH session **6**, administrative console, no broker client. The admin command was running with two output bytes and TX pending during `ssh sessions`, consistent with collecting the sample through admin SSH.
|
- SSH counters: lifecycle starts **1**, start-failures/stops/TCP connections/capacity rejects **0**. All handshake, authentication, request-rejection, broker, admin-console and stream counters **0**, including failures, backpressure and revocations.
|
||||||
- Broker listed exactly two clients, both with zero pending bytes/events. No USB broker client was present; physical USB attachment/DTR was not reported. This is not the planned two-browser-plus-USB full workload.
|
- Web counters: lifecycle starts **1**, start-failures/stops **0**. Requests total **29**, authenticated **29**, status **29**; auth-failures/root/tickets/assets/response-errors **0**. All ticket, WebSocket session, RX, TX, writer-control and failure counters **0**, including service-start/broker failures and closes.
|
||||||
- Flashed revision/configuration, browser/version and origin, baud/framing/flow, uptime, traffic volume, soak duration, cycle counts and stack margins were not supplied. The transcript is accepted as the runtime baseline, but does not independently tie the device to the build hash above or prove serial data integrity, both-role browser login, recovery/USB operation or lifecycle stability.
|
- The 29 authenticated status requests mean this is a settled boot with HTTPS status activity, not a no-HTTP-traffic idle sample. Browser/version, request origin and polling source were not supplied; do not infer an additional controlled browser-only workload measurement from these counters.
|
||||||
|
- Follow-up user-provided `ssh status` for settled boot: initialized/running, not transitioning, port **22**, `last-error=ESP_OK`, sessions **0/2**. Authentication reports role-based password and SSH public key via the user database; admission reports shell/PTY only, with exec, subsystem, forwarding, SCP and SFTP disabled. Owner task on core **1**, configured stack **20,480 B**, stack minimum-free **18,464 B**. This is a settled-boot stack low-water measurement, not a loaded-workload margin or approved reserve floor.
|
||||||
|
- Exact flashed revision/configuration or binary hash was not supplied. The user's 8D.0 firmware attribution is retained without independently tying this device to the build hash above. This sample does not validate 8D.1, establish reserve floors or measure post-load cleanup; do not treat comparisons with the earlier concurrent samples as controlled per-client allocation deltas.
|
||||||
|
|
||||||
The lifetime minimum-free values may reflect earlier workloads in the same boot. This one sample does not establish a leak/fragmentation trend, per-connection cost or safe allocation allowance. In particular, **6,120 B minimum-free DMA** and **13,876 B minimum-free internal 8-bit heap** are observed lows, not approved reserve floors. Preserve all nine exact values for future like-for-like comparisons.
|
### Browser/status sample with active serial WebSocket
|
||||||
|
|
||||||
|
The user supplied this additional baseline transcript on 2026-09-05 labelled "Basic-authenticated browser/status, serial explicitly disconnected." However, the supplied `web status` reports **one active serial writer**, and counters report one connection with zero disconnects/closes. Preserve the measurements separately; the later disconnected sample below also stops the UART service. Commands were `memory`, `ssh sessions`, `ssh counters`, `web counters`, `web status`, `mdns status`, then `ssh status`, so the snapshots are not atomic.
|
||||||
|
|
||||||
|
- HTTPS initialized/running, not transitioning, port **443**, `last-error=ESP_OK`; HTTP Basic via the user database, four users and two admins, unchanged endpoint list. Web serial attached, sessions **1/2**, zero tickets; slot **0**, fd **56**, generation **1**, role-`user` password authentication, broker **8 writer**, no TX pending or closing state. No `broker clients` snapshot was supplied, so other broker-client presence is not established.
|
||||||
|
- Web lifecycle: starts **1**, start-failures/stops **0**. Requests total/authenticated **28**, root **1**, status **26**, tickets **1**, assets **0**, auth-failures/response-errors **0**. Tickets issued/consumed **1**, rejected/expired **0**. WebSocket connects **1**, disconnects **0**, connect/service-start/broker failures **0**.
|
||||||
|
- WebSocket RX: **14** accepted frames / **14 B**, no rejected frames/bytes. TX: **18** binary frames / **753 B**, **2** control frames / **148 B**. Writer requests/grants **1**, denials/releases/revocations **0**; send/queue/protocol failures and closes **0**.
|
||||||
|
- SSH initialized/running, not transitioning, port **22**, `last-error=ESP_OK`, sessions **0/2**; role-based password/public-key authentication and shell/PTY-only admission, with exec/subsystem/forwarding/SCP/SFTP disabled. Owner task core **1**, stack **20,480 B**, minimum-free **18,464 B**. SSH lifecycle starts **1**; all other supplied SSH counters **0**.
|
||||||
|
- mDNS initialized/announced, hostname `sak-1024.local`, suffix `1024`, `last-error=ESP_OK`.
|
||||||
|
- This is user-provided baseline evidence, not an 8D.1 target-validation claim. Exact flashed revision/hash, browser/version/origin, settling duration and serial fixture were not supplied. Web request totals are lower than in the settled-boot transcript; same-boot continuity is not established, and no controlled heap delta is inferred. Lifetime minima include prior activity, including the reported serial traffic.
|
||||||
|
|
||||||
|
### Browser disconnected, UART service stopped
|
||||||
|
|
||||||
|
The user supplied this follow-up 8D.0 baseline transcript on 2026-09-05, reporting that the browser automatically connected serial after login, then was explicitly disconnected and the serial service stopped. Commands were `memory`, `ssh sessions`, `ssh counters`, `web counters`, `web status`, `mdns status`, `ssh status`, then `serial status`; these are sequential observations, not an atomic sample or an agent-executed test.
|
||||||
|
|
||||||
|
- HTTPS initialized/running, not transitioning, port **443**, `last-error=ESP_OK`; HTTP Basic via the user database, four users and two admins, unchanged endpoints. Web serial attached, sessions **0/2**, zero tickets. This confirms browser serial disconnection; no `broker clients` snapshot was supplied to establish other broker-client presence.
|
||||||
|
- Web lifecycle starts **1**, start-failures/stops **0**. Requests total/authenticated **26**, root **1**, status **24**, tickets **1**, assets **0**, auth-failures/response-errors **0**. Tickets issued/consumed **1**, rejected/expired **0**. WebSocket connects/disconnects **1** each; connect/service-start/broker failures **0**.
|
||||||
|
- WebSocket RX accepted/rejected frames and bytes **0**; TX binary frames/bytes **0**, control frames **2** / **148 B**. Writer requests/grants **1**, denials/releases/revocations **0**. Send/queue/protocol failures and closes **0**; the zero closes counter is preserved separately from the reported disconnect count.
|
||||||
|
- SSH initialized/running, not transitioning, port **22**, `last-error=ESP_OK`, sessions **0/2**; role-based password/public-key authentication and shell/PTY-only admission, with exec/subsystem/forwarding/SCP/SFTP disabled. Owner task core **1**, stack **20,480 B**, minimum-free **18,464 B**. SSH lifecycle starts **1**, all other supplied SSH counters **0**.
|
||||||
|
- mDNS initialized/announced, hostname `sak-1024.local`, suffix `1024`, `last-error=ESP_OK`.
|
||||||
|
- UART service **stopped**, RS-232 owner **idle**. Configuration v1: **460800 baud, 8N1, no flow control**, DTR inactive, RTS threshold **96**; RX available/TX pending **0**. Phase 0 hardware commands reported available while stopped; none are claimed executed.
|
||||||
|
- Stopping the UART service changes the allocation workload, so this sample is not a substitute for browser-disconnected memory with the service running. That separate workload is recorded in the fresh-boot sample below. Prior automatic connection/startup can contribute to lifetime minima. Exact build hash, browser/version/origin, settling duration and same-boot continuity with earlier samples remain unspecified; do not infer controlled allocation savings, reserve floors or 8D.1 validation.
|
||||||
|
|
||||||
|
### Browser disconnected, UART service running
|
||||||
|
|
||||||
|
The user supplied this follow-up 8D.0 baseline transcript on 2026-09-05 after a **fresh, settled boot**, with the UART service running and browser serial explicitly disconnected after login. It fills the intended Basic-authenticated browser/status workload row. Commands were `memory`, `ssh sessions`, `ssh counters`, `web counters`, `web status`, `mdns status`, `ssh status`, then `serial status`; these are sequential user observations, not an atomic sample or an agent-executed test. Exact settling duration was not supplied.
|
||||||
|
|
||||||
|
- HTTPS initialized/running, not transitioning, port **443**, `last-error=ESP_OK`; HTTP Basic via the user database, four users and two admins, unchanged endpoints. Web serial attached, sessions **0/2**, zero tickets. No `broker clients` snapshot was supplied to establish other broker-client presence.
|
||||||
|
- Web lifecycle starts **1**, start-failures/stops **0**. Requests total/authenticated **31**, root **1**, status **28**, tickets **1**, assets **1**, auth-failures/response-errors **0**. Tickets issued/consumed **1**, rejected/expired **0**. WebSocket connects/disconnects **1** each; connect/service-start/broker failures **0**.
|
||||||
|
- WebSocket RX accepted/rejected frames and bytes **0**; TX binary frames/bytes **0**, control frames **2** / **148 B**. Writer requests/grants **1**, denials/releases/revocations **0**. Send/queue/protocol failures and closes **0**; closes and disconnects are distinct reported counters.
|
||||||
|
- SSH initialized/running, not transitioning, port **22**, `last-error=ESP_OK`, sessions **0/2**; role-based password/public-key authentication and shell/PTY-only admission, with exec/subsystem/forwarding/SCP/SFTP disabled. Owner task core **1**, stack **20,480 B**, minimum-free **18,464 B**. SSH lifecycle starts **1**, all other supplied SSH counters **0**.
|
||||||
|
- mDNS initialized/announced, hostname `sak-1024.local`, suffix `1024`, `last-error=ESP_OK`.
|
||||||
|
- UART service **running**, RS-232 owner **serial service**. Configuration v1: **460800 baud, 8N1, no flow control**, DTR inactive, RTS threshold **96**; RX available/TX pending **0**. Modem asserted: **DCD=0, DSR=1, CTS=1, RI=0**, valid-voltage **VLD=1**.
|
||||||
|
- Lifetime minima include startup and the browser's initial automatic serial connection, not just the disconnected state. This fresh boot is separate from previous samples; no controlled per-connection or service-stop allocation delta is inferred. Exact flashed revision/hash and browser/version/origin remain unspecified. This fills the workload measurement, not reserve-floor approval, serial data-integrity testing or 8D.1 target validation.
|
||||||
|
|
||||||
|
### After five browser serial disconnect/reconnect cycles
|
||||||
|
|
||||||
|
The user supplied this 8D.0 baseline transcript on 2026-09-05, reporting **five browser serial disconnect/reconnect cycles**. Commands were `memory`, `ssh sessions`, `ssh counters`, `web counters`, `web status`, `mdns status`, `ssh status`, then `serial status`; these are sequential user observations, not an atomic sample or an agent-executed test. The endpoint is **connected**, not settled disconnected cleanup.
|
||||||
|
|
||||||
|
- HTTPS initialized/running, not transitioning, port **443**, `last-error=ESP_OK`; HTTP Basic via the user database, four users and two admins, unchanged endpoints. Web serial attached, sessions **1/2**, zero tickets. Slot **0**, fd **54**, generation **8**, role-`user` password authentication, broker **64 writer**, no TX pending or closing state. No `broker clients` snapshot was supplied to establish other clients or independently check old-client cleanup.
|
||||||
|
- Web lifecycle starts **1**, start-failures/stops **0**. Requests total/authenticated **152**, root **3**, status **140**, tickets **8**, assets **1**, auth-failures/response-errors **0**. Tickets issued/consumed **8**, rejected/expired **0**. WebSocket connects **8**, disconnects **7**, connect/service-start/broker failures **0**. These cumulative counts include more activity than the reported five test cycles; no per-cycle snapshots or counter-reset boundary were supplied.
|
||||||
|
- WebSocket RX **11** accepted frames / **33 B**, rejected frames/bytes **0**. TX **43** binary frames / **8,413 B**, **16** control frames / **1,218 B**. Writer requests/grants **8**, denials/releases/revocations **0**. Send/queue/protocol failures and closes **0**; the zero closes counter is retained separately from seven disconnects.
|
||||||
|
- SSH initialized/running, not transitioning, port **22**, `last-error=ESP_OK`, sessions **0/2**; role-based password/public-key authentication and shell/PTY-only admission, with exec/subsystem/forwarding/SCP/SFTP disabled. Owner task core **1**, stack **20,480 B**, minimum-free **18,464 B**. SSH lifecycle starts **1**, all other supplied SSH counters **0**.
|
||||||
|
- mDNS initialized/announced, hostname `sak-1024.local`, suffix `1024`, `last-error=ESP_OK`. UART service **running**, RS-232 owner **serial service**; configuration v1 **460800 baud, 8N1, no flow control**, DTR inactive, RTS threshold **96**; RX available/TX pending **0**. Modem asserted **DCD=0, DSR=1, CTS=1, RI=0**, valid-voltage **VLD=1**.
|
||||||
|
- This records the reported five-cycle endpoint, successful cumulative admissions/writer grants and traffic without reported web failures. It does not prove byte integrity, paused reconnect behavior, observer isolation, per-cycle cleanup or a leak/fragmentation trend. Only the final normal-user role is shown; five cycles per role, including admin-role browser coverage, remain unverified. Exact flashed hash, browser/version/origin, timing and same-boot continuity with prior samples were not supplied. No reserve-floor approval or 8D.1 target validation is inferred.
|
||||||
|
|
||||||
|
### Updated one-browser plus user/admin SSH baseline
|
||||||
|
|
||||||
|
The user supplied this updated 8D.0 baseline transcript on 2026-09-05 for **one browser serial + user SSH + admin SSH**. Commands were `memory`, `ssh sessions`, `ssh counters`, `web counters`, `web status`, `mdns status`, `ssh status`, then `serial status`; these are sequential user observations, not an atomic sample or an agent-executed test. The superseded original measurement was removed at the user's request.
|
||||||
|
|
||||||
|
- HTTPS initialized/running, not transitioning, port **443**, `last-error=ESP_OK`; HTTP Basic via the user database, four users and two admins, unchanged endpoints. Web serial attached, sessions **1/2**, zero tickets. Slot **0**, fd **53**, generation **1**, role-`user` password authentication, broker **8 writer**, no TX pending or closing state.
|
||||||
|
- SSH initialized/running, not transitioning, port **22**, `last-error=ESP_OK`, sessions **2/2**, both public-key authenticated. Admin session **5**, slot **0**, routes to the admin console with no broker client; user session **6**, slot **1**, routes to broker **9 observer**. Both report active/authenticated, admin-command idle, zero admin output, no RX/TX pending or closing state. Authentication/admission remains role-based password/public-key, shell/PTY only, with exec/subsystem/forwarding/SCP/SFTP disabled. Owner task core **1**, stack **20,480 B**, minimum-free **16,288 B**.
|
||||||
|
- SSH lifecycle starts **1**, TCP connections **2**, start-failures/stops/capacity rejects **0**. Handshake successes/auth attempts **2**, handshake failures/timeouts/auth failures/request rejects **0**. Broker connects **1**, writer requests **1**, grants **0**, denials **1**, failures/disconnects/revocations **0**. Admin admissions **1**, admission failures/input backpressure **0**. Stream RX/accepted/rejected **0**, TX **657 B**, I/O failures/session revocations **0**.
|
||||||
|
- Web lifecycle starts **1**, start-failures/stops **0**. Requests total/authenticated **49**, status **48**, tickets **1**, root/assets/auth-failures/response-errors **0**. Tickets issued/consumed **1**, rejected/expired **0**. WebSocket connects **1**, disconnects/connect failures/service-start failures/broker failures **0**.
|
||||||
|
- WebSocket RX **19** accepted frames / **19 B**, rejected frames/bytes **0**. TX **39** binary frames / **7,681 B**, **3** control frames / **237 B**. Writer requests/grants **1**, denials/releases/revocations **0**; send/queue/protocol failures and closes **0**. The SSH writer denial is consistent with the browser retaining writer ownership.
|
||||||
|
- mDNS initialized/announced, hostname `sak-1024.local`, suffix `1024`, `last-error=ESP_OK`. UART service **running**, RS-232 owner **serial service**; configuration v1 **460800 baud, 8N1, no flow control**, DTR inactive, RTS threshold **96**; RX available/TX pending **0**. Modem asserted **DCD=0, DSR=1, CTS=1, RI=0**, valid-voltage **VLD=1**.
|
||||||
|
- No `broker clients` snapshot was supplied, so the transport snapshots establish the browser writer/user SSH observer but not the absence of additional broker clients such as USB. Exact flashed revision/hash, browser/version/origin, uptime, settling/soak duration and same-boot continuity with earlier samples remain unspecified. This records concurrent admission, traffic counters and an SSH stack low-water measurement, not byte integrity, a leak trend, reserve-floor approval or 8D.1 validation.
|
||||||
|
|
||||||
|
### Follow-up full-client-mix sample
|
||||||
|
|
||||||
|
The user supplied this replacement 8D.0 baseline transcript on 2026-09-05 for **two browser serial + USB + user SSH + admin SSH**, including broker/USB snapshots and requesting that it overwrite the previous measurement. Commands were `memory`, `ssh sessions`, `ssh counters`, `web counters`, `web status`, `mdns status`, `ssh status`, `serial status`, `broker clients`, then `usb status`; these are sequential observations, not an atomic sample or an agent-executed test.
|
||||||
|
|
||||||
|
- SSH initialized/running, not transitioning, port **22**, `last-error=ESP_OK`, sessions **2/2**, both public-key authenticated: admin session **5**, slot **0**, admin-console route with no broker; user session **6**, slot **1**, broker **9 observer**. Both active/authenticated, admin-command idle, zero admin output, no RX/TX pending or closing state. Role-based password/public-key authentication and shell/PTY-only admission remain reported, with exec/subsystem/forwarding/SCP/SFTP disabled. Owner task core **1**, stack **20,480 B**, minimum-free **16,288 B**.
|
||||||
|
- SSH lifecycle starts **1**, TCP connections **2**, start-failures/stops/capacity rejects **0**. Handshake successes/auth attempts **2**, handshake failures/timeouts/auth failures/request rejects **0**. Broker connects **1**, writer requests **1**, grants **0**, denials **1**, failures/disconnects/revocations **0**. Admin admissions **1**, admission failures/input backpressure **0**. Stream RX/accepted/rejected **0**, TX **17,312 B**, I/O failures/session revocations **0**.
|
||||||
|
- HTTPS initialized/running, not transitioning, port **443**, `last-error=ESP_OK`; HTTP Basic via the user database, four users and two admins, unchanged endpoints. Web serial attached, sessions **2/2**, zero tickets, both password-authenticated normal-user sessions for the same account. Slot **0**, fd **56**, generation **2**, broker **16 writer**; slot **1**, fd **57**, generation **1**, broker **10 observer**. Neither slot TX-pending or closing.
|
||||||
|
- Web lifecycle starts **1**, start-failures/stops **0**. Requests total/authenticated **181**, root **2**, status **175**, tickets **3**, assets **1**, auth-failures/response-errors **0**. Tickets issued/consumed **3**, rejected/expired **0**. WebSocket connects **3**, disconnects **1**, connect/service-start/broker failures **0**.
|
||||||
|
- WebSocket RX **25** accepted frames / **25 B**, rejected frames/bytes **0**. TX **274** binary frames / **41,456 B**, **10** control frames / **823 B**. Writer requests **3**, grants **2**, denials **1**, releases/revocations **0**; send/queue/protocol failures and closes **0**. Writer denials are consistent with observer admission, not reported transport failures.
|
||||||
|
- mDNS initialized/announced, hostname `sak-1024.local`, suffix `1024`, `last-error=ESP_OK`. UART service **running**, RS-232 owner **serial service**; configuration v1 **460800 baud, 8N1, no flow control**, DTR inactive, RTS threshold **96**; RX available/TX pending **0**. Modem asserted **DCD=0, DSR=1, CTS=1, RI=0**, valid-voltage **VLD=1**.
|
||||||
|
- Broker lists exactly four clients: web **16 writer** (`web-0-2`), SSH **9 observer** (`ssh-1-1`), web **10 observer** (`web-1-1`), USB **11 observer** (`usb-cdc`), all with **zero pending bytes/events**. Admin SSH is not a broker client.
|
||||||
|
- USB CDC initialized/attached, host-open **yes**, host DTR/RTS **yes**; broker client **11 observer**. Last host line coding **38400 baud, 8N1** is reported only and does not change UART1's **460800 baud, 8N1** configuration. This confirms USB attachment/admission, not USB byte-integrity testing. Both browsers are normal-user sessions, so admin-role browser login remains unverified.
|
||||||
|
- Exact flashed revision/hash, browser/version/origin, fixture, durations and same-boot continuity remain unspecified. This records concurrent network admission and traffic, not serial byte integrity, a timed soak, controlled per-client allocation costs or 8D.1 validation. Internal/DMA minima **17,812 / 10,056 B** are observed lows, not approved reserve floors; DMA overlaps internal heap.
|
||||||
|
|
||||||
|
### Settled post-soak cleanup
|
||||||
|
|
||||||
|
The user supplied this 8D.0 baseline transcript on 2026-09-05 and subsequently confirmed the timing: **15-minute soak**, then client disconnection, then **60 seconds of settled cleanup** before running the commands. This fills the timed soak/cleanup memory row. Commands were `memory`, `ssh sessions`, `ssh counters`, `web counters`, `web status`, `mdns status`, `ssh status`, `serial status`, `broker clients`, then `usb status`; these are sequential user observations, not an atomic sample or an agent-executed test.
|
||||||
|
|
||||||
|
- HTTPS initialized/running, not transitioning, port **443**, `last-error=ESP_OK`; HTTP Basic via the user database, four users and two admins, unchanged endpoints. Web serial attached, sessions **0/2**, zero tickets. SSH initialized/running, not transitioning, port **22**, `last-error=ESP_OK`, sessions **0/2**. SSH role-based password/public-key authentication and shell/PTY-only admission remain reported, with exec/subsystem/forwarding/SCP/SFTP disabled. Owner task core **1**, stack **20,480 B**, minimum-free **16,288 B**.
|
||||||
|
- Broker reports **no clients connected**. USB CDC initialized/attached but host-open **no**, DTR/RTS **no**, broker disconnected. Last host line coding **9600 baud, 8N1** is reported only; UART1 remains independently configured at **460800 baud**. Physical USB attachment therefore remains, without an active broker client.
|
||||||
|
- SSH lifecycle starts **1**, TCP connections **2**, start-failures/stops/capacity rejects **0**. Handshake successes/auth attempts **2**, handshake failures/timeouts/auth failures/request rejects **0**. Broker connects/disconnects **1** each, writer requests **1**, grants **0**, denials **1**, failures/revocations **0**. Admin admissions **1**, admission failures/input backpressure **0**. Stream RX/accepted **5 B**, rejected **0**, TX **84,546 B**, **I/O failures 1**, **session revocations 1**. These two nonzero counters are retained without attributing them to normal disconnect or a defect; the transcript does not establish their cause.
|
||||||
|
- Web lifecycle starts **1**, start-failures/stops **0**. Requests total/authenticated **527**, root **2**, status **521**, tickets **3**, assets **1**, auth-failures/response-errors **0**. Tickets issued/consumed **3**, rejected/expired **0**. WebSocket connects/disconnects **3** each, connect/service-start/broker failures **0**.
|
||||||
|
- WebSocket RX **25** accepted frames / **25 B**, rejected frames/bytes **0**. TX **1,490** binary frames / **177,163 B**, **11** control frames / **918 B**. Writer requests **3**, grants **2**, denials **1**, releases/revocations **0**; send/queue/protocol failures and closes **0**.
|
||||||
|
- mDNS initialized/announced, hostname `sak-1024.local`, suffix `1024`, `last-error=ESP_OK`. UART service **running**, RS-232 owner **serial service**; configuration v1 **460800 baud, 8N1, no flow control**, DTR inactive, RTS threshold **96**; RX available/TX pending **0**. Modem asserted **DCD=0, DSR=1, CTS=1, RI=0**, valid-voltage **VLD=1**.
|
||||||
|
- Relative to the recorded full-client-mix snapshot, free internal/DMA heap is **22,984 B higher** and free PSRAM **49,768 B higher**; largest blocks return to **31,744 B internal/DMA** and **8,126,464 B PSRAM**. Lifetime minima are unchanged. These endpoint observations show headroom recovery, not a controlled per-client allocation measurement or proof of no leak. Relative to the fresh-boot browser-disconnected/UART-running sample, free internal/DMA heap is **300 B lower** and PSRAM **216 B lower**, with equal largest blocks; differing HTTP activity and uncontrolled allocation state prevent treating those differences as a diagnosed leak.
|
||||||
|
- All serial transport clients are disconnected, but cumulative authenticated status requests are present; this is not evidence of no HTTPS polling or retained TLS connections. Exact flashed hash, browser/version/origin, fixture and traffic pattern/verified byte counts remain unspecified. The 15-minute soak and 60-second cleanup durations are user-confirmed; the reported UART configuration is **460800 baud**, not the checklist's separate **115200-baud** soak workload. Full soak/stress acceptance, SSH counter diagnosis, reserve floors and 8D.1 validation remain pending.
|
||||||
|
|
||||||
Resource gates:
|
Resource gates:
|
||||||
|
|
||||||
@@ -152,14 +239,14 @@ Resource gates:
|
|||||||
| Baseline internal free/minimum/largest-block reserve floors | **Pending reserve analysis and remaining workload measurements**; the recorded sample is not a safety floor |
|
| Baseline internal free/minimum/largest-block reserve floors | **Pending reserve analysis and remaining workload measurements**; the recorded sample is not a safety floor |
|
||||||
| PSRAM reserve and largest-block floor | **Pending**, including TLS/SSH connection and handshake peaks |
|
| PSRAM reserve and largest-block floor | **Pending**, including TLS/SSH connection and handshake peaks |
|
||||||
| Stack reserve floors | **Pending** SSH measurement and missing owner-task telemetry |
|
| Stack reserve floors | **Pending** SSH measurement and missing owner-task telemetry |
|
||||||
| 8D.1 incremental budget | **Pending** target reserve + actual padded four-session storage/lock/counter sizes; coexistence with Basic cache must be counted |
|
| 8D.1 incremental budget | **Actual static delta +672 B**, including 664 B store/lock symbols; no module heap allocation, task, route or socket increase. Basic cache retained. Runtime reserve acceptance still pending; see implementation record below. |
|
||||||
| 8D.2 incremental budget | **Pending** exact generation/session bindings added to four tickets/two slots and cleanup integration |
|
| 8D.2 incremental budget | **Pending** exact generation/session bindings added to four tickets/two slots and cleanup integration |
|
||||||
| 8D.3 incremental and cumulative M1 budget | **Pending** four challenge records, throttle, five handlers, parser/CSRF scratch, minus removed Basic cache/key; no new task/socket allowance |
|
| 8D.3 incremental and cumulative M1 budget | **Pending** four challenge records, throttle, five handlers, parser/CSRF scratch, minus removed Basic cache/key; no new task/socket allowance |
|
||||||
| M2 admin allocation/socket budget | **Pending** retained-serial admission design and target M1 measurements; not approved here |
|
| M2 admin allocation/socket budget | **Pending** retained-serial admission design and target M1 measurements; not approved here |
|
||||||
|
|
||||||
To close these gates, record each chunk's actual linked/static and allocated structure sizes, internal-versus-PSRAM placement and worst-case fallback, then measure peak incremental handshakes/traffic and post-cleanup fragmentation under the same workloads. Set numeric reserve floors sufficient for measured recovery/USB/SSH needs and the largest required allocation, with an explicitly justified margin; subtract these floors before approving incremental/cumulative budgets. A percentage of total RAM or a source payload subtotal is not a reserve. Stop on monotonic leak/declining largest block, watchdog/stack fault, lost lease or inaccessible login.
|
To close these gates, record each chunk's actual linked/static and allocated structure sizes, internal-versus-PSRAM placement and worst-case fallback, then measure peak incremental handshakes/traffic and post-cleanup fragmentation under the same workloads. Set numeric reserve floors sufficient for measured recovery/USB/SSH needs and the largest required allocation, with an explicitly justified margin; subtract these floors before approving incremental/cumulative budgets. A percentage of total RAM or a source payload subtotal is not a reserve. Stop on monotonic leak/declining largest block, watchdog/stack fault, lost lease or inaccessible login.
|
||||||
|
|
||||||
Target operator checklist (the user-provided sample above partially covers status/memory collection and concurrent web/SSH admission; other checks remain unverified, and none were executed by the agent):
|
Target operator checklist (user-provided samples cover status/memory collection and concurrent admission of two web serial clients, USB and user/admin SSH, with traffic counters and broker/USB snapshots confirming four broker clients and USB host DTR. Remaining checks are unverified, and none were executed by the agent):
|
||||||
|
|
||||||
1. Identify flashed revision/configuration against this record; record browser/version, IP/mDNS origin, Wi-Fi mode, serial framing/flow/baud and attached peer/fixture. Use existing provisioned accounts; do not expose credentials in evidence. Firmware upload is a separate user-controlled action; no erase is required for this documentation task.
|
1. Identify flashed revision/configuration against this record; record browser/version, IP/mDNS origin, Wi-Fi mode, serial framing/flow/baud and attached peer/fixture. Use existing provisioned accounts; do not expose credentials in evidence. Firmware upload is a separate user-controlled action; no erase is required for this documentation task.
|
||||||
2. On UART0 run `memory`, `serial status`, `broker status`, `broker clients`, `usb status`, `web status`, `ssh status` at settled boot and each table point. Record output without secrets. Use `pio device monitor -b 115200` once a port is available; this is interactive, not a completed automated test.
|
2. On UART0 run `memory`, `serial status`, `broker status`, `broker clients`, `usb status`, `web status`, `ssh status` at settled boot and each table point. Record output without secrets. Use `pio device monitor -b 115200` once a port is available; this is interactive, not a completed automated test.
|
||||||
@@ -168,4 +255,16 @@ Target operator checklist (the user-provided sample above partially covers statu
|
|||||||
5. Run **five** explicit browser serial Disconnect/Connect cycles per role, observing paused reconnect, old broker cleanup, writer/observer correctness and memory after each cycle. Baseline has no logout: do not report Basic-cache reset as a logout test. M1 will repeat five login/serial/logout cycles per role instead.
|
5. Run **five** explicit browser serial Disconnect/Connect cycles per role, observing paused reconnect, old broker cleanup, writer/observer correctness and memory after each cycle. Baseline has no logout: do not report Basic-cache reset as a logout test. M1 will repeat five login/serial/logout cycles per role instead.
|
||||||
6. Run a **15-minute** concurrent soak at **115200 baud, 8N1, no flow control**, using a safe known peer/fixture and a recorded binary pattern/byte count. Transfer writer ownership explicitly among transports, collect memory/status every minute, and record bytes/drops, latency and any watchdog/reset. Repeat a separately recorded **five-minute 460800-baud** stress run with the same mix; historical drops at that load are not permission for new exhaustion or lease loss. These workloads do not reduce supported baud rates. Record any fixture limitation rather than inventing results.
|
6. Run a **15-minute** concurrent soak at **115200 baud, 8N1, no flow control**, using a safe known peer/fixture and a recorded binary pattern/byte count. Transfer writer ownership explicitly among transports, collect memory/status every minute, and record bytes/drops, latency and any watchdog/reset. Repeat a separately recorded **five-minute 460800-baud** stress run with the same mix; historical drops at that load are not permission for new exhaustion or lease loss. These workloads do not reduce supported baud rates. Record any fixture limitation rather than inventing results.
|
||||||
7. Disconnect network clients and USB DTR, wait 60 seconds and capture cleanup memory/status. Compare free/largest-block recovery and lifetime minima with boot/full-load rows. Record SSH stack margin; explicitly retain other stack floors as pending until instrumentation is separately scoped.
|
7. Disconnect network clients and USB DTR, wait 60 seconds and capture cleanup memory/status. Compare free/largest-block recovery and lifetime minima with boot/full-load rows. Record SSH stack margin; explicitly retain other stack floors as pending until instrumentation is separately scoped.
|
||||||
8. Fill measured reserve/incremental budget cells with justified numbers, review failures and confirm 8D.0's runtime gate before 8D.1 (or record the user's explicit decision to proceed with that gate still pending). M1/M2 milestone pauses remain mandatory.
|
8. Fill measured reserve/incremental budget cells with justified numbers and review remaining failures. The user explicitly requested 8D.1 with this gate pending; that is not approval to skip later regression checks or M1/M2 milestone pauses.
|
||||||
|
|
||||||
|
## 8D.1 implementation and validation record
|
||||||
|
|
||||||
|
- **Checkpoint:** Work started from clean `devel` at `02fdeee3453654680c11096c9a6224c26233eced` (documentation-only successor to the build baseline). The user requested 8D.1 after the initial runtime sample and provided the full-client-mix sample while work began. Remaining reserve floors are explicitly pending; this is not an automatic budget approval for subsequent chunks.
|
||||||
|
- **Implemented:** `src/web_session_store.{h,c}` provides four fixed internal records; 32-byte token digests, 32-byte origin digests, separate 32-byte CSRF state, copied principals, one-hour absolute deadlines and non-reused 64-bit IDs. Issue/lookup/currentness/prune/session and user invalidation APIs exist, plus secret-free counts/storage sizes. No raw bearer token is retained. Failed output and retired record cleanup is explicit. Stop wipes records, cancels in-flight issuance/init and never resets IDs/epochs. No task, module heap allocation or internal-fallback allocation is introduced.
|
||||||
|
- **Concurrency:** A short portMUX protects only bounded state operations; RNG/SHA/database work is outside it. Resolution rechecks ID/liveness/deadline after principal validation. Issuance rechecks an invalidation epoch before publication; any explicit invalidation conservatively cancels concurrent issuance, including issuance for another account, without removing unrelated live sessions. Epoch/ID exhaustion is fail-closed. Snapshot counts are cumulative for the boot; views containing CSRF are sensitive request-local results, never status snapshots. HTTP Origin validation remains the future caller's responsibility; the primitive only binds a bounded canonical origin digest.
|
||||||
|
- **Lifecycle integration:** Only an admitted HTTPS start initializes the store; failed starts and accepted stops disable it before cleanup, including failed teardown. Store-init failure is warning-only for the unchanged Basic-auth service. No production caller issues/looks up sessions yet. No login page, cookie route, ticket binding, account-mutation notification hook, new URI, protocol change or generated asset change. Those remain 8D.2/8D.3 scope.
|
||||||
|
- **Build:** Final `pio run` passed in 8.90 seconds after review fixes, with the same PlatformIO/IDF configuration: **95,204 B linked RAM (+672 B)**, **1,600,505 B flash (+532 B)** relative to 8D.0. Target object symbol inspection reports **656 B state + 8 B portMUX = 664 B**; DWARF confirms **152 B per record × 4 = 608 B**, principal 40 B. The aggregate link delta includes eight additional bytes beyond those store symbols. All storage coexists with the existing Basic cache. No post-change runtime heap claim is made.
|
||||||
|
- **Dormant-code accounting:** All functions compile and are exercised by the host harness, but the firmware link currently retains only init/stop and their dependencies; unused issue/lookup/etc. code is garbage-collected. The static state is retained in full. Later production callers must account for the newly linked code and stack/crypto execution costs rather than treating this flash delta as the full M1 cost.
|
||||||
|
- **Focused executable checks:** `python3 tests/web_session_store/run.py` passed using OpenSSL SHA-256 and deterministic RNG/database/time/FreeRTOS doubles. Coverage includes failed init/retry/idempotence, capacity/no eviction, token/origin mismatch, exact expiry/no renewal, per-session/account isolation, stale principals and DB failure, stop/reinit/stale IDs, invalidation during pruning and candidate issuance, replacement during lookup, expiry during revalidation, stop during init, and post-token SHA failure output wiping. RNG/SHA/database doubles assert that no store lock is held. This narrow harness is not a general firmware test suite.
|
||||||
|
- **Review-only limits:** ID/epoch exhaustion, collision rejection and private record wiping were inspected, not forced by public-API tests. Callback races are deterministic interleavings, not real multicore scheduling. Host tests do not test device DRBG, mbedTLS integration, HTTPD lifecycle races, heap/stack margins or future dormant browser paths. Independent source review found and verified the fix for reinitialization during a rejected concurrent start.
|
||||||
|
- **Post-change target gate:** Boot this build through a user-controlled upload; check UART0 recovery, unchanged admin/user Basic login and assets/status, explicit serial Disconnect/Connect, USB, user/admin SSH and full-client-mix memory/status/counters against both pre-change samples. Run five serial lifecycle cycles per role; include HTTPS stop/start and observe no new failures. Record `ssh status` stack margin and the remaining soak/cleanup measurements above. No target run of this changed firmware has been supplied or performed. Stop at 8D.1; request 8D.2 only after the regression checkpoint or an explicit decision acknowledging it remains pending.
|
||||||
|
|||||||
Reference in New Issue
Block a user