Replies: 4 comments
|
Same family as #1497 — seq overlap/rollback in the committed region. Two zero-history-loss options (verified against the unpatched npm 0.1.1-rc.2: 931,455 events, no seq gap,
Pick #2 if the log is already broken; patch the readers if you want future crashes to stay invisible. |
Three independent reproductions of the resume-after-end-seed seq collision (macOS, dsh 0.1.1-rc.2) — plus a secondary publication failure after seq repairFollowing up on this thread and #1364 with three incidents from a single macOS deployment today (two daemons, four affected session logs). Our evidence adds three points not yet covered here: (1) the collision is independent of write timing, (2) seq repair alone is insufficient — a secondary publication failure persists until the session identity is rotated, and (3) a workable containment design. Environment
Incident chain (all three logs, identical signature)Each incident started with a daemon restart while a conversation had a live agent:
Observed on three logs: advisor group chat (seed seq 177), juna private gen-1 (seed seq 78), juna private gen-2 live session (seed seq 18562). Evidence ① — collision is independent of write timingTime gap between the drained end-seed and the colliding write: 42 seconds in one incident, ~1 hour in another. The colliding event is written long after all I/O has settled, so this is not a torn-write/flush race — the resumed process deterministically computes its next seq excluding the end-seed the previous lifecycle persisted. In the 1h case the intermediate turns were fully functional; only the accounting was wrong. Evidence ② — seq repair alone is insufficient: secondary alias rejection on publishWe repaired the log surgically: removed the duplicate After repair, resume still failed — now at a later stage: i.e. the alias rejection in Upshot: when a log ends in [end-seed → events appended by the stale-base process], removing the duplicate line is not enough — the whole post-seed segment is poisoned and the durable fix is to truncate at the end-seed (validated live on one log; a second log was recovered by epoch rotation instead). Evidence ③ — containment design that survived contactWe deployed a session-log doctor (exit-code contract for launchd/heartbeat integration):
Regression-tested against four real corrupt logs from today: all detected, repaired, and re-validated CLEAN. Questions
Happy to provide the affected logs (redacted) or the validator/repair script if useful. |
|
Follow-up: this hit three more times today on a second macOS deployment (dsh 0.1.1-rc.2, launchd-managed daemons, zstd multi-frame JSONL sessions) — identical signature each time. After a restart, the resumed process re-emits Two additions to the evidence base: 1. Seq repair alone is not enough — secondary publication failure. — the alias rejection in 2. Containment that works (until the fix ships). Question on the fix: is the resume-base accounting (the resumed lifecycle's next seq counting the drained Environment: dsh 0.1.1-rc.2 full stack, macOS 26.6.2 arm64, Node v26.5.0. |
|
Independent confirmation from a third deployment (Windows 11, dsh
We wrote up the full three-layer root cause with frame-level timelines, a validated fix, and pointers to this thread and #2167 in #5408: #5408 TL;DR of the fix we run locally (verified on all three corrupted sessions + a 23-case integration suite over zstd and plain layouts): a seq-aware convergence step in |
Uh oh!
There was an error while loading. Please reload this page.
corrupt session log: "seq gap in committed region" after restart when
session/end-seedwas committed in a separate appendSymptom
After restarting DSH, opening a previously-used session fails with:
and resuming the same session for chatting fails with:
Two sessions were affected on this machine. Both had been created and used in a previous DSH run, then became unreadable on the next startup.
verify-logs-style inspection confirmed the corrupted pattern in both.Observed log state
In the affected
session.jsonl.zstd, the committed region contained two events with the same seq:The validator walks the committed prefix and requires contiguous
seq = 0,1,2,...; it reportsexpected 4, got 3at the duplicate line. Because the duplicate breaks contiguity, the committed region is truncated there and every later event (the whole conversation) becomes unreadable — the session's history is effectively lost from the readable region.Suspected root cause
Both writers computed the same next-seq from the same committed base (3 events: seq 0..2), but the
session/end-seedwas written by a path whose commit was not included in the base the next writer used:When DSH creates or resumes a session whose seed does not already end with
session/end-seed, theSessionconstructor appends one:This appended
session/end-seedis a live-session write, flushed to persistence as its own append batch (it occupies a seq that a consumer reading stored history must account for).On the following startup, the recovery/next-seq computation for that session apparently did not count that separately-committed
session/end-seedbatch, so the first post-resume write (agent/inbox/spliced) reused the end-seed's seq → duplicate seq in the committed region.This is presented as the suspected mechanism from the observed log evidence and the constructor behavior above; I could not fully trace the recovery-cursor code path, so the exact line responsible still needs confirmation. The bug is in DSH's own session lifecycle/persistence (the affected sessions were created by DSH itself, not by any external tool).
Reproduction
The trigger appears to be: a session whose log received a
session/end-seedin a separate append batch (the live-session append path described above), followed by a DSH restart, followed by a new write to that session. It did not reproduce for sessions whose whole seed (including any end-seed) was committed in a single append.Impact
cannot prepare/corrupt log), so the session cannot be selected/used.Workaround
Manually repair the log by removing the duplicate line (the separately-committed
session/end-seedwhose seq was reused), restoring contiguous seqs, and re-encoding the zstd frame. This recovered both affected sessions successfully. Take a backup of~/.dsh/sessions/**/session.jsonl.zstdfirst.Environment
All reactions