Repository navigation
ui-react: the journal runtime test finishes its memory turn before the awaited memory record, failing two cells #2889
Description
Context
packages/ui-react/tests/turn-journal-runtime.test.ts fails two cells on origin/main (1c5666e): "persisted external memory uses the existing reader and authenticated recovery dark 320" and "… light 1280". Both report 0 changed files · 0 steering where 1 steering is expected, and the run logs an unhandled The change journal cannot safely retain this observation: memory observation requires an active turn between tests.
The fixture calls memoryState.persist(temporary, undefined, (change, save) => app.wsHost.journal!.persistClaudeMemory(memoryId, change, save)) without awaiting it (packages/ui-react/tests/turn-journal-runtime.test.ts:75), then finishes the turn on the next line. persist returns a Promise whenever the host records notes asynchronously (const persistNotes, packages/ui-backend-claude/src/worker-state.ts:326-335), and the journal's memory record runs after persistClaudeMemory awaits its retained objects, so journal.finish(memoryId) ends the turn first and recordClaudeMemory refuses (async recordClaudeMemory, packages/ui-server/src/brain/turn-journal.ts). Journal writes became off-loop and asynchronous in #2830, which is probably when the race became deterministic.
Found while running the ui-react runtime suite for #2873; reproduced identically on a clean origin/main worktree.
Scope
- Await the fixture's
persist(...)result beforememoryState.release()andjournal.finish(memoryId). - Keep the test's assertions; do not weaken them.
Out of scope
- Any change to
persistClaudeMemory,recordClaudeMemoryor the worker-state persistence order in product code, unless the fix shows the product path also finishes a turn before a pending memory record (then file it separately).
Acceptance criteria
- Both "persisted external memory …" cells pass in
bun run test packages/ui-react/tests/turn-journal-runtime.test.ts, and the unhandledmemory observation requires an active turnerror no longer appears. - Removing the added
awaitmakes those two cells fail again on the1 steeringassertion (mutation receipt in the PR).
Verification
bun run test packages/ui-react/tests/turn-journal-runtime.test.ts (real Chrome).
Contract impact
None: test fixture only.
Activity
test(ui-react): await the memory copy-out before ending the fixture's…
fix(ui-server): record a Claude memory save in the journal's observat…