Master advanced from 5143fac7f to be363166e with the Cordis and loader vendor update after the previous PR merge was validated. GitHub therefore tested a new synthetic merge where packages/util/home still selected Cordis rc.6 with loader rc.4 while the updated workspace graph requires Cordis rc.7 with loader rc.5. That stale importer made pnpm-lock.yaml semantically incomplete even though Git merged it without a textual conflict, so every Node, sandbox, and real-API job failed during immutable install before running tests. Merge the exact current master tip and regenerate the lockfile so the home package resolves the same peer graph as the updated workspace. Verified the repaired merge with pnpm install --frozen-lockfile; the full pre-push gate runs on the committed merge before it is published.
@deepseek-ai/dsh-session-persistence-jsonl
The JSONL durable session-persistence backend — a concrete SessionPersistence (the dsh-session-persistence seam). One append-only .jsonl event log per session.
On-disk layout
<root>/
cwd-<sha256(cwd)[:12]>/ # per-project bucket (or _no-cwd/ when no cwd)
<encoded-id>.jsonl # header line + one SessionEvent per line (verbatim)
- The first
.jsonlline is the immutableSessionHeadertagged{ type: 'session', version, id, cwd?, createdAt, parentSession?, seedLength? }; every subsequent line is oneSessionEventJSON, verbatim includingassistant/chunksoseqstays contiguous (events[i].seq === i). - Session ids are unvalidated branded strings, so they are percent-encoded to a single safe path segment before use (no traversal, no collision).
Config
| Key | Type | Notes |
|---|---|---|
root |
string (required) |
Root directory for all session files. No default — a process.cwd() default would scatter files as the process's cwd changes (bash calls, subprocesses). |
locate(meta) returns { kind: 'jsonl', path } using the resolved absolute root and the same cwd-bucket/id encoding as materialization. It performs no filesystem I/O: the target can be returned before the file exists, and an existing file contains only the last flushed prefix.
Durability and crash semantics
- Lazy materialization.
create(meta)writes nothing; on the firstappend, the backend writes andfsyncs a temporary file, publishes it without overwrite via a hard link, thenfsyncs the directory. A created-but-never-appended session leaves nothing on disk and is absent fromlist. - Append-only. Committed events (at or below a flushed
turn/end) are never rewritten. Subsequent appends are line appends at EOF +fsync. - Crash recovery — preserve valid tail work.
loadkeeps the contiguous valid prefix of an interrupted final turn. It truncates from the first unparsable or sequence-gapped uncommitted record, then appends the synthetic tool, step, and turn closers required by the shared persistence contract; the same defect at or before the last committedturn/endrejects. - Contiguous-seq.
appendrejects a batch whose firstseqdoes not continue the stored log, and rejects non-JSON-serializableevent.datanaming the offending event type.
Write path
The plugin buffers frozen session events and drains them on flush or disposal. A per-session cursor prevents resumed sessions from re-appending stored events, and live sessions are seeded when the plugin loads. Operations for one session are serialized; disposal waits for initialization and the final drain so no write lands after teardown.
Model Experience
Resumed conversation history
What the model sees: JSONL storage contributes no live prompt or schema. Loading restores stored surface history and preserves prior request headers for reconstruction; the new loop composes its current envelope. Each unanswered call in an interrupted tail is balanced with the exact error text Tool call interrupted by a crash; no result was recorded. Raw assistant/chunk records do not duplicate messages.
Token effect: Zero live-request tokens. A resumed agent pays for retained history and its current envelope, plus the quoted repair result for each interrupted call.
Known Limitations and Deferred Work
- Only the current
SESSION_FORMAT_VERSION(v0) loads — the on-disk format is pre-release/unstable: a breaking format change is absorbed at v0 and non-current logs are rejected; there is no migration. - Nothing deletes session files — logs accumulate under
rootuntil removed externally (the seam has no deletion surface). - Single-process assumption — per-session serialization and the write cursor live in this process; two processes appending to the same
rootare not coordinated. - Initial materialization requires hard-link support — first append uses
link()so same-id races fail instead of overwriting a committed log; a filesystem that cannot create hard links cannot host this backend.