Skip to content
dsh.fish
Bundle

dsh-death-forensics

In-process death black box for DeepSeek Harness (dsh) hosts: heartbeat windows, crash stacks, end-kind self-check, death_forensics_report tool.

Source
shenhuanageshei
License
MIT
Updated
Updated 6 days ago

Readme

# dsh-death-forensics

In-process death black box for a DeepSeek Harness (dsh) host. A Cordis plugin
(bundle format) that records **what happened before the host died** — heartbeat
windows, crash stacks, and an end-kind self-check at the next boot.

## Why

dsh web processes can die without a trace (external kills, frozen event loops,
crashes). An external launcher can record *how* the process died (exit code /
stderr / uptime), but only something **inside** the process can record *what
happened before*: when the last heartbeat was, what the crash stack was, and
whether the previous boot ended gracefully.

This plugin is the in-process half. Pair it with an external launcher (see
DESIGN.md) for a complete picture.

## Features

| Feature | Mechanism |
|---|---|
| Heartbeat | append JSONL to `<DSH_HOME>/death-forensics/heartbeat.log` every `heartbeatIntervalMs` (default 15s, bounded file) |
| End-kind self-check | SIGTERM/SIGINT record `graceful`; `exit` event records neutral `exit`; crash/kill leaves `running` → next boot detects a **non-graceful end** and appends a record to `crash.log` |
| Crash stacks | `uncaughtException` (incl. unhandled rejections via Node's default throw chain) records the full stack, then reprints it and exits(1) — host behavior is byte-identical to the no-plugin case |
| Report tool | `death_forensics_report` — current boot, previous end kind, death window (last heartbeat → next boot), crash log tail, external launcher log tail (if present) |

## Data files (`<DSH_HOME>/death-forensics/`)

- `state.json` — current boot identity + last end kind (single source of truth)
- `heartbeat.log` — append-only JSONL, truncated at `maxHeartbeatLines`
- `crash.log` — append-only JSONL records (crashes + detected non-graceful ends)

## Safety contract

- **Zero child processes** — never spawns anything; only file writes.
- Hot paths are synchronous writes with try/catch degrade — failures disable
  the black box, never the host.
- Hooks are additive listeners only, cleaned up on plugin dispose.
- No monkey-patching of host services.

## Install

Add to a dsh profile (e.g. `profile/profiles/web/package.json`):

```json
"dependencies": {
  "dsh-death-forensics": "link:/path/to/dsh-death-forensics"
},
"dsh": {
  "profile": {
    "bundles": [ ..., "dsh-death-forensics" ]
  }
}
```

Then restart dsh. The bundle patch inserts entry id `death-forensics`.

Alternatively, via CLI: `dsh plugin --profile web add /path/to/dsh-death-forensics`.

## Build

Requires a dsh checkout or profile install carrying `@deepseek-ai/*` packages
(resolved via `$DSH_CHECKOUT`, or `$HOME/dsh-harness`, `$HOME/dsh`,
`$HOME/.dsh/dsh-harness`), plus `typescript`:

```sh
# install devDependency offline (from any pnpm store)
node <pnpm.mjs> install --store-dir=<pnpm-store-dir> --prefer-offline \
  --config.node-linker=hoisted --config.auto-install-peers=false
# compile src/ → lib/
bash scripts/build.sh        # Git Bash on Windows; node must be on PATH
node lib/selftest.js         # 17 pure-logic assertions
```

The published `lib/` is committed so the plugin works from a plain clone.

## Configuration

| Key | Default | Description |
|---|---|---|
| `heartbeatIntervalMs` | 15000 | heartbeat interval (min 5000) |
| `maxHeartbeatLines` | 20000 | heartbeat file line cap |
| `reportTailLines` | 40 | tails shown by the report tool |
| `dataDir` | `<DSH_HOME>/death-forensics` | data directory override |

## Docs

- `DESIGN.md` — full design (Chinese): state machine, hook semantics, acceptance criteria.
- Death-window interpretation: `[last heartbeat of previous boot, this boot's start]`.

## License

MIT — see [LICENSE](LICENSE).

Install

dsh plugin --profile web add github:shenhuanageshei/dsh-death-forensics

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source