ITADN
obra/lace/Issues

fix(prompt+storage): fallback turn_end + dedup invariant (PRI-1818 #2)

#342Pull Requestobra 创建于 2026-05-24
O
obracommented
## Summary Defense-in-depth half of PRI-1818. Restructures `prompt.ts` so any throw from `runner.run()` synthesizes a fallback `turn_end` (`stopReason: 'prompt_handler_caught'`), and adds a storage-layer dedup keyed on `turnId` so the fallback is a silent no-op when the runner already wrote its own `turn_end`. Pairs with PRI-1818 #1 (separate branch, makes the runner authoritative on classified error paths). #2 is the safety net for paths #1 can't cover — throws between `turn_start` and `runner.run()` starting, throws from runner construction, or future bugs in #1's classifier. Bases off `main`; should merge cleanly alongside #1 (different files). ## Changes - `storage/event-log.ts`: `appendDurableEvent` rejects a second `turn_end` for the same `turnId` (warn-logs, returns existing event, leaves state unchanged). New `findTurnEndEventByTurnId` helper for the lookup. - `storage/event-types.ts`: exports `PROMPT_HANDLER_CAUGHT_STOP_REASON = 'prompt_handler_caught'` constant. - `rpc/handlers/prompt.ts`: hoists `writeAndAdvance` out of the try; adds `catch (err)` that writes the fallback `turn_end` if `turn_start` was actually written, then rethrows. Runner's stopReason wins when both fire (dedup). - Tests: 3 storage cases (skip duplicate, allow different turnId, no-turnId edge) + 3 prompt cases (runner throws without turn_end / runner throws after turn_end / runner succeeds). ## Test plan - [x] `npm run lint --workspace=packages/agent` clean on changed files (pre-existing lint errors in unrelated files: manage_reminders.ts, recall.test.ts, persona scheduler tests — not my changes) - [x] `npm run typecheck --workspace=packages/agent` clean - [x] `npx vitest run --root packages/agent src/storage src/rpc src/core/conversation` — 269 tests pass including 37 new - [x] `npm run build --workspace=packages/agent` clean - [ ] E2E suite has 107 pre-existing failures (Node deprecation warning leaking to stderr in spawned child processes); verified by stashing my changes and reproducing same failure on clean tree. Out of scope. Closes one half of PRI-1818.
合并状态:未合并 1 条评论