fix(web): bind first prompt to created session - #490
Conversation
tt-a1i
left a comment
There was a problem hiding this comment.
Reviewed at exact head 6bed11a. The core Session-target binding fix is correct and no P0/P1 was found, but this changes first-prompt Session identity and is therefore not on the low-risk auto-merge path.
Spec
[P2] An uncertain create response can still create a second blank Session. If the Host successfully activates a new Session but the HTTP response is lost, the catch path refreshes and resets selection while retaining workspaceDraft, then a manual retry sends a fresh creation command ID. Even if refresh observed the first Session, the next send can create another one. The existing creation-failure test models a pre-mutation throw only. Please preserve/reconcile the original creation identity, or make retries idempotently reuse it, and test post-commit response loss.
Standards
No actionable standards finding. The implementation otherwise keeps SessionManager authoritative and revalidates the receipt identity after async boundaries.
Problem
Closes #466. A newly created Web Session returned a creation receipt, but the browser discarded its stable identity and later read the first prompt target from a refreshed snapshot. Another tab could activate a different Session between those steps, causing the original prompt or preselected model to be retargeted. The path-based confirmation added by #482 also could not represent a Pi Session before its first persisted file exists.
Value
The first prompt and its draft model stay bound to the Session the user created. Cross-tab activation now stops the send and preserves the Composer input instead of silently adopting another workspace or Session.
Approach
sessionIdfrom the Pi runtime and Host creation receipt/events; keepsessionPathoptional before first persistence.{ commandId, sessionId, optional sessionPath, workspacePath, epoch }while preserving the existingworkspaceDraftauthority from fix(web): bind workspace drafts to confirmed Pi sessions #482.SESSION_CONFLICTand prompt idempotency boundaries.docs/design/WEB_SESSION_CREATION_TARGET.md.Validation
bun run checkpassed: config contract, discipline ledger, Web build/typecheck, format, lint, and TypeScript typecheck.bun run testpassed: 1,465 Node tests passed, 1 platform-specific test skipped, 0 failed; Web suite 134/134.bun run test:web:e2epassed: 12/12. The new test starts the current checkout's standalone Host/Pi runtime, delays Session A's HTTP receipt, switches to Session B through an independent request while suppressing SSE, and verifies that no prompt is sent and A's input remains in the Composer.commandIdcorrelates events and the receiptsessionIdis the target authority. Removing receipt-boundsessionIdvalidation restores the reported retargeting failure.piexecutable, so installed-packagepi listprovenance was unavailable. Playwright invokedbin/openpi.jsdirectly from this checkout. No model call was made.Impact