Goal
Make the session/directory lifecycle explicit after #436, so PawWork no longer relies on provider remounts, stale route snapshots, or scattered readiness booleans to keep session UI and execution actions correct.
When this task is done:
Scope
In scope:
- Define
SessionScope, likely { serverKey, sessionID }.
- Define
ExecutionScope, likely { directory, client, store, setStore, epoch }.
- Keep timeline rendering keyed by
SessionScope.
- Keep execution actions keyed by
ExecutionScope.
- Replace scattered action gates with one observable action-readiness selector, with components such as
cacheReady, statusReady, commandsReady, providerReady, and localModelReady.
- Block
/custom-command submit until command hydration is ready.
- Block or defer sends until directory-local model selection hydration is ready.
- Move follow-up persistence and queued draft ownership to
{ serverKey, sessionID } or an equivalent collision-proof scope.
- Persist source scope with queued follow-up drafts and verify it before auto-send.
- Add epoch/revision guards for async revert/restore, prompt rollback, VCS/review, and artifact result application.
- Add a stable e2e, browser-level, or diagnostics-backed regression for
enter-worktree -> exit-worktree -> follow-up on a long session.
- Clean up duplicate or misleading readiness/state names such as
session_status_ready, session_status_state, statusKnown, and routeReady where practical.
Already handled in #436, do not duplicate unless a regression appears:
- Same-session
activeDirectory changes do not unmount MessageTimeline.
- Last-good timeline messages survive transient same-session cache misses.
- Follow-up, revert, and review helpers no longer use initial directory/client snapshots.
- Review VCS diff tasks/results are guarded by execution directory.
session.status() hydration preserves active events that arrive during the request and clears stale pre-request busy / retry when the fresh snapshot is idle.
- Current-directory child-store retention follows the live directory accessor instead of a long-lived provider owner.
Out of scope:
Relevant files or context
Related issues and PRs:
Likely files and areas:
packages/app/src/context/sync.tsx
packages/app/src/context/global-sync.tsx
packages/app/src/context/global-sync/bootstrap.ts
packages/app/src/context/global-sync/child-store.ts
packages/app/src/context/local.tsx
packages/app/src/pages/session.tsx
packages/app/src/pages/session/use-session-followups.ts
packages/app/src/pages/session/use-session-revert.ts
packages/app/src/pages/session/use-session-review-state.ts
packages/app/src/pages/session/use-session-timeline-data.ts
packages/app/src/components/prompt-input.tsx
packages/app/src/components/prompt-input/submit.ts
Important review context from #436:
- Same
sessionID under different server/workspace must not reuse timeline, follow-up, or action state accidentally.
- Directory switch followed by immediate
/custom-command must not send command text as a normal prompt before command.list hydrates.
- Directory switch followed by immediate send must not use fallback model/provider while local persisted model selection is still hydrating.
- Click revert, switch directory before the request settles, and verify API client, store writes, and prompt rollback only affect the click-time execution scope.
- Old async results must not overwrite a newer execution context even if the directory string is reused.
Verification
Required checks for the closing PR:
- Add focused unit tests for
SessionScope and ExecutionScope behavior.
- Add action-readiness tests covering command hydration, provider/model hydration, session cache readiness, and status readiness.
- Add follow-up queue tests proving two servers/workspaces with the same
sessionID do not share queued drafts.
- Add async stale-result tests for revert/restore, prompt rollback, and VCS/review result application.
- Add a stable regression for the original long-timeline path:
enter-worktree -> exit-worktree -> follow-up.
- Verify
MessageTimeline does not unmount, rendered count does not reset to the initial small window, scrollTop does not jump near 0, and follow-up sends against the intended execution directory.
- Run the relevant focused app tests.
- Run
bun --cwd packages/app run typecheck.
- Run
bun --cwd packages/app run test:unit unless the closing PR gives a concrete reason to use a narrower suite.
- Run
git diff --check.
Execution mode
Agent should investigate and propose a plan first.
Goal
Make the session/directory lifecycle explicit after #436, so PawWork no longer relies on provider remounts, stale route snapshots, or scattered readiness booleans to keep session UI and execution actions correct.
When this task is done:
Scope
In scope:
SessionScope, likely{ serverKey, sessionID }.ExecutionScope, likely{ directory, client, store, setStore, epoch }.SessionScope.ExecutionScope.cacheReady,statusReady,commandsReady,providerReady, andlocalModelReady./custom-commandsubmit until command hydration is ready.{ serverKey, sessionID }or an equivalent collision-proof scope.enter-worktree -> exit-worktree -> follow-upon a long session.session_status_ready,session_status_state,statusKnown, androuteReadywhere practical.Already handled in #436, do not duplicate unless a regression appears:
activeDirectorychanges do not unmountMessageTimeline.session.status()hydration preserves active events that arrive during the request and clears stale pre-requestbusy/retrywhen the fresh snapshot is idle.Out of scope:
activeDirectorychanges.Relevant files or context
Related issues and PRs:
Likely files and areas:
packages/app/src/context/sync.tsxpackages/app/src/context/global-sync.tsxpackages/app/src/context/global-sync/bootstrap.tspackages/app/src/context/global-sync/child-store.tspackages/app/src/context/local.tsxpackages/app/src/pages/session.tsxpackages/app/src/pages/session/use-session-followups.tspackages/app/src/pages/session/use-session-revert.tspackages/app/src/pages/session/use-session-review-state.tspackages/app/src/pages/session/use-session-timeline-data.tspackages/app/src/components/prompt-input.tsxpackages/app/src/components/prompt-input/submit.tsImportant review context from #436:
sessionIDunder different server/workspace must not reuse timeline, follow-up, or action state accidentally./custom-commandmust not send command text as a normal prompt beforecommand.listhydrates.Verification
Required checks for the closing PR:
SessionScopeandExecutionScopebehavior.sessionIDdo not share queued drafts.enter-worktree -> exit-worktree -> follow-up.MessageTimelinedoes not unmount, rendered count does not reset to the initial small window,scrollTopdoes not jump near 0, and follow-up sends against the intended execution directory.bun --cwd packages/app run typecheck.bun --cwd packages/app run test:unitunless the closing PR gives a concrete reason to use a narrower suite.git diff --check.Execution mode
Agent should investigate and propose a plan first.