- Home
- Plugin
- Git e code review
- dsh-provenance
dsh-provenance
ruaibeite/dsh-provenance
Line-level provenance and a decision ledger for agent edits: which session, model and tool wrote each change, with Markdown/JSON export.
Installazione
dsh plugin --profile web add github:ruaibeite/dsh-provenanceREADME
dsh-provenance
Line-level provenance and a decision ledger for agent edits. Answer "who wrote this line — which session, which model, which tool?" for every file the agent changed on this machine, then pin the important changes as decisions and export an audit trail as Markdown or JSON.
Screenshots

Screenshots are taken from a demo profile seeded with synthetic sessions; no user data is shown.
Install
-
DSH marketplace: install
@ruaibeite/dsh-provenancefrom the community plugin catalog (requires thedsh-plugintopic). -
From source: clone this repository, then add the plugin to your profile's layer stack:
git clone https://github.com/ruaibeite/dsh-provenance.gitAdd
@ruaibeite/dsh-provenanceto your web profile'sdsh.profile.bundles(or symlink the directory into the profile'snode_modules/@ruaibeite/), then restart DSH. The page appears in Settings → Provenance (idprovenance, order 5).
What it does
A single Settings page with a master-detail browser:
- Workspaces — every workspace the agent has touched on this machine, newest first.
- Files — per workspace, the changed files with record counts and the models that wrote them.
- Record timeline — one card per
write/editcall:#seq · time · model · tool, a copyable snippet, the line delta, before/after content hashes, and a Pin as decision button. - Decision ledger — your own pinned entries with an optional note ("why was this change made?"); remove them at any time.
- Export — Markdown (human-readable audit) or JSON (machine-readable), downloaded straight from the page.
The three panes adapt to the narrow Settings dialog: the workspace and file lists share the first row, the record timeline spans the full width, and long snippets wrap inside their card instead of being clipped.
It also normalizes relative paths against the session's working directory and keeps records that point outside it (with no relative path).
How it works
- The host half reads the local session history, read-only. Preferred source:
ctx.sessionQuery.listSessions()+readSession(id). When the session service is unavailable it falls back to scanning$DSH_HOME/sessions/**/session.v4.jsonl.zstddirectly, decoding every Zstandard frame (the JSONL backend appends one frame per flush batch, so single-frame decoders would miss most events). - Only
tool/callevents whose tool iswriteoreditbecome records. The model route is taken from the most recentassistant/messagesource, the turn/step from the tool call, and calls whosetool/resultreportsok:falseare dropped. - Records are aggregated per workspace and file and cached at
$DSH_HOME/cache/provenance/index.json. The index is rebuilt when older than 5 minutes (background, single-flight) or when you press Refresh. Per-file history keeps the newest 200 records; the whole index is capped at 20k records. Decisions live in$DSH_HOME/cache/provenance/decisions.jsonand never trigger a rebuild. - The browser half only calls this plugin's own same-origin route (
GET|POST /dsh-provenance/api); it imports nothing from@deepseek-ai/*and uses theme tokens only.
Privacy
- Local-only: no network request, no upload, no telemetry.
- Read-only: the plugin never writes session logs, never appends events and never modifies your repository.
- Its own cache only: the only writes are
$DSH_HOME/cache/provenance/index.jsonanddecisions.json(atomic temp file + rename). - It does not read credentials or print prompts to logs.
Known limitations (v0.1.0)
- Only the built-in
write/edittool calls are tracked. Changes made through shell redirection, formatters, external editors,gitor other tools are not visible. - A record describes the call intent, not the final file line number — code keeps changing, so use the content hashes (sha256, first 16 hex chars) to locate changes.
- Failed calls are filtered only when the matching
tool/resultcarriesok:false; an interrupted session may still list attempted edits. - Paths are normalized with
path.resolve; symbolic links are not resolved. - Subagent sessions (
delegationDepth > 0) are skipped to keep the ledger readable. - The decision ledger is a lightweight ADR: notes are user-authored, no ADR is generated automatically.
- Only sessions visible to
sessionQuery(or present as local logs) are indexed; at most the newest 200 sessions / 50k events per session are scanned.
Verify
cd dsh-provenance
node --check index.js && node --check client.js
npm test # host.mjs (31 tests) + render.mjs (14 tests), no browser / no network / no real ~/.dsh
The tests use inline fixtures and temporary DSH_HOME directories only.
License
MIT.
Plugin correlati
dsh-web (dsh-git-graph)
zhu1090093659/dsh-web
plannotator
backnotprop/plannotator
dsh-web-ui (dsh-git-graph)
zhu1090093659/dsh-web-ui
codex-guard (dsh)
akimiya-z/codex-guard