From 4c436f4ce493028c5f602035a29ce27d8a266d92 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sat, 12 Sep 2026 20:28:22 -0500 Subject: [PATCH] plan: confirm all-seat WebUI session chat and gated delivery (#1507) --- docs/plans/2026-09-13_webui-session-chat.md | 323 ++++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100644 docs/plans/2026-09-13_webui-session-chat.md diff --git a/docs/plans/2026-09-13_webui-session-chat.md b/docs/plans/2026-09-13_webui-session-chat.md new file mode 100644 index 00000000..58fb11f8 --- /dev/null +++ b/docs/plans/2026-09-13_webui-session-chat.md @@ -0,0 +1,323 @@ +# WebUI session chat: refined brief and delivery plan + +Tracking #1507. Author/frontend owner Dewey. Product acceptance Jason. +Backend accountable owner/proposed sequential author and launcher/fleet +coordinator Darkwing, per #1507 comment 26088; exact per-task assignments +remain pending charter. Independent reviewer Filbert, except work he authors must +have a different independent reviewer. + +Status: Q1-Q22 answered by Jason through ms-grill-me on 2026-09-13. +Jason confirmed shared understanding and authorized bounded CHAT-00 +protocol/contract preparation on 2026-09-13 with "yes" to the assembled summary. +This is not a runtime implementation charter or live cutover authorization. + +## 1. Outcome and baseline + +Jason can select a project and one of its sessions in the left sidebar, read +and participate in its complete conversation, respond to tools and approvals, +and stop work without returning to a native seat terminal or the old board. +All repository and fleet seats are required, including Pi and Claude Code. +A missing required seat/capability blocks acceptance; it is not an exclusion. + +Published Console source is ea00ec66d93d1d554463f94711c343c9c8df20c4, +records 11659cf2a1de5fec21e324a20acbb0487e126742. Its 208 passing tests and +Filbert approval cover the original board-only piece, not this expanded chat +scope or Jason acceptance. Planning checkout HEAD observed at +0e77cfd10adeb6d31ba9fb72380733993dcd4db6. No existing runtime is changed by +this plan. Reverify the baseline and other owners' work at each writer handoff. + +Jason's reported failure is preserved: sending is available, but the return +conversation is absent in actual use. Investigation found a 240-character +last-assistant preview and no test of a later assistant answer after sending. +This explains the product limitation, not a proven live root cause. Reproduce +and retain a regression for the reported sequence before claiming it fixed. + +## 2. Settled design tree + +These WEBUI question numbers are distinct from the older foundation interview. +Durable round records are #1507 comments 26083 through 26087; final round and +this plan pointer are recorded in the subsequent plan comment. + +| ID | Jason's ruling | +|---|---| +| Q1 | Conversation, interrupt, file/image attachments and needed native approval responses required. Model switching and creating fresh conversations deferred. | +| Q2 | Full user/assistant text with Markdown/code; expandable tool activity/results; working/error states; incremental output; reasoning collapsed where legitimately available; preserve reading position. | +| Q3 | All seats, including repository/fleet Pi and Claude Code Rocko. | +| Q4 | Project > current sessions first; collapsed earlier conversations selectable read-only. Opening history does not resume it. | +| Q5 | Terminal and WebUI share the same underlying conversation, without restart/fork on opening. One input controller and explicit takeover. | +| Q6 | Send while busy queues a visible follow-up. Edit/cancel before dispatch. Send never silently interrupts. Separate nuclear stop option required. | +| Q7 | File picker, drag/drop and clipboard image paste. Preview/remove before Send; retain draft/attachments on failure. Nothing reaches agent before Send. | +| Q8 | Normal Interrupt turn plus confirmed Force stop session. Force stop targets only selected agent and attributable local tool cohort, cancels queued input, preserves drafts/history. No other-seat cascade or rollback claim. | +| Q9 | Interfaces open as observers until explicit takeover. Enforce input transfer without interrupting active work; losing interface cannot submit. | +| Q10 | Active branch by default, explicit compaction markers, other branches read-only; never interleave alternate histories as one conversation. | +| Q11 | Exact native approval choices, including denial, bound to the outstanding request. Reject stale replies; no auto-approval, permission widening or ordinary chat yes as authority. | +| Q12 | Private conversation-keyed drafts/uploads survive browser and WebUI restart until sent/discarded. Sent attachments remain linked to messages; visible storage usage; no silent expiry or workspace overwrite. | +| Q13 | Takeover invalidates old queued input and recovers it as unsent drafts. New controller explicitly resubmits; dispatched work retains original identity/status. | +| Q14 | Browser disconnect does not stop running work or acknowledged follow-ups. Reconnect reconciles actual state; uncertain sends are not blindly replayed. | +| Q15 | After force stop, explicit Resume session only after termination/effects reconciliation. No automatic restart or canceled-message replay. This is recovery, not Fresh. | +| Q16 | Browser stays local to Jason's workstation. Remote seats use authenticated private connectivity; no exposed unauthenticated API. | +| Q17 | At most 10 attachments/message, 20 MiB/file, 100 MiB/message. Images use native image input where supported; other files are private explicitly staged attachments for the exact seat. No automatic execution/extraction or silent truncation. Show stricter harness limits before Send. | +| Q18 | Planned one-seat-at-a-time interruption is acceptable for migration. Fixtures for both harnesses first; exact cutover/rollback presented for separate Jason approval before any live migration. Preserve exact conversation/branch. | +| Q19 | Inventory and access verification for every required seat, then full interaction demonstration for every supported harness/host combination, including the reported return failure, before the workday acceptance. | +| Q20 | Ordinary Interrupt cancels the active turn, fences dispatch and recovers undispatched follow-ups as unsent drafts; explicit resend after reconciliation. Already-dispatched work retains actual/uncertain status. | +| Q21 | Scoped expanded implementation commits/pushes to refactor authorized after independent approval and passing applicable checks. No deployment, live migration, credentials or policy expansion authorized by publication. | +| Q22 | Preserve existing piece-5/#1508/fleet-launch ordering. Independent local implementation and isolated fixtures may proceed after charter; dependent fleet work waits for prerequisites. All-seat acceptance remains blocked until those dependencies pass; no other queue item auto-starts. | + +Also required by Jason's initial feedback: restore the board's relative Age. +Label it as time since last activity. Conversation creation, engine launch and +last activity are separate timestamps; missing values are unknown, never guessed. + +### How the screen behaves + +Keep Console's existing palette/appearance and project overview. The sidebar +contains real projects and their sessions, with workspace context where needed +to disambiguate. Do not guess project membership from a filename or basename. +Selecting a current session opens its chat, not a dashboard card inspector. +Selecting history opens a clearly read-only conversation. No silent resume. + +Conversation view has a stable heading identifying project, workspace, seat, +conversation and control mode. Full messages, code and tool output are readable, +with safe rendering and collapsed detail. Show unavailable reasoning honestly. +Use a bounded paginated history and incremental updates; reconcile temporary +streaming content with persisted terminal entries without duplication. + +Keep the draft, selection/caret and scroll keyed to conversation identity. +If the reader is above the latest output, show a new-messages indicator rather +than scrolling them away. When following the bottom, follow new output. +Show disconnected/stale/loading/empty/error/read-only and approval states plainly. +Do not erase already loaded conversation when refresh or reconnection fails. + +Separate local draft, durable queued, dispatched, harness acknowledged, working, +finished, failed and delivery-unknown states. A transport receipt is not an +assistant answer. Send remains separate from Interrupt and Force stop. +Cancel/edit is allowed only before dispatch; show a race refusal if already sent. +No automated retry under a new request identity after an uncertain outcome. + +Q8 and Q20 settle queue cancellation for both stop controls: cancel +undispatched follow-ups into recoverable unsent drafts, so Interrupt cannot +immediately start another turn. Previously dispatched work remains subject to +actual cancellation/reconciliation, never relabeled unsent. Verify the exact +native queue/abort sequence in CHAT-00/03 rather than guessing from the label. + +## 3. Recovered decisions and contract extensions + +`docs/plans/foundation-v1-candidate/REVIEW.md` records phase-2 planning baseline +accepted 2026-09-06. Older draft-status prose does not revoke that acceptance. +It is a design contract, not evidence of implemented enforcement or authority to +install the entire foundation runtime now. + +Relevant earlier requirements are in +`2026-09-06_agent-project-workspace-foundation.md`: +R4/R5/R11/R12 scoped histories and shared cross-interface work; R7 Resume/Fresh +and damaged-history refusal; R22 separate conversation access; R24 exclusive +controller/authorized observers; R25/R26 checked recovery/no blind replay; +R30 reviewed legacy adoption; R34 mediated terminal permitted without native +shortcut parity. Filbert recovered these source references read-only. + +`foundation-v1-candidate/RUNTIME.md` sections 3-5 require authoritative session +and branch binding, execution/controller generations, transfer invalidation, +claim retention across disconnect, exact correlated dialog responses and +request identity/deduplication. Stop is not proven by a signal or idle response; +the attributable process cohort and unfinished effects need reconciliation. + +Explicit extensions for this delivery: Pi-only bounded-text proposals cannot +satisfy all-seat Claude support, files/images and full interactive WebUI. Those +contracts need bounded reviewed extensions. Do not inherit raw RPC access, +provider credentials or blanket log visibility. CHAT-00/01 must explicitly map +the older reviewed tool-bridge, no builtin-tool escape, no ambient extension/context +loading and no tool execution inside credential-bearing engines requirements. +Native approvals are not equivalent enforcement. Retain those boundaries unless +Jason makes an exact bounded contract ruling with independent security review. +Do not silently waive them or implement the entire parked registry to avoid a +scope decision. Historical contracts remain unedited without separate charter. +A mediated terminal may be +necessary to enforce Q9; leaving the losing native TUI writable is not conformance. + +`agents/dewey/work/wui/FEATURES.md` and `DESIGN.md` are inventories/mockups, +not backend commitments. Their transcript excerpt and simulated controls do +not settle runtime mechanics. The current Q rulings settle the product behavior. + +## 4. Technical prerequisites and intended architecture + +Recommendation, subject to exact contract/security review: a single Mosaic +conversation controller owns each engine and exposes bounded authorized commands +and events to WebUI and a mediated terminal. Per-harness adapters translate +verified Pi and Claude protocols. The browser never talks raw engine RPC or tmux. +One conversation/execution has one writer; clients observe or explicitly control. + +Keep board summary compatibility, but do not grow scan.mjs into an engine +controller. A dedicated package is the smallest separation for lifecycle, +streaming, queue, uploads and approval contracts. Exact module/API/schema names +are implementation decisions after protocol evidence, not invented live APIs. + +### Evidence matrix + +| Required class/capability | Known evidence | Missing proof before implementation/cutover | +|---|---|---| +| Pi history | Session header UUID/time/cwd; entry ids/parents; user image/text; assistant text/thinking/toolCall; results/compaction/branches | Safe bounded read-only catalogue and active branch binding; no migrating session loader | +| Pi live control | Installed rpc.md and implementation report prompt/images, steer/follow_up, abort/clear_queue, get_state/get_entries/get_tree, text/tool events and correlated extension UI | Complete pinned-doc review; compatible approval extensions, queue/cancel ordering, mediated terminal and native session handoff fixtures | +| Claude Code | Rocko launcher selects Claude; local 2.1.269 help advertises stream-json, partial messages, permission host, UUID/resume | Official pinned control/approval/interrupt/attachment/transcript contracts and synthetic fixtures. CLI help alone is insufficient. Preserve workspace trust/settings refusal behavior. | +| Fleet | Existing board knows Pi seat/socket summaries; no permission to expose remote engine API | Reviewed host/seat/incarnation/identity catalogue, private authenticated mapping, uploads transfer, remote cohort supervision and rollback | +| Return flow | Existing summary is clipped; no post-send answer-append test | End-to-end correlated send -> user -> tools -> new assistant answer for both adapters and host classes | + +Pi documentation must be read completely with related references before Pi +implementation, per repository instructions. Research receipts are pointers, +not a substitute for the implementer's protocol verification. Pin dependencies; +no unversioned installation or model invocation for discovery. + +### Security and data rules + +- Server resolves opaque conversation IDs under explicitly approved source roots. + No browser-supplied file paths, symlink escapes, parent-session traversal or + global filesystem scan. Preserve legacy logs; explicit reviewed identity mapping. +- Bind control to host, seat, harness, conversation, branch, execution incarnation, + connection/controller generation and authenticated actor. Revalidate at admission + and dispatch. Old UUID/pid/socket/name alone is insufficient proof. +- Fence every old ingress: old board Reply, agent-send/tmux, native terminal, + harness-native queued input and supervisor restart, not just the WebUI form. + A preamble is not authenticated actor evidence. Tests must reject old-controller + input, inherited queues, stale approvals and launch/claim bypass. On supervisor + crash/uncertainty, refuse a second writer until prior execution is reconciled. +- Local owner channel and authenticated private fleet channel require exact review. + Loopback is not sufficient authorization for destructive control. Do not reuse + provider credentials or trust client principal headers. Specify controller and + observer grants, origin/CSRF defense, credential lifecycle and revocation for + local and remote connections. No public browser endpoint. +- Uploads stay outside repository/evidence logs and tool-visible workspace until + intentional delivery. Private staging, digest/size/type validation, opaque IDs, + no path overwrite, no extraction/execution, exact-seat transfer acknowledgement. + Browser staging is not delivery to the agent. Enforce capacity limits explicitly + without silently deleting drafts. Sent content access follows conversation access. +- Treat Markdown, tool results, reasoning and filenames as untrusted data. Prevent + active HTML/script, unsafe links, terminal escapes and secret exposure. Do not + render private hidden state merely because an OS file is readable. +- Approval request id, tool, intent, scope, incarnation and controller must match. + Reject stale, duplicate-conflicting and foreign responses. Native deny rules + remain authoritative. Disconnect never implies permission to allow. +- Keep stopping/uncertain visible until the supervisor proves the exact cohort + stopped. Record external effects as completed or uncertain, never undone by kill. + +## 5. Dependency-ordered implementation preparation + +This table is the decomposition under QUEUE row 5, not another global queue. +Shared understanding is confirmed; CHAT-00 is authorized for preparation and +awaits Darkwing's exact per-task charter. Later tasks remain planned behind their +technical gates. Darkwing names exact backend authors before source work. +Use issue comments for assignments/reviews and hash-pinned candidates, not a new +file under reviews for every exchange. Child issue IDs can be created at charter +if separate ownership needs them; #1507 remains the acceptance issue. + +| Task | Owner proposed | Depends on | Deliverable and exit evidence | +|---|---|---|---| +| CHAT-00: protocol and scope charter | Darkwing proposed author/accountable owner; Filbert reviews | Jason confirms this brief | Pi/Claude version-pinned capability matrix, verified Claude schemas, named host/seat classes without private content, source-root/identity adoption proposal, exact paths, security mapping, foundation tool-bridge/ambient/escape requirement disposition, Q22 dependency disposition and no-live-effects fixtures. Unverified capabilities block their implementation, not disappear from acceptance. | +| CHAT-01: conversation/control contracts | Backend author assigned by Darkwing; Filbert reviews | CHAT-00 | Bounded catalogue/transcript/event/upload/queue/approval/recovery schemas, identity and generation fencing, dedup/uncertainty rules, transfer/disconnect rules, threat cases, exact allowed operations. Q20 queue disposition encoded/tested and independent contract approval required. | +| CHAT-02: read-only histories and Age | Backend author plus Dewey in sequenced files | CHAT-01 | Both harness catalogues, safe full branch history with pagination/cursors, separate timestamps, relative activity age; fixtures for malformed/truncated/replaced/touched logs, cross-project/symlink denial, no log writes. | +| CHAT-03: live adapters and mediated terminal | Backend/launcher author assigned by Darkwing; independent reviewer | CHAT-01 | Pi and Claude engine integration, incremental events, exact active binding, single writer/controller, native approval dialogs, stop/cohort proof and explicit recovery. Fake engine/tool tests and hostile control races pass; no real seat migration. | +| CHAT-04: durable queues and attachments | Backend author; independent reviewer | CHAT-01 and verified CHAT-03 adapter inputs | Persistent draft/queue state, request identities, pre-dispatch edit/cancel, takeover-to-draft, no blind replay, bounded private uploads and exact-seat transfer; restart/disconnect/disk-full/permission/size/type/path tests pass. | +| CHAT-04R: private remote control and transfer | Named host/backend owner assigned by Darkwing; independent security reviewer | CHAT-01, CHAT-03/04 contracts, Q22 prerequisite gates passed and exact host/path/authority approved | Implement authenticated and authorized host control, exact-seat upload transfer and remote cohort supervision. Fixtures prove identity/replay/stale-incarnation refusal, connection-loss and remote-stop uncertainty, unrelated-cohort survival, transfer acknowledgement and denied access. No live fleet service activation. | +| CHAT-05: Console session chat UI | Dewey; Filbert reviews | CHAT-02, approved CHAT-03/04 contracts | Project/session sidebar, branch/history chat, safe Markdown/code/tools/reasoning, composer/uploads/queue/approval/stop/takeover/recovery, stable draft/caret/scroll, all states. Served-browser tests on contract fixtures pass. | +| CHAT-06: combined candidate and handoff plan | Darkwing integrates, Dewey verifies UI, independent exact-candidate reviewer | CHAT-02..05 including CHAT-04R | Both harness/host-class end-to-end fixtures, reported-return regression, security/stop/reconnect races, independent exact-tree approval, green applicable suites; exact one-seat cutover/rollback and privacy-safe inventory ready for Jason. | +| CHAT-06P: source/artifact publication | Darkwing integrates; exact author/publisher named in charter | CHAT-06 and explicit expanded-scope publication authority, Q21 | Reverify reviewed-byte equality and green applicable suites/CI; commit only approved paths, publish exact commit/artifact pin and verify remote/artifact identity. Record pinned prior rollback artifact. Earlier board-only publication authority is not sufficient. No activation. | +| CHAT-07: controlled runtime handoff | Darkwing/fleet owners | CHAT-06P plus separate Jason approval of live cutover | One seat at a time; preserve history/config/branch, prove prior writer stopped before next starts, verify binding/permissions, stop and roll back on failure. No unrelated fleet launcher migration or provider/role expansion. | +| CHAT-08: all-seat acceptance, Gate E | Dewey demonstrates, Jason accepts | CHAT-07 | Every required seat identified/access-verified, full interaction matrix below demonstrated, then Jason workday ruling with exceptions. #1507 closes only on acceptance. | + +Implementation order is sequential by default. Parallel source work requires +isolated worktrees, named authors, non-overlapping path authority and a declared +integration order. No blanket staging in the shared checkout. + +### Proposed exact path boundaries for Darkwing's review + +- Dewey writer: `packages/webui/**` and this brief plus only WebUI tracking rows. +- New backend, proposed name: `packages/conversation/**`. Ownership unassigned; + Darkwing supports this package name and is proposed backend author/accountable + owner per comment 26088; he narrows per-task authority before creation. +- Board integration, only if approved: `packages/control-board/src/scan.mjs`, + `packages/control-board/src/serve.mjs`, associated `tests/` and `README.md`. + Darkwing coordinates each actual edit; existing page/transport not a control bypass. +- Seat binding extension, only if approved: `packages/seat/src/seat.mjs`, its + tests and README. Any schema/record changes receive explicit contract review. +- Repository launcher handoff, only if approved: `scripts/agent-host-dev.sh`, + `agents/{darkwing,dewey,filbert,rocko}/launch.sh` and their existing fixture tests. + Do not edit untracked Sage or other owners' definitions without separate scope. +- Fleet integration: no writable external path currently granted. Fleet owner must + supply exact host/path/authority and authenticated-channel plan at CHAT-00/06. +- Existing `tools/tmux/**`, `roles/**`, immutable `contracts/**`, auth/provider + state, root files, registry increment 3 and queue-as-data work are excluded. + If a prerequisite needs these, escalate an exact bounded change, never work around. + +These path proposals are not writer claims or permission to change schemas, +policy, auth or live fleet. Runtime configuration/data stay outside the repo. + +## 6. Verification, cutover and acceptance + +Keep reproducible evidence split into design agreement, fixtures, independent +candidate review, publication, observed runtime behavior and user acceptance. +The old 208/208 count is only baseline regression evidence. New functionality +needs its own tests. Run existing board, seat, ledger, registry and affected +launcher checks; run any CI configured at the trusted baseline, and identify +important missing coverage without silently expanding CI scope. + +Browser checks: real served UI, actual input/keyboard interaction, both themes +and all retained palette modes, 320px and desktop, zoom/long content, contrast, +focus/caret and scroll restoration. Test loading/empty/error/disconnected, +read-only/history, denied/stale approvals, canceled/unknown send, transfer, +stopping/uncertain/stopped, upload rejection and preserved drafts on failure. + +Protocol/security checks: cross-seat/project/branch rejection; no arbitrary +paths; stale generations; duplicate and conflicting request ids; late events +from prior execution; queue edit/dispatch races; disconnect and broker restart; +incomplete records/cursor invalidation; lost acknowledgements; upload replacement, +count/byte/type violations and capacity failures; approval allow/deny/cancel/ +timeout; attributable stop and unrelated-cohort survival; preserved native trust +and permission checks. No fixtures may write into live registrations or histories. + +Required return-flow regression: send, acknowledge, append/stream user, toolCall, +toolResult and new final assistant answer, then display that answer in the SAME +selected conversation without manual refresh, stale-preview substitution, +duplication, branch mixing or loss of input/reading position. Cover both engines, +delayed results and old-controller events. While deliberately paused or +disconnected, retain the snapshot and explicit status rather than promising live +updates; reconcile automatically on Resume/reconnect without a separate manual +refresh. + +Before live cutover, present exact target seat/incarnation, preserved session and +branch, engine/config pins, private source mapping, new process/channel topology, +permission changes if any, backup/snapshot procedure, stop proof, health checks, +exact published candidate and prior rollback artifact pins, and responsible owner. Jason separately approves EACH exact bounded live envelope; the first seat's +approval is not permission for the next seat or host class. Do not start another writer with the same UUID while old one runs. +If failed, stop new admission, reconcile uncertain work, prove new cohort stopped, +then restore verified old session/config under one writer. Never replay prompts +or approvals to make rollback appear successful. + +Before Gate E, verify every required seat is present, correctly mapped and +accessible. For each actual harness/host combination, demonstrate full two-way +conversation, tool updates, file and image attachment, native approval and denial +where supported, queued follow-up/edit/cancel, takeover, reconnect, ordinary +interrupt, confirmed force stop and explicit recovery. Unsupported required +interaction is a blocker with evidence, not a reason to omit the seat. Force-stop +demonstrations use separately approved sacrificial executions, not arbitrary +active work. Every real target remains governed by the cutover/test envelope. + +Gate E is then Jason's workday without opening the old board or a native seat +terminal for the required interaction. Jason records exceptions and gives the +end-of-day ruling. The original Monday target does not waive missing capability +or authorize rushed migration. No date guarantee is inferred. + +## 7. Current checkpoint + +Q1-Q22 are settled. Technical prerequisites remain explicit tasks, not claimed +implementations. Jason confirmed shared understanding and CHAT-00 preparation. +Next: Darkwing records its exact author/path/evidence charter and executes the +bounded protocol/contract investigation; runtime implementation remains gated. Filbert's initial plan review +identified missing explicit remote implementation and publication tasks; CHAT-04R +and CHAT-06P now cover them. Their closure review remains pending. No new code, launcher, live adapter, upload, interrupt, permission +response, migration, credential access or deployment has occurred in refinement. +Budget/usage aggregate unavailable; no numeric operator budget was supplied. + +No other global queue row is started, completed, parked or reordered by this brief. +Darkwing identified an actual dependency conflict with row 6, required #1508 +and fleet-launch row 8. Q22 explicitly preserves that ordering; no dependent fleet launcher/control +implementation starts before those prerequisites. +All-seat acceptance stays blocked on that dependency. No global row reorder or +piece-5 start is inferred; isolated protocol/fixture planning can proceed without +live effects.