Skip to content

softcane/ccverdict

Repository files navigation

ccverdict

CI

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.

ccverdict statusline examples

The demo cycles through example statusline states: healthy editing, unchecked-edit drift, repeated validation failure, repeated file reads, high context, and unreadable evidence.

Dot Legend

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%!

What It Catches

  • 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.

Install

Requirements:

  • Node.js 20 or newer
  • Claude Code with status line support
npx --yes ccverdict install --scope local

Restart 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 --replace

Use observe-only when you only want the gauge and local history:

npx --yes ccverdict install --scope local --observe-only

Use guard when you want coach feedback plus strict denial of high-confidence repeated validation retries:

npx --yes ccverdict install --scope local --guard

Skip baseline creation and lesson memory:

npx --yes ccverdict install --scope local --no-learn

Uninstall:

npx --yes ccverdict uninstall --scope local

Supported 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 local

Feedback Modes

observe-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.

Try Before Installing

Run an audit against recent local Claude Code history:

npx --yes ccverdict audit --project .
npx --yes ccverdict audit --all-projects --recent 200

audit does not install a statusline or hooks. Use --all-projects only when you want to inspect the newest transcripts across local Claude projects.

Audit

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.

Audit Writes

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.

Useful Commands

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 --purge

audit --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.

Validation Signals

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.

More Examples

● 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.

Privacy

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.json stores derived local decisions, hook events, and feedback outcomes.
  • baseline.json stores the personal aggregate baseline.
  • project-baselines/<hashed-project>.json stores aggregate project baselines.
  • project-lessons/<hashed-project>.json stores decaying project lesson memory.
  • litellm-pricing.json caches 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

About

A stop-loss statusline for Claude Code.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors