Add broker management and writer transfer UI
This commit is contained in:
@@ -237,6 +237,14 @@ Configuration modules generally choose RAM defaults without erasing incompatible
|
||||
|
||||
Bounds:256-byte/four-receive request,128-byte snapshot,96-byte result, one slot;30 URI handlers/six sockets, no new task/timer/stack-size/queue/schema expansion. Optional staged allocation failures retain other routes. Host tests/build pass; target and memory/stack margins pending. Full contract, resource evidence and checklist: `docs/phase8d14_implementation.md`.
|
||||
|
||||
## Typed Broker management (8D.16)
|
||||
|
||||
`web_broker_settings` provides admin-only bodyless GET management snapshot and GET/POST assignment/result routes, using Display-style bounded parsing, one login-isolated result slot and the existing typed dispatcher. Only a numeric ID is queued. Original principal/session and30-second dequeue deadline are checked before owner admission; already-admitted work can finish after logout. Optional staged registration preserves other services. Bounds:256-byte/four-receive request,2048-byte snapshot,96-byte result;33 handlers/six sockets, no new timer/task/queue/stack-size/assets changes.
|
||||
|
||||
The broker copies compact client rows and writer/lease generation together under its existing mutex with zero wait. Conditional assignment compares generation and connected non-reused target under the same force-writer lock before any effect. Lease grant/release/revoke events advance a separate saturating32-bit generation before delivery attempts, including same-writer ABA; counter clears and dropped events cannot invalidate this fence. UINT32_MAX disables conditional assignment, not ordinary transport/console recovery. Client IDs retain three slot/29 generation bits, but exhausted slots now retire until reboot rather than reusing IDs. Reboot invalidates originating web sessions. Existing unconditional force APIs and one-writer/multiple-observer policy remain unchanged.
|
||||
|
||||
Browser Settings/Broker shows safe ID/type/name/role/pending/HWM/drop rows and clears selection on Refresh. Native confirmation captures exact target/generation before session revalidation. Viewing/selecting never mutates; completion checks are bounded to10 one-second GETs/15seconds, no mutation replay. There are no contextual popovers or diagnostic/service controls. Complete contracts, wrap analysis, evidence and pending parent/target review: `docs/phase8d16_implementation.md`.
|
||||
|
||||
## Local UI and hardware boundaries
|
||||
|
||||
`board_pins.h` centralizes project-assigned RS-232, diagnostic, RGB LED, and local-UI hardware resources; UART0 GPIOs remain local to `main.c`, and native USB uses platform wiring. `local_display` solely owns I2C0, the SSD1315-compatible OLED, its static framebuffer, and display mutex. Display frames belong to the initiating task. Dirty-page commits and I2C transactions are bounded.
|
||||
|
||||
@@ -34,6 +34,8 @@ This is a semantic map, not a complete file inventory. Start here, then read the
|
||||
|
||||
## Session broker
|
||||
|
||||
- **8D.16 management:** `session_broker_get_management_snapshot()` copies compact eight-client rows plus writer/lease generation atomically with zero wait; `session_broker_assign_writer_current()` compares generation and target under the force-writer lock. 29-bit client generations retire slots instead of wrapping; saturating lease generation fences ABA, survives counter clear, and leaves ordinary recovery available. Actual canonical regressions extend `tests/session_broker_diagnostics/run.py`. Full contracts/wrap analysis: `docs/phase8d16_implementation.md`.
|
||||
|
||||
**Responsibility:** mediate all transport access to the serial service; provide one writer lease and multiple isolated observers.
|
||||
|
||||
- Files: `src/session_broker.{h,c}`, `src/session_console.{h,c}`
|
||||
@@ -59,6 +61,8 @@ This is a semantic map, not a complete file inventory. Start here, then read the
|
||||
|
||||
## Web and WebSocket serial
|
||||
|
||||
- **8D.16 Broker (2026-09-13):** `web_broker_settings.{c,h}` owns optional admin-only GET `/api/settings/broker`, GET/POST `/api/settings/broker-operation`; existing dispatcher queues only IDs. `web_ui.c` adds Serial/Display-style full-page rows and explicit confirmed assignment, no mutation on view/selection. 256-byte/four-receive request,2048-byte snapshot,96-byte result, one login-bound slot/no timer;33 handlers/six sockets, unchanged tasks/stacks/queue/assets/CPU160/combined WS send. Tests: cookie `--broker`6+shared, broker management/wrap, dispatcher, lifecycle25, UI119+HTML/CSP and broad regressions. Baseline100,196/1,765,233 B → final100,300/1,782,613 RAM/flash. Independent parent review and target sign-off pending. Contracts/resources/checklist: `docs/phase8d16_implementation.md`.
|
||||
|
||||
- **8D.14 Display (2026-09-09):** `web_display_settings.{c,h}` owns optional admin-only GET `/api/settings/display`, GET/POST `/api/settings/display-operation`; `web_ui.c` supplies Serial-style dim/off settings and bounded completion checks. `local_status_ui` owns generation-safe config/storage reservation shared with CLI; buttons do not edit timeouts. No I2C changes. 256-byte/four-receive request,128-byte snapshot,96-byte result, one slot/no timer;30 handlers/six sockets, unchanged tasks/stacks/queue/schema. Tests: cookie `--display` (7+shared), UI111, lifecycle23, dispatcher and broad regressions. Actual baseline100,100/1,748,513 B → final100,196 RAM/1,765,233 flash at160MHz. Target pending; exact API, reset ordering, deadlines, resource/validation limits: `docs/phase8d14_implementation.md`.
|
||||
|
||||
- **Current 8D.12/8D.13 — user functional sign-off 2026-09-08, including Settings presentation:** `web_network_settings.{c,h}` owns optional admin-only GET `/api/settings/network` and GET/POST `/api/settings/network-operation`; `web_ui.c` supplies Network, UTF-8/hex SSID editing and explicit transient-secret/connection controls. `wifi_manager` owns generation-checked secret-free snapshots/patch/save/stored-only load and radio transitions; `mdns_service` owns independent conditional hostname persistence, with manager reannouncement. Existing dispatcher receives IDs only. 768-byte request/2,048-byte snapshot/128-byte result, one slot/one-second timer with 30-second queued expiry plus scheduling latency; no hard cancellation. 27 handlers/six sockets, no task/stack/queue/schema growth. Parent integrated tests/build PASS; latest styling UI100 + renderer/CSP/Chromium checks, 99,548 B RAM / 1,744,325 B flash. User full-mix evidence accepted; loaded internal/DMA minima2,276/156 B remain resource follow-ups, not reserve approval. Full contract/exclusions/checklist: `docs/phase8d12_13_implementation.md`. Both phases user-authorized together; no 8D.14/M3 claim. Older next-phase statements below are historical.
|
||||
|
||||
@@ -4,6 +4,8 @@ This file is working memory. Update it during active work and before handoff; do
|
||||
|
||||
## Development state
|
||||
|
||||
- **8D.16 implemented (2026-09-13), user-authorized; host/build verified, independently reviewed; target sign-off pending:** Admin Settings/Broker has bounded detailed client rows and explicit confirmed writer assignment, no view/selection mutation, no8D.17/18 popovers/icons. `web_broker_settings` uses256-byte/four-receive requests,2048-byte snapshot,96-byte result, one login-isolated slot and existing typed dispatcher IDs/30-second dequeue deadline; no new timer/task/queue/stack/assets. Broker owns atomic zero-wait client/writer/lease snapshot and conditional generation+target check under force lock;29-bit client generations retire slots rather than wrap, separate saturated32-bit lease generation fences ABA/counter clears/dropped events, ordinary recovery retained.33 handlers/six sockets. PASS cookie Broker6+shared, canonical broker7+2 management/wrap, dispatcher, lifecycle25, UI119+five-view HTML/CSP, all existing cookie variants, canonical Network/accounts, parser294, console lifecycle/policy, transport/tickets/store, idle/diagnostics/performance/login and diff checks. Baseline pio7.14s100,196 RAM/1,765,233 flash; substantive-source final20.54s100,300/1,782,613 (+104/+17,380 B); final post-review confirmation21.20s unchanged. Initial worktree clean; CPU160 confirmed defaults/active/generated, signed-off combined WS send untouched. Tests fixed row-schema count and harness extraction/capacity/count issues. Independent final review found no actionable findings; reviewer reran broker7+2, cookie Broker/Display, dispatcher, lifecycle25, UI119+C/HTML/CSP, throughput and diff checks PASS. Parent final pio confirmation PASS6.93s at100,300/1,782,613 B; diff check PASS. Target/full-mix/HTTPD-dispatcher margins and user sign-off pending; no reserve/M3 claim. Exact API/wrap/resources/test limits and target checklist: `docs/phase8d16_implementation.md`. No upload/erase/commit/SDK changes. Older next8D.16 authorization wording below is historical.
|
||||
|
||||
- **8D.15 removed from plan (2026-09-09), explicit user scope decision:** Network diagnostics stay exclusive to the admin shell; no dedicated typed diagnostics endpoints/settings UI. Removed the planned deliverable from `docs/phase8d_plan.md`; retain later phase numbers, so next planned chunk after8D.14 is8D.16, only on separate request. Existing shell permissions and implemented Network settings/status unchanged. Documentation only; no firmware/build/device action or8D.14 target sign-off implied.
|
||||
|
||||
- **8D.14 Display implementation complete (2026-09-09), user-authorized; host-tested/build-verified, target pending:** Admin Settings → Display supplies typed dim/off0–86400s, Apply/Save/Load/Defaults/Reset, Serial-style label/value presentation and bounded result polling. `web_display_settings` owns one secret-free login-bound slot, 256-byte/four-receive requests,128-byte snapshot/96-byte results; IDs use the existing dispatcher. `local_status_ui` owns nonwrapping config generation and zero-wait reservation across NVS outside critical sections; CLI shares the gate, buttons retain independent activity/reprobe behavior. Reset now commits defaults before RAM publication (CLI too), eliminating rollback overwrite. Absent panel does not gate config if UI task is available; no I2C/renderer ownership change.30 handlers/six sockets, no new task/timer/stack size/queue/schema/assets changes.30-second dequeue admission deadline, not timed cancellation; admitted work may finish after logout. PASS Display7+shared auth, UI111+C/HTML/CSP, lifecycle23, dispatcher/accounts/policy, cookie all variants, canonical Network, parser294, transports/tickets/store/idle/diagnostics/throughput/broker/login regressions and diff check. Separate self-review fixed strict result status/action/replacement handling. Independent final review found no actionable findings and independently reran Display7+shared auth, dispatcher boundary, lifecycle23, UI111+C/HTML/CSP and diff checks PASS. Parent final pio confirmation PASS9.08s, unchanged100,196/1,765,233 B; diff check PASS. Actual pre-edit pio12.10s100,100 RAM/1,748,513 flash; final pio26.09s100,196/1,765,233 (+96/+16,720 B). CPU160 confirmed in defaults/active/generated configuration; throughput fix and user sign-off preserved. Initial worktree reported clean. Optional Chromium geometry attempt blocked by sandbox socket/crash-report restrictions; no geometry pass. Target display/save-reboot/absent-panel/buttons-concurrency/full-mix/heap/HTTPD-dispatcher margins and sign-off pending, no reserve approval or full M3 claim. Exact contracts/tests/resources/checklist: `docs/phase8d14_implementation.md`. No upload/erase/commit or later phase; older no-8D.14 authorization statements below are historical.
|
||||
|
||||
@@ -60,6 +60,14 @@ Phase 8D.2 adds a third identity: non-reused 64-bit originating web-session IDs
|
||||
|
||||
**Relevant files:** `src/session_broker.{h,c}`, `src/ssh_transport.c`, `src/web_serial_transport.c`, `src/admin_ssh_console.c`, `src/user_database.{h,c}`
|
||||
|
||||
## Confirmed writer transfer compares a lease version inside the broker lock
|
||||
|
||||
**8D.16 decision:** A client ID alone cannot authorize a stale browser confirmation: the writer may release and reacquire while a dialog is open. The compact management projection copies clients, writer and a separate lease generation under one zero-wait mutex acquisition. Conditional assignment validates target and lease generation in the same force-writer lock before any changes; existing unconditional console/recovery APIs remain available.
|
||||
|
||||
**Wrap contract:** Three-slot-bit/29-generation-bit broker IDs now retire exhausted slots instead of wrapping. A32-bit lease generation saturates at UINT32_MAX, survives counter clear, and advances for each grant/release/revoke emission before advisory queue delivery. Forced transfer can advance twice; it is an opaque version, not a count. Saturation rejects typed assignment but never prevents normal release/disconnect/request or recovery force. Future writer transitions must preserve the central event-emission invariant. Reboot resets broker state but invalidates web sessions, so authorized old browser work cannot span boots.
|
||||
|
||||
**Consequence:** Never implement snapshot-check-unlock-force, compare only current writer ID, or renew a confirmation implicitly during Refresh. UI must require explicit target selection and confirmation, retain uncertain-outcome handling and never retry mutations automatically. Bounded login-isolated result slots and the existing dispatcher remain the typed HTTP boundary. Details/tests: `docs/phase8d16_implementation.md`, `src/session_broker.{c,h}`, `src/web_broker_settings.{c,h}`.
|
||||
|
||||
## UART0 is the physical recovery authority
|
||||
|
||||
**Decision:** UART0 remains independent of UART1 and networking. The first administrator is created with normal `user add` on UART0; explicit unavailable-user-database recovery to empty is UART0-only and refuses healthy storage. No bootstrap command/API remains.
|
||||
|
||||
Reference in New Issue
Block a user