dshbase

Plugin directory / Developer / dsh-session-integrity

dsh-session-integrity

Verified · install-tested on dsh DON738110198

✓ Actively maintained

View on GitHub ↗ ← Back to plugin directory

0Stars
0Forks
0Open issues
—Language
2026-08-20Last push
Cross-platformPlatform

What it does

Diagnose poisoned DeepSeek Harness sessions and continue from provider-safe recovery boundaries

✅
Our take
Works — verified, early-stage project

Diagnose poisoned DeepSeek Harness sessions and continue from provider-safe recovery boundaries It installs cleanly and boots without issues in our testing. It's early-stage but functional.

“Verified” means our automated CI actually ran dsh plugin add in a clean profile and it booted — nothing more. Feature descriptions and version compatibility are the author’s claims. This is not a security audit and not an endorsement of third-party code.

README

dsh-session-integrity

English | 简体中文

Session integrity diagnosis and non-destructive recovery for
DeepSeek Harness.

A single internal scheduler exception can turn an ordinary tool failure into a
durable transcript defect that makes every later model request fail before the
model can answer.

The problem

The provider invariant

When an assistant message requests tools, every provider-visible tool call id
must be followed by its matching tool result. A normal tool failure is safe for
the conversation because Harness serializes the failure as that result and the
model can decide what to do next.

The broken case is different: Harness persists the assistant request and the
execution start, but no result reaches the model-visible Session surface.

assistant/message  tool-call c1
tool/call          c1
scheduler.prepare  throws
step/end
turn/end           error

# Missing: tool/result c1

The next request replays the assistant tool call without a result. DeepSeek
rejects the request before inference with a protocol error such as:

An assistant message with 'tool_calls' must be followed by tool messages
responding to each 'tool_call_id'.

This is why sending another user message does not recover the Session. The
invalid history is durable and is sent again on every turn.

sequenceDiagram
    participant M as Model
    participant H as Harness
    participant S as Tool scheduler
    participant P as Provider
    M-->>H: assistant tool-call c1
    H->>H: persist assistant/message and tool/call
    H->>S: prepare(c1)
    S--xH: throws
    H->>H: persist turn/end(error), no tool/result
    H->>P: later request replays unmatched c1
    P--xH: HTTP 400 before inference

Why one error becomes permanent

There are three separate layers:

  1. Trigger: prepare() or another internal scheduler boundary throws. A
    duplicated runtime package and mismatched symbol can cause this, but it is
    only one possible trigger.
  2. Persistence defect: tool/call has already been recorded, while the only
    path that appends tool/result is never reached.
  3. Replay amplification: the turn still receives turn/end, so open-tail
    crash recovery does not repair it. Every later provider request contains the
    same unmatched tool call and fails again.

The structural bug therefore exists independently of the original trigger.
Any exception in the vulnerable interval can poison a previously healthy
Session.

Why blindly adding a generic error is unsafe

If failure happens before dispatch, the tool definitely did not run and a retry
is safe when still needed. If dispatch started but its result was not durably
committed, external side effects may already exist. That outcome must be marked
unknown and verified before retrying a write, payment, deployment, or other
non-idempotent operation.

What this project does

  • The Cordis plugin scans live Sessions at load and after turn/end.
  • The offline CLI checks exported JSON or uncompressed JSONL without starting a
    model request.
  • Provider-visible defects are separated from raw execution gaps already
    shadowed by compaction.
  • Reports use hashed references and omit prompts, tool arguments, and tool
    results.
  • The recovery planner finds the latest completed prefix that is still safe to
    send to a provider.
  • The Web plugin adds Continue from here to historical assistant turns. It
    creates and opens a fork while retaining the original Session.
  • The analyzer and planner are read-only. Recovery uses Harness's public fork
    operation rather than rewriting durable history.

The issue was reproduced on a clean dsh-v0.1.0-rc.8 / master baseline: the
unpatched regression recorded one tool/call and zero tool/result events.
The tested prevention patch in the linked fork closes undispatched calls with
TOOL_SCHEDULER_FAILED_BEFORE_DISPATCH and dispatched calls with
TOOL_SCHEDULER_OUTCOME_UNKNOWN, without rerunning dispatch or finalizers.
It is a proposal for upstream review, not a change already merged by DeepSeek.

DeepSeek Harness currently routes external contributions through Discussions,
plugins, guides, and community support rather than external Pull Requests; see
the official contribution policy.
The fork keeps the complete patch reviewable until maintainers invite or reopen
the PR path.

Safety contract

  • Never mutates, repairs, deletes, or replaces events in the source Session.
  • Recovery creates a child Session through Harness's fork API. It never retries
    tools and never claims that external side effects were rolled back.
  • Never logs prompt text, tool arguments, tool output, raw Session ids, or raw
    tool call ids.
  • Separates provider-visible transcript defects from shadowed execution-log
    warnings.
  • Does not implement hard deletion. The current public persistence service has
    no backend-independent Session deletion operation.

Install from GitHub

dsh plugin --profile web add github:DON738110198/dsh-session-integrity#v0.2.1
dsh --profile web --dump-config
dsh --profile web

The package ships built JavaScript, so a Git install does not need a build
allowance. The Host plugin scans already-live Sessions when it loads and checks
a Session again at turn/end. Each distinct defect is logged once.

In the Web UI, finalized assistant messages that have later conversation
history receive a branch icon. Pressing it creates a child through the official
Session fork API and opens that child. It refuses while the source turn is
running, retains the original Session, and does not archive it automatically.

Offline check

Use an uncompressed session.jsonl artifact or an exported JSON document with
an events array:

dsh plugin --profile web exec dsh-session-integrity ./session.jsonl
dsh plugin --profile web exec dsh-session-integrity ./session.jsonl --json > integrity-report.json
dsh plugin --profile web exec dsh-session-integrity recover ./session.jsonl --json > recovery-plan.json
dsh plugin --profile web exec dsh-session-integrity recover ./session.jsonl --at 42

From a repository checkout, use node ./cli.js ./session.jsonl instead. The
package is not published to npm yet, so a bare npx dsh-session-integrity
command is intentionally not documented as an available install path.

recover interprets --at as a Session event anchor. It first considers the
completed turn at or after that anchor, then walks backward until the prefix has
no provider-blocking defect. The output is a plan only: it does not modify the
artifact or a live Session.

For scan, exit codes are 0 for no provider-blocking defect, 1 for an input
error, and 2 for a critical defect. For recover, 0 means a safe fork
boundary was found and 2 means a fresh Session is required. Zstandard logs
are intentionally not decoded independently; use a Harness export or an
uncompressed backend.

Why recovery is a fork, not rollback

Harness Sessions are append-only event logs. Removing a visible message can
also remove tool calls, request headers, compaction provenance, or evidence of
an external side effect. Continue from here therefore creates a new lineage
from a completed turn instead of pretending the old events never happened.

Permanent deletion is a separate core capability: it must coordinate the live
agent, JSONL and SQLite backends, workspace accounting, projections, cached
indexes, and attachment retention. A frontend-only delete button or direct file
removal would not provide that contract, so this plugin deliberately does not
offer one.

What it checks

  • assistant tool requests missing matching provider-visible tool results
  • unexpected or mismatched tool results
  • duplicate assistant call ids and duplicate execution events
  • unsettled tool/call records hidden from the current surface
  • malformed or invalid surface operations
  • non-monotonic event sequences

Development

npm test
npm run check
npm run pack:check

The fixture suite covers healthy and poisoned recovery boundaries, a
prepare()-style failure, synthetic cancellation, an open crash tail, a
compaction-shadowed orphan, packed JSONL rows, browser fork orchestration,
plugin warning deduplication, and CLI exit behavior.

Status

0.2.x targets DeepSeek Harness dsh-v0.1.0-rc.8. Harness is a developer
preview, so compatibility is tested per release rather than assumed.

License

MIT

Install

🧩 Let your agent install it (recommended)

Install the catalog once, then DeepSeek Harness can find and install any plugin from this site automatically:

dsh plugin add dshbase-catalog

Then say "install dsh-session-integrity for me" — your agent finds it in the directory and installs it. Docs: dshbase-catalog · verified packs.

This plugin is GitHub source (not published to npm) — install it straight from the repo:

Web profile:

dsh plugin --profile web add github:DON738110198/dsh-session-integrity

Headless (CLI) profile:

dsh plugin --profile headless add github:DON738110198/dsh-session-integrity

Test report

Verified: L1 install + L2 load + L3 runtime from GitHub source on dsh 0.1.0-rc.6.

Security: not yet scanned — our daily static scan will cover it shortly.

Share this badge

More in Developer

Browse all 7819 plugins →