Replies: 2 comments
|
Verified against rc.8 (141eb6f) — the bug is still present in-tree (not just rc.7), and your root-cause analysis is the right shape. This is a new member of the session-corruption family, with a clean minimal repro. My additions: 1. rc.8 status: still open, same three throw sites
No reorder/tolerance logic added between rc.7 and rc.8. So the fix is still pending in-tree, and your workaround.patch (option 1: move the start to 2. The mechanism is a genuine corruption-family member (data-driven, not plugin-caused)I traced the producer side to confirm your "replacement copies" claim: compaction-basic emits exactly one replace — This joins the family of "load-side strictness turns data-driven session shapes into unreadable sessions": #2900/#2661 (balanced-but-dangling tool calls), #2998 (frame-shape throws), #3198 (end-seed seq gap). Like those, the strictness is deliberate (an out-of-order start could indicate corruption) — but here the producer is in-tree compaction itself, so the invariant "replacement copies preserve turn-boundary order" is one the harness cannot guarantee for old/compacted sessions. That changes the calculus: the load side must tolerate it. 3. Your option 1 vs option 2 — and the right call
One implementation note for option 1: when you move the late start to 4. Family + PR shapeThis is the 13th report / 11th mechanism in the session-corruption family (12 reports / 10 mechanisms as of #3198; your #3450 adds the replay-ordering mechanism). The PR-ready blueprint: the 3-guard reorder (option 1) + a "late vs missing start" discriminator + a regression test using your two-event repro + a producer-side hygiene note for compaction-basic's replace emission. Your workaround.patch is already validated against 31 sessions — that's the regression corpus. Nice find — the two-event minimal repro is exactly what makes this actionable, and the "replacement copies are seq-ordered, not turn-ordered" framing is the key insight that separates it from the earlier corruption members. |
|
I turned the rc.7 reproduction plus the still-present rc.8 ( The key operational boundary is to preserve the untouched Session before changing the reader: this signature is a client conversation-projection refusal and does not by itself prove corrupt persistence bytes. The guide therefore routes export/copy, fresh-Session isolation, safe continuation, and archive before any patched-build experiment. It also carries a 12-gate repair matrix across |
Uh oh!
There was an error while loading. Please reload this page.
Environment
0.1.0-rc.7(Windows 11; also reproduced with the same code on WSL)Error
9:turn-tail8is the turn-tail business context for turn 8 (kind="turn-tail", id8).Root cause
ConversationNodeAssemblerin@deepseek-ai/dsh-client-runtimethrows in three places(
acceptMatch,applyPendingMatches,replayContext) when a turn-tail update matcharrives before its start match.
Real session logs can contain surface replacement copies (
surfaceOp: {op:'replace', start, end})whose ordering does not preserve turn boundaries: a replacement copy of an update
(
assistant/message, turn N) can be emitted before the replacement copy of that turn'sturn/start. In our case:assistant/message(turn 8) atseq 149006, thenturn/start(turn 8) at
seq 149009— both inside the same replacement range. Replaying the engine overall stored sessions reproduced the crash in 3 of 31 sessions (turn-tail 2 / 8 / 13).
Minimal reproduction
Two sanitized events are enough (see
repro-events.json): feed them in seq order toConversationNodeAssembler.replaceWindow()with the turn-tail Definition registered(the Definition is copied verbatim from
dsh-client-ui-conversation).Run the included
repro.mjsagainst a checkout ofdsh-client-runtime:✅ BUG REPRODUCED: conversation Context 9:turn-tail8 received an update before its start Match✅ OK: no crashImpact
Any session whose surface replacement range splits a turn can fail to load in the chat view.
This is data-driven (old/compacted sessions), not caused by any plugin.
Suggested fix
Either:
matches, move it to
matches[0]instead of throwing (same inapplyPendingMatches/replayContext); orturn/startbefore updatesof the same turn).
Local workaround
workaround.patchimplements option 1 againstdsh-client-runtime/lib/client.js(three guard points; validated by replaying all 31 sessions: 0 failures, no behavior change
for well-ordered sessions).
Note: real session logs are intentionally NOT attached because they contain private
conversation content. The synthetic events above reproduce the bug exactly.
repro-events.json
All reactions