PR: #351: [Story-1373] Agent rail resilient to mount churn + reconnect-refetch by @ankitmaheshwari-com
View PR →
Story 1373

Agent rail resilient to mount churn (StrictMode / remount) + reconnect-refetch

The Step-5 "infinite thinking" hang (pramaan-spec#1372) was a frame delivery failure. The broker (pramaan-functions #356, merged) pushes the only-frame-that-settles-the-UI (turn.completed/run.done) to the connection frozen at launch. When the browser's WebSocket churns mid-run — React StrictMode every dev run, a real parent remount for ~15% of prod runs — that launch connection is dead (410 Gone), so the reconnected client never sees the terminal frame and hangs forever. This change kills the churn at the source on the app side and adopts #356's recovery.

Root cause: the socket lived inside the component

useAtlasRail owned its WebSocket inside AddMatterWizard. The hook's unmount cleanup closed the socket and the next launch reopened a new one. So any churn of the component holding the hook tore the live run down:

The fix: lift the connection out of the React tree

AC#2 — stop the prod remount from orphaning the run

The connection is keyed by formId. For a remount to reuse the live run, that key must be stable across the remount — but formId was useState(crypto.randomUUID()) inside the wizard, so a wizard remount minted a fresh id and a fresh run, orphaning the old one.

AC#3 — consume #356's query replay on a genuine drop

Before → after

Before After
Socket owned by useAtlasRail (in the component) Socket owned by a module-scoped AtlasRailConnection
StrictMode / remount → cleanup closes socket → relaunch Remount re-subscribes within a 3s grace → socket + run survive
formId minted inside the wizard (resets on remount) formId owned by the stable list page (stable across remount)
Mid-run drop → permanent "disconnected" / infinite thinking Mid-run drop → reconnect + query replay → settles once

Acceptance criteria

Verification

Files changed

8 file(s), +746 / -209 lines

Path Role + -
src/components/add-matter/add-matter-modal.tsxComponent+3-0
src/components/add-matter/add-matter-wizard.tsxComponent+14-1
src/components/matters/live-matters-list-page.tsxComponent+13-2
src/lib/agents/__tests__/atlas-rail-store.test.tsLibrary+267-0
src/lib/agents/__tests__/atlas-rail.test.tsLibrary+11-0
src/lib/agents/atlas-rail-store.tsLibrary+380-0
src/lib/agents/atlas-rail.tsLibrary+20-0
src/lib/agents/use-atlas-rail.tsLibrary+38-206