Fix project chat plan persistence#1546
Merged
simple-agent-manager[bot] merged 4 commits intoJul 8, 2026
Merged
Conversation
Contributor
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
role='plan'messages via the shared chat-agent state resolver.Validation
pnpm lintpnpm typecheckpnpm testpnpm build, and Playwright visual audit at 375px and 1280px..claude/rules/47-control-loop-io-budget.md). N/A: no sweep/cron/alarm loop candidate selection change.Staging Verification (REQUIRED for all code changes — merge-blocking)
All checkboxes below are mandatory for any PR that changes runtime code (
.ts,.tsx,.go, etc.). WriteN/A: docs-onlyONLY if the PR contains zero runtime code changes. See.claude/rules/13-staging-verification.md.Staging Verification Evidence
Human-approved exception: Raphaël explicitly authorized skipping the staging deployment gate for this PR. Local quality gates, targeted regression tests, full test/build gates, Playwright visual audit, and local specialist reviews passed. Per the exception, this PR should merge directly to
mainafter CI passes, then Deploy Production must be monitored to completion and the fix verified on production.UI Compliance Checklist (Required for UI changes)
.codex/tmp/playwright-screenshots/.End-to-End Verification (Required for multi-component changes)
.claude/rules/10-e2e-verification.md)Data Flow Trace
Persisted plan rows are read by
getLatestPersistedPlan()inapps/api/src/durable-objects/project-data/session-state.ts, exposed throughProjectData.getLatestPersistedPlan()andprojectDataService.getLatestPersistedPlan(), then overlaid byresolveChatAgentState()inapps/api/src/routes/chat-agent-state.ts. The full chat detail route inapps/api/src/routes/chat.tsand lightweight state route both use that resolver. The web poll inapps/web/src/components/project-message-view/useSessionLifecycle.tsincludes plan identity in the fingerprint and hydratescurrentPlan;useActivityVerifyTimer.tsalso forwards state snapshots;CompletionDock.tsxrenders the plan pill wheneverhasPlanis true.Untested Gaps
The Durable Object worker regression test exists in
apps/api/tests/workers/project-data-do.test.ts, but localpnpm --filter @simple-agent-manager/api test:workers -- tests/workers/project-data-do.test.tscould not complete becauseworkerdrepeatedly crashed with SIGSEGV during runtime startup in this environment. Covered locally by resolver/unit tests, fullpnpm test, and Playwright visual audit.Post-Mortem (Required for bug fix PRs)
What broke
Plans were durably persisted but project chat did not reliably show them after missed WebSocket broadcasts, reloads with stale state mirrors, or false-idle activity transitions.
Root cause
PR #1487 changed the poll fingerprint without including plan identity, so plan-only updates skipped hydration. Existing hydration only used truthy
session_state.currentPlanand never reconstructed from durablerole='plan'messages. The CompletionDock also hid the plan pill behindworking && hasPlan.Class of bug
Client-state recovery gap across WebSocket, fallback polling, and cached durable state mirrors.
Why it wasn't caught
Tests covered activity/message changes but not plan-only state changes, stale/missing plan mirrors, or idle plan-pill persistence.
Process fix included in this PR
Regression tests were added for plan-only poll rehydration, state-endpoint plan hydration, reload recovery from durable plan rows, and idle plan-pill visibility. No shared process documentation file was changed.
Post-mortem file
tasks/archive/2026-07-08-fix-plan-persistence-project-chat.mdSpecialist Review Evidence (Required for agent-authored PRs)
needs-human-reviewlabel added and merge deferred to humanpnpm testpassed.Exceptions (If any)
Agent Preflight (Required)
Classification
External References
N/A: no external API or third-party documentation was needed; work was based on the supplied root-cause analysis and local repository code.
Codebase Impact Analysis
Affected paths:
apps/api/src/durable-objects/project-data/*,apps/api/src/routes/chat-agent-state.ts,apps/api/src/services/project-data.ts,apps/web/src/components/project-message-view/*, API/web unit tests, andapps/web/tests/playwright/completion-dock-audit.spec.ts.Documentation & Specs
N/A: no public docs or specs required updates; this is an internal bug fix with task evidence archived in
tasks/archive/2026-07-08-fix-plan-persistence-project-chat.md.Constitution & Risk Check
Checked no-hardcoded-values and test-coverage expectations. The only added fixed values are test fixtures and a cheap local hash for plan fingerprinting; runtime behavior uses existing API/state contracts. Primary risks were stale cached state, plan clearing, and UI idle visibility, all covered by targeted regressions and Playwright audit.