Keep your AI context honest.
Your agent reads CLAUDE.md, AGENTS.md, and .cursorrules as ground
truth — and those files rot. Paths go dead, dependency claims go stale,
counts drift. Depthfinder scans the claims your context files make and
verifies them against the repo itself.
$ npx depthfinder
Scanning CLAUDE.md against 1,204 tracked files…
Health ████████████████░░░░ 67 · Caution
↳ Honesty ████████░░░░░░░░░░░░ 41 — share of checkable claims that still hold
↳ Weight ████████████████░░░░ 80 — tokens these files load into the agent every turn
↳ Coverage █████████████████░░░ 88 — how much of the context is checkable vs unknown
Hotspots 10 false · 3 stale · fix all → Health 67→89 · Honesty 41→100
1. [CRIT] ✗ CLAUDE.md:67 "auth flows live in `src/auth/oauth.ts`"
└ no such tracked file — deleted at a1b3f2e, 38 commits ago
→ fix: repoint or remove this path fix gain → Health +1 · Honesty +4
2. [HIGH] ✗ CLAUDE.md:41 "wake word handled by `openWakeWord`"
└ not in any package.json (checked 3 manifests)
→ fix: remove the line, or add `openWakeWord` fix gain → Health +1 · Honesty +4
3. [LOW] ✗ CLAUDE.md:23 "model routing uses 4 tiers (see `router/config.js`)"
└ router/config.js defines 3 tiers, not 4
→ fix: update the count to 3 fix gain → Health +1 · Honesty +4
Weight ~14,000 tokens load every turn
10 false claims · 3 stale · ~8,100 tokens describe code that no longer exists
The meters lead the card: the composite Health, then its three
dimensions indented under it (each colored by value on a real terminal —
Critical / Caution / OK / Great — and plain when piped or in CI). Each
Hotspot carries a criticality tag and the score it returns if you fix it
(Health first, then Honesty). Step through and apply the fixes interactively
with npx depthfinder --triage (below).
The Honesty meter is your Context Honesty score — the contract tier:
the files your agent auto-loads every turn (CLAUDE.md, AGENTS.md,
.cursorrules, and the docs they tell it to read first). Run with --docs
to also get a separate Doc Honesty line over the wider repo docs your agent
reads on demand — runbooks, design notes, package READMEs:
↳ Honesty ████████░░░░░░░░░░░░ 41 — share of checkable claims that still hold
Doc Honesty 91 · 188 checkable claims · 34 docs · 4 dead refs
...
They're separate because they're different trust tiers; a dead link in a runbook shouldn't drag down your contract score. Doc scanning is precision- hardened (it ignores code examples, past-tense narration like "we removed X", and generated-artifact paths). It's opt-in for now — the doc grammar isn't yet validated across enough repos to accuse by default, which for an honesty tool is a line we won't cross until it's earned.
Weight is what the Context files cost on every single agent call. False claims never matched the repo's history (fabricated or always wrong); stale claims were once true — git proves the file existed before it was deleted or moved. Both count against the score; the split tells you whether your docs rot or lie.
Zero config. Sub-5 seconds. No model calls by default — nothing leaves
your machine unless you explicitly opt in with --burn (below).
Deterministic checks only: if Depthfinder can't decide a claim safely, it
says unknown — it never guesses and never accuses.
The default card tells you a stale line would mislead your agent. --burn
shows you. It takes the top false claim, feeds the rotten line to a coding
agent you already have (claude, else codex), and prints what the agent
actually says — which confidently names the file that no longer exists:
$ npx depthfinder --burn
✗ CLAUDE.md:5 "Auth flows live in `src/auth/oauth.ts`."
└ no such tracked file — deleted at fccd7c9, 1 commit ago
▶ claude -p answered (your context, no repo to check):
To fix the auth bug, open src/auth/oauth.ts and check the
token validation in the oauth handler first.
└ stated as fact — from a line your repo already contradicts.
--burn is the only path that calls a model. It's opt-in (the flag is
your consent), it prints exactly what it's about to send before it runs, and
it sends only that one line — not your repo — to a coding agent you already
run (so it goes wherever your own claude/codex already sends prompts).
Known secret shapes (API keys, tokens) are redacted from the line first;
redaction is best-effort and pattern-based, so don't rely on it to scrub an
exotic secret. Override the agent with --burn-agent "<cmd>" or
DEPTHFINDER_BURN_AGENT.
Because --burn runs your agent in headless mode (claude -p / codex exec),
each burn counts against that agent's usage quota. On Claude subscription
plans (from 2026-06-15) that's the separate Agent SDK allotment, metered
apart from your interactive sessions. It's one call per run, but keep it in
mind before wiring --burn into CI or a loop.
--triage turns the card into a fix workflow. It draws the hotspots as a list
you arrow through (↑/↓), and when you pick one it hands a targeted fix to the
coding harness you already run — claude, else codex, else
$DEPTHFINDER_BURN_AGENT:
$ npx depthfinder --triage
3 hotspots · ↑/↓ move · enter to fix · q to quit
› 1. [CRIT] CLAUDE.md:67 src/auth/oauth.ts (Honesty +4)
2. [HIGH] CLAUDE.md:41 openWakeWord (Honesty +4)
3. [LOW] CLAUDE.md:23 4 tiers → 3 (Honesty +4)
Will run in claude, in this repo:
A line in this project's AI context file (CLAUDE.md:67) is no longer true: …
run in claude? [y/N]
It prints the exact prompt and asks before it spawns — the same consent
posture as --burn. The rotted line is redacted first, and the prompt tells the
agent to fix the doc and never invent a target. --triage is interactive
only: it needs a real terminal, so it errors (exit 2) in CI, a pipe, or
alongside --json — it can't wedge a script.
The colored meters and criticality tags auto-enable on a terminal — including
terminal apps / multiplexers (tmux, Cmux, iTerm, ghostty…) that advertise color
via COLORTERM / TERM_PROGRAM even when they don't hand the command a TTY. They
stay plain in CI and when redirected to a file, so --json, logs, and the golden
snapshot stay clean. No flag needed in a normal terminal; override either way with
--color / --no-color (or FORCE_COLOR / NO_COLOR) — off always wins.
npx depthfinder # scan the repo you're in
npx depthfinder ~/proj # scan another repo
npx depthfinder --json # machine-readable claims + score (stdout)
npx depthfinder --out dir # also write claims.json (atomic; the only write to the repo dir)
npx depthfinder --no-history # don't record this run / show a "since last run" delta
npx depthfinder --no-follow # don't follow "read first" links into repo docs
npx depthfinder --docs # opt in to the wider-docs scan (Doc Honesty)
npx depthfinder --burn # run your agent against the top false claim (opt-in; calls a model)
npx depthfinder --strict # CI gate: exit 20 when your context has rotted (false claims)
npx depthfinder --strict --max-false 5 # ...allow up to 5 before failing (ratchet)
npx depthfinder --warn-below 80 # warn if a Health dimension scores < 80 (advisory; gates under --strict)
npx depthfinder --weight-budget 8000 # token budget for the Weight dimension (heuristic; default 10000)
npx depthfinder --fix # repoint paths git proves were renamed (dry run — shows the diff)
npx depthfinder --fix --write # ...actually apply the rename-fixes (the only write to your repo)
npx depthfinder --triage # interactive: arrow through hotspots, hand a fix to claude/codex
npx depthfinder --no-color # force plain output (color auto-detects terminals, incl. tmux/Cmux/iTerm)
npx depthfinder --convention >> CLAUDE.md # add a snippet so agents self-check this file
npx depthfinder --install-skill # install the /depthfinder agent skill (Claude Code + Codex)
npx depthfinder --version # print the version and exit (-v); --help (-h) for usageBy default, when a context file links repo docs under a "read first" /
"project brain" heading, Depthfinder follows those links one hop and
scans the linked docs too — that pointed-to surface is context your agent
reads as well. Linked-doc claims count toward the score; they don't count
toward Weight (they don't load every turn). --no-follow turns this off.
Requires Node ≥ 20 and git (evidence comes from git history;
shallow clones degrade gracefully). The default run writes nothing to the
scanned repo. It does keep a small score history in your cache dir
(~/.cache/depthfinder/…, honoring XDG_CACHE_HOME) so the card can show a
delta on the Honesty meter — … 95 (▼17 since last run). That stays on your
machine; --no-history turns it off.
The cheapest way to get an agent to use Depthfinder is to tell it to, right in
the context file it already reads every turn. --convention prints a drop-in
snippet for your CLAUDE.md / AGENTS.md:
npx depthfinder --convention >> CLAUDE.md # stdout is the snippet; the how-to prints to stderrIt adds a short "before you trust the claims in this file, run npx depthfinder
and treat anything it flags as false or stale as unreliable" rule. Now any agent
reading the file knows to verify the docs against the code instead of trusting a
rotted line — no plugin and no MCP server, just the CLI it can already run. (An
agent with a shell can run npx depthfinder --json directly; this snippet is the
nudge that makes it think to.)
For a more discoverable, invokable /depthfinder skill (vs the in-file
convention line), install the agent skill. It's one SKILL.md that works across
harnesses — Claude Code, Codex, OpenClaw, and Hermes all use the same format:
# Claude Code + Codex — local file install (writes ~/.claude/skills, ~/.agents/skills):
npx depthfinder --install-skill
# Hermes / Vercel open-agent-skills — install the SAME skill from this repo:
hermes skills install phdev/Depthfinder/skills/depthfinder
npx skills add phdev/Depthfinder/skills --skill depthfinder--install-skill detects which harnesses you have and drops the skill into each.
The canonical skill lives at skills/depthfinder/SKILL.md
(byte-identical to what the flag writes — pinned by a test). MCP is deliberately
not shipped: for a shell-capable agent it adds nothing over npx depthfinder --json; the skill is the discoverability layer, the CLI does the work.
The default scan is advisory (always exit 0). --strict turns it into a gate:
it exits 20 when your Context Honesty has any false claim — so a PR that lets
CLAUDE.md drift out of sync with the repo fails the build.
# .github/workflows/context-honesty.yml
on: [pull_request]
jobs:
depthfinder:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # fetch-depth:0 if you want stale/rename evidence
- uses: phdev/Depthfinder@v1 # the reusable context-honesty gate
with:
max-false: 0 # ratchet down over time; warn-below / docs also supported(Or run it directly without the Action: - run: npx depthfinder@1.3.0 --strict.)
- Gates the Context tier only (your convention files + nested + the "read
first" links they follow, minus
--no-follow).--docs(Doc Honesty) is advisory and never fails the build. --max-false Nallows a budget ofNfalse claims (default 0). Adopt on an already-rotten repo at a highN, then ratchet it down each sprint.- Pin the npm version (
npx depthfinder@1.3.0, not barenpx depthfinder). The false count is extractor-dependent; a future release could change it and turn your build red with zero repo changes. Pinning makes--max-falsestable. - Fails closed. If a context file can't be read (UTF-16, permissions), the gate fails rather than passing on a file it never checked — "couldn't verify" is not "clean."
- Exit 20 is outside Node's reserved range (1, 3–12 are Node's own internal
failures), so a wrapper can tell "your context rotted" from "depthfinder
broke."
--jsoncarries agate: { strict, maxFalse, false, tier, unverifiedFiles, failed }object (failed= rot or couldn't-verify) for programmatic use.
The same exit code that gates CI also makes a clean termination signal for an agent loop. Because the scan is deterministic, "0 false claims" is a real done-signal — not a "looks finished" guess — so an agent fixing rot can loop until depthfinder passes:
until npx depthfinder --strict --no-history >/dev/null 2>&1; do
npx depthfinder --json --no-history # the false/stale claims + each fix to apply
# …fix the top claim (repoint the path, drop the dead dep, correct the count)…
done--strict exits 0 once nothing is false and 20 while anything still is,
so the loop stops exactly when the context is honest again. --no-history keeps
the inner passes out of your score-delta history. This is the pattern the
/depthfinder agent skill ships, so an installed agent already knows it
(--install-skill).
| Code | Meaning |
|---|---|
| 0 | ran (findings or not — the scan is advisory) |
| 1 | internal error |
| 2 | usage error · not a git repo · git missing · bad --out |
| 3 | no context files found |
| 20 | --strict gate breach: Context Honesty has > --max-false false claims, or a context file couldn't be verified (fail-closed) |
| Oracle | Claim shape | Verified against |
|---|---|---|
| path | `src/auth/oauth.ts` (delimited) |
git ls-files |
| dependency | "handled by `pkg`" |
every package.json (workspaces, all 4 dep fields) |
| symbol | "exports `startEngine`" |
ESM/TS export forms |
| count | "4 tiers (see `router/config.js`)" |
literal cardinality |
Scanned conventions: root CLAUDE.md / AGENTS.md / .cursorrules,
.cursor/rules/**/*.mdc, nested CLAUDE.md / AGENTS.md (tracked).
Secrets matching common token patterns are redacted from all output.
The repo also contains a local-only web visualizer (five tabs: Summary,
Context graph, Token Currents, Evals, Drift) used to analyze a single repo
in depth. npm start → http://127.0.0.1:4317 (loopback only; LAN=1 to
opt into LAN). See CLAUDE.md for its architecture and invariants.
npm test # 35 tests: precision gate, golden card, boundary…
npm run bench # per-phase timings + local 5s tripwire
npm run corpus # manual external-repo run (pre-tag ritual)
npm run snapshot:update # re-approve the golden card after render changesThe hard ship gate: zero false accusations on the labeled fixture corpus, on every push, on every OS lane. A missed lie is acceptable; a false accusation is fatal.
MIT © Peter Howell