dsh-anchor

August 26, 2026 · View on GitHub

Long-running sessions without limits. Every high-entropy tool action gets a pre-committed intent and immediate reconciliation; the anchor tree on disk is the session's source of truth. Crash the process, rescan the tree, adopt, continue — nothing is lost.

中文版见 README.zh-CN.md

license ci topic: dsh-plugin topic: dsh

Why this exists

The mainstream answers to "long-running tasks" rely on two things: context compression (loses precision) and memory retrieval (loses consistency). Real incident history says otherwise: the main cause of failure is never "forgetting" — it is actions landing on wrong assumptions about the environment (uncontrolled side effects: corrupted code, killed wrong processes, leaked state).

dsh-anchor takes a different path: don't remember the past, lock down the future.

Before every action: intent (what I will do) + pre (environment fingerprint)  = pre-commit
After every action:  post (actual result) reconciled immediately → OK / DIVERGED
  • Incidents surface in the moment, not in after-the-fact investigations
  • The anchor tree = the session's progress truth: the session dies, the tree remains; a new session scans the tree, adopts, and continues (aligned with the official subagent cold-resume semantics, plus environment reconciliation it does not have)
  • Maps to official public pain points: force-kill drops the write-behind tail (#483) → we flush to disk immediately with zero buffering; one bad log kills a session (#1593) → our source of truth is the directory structure; a broken anchor only costs that one step

Who is this for

  • Operators of long sessions (tens to hundreds of steps) who have been bitten by "actions landing on wrong assumptions": code corrupted by edits, wrong processes killed, state leaked;
  • People who want the progress truth back after a mid-session crash — the anchor tree lives outside the session log; cold start scans and adopts (clean / dirty / contaminated / fresh);
  • People who need an audit trail — every high-entropy action's intent/pre/post lands on disk immediately; "expected vs actual at the time" is inspectable and reproducible.

Not for: short conversations of three to five steps — the sampling discipline (minimum gap 7) anchor cost would be wasted.

How it works

Mounted on official extension points, zero intrusion:

Official seamOur mount
tools/pre-execute (pre-action waterfall)anchorOpen: write intent + pre fingerprint
tools/post-execute (post-action, before result materialization)anchorClose: environment reconciliation + verdict

Reconcile against the environment, not self-reports: for write/edit-class actions, reconciliation reads the disk to verify the real content (expected = the target content declared by parameters, measured = the actual bytes on disk) — the tool claiming success doesn't count; the anchor checks the environment.

Sampling discipline (measured-verdict hardened):

  • High-entropy actions (file writes/processes/subtasks) are anchor-mandatory — the actions with the biggest side-effect entropy are locked down
  • Minimum gap 7 — the no-gap form's overhead spikes (per-capture cost 98.6 → 25.1, measured)
  • Low-entropy actions (reads/pure queries) run free — their failures are either harmless or propagate into a high-entropy action and surface there
  • DIVERGED feedback: the moment of failure switches to panic mode (all-anchor); 3 consecutive OK steps restore normal — automatic switching between order track and chaos track

Anchor tree anatomy:

session-anchors/
├── 00027-write#27/           # one action = one anchor directory
│   ├── intent.json           # pre-commit: action name + expected fingerprint
│   ├── pre.json              # pre-action environment fingerprint (+ recorded process pids)
│   ├── post.json             # post-action measurement
│   └── verdict               # OK / DIVERGED (verdict at the moment)
└── ...

Quick start

# Install (git source, pinned tag)
dsh plugin --profile <name> add "github:Wang-Lin-Chang/dsh-anchor#v0.2.2"

Then mount it in the profile's cordis.patch.yml:

# cordis.patch.yml
- insert:
    - name: 'dsh-anchor'
      config:
        anchorRoot: 'C:\path\to\session-anchors'   # anchor tree root (source of truth)
        minGap: 7                                  # sampling gap discipline (default 7)

After restart the plugin is on duty: every high-entropy tool action gets an anchor and immediate reconciliation. Cold start automatically scans the anchor tree for adoption adjudication.

import { apply } from 'dsh-anchor'
const service = apply(ctx, { anchorRoot: './data/session-anchors' })
service.report()      // tree scan report (last complete anchor / dirty site / fingerprint chain)
service.adoptState    // cold-start adoption verdict (clean/dirty/contaminated/fresh)

Acceptance evidence

All tests live in npm test (37 assertions green). Measured environment: Windows 11 Pro · Node 25.8.

SuiteVerifiesAssertions
samplingSampling discipline (high-entropy lock / gap 7 / panic feedback / recovery)10
plugin-anchorOfficial seam mounting + environment reconciliation + no interception + cold start12
plugin-adoptReal process kill -9 → cross-process adoption → continued run with consistent terminal state7
plugin-blindDouble-blind external pollution (independent process corrupts the environment, plugin unaware)8

Real-machine duty record (anchor tree excerpt from a real DSH instance):

00027-write#27   DIVERGED   ← write to a read-only file blocked by EACCES; reconciliation read the disk and caught it on the spot
00028-pwsh#28    OK         ← only 1 step since the last anchor, yet anchored = panic triggered (discipline overridden)
00029/30/31-read OK         ← panic-mode low-entropy all-anchor ×3, each OK advances recovery
(reads after this: zero anchors)  ← 3 OK steps recovered → low-entropy runs free again, zero false alarms

vs. dsh-witness

dsh-witnessdsh-anchor
GranularityTask (one task one directory, five-state adoption)Action (one action one anchor, verdict reconciliation)
GovernsBackground task lifecycleSession/agent long-running action supervision
Shared coreAnchorCore four primitives (open/close/recover/adopt)The same core

A task is just a "big action", an action is just a "small task" — both packages share one philosophy: the filesystem is the source of truth.

Honest boundaries

  • Windows-first. Measured on Windows 11 + Node 25.8. The anchor tree protocol itself is cross-platform, but only the Windows real machine has verified it so far; untested platforms are not claimed.
  • Reconciliation coverage v0: environment reconciliation currently covers write/edit/create_file (reads the disk to verify); other tools use fallback reconciliation (checks for abnormal self-reports only). Extending the reconciler by tool type is the planned path.
  • Adoption v0 weak checks: cold-start adoption scans the tree for structural verdicts (clean/dirty/contaminated); the full form of environment-level diff verification exists in dsh-witness's task adoption, and full session-level environment verification is on the roadmap.
  • The anchor is an observer, not a gate: failed reconciliation only marks DIVERGED and triggers denser sampling; it does not intercept tool execution (interception belongs to the official guard mechanism).

Development

npm test   # 37 assertions: sampling 10 + plugin-anchor 12 + plugin-adopt 7 + plugin-blind 8

Requires: Node ≥ 22.5 (no dependency beyond node:sqlite, measured on 25.8), Windows PowerShell 5.1 (real-machine verification environment).

License

Apache-2.0