插件目录 / Data / dsh-single-instance-guard
dsh-single-instance-guard
已验证 · 实测可装 Tang-mm95
功能简介
DSH_HOME single-instance lock plugin for DeepSeek Harness: aborts startup loudly when another dsh server uses the same data directory (prevents session-log corruption)
可用 — 实测通过,早期项目
DSH_HOME single-instance lock plugin for DeepSeek Harness: aborts startup loudly when another dsh server uses the same data directory (prevents session-log corruption) 实测能干净安装、正常启动。早期项目,但功能可用。
「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。
README
dsh-single-instance-guard
A zero-dependency DeepSeek Harness plugin that takes an exclusive lock on the DSH_HOME data directory at startup and aborts loudly when another live dsh server already uses it.
Why
The JSONL session persistence backend documents "One live writer per session" and has no cross-process defense. Two dsh servers sharing one DSH_HOME (a desktop wrapper spawning its own server, or two dsh web processes) append batches with stale sequence cursors, corrupting session logs:
history unavailable for session "…": Error: corrupt session log: seq gap in committed region …
See this report for the full diagnosis, a read-only scanner, and a manual repair procedure.
This plugin turns the silent corruption into a loud startup failure.
Install
After publishing to npm:
dsh plugin --profile <profile> add dsh-single-instance-guard
Manual (any dsh install): add the row to the profile's cordis.patch.yml before session-related bundles:
- insert:
- id: single-instance-guard
name: 'dsh-single-instance-guard'
The guard is a profile bundle: its manifest declares the same patch, so the CLI installs it as a patch layer.
How it works
- Creates
<DSH_HOME>/.dsh-server.lockatomically (O_EXCL), holding{ pid, startedAt, hostname }. - On conflict, probes the holder's pid liveness: a live holder aborts startup with a clear bilingual error; a stale lock (dead pid or unparsable file) is removed and acquisition retried once.
- On process exit the lock is removed — only if still owned by this process.
DSH_HOME is resolved exactly like dsh itself: $DSH_HOME or ~/.dsh. Servers with different data roots never conflict.
Known limits
- The unlink+retry path has a tiny race when two processes discover the same stale lock simultaneously; the atomic
O_EXCLwrite still admits exactly one winner, and the loser fails correctly on the retry. - The lock protects against concurrent servers sharing one
DSH_HOME. It does not protect against two dsh instances deliberately pointed at the same session file via different roots (unsupported anyway).
Development
npm test # node --test
License
MIT
安装
装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:
dsh plugin add dshbase-catalog 然后对 agent 说「帮我装 dsh-single-instance-guard」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。
该插件是 GitHub 源码(未发 npm)——直接从仓库装:
Web profile:
dsh plugin --profile web add github:Tang-mm95/dsh-single-instance-guard Headless(CLI)profile:
dsh plugin --profile headless add github:Tang-mm95/dsh-single-instance-guard 实测报告
验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。