A local behavior gauge for Claude Code sessions.
Claude Code can look busy while it drifts. It can retry the same failed check, edit files without validation, reread a file it already saw, or push the context window too high.
Many statuslines show facts like model, branch, cost, or time. ccverdict adds a behavior verdict:
progressing · drifting · needs intervention · no signal
It watches derived local metadata and answers one question:
What is the agent doing right now, and does its behavior look healthy?
Try it before installing hooks:
npx --yes ccverdict audit --project .Install it when you want the verdict live in your Claude Code statusline.
The live gauge prints one short line:
<dot> · <verb> · <evidence> · <files> · <ctx> · <cost>
● editing · 1 file, 1 unchecked (auth.ts…) · ctx 42% · $0.18
◐ editing · 3 files, 2 unchecked (auth.ts…) · ctx 42%
■ retrying tests · 3 fails, no fix between runs
■ exploring · reread config.ts 3x
○ no signal · transcript unreadable
● idle · no activity yet
ccverdict prints no instructions on the line. It shows the dot, the current activity, and the evidence behind the dot.
The file segment shows counts plus one basename hint: the latest unchecked file. It does not list every file.
The demo cycles through example statusline states: healthy editing, unchecked-edit drift, repeated validation failure, repeated file reads, high context, and unreadable evidence.
The dot has both a color and a shape, so it still works with NO_COLOR.
| Dot | Light | Meaning |
|---|---|---|
● green |
progressing | the behavior looks healthy |
◐ blue |
drifting | check the session when you have a moment |
■ red |
intervene | retry loop, repeated failure, or critical context pressure |
○ gray |
no signal | ccverdict cannot read the evidence |
Activity verbs use this priority when several apply:
retrying > testing > editing > exploring > idle
Context and cost are facts. They do not change the dot by themselves. The exception is context at 92% or higher, which turns red because the session is close to full.
At 80% through 91%, ccverdict highlights only the ctx segment. With color disabled, it uses a marker:
● exploring · ctx 85%!
- The same validation check failing again without a fix.
- Test, lint, typecheck, or build failures that repeat.
- Edits that pile up without a passing check.
- Read-heavy sessions with no recovery signal.
- The same unchanged file being read again.
- A large tool result that adds many input tokens.
- Prompt-cache reuse dropping after it was working.
- Context pressure before the session gets too full.
- Cost or time climbing while validation still fails.
- Compaction boundaries that need a fresh goal check.
Permission prompts are separate. If you deny a tool permission prompt, ccverdict does not count that as a command failure or retry loop.
Requirements:
- Node.js 20 or newer
- Claude Code with status line support
npx --yes ccverdict install --scope localRestart Claude Code in the project. The statusline appears at the bottom.
Default install uses coach mode and builds a small local baseline when it can. It preserves an existing Claude Code statusLine unless you pass --replace.
npx --yes ccverdict install --scope local --replaceUse observe-only when you only want the gauge and local history:
npx --yes ccverdict install --scope local --observe-onlyUse guard when you want coach feedback plus strict denial of high-confidence repeated validation retries:
npx --yes ccverdict install --scope local --guardSkip baseline creation and lesson memory:
npx --yes ccverdict install --scope local --no-learnUninstall:
npx --yes ccverdict uninstall --scope localSupported scopes are local, project, and user. Use local for one repo unless you need to edit project-level or user-level Claude settings.
Prefer a global install?
npm install -g ccverdict
ccverdict install --scope localobserve-only keeps the statusline and local derived event data. It sends no feedback to Claude.
coach is the default. It can send short Claude-facing notes when ccverdict sees a risky pattern, such as unchecked edits, repeated validation failure, or unresolved validation risk at finish.
guard includes coach feedback. It can deny a high-confidence repeated Bash validation retry, such as rerunning the same test, lint, typecheck, or build category after repeated failures without an edit or passing check. It does not block normal reads, edits, or arbitrary commands.
ccverdict also records safe feedback outcomes. If coach feedback asks for validation and Claude later runs a passing test, audit can show that the loop resolved:
Recent ccverdict loop:
1. Coach feedback: edits needed validation.
2. Claude ran tests.
3. Tests passed.
4. Outcome: resolved.
Run an audit against recent local Claude Code history:
npx --yes ccverdict audit --project .
npx --yes ccverdict audit --all-projects --recent 200audit does not install a statusline or hooks. Use --all-projects only when you want to inspect the newest transcripts across local Claude projects.
audit is the offline view of the gauge. It prints three sections.
[1] Current session
Shows the latest ccverdict decision for the current project only: dot, light, age, all findings, edit ledger, and coach or guard feedback outcomes. If the project has no ccverdict history, audit says so. It does not show another repo's session.
[2] Recent patterns
Reports aggregate local patterns: blind retries, unchecked-edit streaks, repeated reads, recovery after change, compaction risk, and session-end risk.
[3] Instruction report
Reads CLAUDE.md and compares instruction lines against recent finding categories. It prints only non-empty subsections:
- Candidates for removal: lines that matched no recent finding category.
- Apparently followed: lines whose category already has high compliance.
- Gaps: recurring finding categories that no instruction line addresses.
The report uses "matched" and "didn't match" language. It does not claim that an instruction caused an outcome.
Plain audit writes nothing outside ccverdict's own store.
audit --apply prints a unified diff, then writes only inside ccverdict's marked CLAUDE.md block. It backs up first. It adds at most two generic lines per run, and it never writes raw prompts, commands, paths, or tool output.
ccverdict does not delete or edit user-written CLAUDE.md lines. Removal suggestions appear as commented proposals in the diff. audit --cleanup removes the marked block after a backup.
Project-specific lessons route to ./CLAUDE.md. Cross-project habits route to ~/.claude/CLAUDE.md when you use --global or --all-projects. audit does not edit AGENTS.md.
ccverdict audit --project .
ccverdict audit --all-projects --recent 200
ccverdict audit --apply --project .
ccverdict audit --cleanup --project .
ccverdict doctor
ccverdict doctor --baseline
ccverdict uninstall --scope local
ccverdict uninstall --purgeaudit --json returns machine-readable output for all three audit sections.
doctor checks Node, Claude settings, optional hooks, transcript access, pricing cache, store version, and baseline diagnostics.
doctor --baseline shows safe aggregate baseline facts.
uninstall removes ccverdict-owned statusline and hooks. When a valid backup exists, it restores the previous Claude Code statusline. uninstall --purge also deletes learned baselines, lesson memory, and the derived event store.
ccverdict observes checks Claude Code runs. It does not run tests, lint, typecheck, or build commands by itself.
It recognizes common Bash validation commands and groups them into safe categories:
- tests
- lint
- typecheck
- build
ccverdict uses those categories for retry-loop detection, recovery baselines, coach feedback, and guard-mode retry denial.
If your project uses custom validation commands, add .ccverdict.json:
{
"validationCommands": {
"tests": ["make test"],
"lint": ["make lint"],
"build": ["make build"]
}
}This file is optional. ccverdict uses it for classification, but it does not copy those raw commands into event history.
● exploring · ctx 24% · $0.12
● editing · 2 files, 1 unchecked (router.ts…) · ctx 31%
◐ editing · 4 files, 3 unchecked (router.ts…) · ctx 44%
◐ testing · tests failed twice · ctx 52%
◐ exploring · cache reuse dropped from 68% to 29%
◐ idle · compaction boundary open
■ retrying tests · 3 fails, no fix between runs
■ exploring · reread config.ts 3x
■ exploring · ctx 93%, nearly full
○ no signal · transcript session mismatch
On narrow terminals the line shrinks to compact counts:
◐ editing · 3✎? · 44%
◐ 3✎? 44%
The dot stays visible.
ccverdict is local-first. It has no cloud backend, SaaS dashboard, transcript upload, proxy, gateway, or message router.
Current gauge records use derived metadata only: light, activity, finding categories, confidence labels, counts, rates, percentiles, feedback outcomes such as resolved or ignored, safe validation categories such as tests, token and cost fields, context fields, timestamps, hashed file identities, hashed session keys, and hashed project keys.
The event store does not store prompts, assistant text, tool output, shell output, command arguments, file contents, transcript paths, workspace paths, API keys, raw Claude session ids, or raw MCP names.
For repeated-read warnings, ccverdict may show a basename hint such as auth.ts. It does not store or print the full local path.
Local files live under ~/.claude/ccverdict by default, unless you set CCVERDICT_HOME or another override:
events.jsonstores derived local decisions, hook events, and feedback outcomes.baseline.jsonstores the personal aggregate baseline.project-baselines/<hashed-project>.jsonstores aggregate project baselines.project-lessons/<hashed-project>.jsonstores decaying project lesson memory.litellm-pricing.jsoncaches public pricing data when refreshed.backups/stores Claude settings backups used by uninstall.
Install backups are local settings snapshots. They may contain whatever statusline, hook commands, or paths already existed in those Claude settings. ccverdict does not upload them.
LiteLLM is used only as public pricing data for cost estimates. ccverdict does not run a LiteLLM proxy or route messages.
Set budget thresholds with environment variables:
CCVERDICT_BUDGET_COST_USD=1.25
CCVERDICT_BUDGET_COST_DELTA_USD=0.25
CCVERDICT_BUDGET_DURATION_MINUTES=30