Replies: 1 comment
|
Verified your full chain at master 49a606b (the exact commit you cite) — every line reference matches, and I can add the missing piece: the persistence contract over-promises. This is not the first report of the mechanism — it is corruption-family mechanism #1. #1452 (2026-08-14, rc.6) reproduced it byte-for-byte: Web backend + desktop shell on the same DSH_HOME both appended to one Your proposed fix already has a tested community implementation. wellorbetter's fork from #1550 (commit Two caveats worth carrying into any upstream fix:
Confirmed open upstream at alpha.5. Suggest upstream adopt the lease design (it is community-tested) or at minimum scope the contract and fail loud. Worth auditing sibling backends for the same pattern — SQLite's physical-collision guard was likewise reported per-process-only (#4264). |
Uh oh!
There was an error while loading. Please reload this page.
Observed behavior
At commit
49a606bc(0.1.2-alpha.5), two DSH processes using the same JSONL persistence root can both resume the same session for writing. Neither process receivesSessionAlreadyOwnedError.Evidence
The persistence contract says that
open(id, 'write')“atomically claims single-writer ownership” and rejects an active owner (packages/session/session-persistence/src/index.ts:149-160).The JSONL implementation claims ownership in
open()throughtracker.claimWrite(id)(packages/session/session-persistence-jsonl/src/index.ts:215-256). That tracker stores writers in an instance-localMap, andclaimWrite()checks only that map (packages/session/session-persistence-jsonl/src/storage.ts:319-361). A second process has a separate map and therefore accepts the same session.The append path then opens the shared log in append mode (
packages/session/session-persistence-jsonl/src/index.ts:838-866). Both writers can start from the same logical cursor and append overlapping sequence numbers, making the stored log ambiguous or invalid on its next read.Minimal reproduction
root(use different listen addresses if running two Web profiles).Expected: the second resume fails with
SessionAlreadyOwnedError.Actual: both resumes succeed and both processes append to the same session log.
Impact on plugin authors
A plugin or alternate UI cannot safely offer session resume when another DSH process may use the same persistence root. Adding a plugin-owned lock would duplicate persistence ownership and cannot cover other DSH clients.
Possible fix
The JSONL backend could hold an exclusive cross-process lock keyed by session id for each write handle, recording host/pid ownership for safe stale-owner recovery and releasing it from
close().All reactions