Bundle
dsh-double
Self-management & self-evolution for DeepSeek Harness: health snapshots, config pre-check, blue-green evolve with auto-rollback, and an on-demand standby supervisor — let dsh manage itself.
- Source
- Junkrat9527
- License
- MIT
- Updated
- Updated 3 days ago
Readme
# dsh-double
**dsh manages dsh — and twin dsh talks to twin dsh.** A self-management,
self-evolution & twin-communication plugin for
[DeepSeek Harness](https://github.com/deepseek-ai/dsh): blue-green self
upgrades, health probing, last-known-good snapshots, plus an isolated
**testbed twin** — a full second dsh instance the main can operate freely,
that talks back agent-to-agent and evolves the main after proving changes in
its sandbox.


## What it does
A typical agent that modifies itself dies on restart, then needs an *outside*
agent to come rescue it. dsh-double closes that loop so the agent can evolve
itself safely:
1. **Self-evolution (blue-green)** — a change set is applied to a standby copy
first, statically pre-checked (`dump-config`, YAML/JSON syntax, bundle
resolvability, NO_ADAPTER guard, duplicate loader-entry detection) *and*
trial-booted. Only when both pass is the change applied to the **main** dsh,
which then restarts and must confirm healthy **before the standby is
stopped**. If the main fails to boot, it auto-rolls back to the pre-evolution
snapshot.
2. **Health probing** — main instance health is verified by TCP + HTTP + process
checks (dsh writes no pid file), with the evidence chain shown in `status`.
3. **Snapshots / last-known-good** — a baseline snapshot is taken before any
evolution and restorable on demand.
4. **Wake-on-demand standby** — when the main is stuck and mechanical recovery
failed, the dormant standby (a disk-only copy, zero processes, zero ports)
is woken as a temporary dsh instance on a separate port as a "spare brain"
to diagnose and repair the main. It is never left running in normal
operation.
5. **Twin dsh (peer brains)** — `~/.dsh/double/testbed/` is a real, fully
isolated second dsh (own `DSH_HOME`, port 3081, fresh sessions; config
cloned from main; `node_modules` / attachment objects shared read-only).
Disk-dormant by default, woken on demand. Each side gets `twin_*` tools
with **full mutual operational control** over the other (exec, fs
read/write, lifecycle, evolve).
6. **Agent-to-agent communication** — `twin_message` sends text to the twin's
own agent over the official `/api` gateway (`session.create` →
`session.prompt` → poll `session.history` to `turn/end`) and returns its
reply: the two LLM brains genuinely converse and collaborate. When the
testbed has proven an evolution in its sandbox, the main can tell it
"now evolve me" and the twin agent runs `twin_evolve` itself — blue-green,
restart and all.
7. **Anti-black-box by design** — every `twin_message` lands as a *real,
replayable session* in the receiving instance's UI; every interaction is
appended to a shared, auditable transcript
(`~/.dsh/double/comm/transcript.jsonl`, surfaced by `twin_log`, the
`dsh-double.py comm` CLI and the dashboard card).
The heavy lifting lives in the battle-tested, zero-dependency CLI
[`bin/dsh-double.py`](bin/dsh-double.py) and a small out-of-process
[`bin/dshd-supervisor`](bin/dshd-supervisor) — boot-time failures happen before
any plugin runs, so life-support must stay outside the dsh process. This plugin
exposes that machinery to the ecosystem.
## Features
- **In-harness tools** (`double_*`) — the agent inside dsh can run its own
evolution cycle end-to-end:
`double_status`, `double_check`, `double_snapshot`, `double_evolve`,
`double_rollback`, `double_wake`, `double_stop`.
- **Twin tools** (`twin_*`, role-relative — each side operates its peer):
`twin_status`, `twin_message` (agent-to-agent request/response),
`twin_exec`, `twin_fs_read`, `twin_fs_write` (full operational control),
`twin_evolve` (blue-green the *twin*: testbed→main or main→testbed),
`twin_restart`, `twin_log`; main side additionally:
`twin_up` / `twin_down` / `twin_init` / `twin_sync` / `twin_reset` /
`twin_diff` / `twin_baseline`.
- **HTTP API** — `GET /double/status`, `GET /double/check`,
`POST /double/snapshot`, `POST /double/evolve`, `POST /double/rollback`,
`POST /double/wake`, `POST /double/stop`, plus the `/double/twin/*`
surface mirroring the twin tools (status/log/message/exec/fs/evolve/up/
down/restart/init/sync/reset/diff).
- **Settings dashboard** — two cards in dsh 设置: the self-management panel
(main health, last-known-good, snapshots, standby, one-click actions) and
the **twin communication panel** (peer status, lifecycle buttons, a message
box that talks to the twin's agent, and a live feed of the shared comm
transcript).
- **Testbed-first workflow guidance** — a global `~/.dsh/AGENTS.md` iron rule
plus the `dsh-twin-workflow` skill (`skill/`) steer agents to experiment in
the twin (3081) and only then `twin_diff` + `twin_evolve` the proven delta
back; `testbed clone/reset` carries the rule and skills into the twin.
- **Twin session visibility** — `GET /double/twin/threads` replays both twin
threads (text + tool calls/results) in the main dashboard card, so watching
only the main page is enough to follow everything the twins said.
- **Transparent main restarts** — testbed→main evolves announce themselves in
the transcript and wait `evolveNoticeSec` (8s default) before dropping the
page; after dsh's auto-reconnect the card banners the outcome. Opt-in
`requireEvolveApproval` queues twin evolves for main-UI approve/reject; the
approved engine runs in a double-forked detached wrapper that survives the
restart and records the final result.
## Install
> Requires the dsh-double CLI + supervisor on the host (shipped in this repo
> under [`bin/`](bin/)):
> install `bin/dsh-double.py` and `bin/dshd-supervisor` to
> `~/.local/bin/` (make them executable).
```bash
dsh plugin add dsh-double
```
Or link it from source:
```bash
git clone https://github.com/Junkrat9527/dsh-double.git ~/dsh-double
cd ~/dsh-double && npm install && npm link
dsh plugin add dsh-double
```
Then restart dsh and check **设置 → 自我管理(dsh-double)** or call
`GET /double/status`.
## Usage
Ask the agent, or call the API/tools directly:
```text
"先跑 double_check 预检我的配置,然后 double_evolve 应用我准备好的变更目录,
成功后 double_status 确认主实例健康、备用身已休眠。"
```
Or via HTTP:
```bash
curl http://127.0.0.1:3080/double/status
curl -X POST http://127.0.0.1:3080/double/evolve -H 'content-type: application/json' \
-d '{"change_dir": "/path/to/change-set"}'
```
Twin workflow (experiment in the sandbox, then let the twin evolve the main):
```bash
dsh-double.py testbed init && dsh-double.py testbed up # wake the twin @3081
# ...experiment in the twin (its UI at http://127.0.0.1:3081 is fully isolated)...
dsh-double.py testbed diff # delta vs baseline
curl -X POST http://127.0.0.1:3080/double/twin/message -H 'content-type: application/json' \
-d '{"text": "验证通过后,请调用 twin_evolve 把你的增量应用到主 dsh"}'
dsh-double.py comm 20 # audit the whole exchange
```
## Architecture
```
~/.dsh/double/
├── snapshots/ # baseline snapshots (health-baseline copies)
├── standby/ # dormant standby copy (blue-green precheck target)
├── evolutions/ # evolution event log (pass/fail, rollback?)
├── comm/transcript.jsonl # shared twin-communication audit log
├── supervisor.log # life-support events
├── last-known-good # pointer to the last healthy snapshot
└── testbed/ # the twin: a full, isolated second dsh (DSH_HOME, port 3081)
├── ... # config cloned from main; node_modules & attachment
│ # objects symlinked read-only; FRESH sessions/storages
└── baseline/ # main-config reference for twin diff
```
Ports: **main 3080** (no `--port` arg), **testbed 3081**, **blue-green trial
boot 3082** — process probes anchor on these so the twins never confuse each
other's health.
- **L0 life-support shell** (`dshd-supervisor`, out-of-process): probes main
health, auto-restarts, rolls back to last-known-good, wakes the standby —
works even when dsh itself cannot boot.
- **L1 self-management** (`dsh-double.py` + this plugin): snapshot / check /
evolve / rollback / wake / stop; the in-harness agent drives it via tools.
## License
MIT — Copyright (c) 2026 Junkrat9527
Install
dsh plugin --profile web add github:Junkrat9527/dsh-double#634f30b20e8847a680f4d43e60c7a4a4b48727b7
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-double from the hub