Skip to main content

Privacy

Collection makes no network calls

The hooks, the daemon and dun ingest read git and local transcripts and write a local SQLite journal. Nothing contacts the network.

The one exception is opt-out and unrelated to collection: dun checks once a day whether a newer release exists, on bare dun only, never from a hook. Disable it with dun config set version_check off, or DUN_NO_VERSION_CHECK / DO_NOT_TRACK in the environment.

What is never recorded

The journal schema has no field that could hold prompt text, message content, file contents, hostnames or remote URLs. This is a structural guarantee rather than a filtering step — there is nowhere to put them.

Explicitly out of scope, and named because they were considered and rejected: Claude Code's toolUseResult as a whole (it carries stdout, stderr, and the before/after text of every edit), Codex's agent_message.message, agent_reasoning.text, user_instructions and unified_diff, and Antigravity's CodeContent and ReplacementContent.

Two more are countable but never stored, because they carry user intent verbatim: MCP tool-call arguments, and web-search queries.

What is recorded, and identifies someone

Stated plainly, because a privacy page that omits this is worse than none — a reader who finds it later has reason to distrust everything else on the page.

File paths. The journal stores which files an agent edited. That reveals what someone worked on, not merely how much.

A contributor email. whodunit_repos stores the git committer email for the repository — the same address already in every commit you author. A shared database needs it to attribute anything to anyone.

Both stay local until you run dun sync.

Where it lives

PathWhat
~/.whodunit/config.jsonSettings: retention, backups, sync target, version check
~/.whodunit/repos.jsonWhich repositories you instrumented
~/.whodunit/data/journal.dbOne row per agent edit, scoped by repository
~/.whodunit/baselines/<repo>.jsonPre-adoption snapshots

Everything is owner-only — 0700 directories, 0600 files — and repaired on open if it was ever created more permissively. On Windows, where os.Chmod cannot express that, the files carry an access control list naming only the owner.

Nothing is ever written into your repositories, committed or pushed.

dun journal show # exactly what has been recorded, in full
dun journal purge # delete it, for this repository only

What dun sync sends

dun sync is the one command that transmits anything. It is never run for you and does nothing until you configure a target.

Six tables, listed in full so there is no need to take this on trust:

TableContents
whodunit_reposRepository id, contributor email, spec version
whodunit_commitsSHA, timestamp, status, method, agent, purpose, ratio, line and file counts
whodunit_eventsPer edit: timestamp, agent, session, tool, file path, lines, hunk hash, outcome, model, branch, MCP server, human-edited
whodunit_sessionsPer session: message and tool counts, tokens, timing, effort, permission mode
whodunit_event_linesLine hashes and first-seen timestamps
whodunit_baselinesPre-adoption commit counts, median diff size, revert rate, cadence

The repository id is its root commit SHA — stable across clones and machines, and identifying the repository without revealing its name or remote. A filesystem path would break when the repository moved; a remote URL would record the org and repository name, which this tool never stores.

Not sent: prompt text, message content, file contents, and the lines themselves.

dun sync --dry-run # print the exact payload before any target is contacted