DeepSeek Harness plugin

dsh-audit-log

Runtime data-flow audit log for DeepSeek Harness: who mutated what, in what order — per-plugin, per-fiber attribution.

Jump to install

Source facts

Repository
ssdyg4444-sys/dsh-audit-log
Latest update
Aug 19, 2026
Category
Development & Runtime
GitHub stars
0
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/ssdyg4444-sys/dsh-audit-log
Plugin: dsh-audit-log
Author: ssdyg4444-sys

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.mdSource · read only
README language

dsh-audit-log

> Who mutated my data flow? — Runtime data-flow audit log for DeepSeek Harness plugins, with per-plugin, per-fiber attribution.

English | 简体中文

dsh-audit-log answers the question every plugin ecosystem eventually asks: when a field in your session data disappears or gets rewritten, which plugin did it, in what order, and what exactly changed?

It is a read-only observer: it never blocks, never rewrites, and never stores payload values — only structural fingerprints (types, keys, lengths). Secrets never enter the log.

Why

Cordis (the framework under DeepSeek Harness) shares the same args array across every listener of a waterfall dispatch, and the internal/get / internal/set interception points are public. Any plugin can silently rewrite data flowing through the system. With hundreds of plugins, "which plugin washed out my field" is otherwise nearly impossible to answer.

dsh-audit-log makes it answerable:

  • Dispatch-level diff — every audited dispatch snapshots argument shapes before and after, and records

the mutations in between.

  • Per-listener window attribution — each listener is wrapped at registration; mutations are attributed

to the exact plugin + fiber that performed them (confidence: "window"), not a heuristic.

Install

# into your web profile
cd ~/.dsh/profiles/web
pnpm add dsh-audit-log

Then add dsh-audit-log to dsh.profile.bundles in package.json (or use dsh plugin --profile web add dsh-audit-log), and restart your dsh instance.

The plugin registers ctx.auditLog and starts recording immediately. No configuration required for basic use.

Usage

Query the audit trail from any plugin:

const records = await ctx.auditLog.query({
  events: ['message/send'],
  mutationsOnly: true,   // only dispatches that changed something
  fromSeq: 100,
  limit: 50,
})

// Each mutation carries exact attribution (when attribute_by_window is on):
//   { listenerIndex, package, fiber, confidence: 'window' }
const culprit = records[0].mutations[0].attribution?.package

// Raw per-listener windows:
const windows = ctx.auditLog.queryWindows({ event: 'message/send' })

Record shape

{
  "v": 1, "ts": "2026-08-19T08:00:00.000Z", "seq": 42,
  "mode": "waterfall", "event": "message/send",
  "listeners": [{ "order": 0, "package": "my-plugin", "fiber": 3 }],
  "before": [ { "type": "object", "keys": ["content"] } ],
  "after":  [ { "type": "object", "keys": ["content"] } ],
  "mutations": [{
    "argIndex": 0, "path": "arg[0].content",
    "kind": "replace", "beforeLength": 56, "afterLength": 36,
    "attribution": { "listenerIndex": 1, "package": "spam-filter", "fiber": 7, "confidence": "window" }
  }]
}

Configuration

Via the profile patch layer (cordis.patch.yml), or $DSH_HOME/settings.yaml namespace audit-log:

FieldDefaultMeaning
enabledtrueGlobal switch
capacity10000Ring-buffer size (oldest dropped first)
mutations_onlyfalseOnly keep dispatches that mutated something
attribute_by_windowtruePer-listener attribution (wrap listeners)
package_allowlist[]Regex sources; empty audits all packages
package_blocklist[]Regex sources; excludes after allowlist
events[]Exact event names to audit; empty audits all
event_allowlist[]Regex sources for event names
- id: audit-log
  config:
    events: ["message/send", "before/*"]
    package_blocklist: ["my-noisy-plugin"]

How it works

dispatch → internal/dispatch (prepend) → fingerprint(args) → listeners run → fingerprint(args) → diff → store

1. Dispatch-level diff (P0/P1) — Cordis emits internal/dispatch synchronously before public listeners run. The service mounts that one hook (prepend: true, global: true), snapshots argument shapes, lets the dispatch proceed, then diffs and stores. Shape-only fingerprints (maxDepth 3, maxKeys 20) keep the overhead negligible and payload values out of the log. 2. Per-listener window attribution (P2) — intercepts internal/listener (bail) at registration time and wraps every non-internal listener. Each wrapped call snapshots the shared args before and after that listener, so mutations are attributed to the exact plugin + fiber (confidence: "window"). Framework-internal events are never wrapped — no recursion, no self-noise.

Limitations

  • Shape-only fingerprints: equal-length string swaps ('by-c''by-d') and in-place number edits are

invisible to the diff. This is a deliberate privacy/cost trade-off; a value-aware deep mode is future work.

  • Sync-path timing: the microtask resume is exact for synchronous emit; for async listeners in

serial/parallel/waterfall, the per-listener window wrapper (P2) covers the gap precisely, while the dispatch-level diff remains a coarse overview.

Relationship to other plugins

Observability tools in the ecosystem come in layers: some show what plugins put into the model prompt (context layer), while dsh-audit-log shows what plugins changed in the event data flow (runtime data layer). They are complementary — install both.

Development

npx @dsh-io/dsh-dev check    # validate manifest, YAML, build
npx @dsh-io/dsh-dev dev      # run under dsh web with file watching

Tests (no framework needed):

node --test tests/

License

MIT