Skip to content

fix(cloud-task): make question answered state durable across chat switches and restarts#3241

Merged
tatoalo merged 2 commits into
mainfrom
posthog-code/durable-question-answer-state
Jul 7, 2026
Merged

fix(cloud-task): make question answered state durable across chat switches and restarts#3241
tatoalo merged 2 commits into
mainfrom
posthog-code/durable-question-answer-state

Conversation

@tatoalo

@tatoalo tatoalo commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Problem

A question's answered state was never durable.

  • question responses were stored in component state, so switching chats unmounted the permission card and reset all progress. Returning to the chat always restarted multi-step questions from the beginning.

  • permission requests answered after a run had already terminated were never durably marked as resolved. The response resumed on a new run, but no _posthog/permission_resolved entry was written, allowing the same request to reappear after app reloads, session rebuilds, on another device, or from stale snapshots. Replayed permission_request events also bypassed stream deduplication.

Fix

  • persist in-progress question drafts in a shared Zustand store keyed by toolCallId, preserving step progress and free-text input across remounts. Drafts are cleared on submit or cancel.

  • write _posthog/permission_resolved to the run log when resolving or cancelling terminal permission requests, ensuring responses are durably recorded even after the original sandbox has exited.

  • prevent duplicate permission prompts by tracking responded request IDs until the durable log entry is available, and deduplicate all replayed SSE events, including permission_request frames.

@trunk-io

trunk-io Bot commented Jul 7, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit fb6d4b7.

…tches and restarts

Since questions relay over the durable event stream (#3199, #3215), users
report that switching chats resets answered questions. Two gaps cause it:

1. The question card held its in-progress step answers in component state.
   Switching chats unmounts the card, so every answer selected so far was
   wiped and the card restarted at question 1 on return. The answers now
   live in a view store keyed by toolCallId, and the card restores them
   (including free-text input, via a new ActionSelector initialCustomInput
   seed) on remount. Submit and cancel clear the draft.

2. A question answered after its run terminalized (the resume-as-prompt
   path) never got a `_posthog/permission_resolved` record: the sandbox
   that would write one is gone, so the request stays pending in the
   persisted log forever and any log derivation that escapes the in-memory
   guards (app restart, another device, a session rebuild) re-surfaces the
   answered question as a fresh card. The client now appends the resolved
   marker to the owning run's log itself, tracks responded requestIds so
   stale snapshots (a marker not yet flushed to storage) cannot re-add
   them, and the watcher dedups replayed permission_request frames by
   stream id — they previously bypassed the seenEventIds guard entirely.

Generated-By: PostHog Code
Task-Id: 9c723d92-b8ef-4c9f-9317-2f53b4644f33
@tatoalo tatoalo force-pushed the posthog-code/durable-question-answer-state branch from b5c7a04 to 2e05b82 Compare July 7, 2026 17:03
@tatoalo tatoalo self-assigned this Jul 7, 2026
React Doctor flagged exhaustive-deps on the question card: allQuestions
was re-parsed (Zod safeParse) and re-allocated on every render, so every
useCallback depending on it re-created each render. Wrap the parse in
useMemo keyed on toolCall._meta.

Generated-By: PostHog Code
Task-Id: 9c723d92-b8ef-4c9f-9317-2f53b4644f33
@tatoalo tatoalo marked this pull request as ready for review July 7, 2026 18:08
@tatoalo tatoalo requested a review from a team July 7, 2026 18:09
@tatoalo tatoalo added the Stamphog This will request an autostamp by stamphog on small changes label Jul 7, 2026

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR exceeds the auto-approval size ceiling (671 lines, 10 files) and has zero reviews. The changes are focused and well-tested, but they touch session permission handling, cloud run log mutation (appending to run logs), and state durability across restarts — all meaningful behavioral changes that warrant at least one human reviewer before merging.

@stamphog stamphog Bot removed the Stamphog This will request an autostamp by stamphog on small changes label Jul 7, 2026
@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(ui): memoize question meta parsing f..." | Re-trigger Greptile

@tatoalo tatoalo merged commit 49cf9ee into main Jul 7, 2026
31 checks passed
@tatoalo tatoalo deleted the posthog-code/durable-question-answer-state branch July 7, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants