Skip to main content

bridle-audit

CI PyPI Python versions License: MIT

Your Claude Code config grows in silence. Hooks pile up in settings.json — some fire on every single turn — and keep firing long after the script they point at was deleted. The same linter gets wired twice by two different sessions. Skill descriptions are loaded into context at every session start, and nobody counts what that boot costs. Configs only ever grow; nothing prunes them.

bridle-audit is the pruner: one command, zero dependencies, reads your real config and tells you exactly what is dead, doubled, or dormant.

  • Dead hooks — commands wired to scripts that no longer exist (fired every turn, for nothing).
  • Duplicate levers — the same script wired several times inside one event.
  • Dormant cost — how many characters of skill descriptions you pay at every boot.

Install

pipx install bridle-audit

or

pip install bridle-audit

or straight from source:

pipx install git+https://github.com/trinity-organism/bridle-audit

Python >= 3.9. Zero dependencies — standard library only.

Usage

bridle-audit                 # audit $CLAUDE_CONFIG_DIR, falling back to ~/.claude
bridle-audit --config DIR    # audit a specific config directory
bridle-audit --json          # machine-readable output

Exit codes: 0 clean (or no config found), 1 at least one dead hook or duplication, 2 config unreadable — so it drops straight into CI or a shell prompt.

Before / after

Real output (username anonymized). Before — a config that grew for six months:

$ bridle-audit
bridle-audit — installed levers vs the ladder (context < skill < tool < hook < daemon)
hooks source: /Users/you/.claude/settings.json

[per session] SessionStart (1 hook)
  ok    session-banner.sh — /Users/you/.claude/hooks/session-banner.sh

[per turn] PreToolUse (2 hooks)
  ok    format-check.sh — /Users/you/.claude/hooks/format-check.sh
  ok    format-check.sh — /Users/you/.claude/hooks/format-check.sh
  DUP   format-check.sh x2 — same script, 2 voices in one event (one behavior, one lever, one place)

[per turn] Stop (1 hook)
  DEAD  notify.sh — /Users/you/.claude/hooks/notify.sh

dormant cost — 3 skills, ~414 chars of descriptions loaded at every session start

verdict — dead hooks: 1 · duplicate levers: 1 · skills: 3 (~414 chars/boot)
$ echo $?
1

After pruning the dead Stop hook and merging the duplicate into one matcher:

$ bridle-audit
bridle-audit — installed levers vs the ladder (context < skill < tool < hook < daemon)
hooks source: /Users/you/.claude/settings.json

[per session] SessionStart (1 hook)
  ok    session-banner.sh — /Users/you/.claude/hooks/session-banner.sh

[per turn] PreToolUse (1 hook)
  ok    format-check.sh — /Users/you/.claude/hooks/format-check.sh

dormant cost — 3 skills, ~414 chars of descriptions loaded at every session start

verdict — dead hooks: 0 · duplicate levers: 0 · skills: 3 (~414 chars/boot)
$ echo $?
0

And when there is nothing to audit:

$ bridle-audit --config /some/empty/dir
bridle-audit: no settings.json found in /some/empty/dir
Nothing to audit. If your Claude Code config lives elsewhere, point at it with --config DIR or $CLAUDE_CONFIG_DIR.

Hook commands are resolved the way a shell would: quoting (paths with spaces), wrappers (nohup, bash -c, python3, ...), VAR=val prefixes and $HOME/~ are all handled before the target is checked.

Philosophy

A bridle, not a harness rack: one behavior, one lever, one place — and always the cheapest lever that actually steers. A line of context beats a skill, a skill beats a tool, a tool beats a hook, a hook beats a daemon. This tool shows you where your config climbed that ladder without need.

Development

pip install -e ".[dev]"
pytest

The test suite fabricates synthetic configs in temp directories — it never reads your real ~/.claude.

License

MIT

Metadata

Release files for bridle-audit 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bridle-audit 0.1.0
File Size Uploaded
bridle_audit-0.1.0.tar.gz 9.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bridle-audit 0.1.0
File Interpreter ABI Platform
bridle_audit-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 17.8 kB

Release files / bridle_audit-0.1.0.tar.gz

Download URL bridle_audit-0.1.0.tar.gz
Size 9.9 kB
Tags Source
SHA-256 checksum
How to use checksums
61e7e7670c5f72865f4c802f2ee018c348beddc2b3c36e7ee48d058f18745ffe
BLAKE2b-256 checksum
How to use checksums
be3da9643ad47ae5c3c29362171540f3ee23880d6c2e910db49d4c91cb313afb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / bridle_audit-0.1.0-py3-none-any.whl

Download URL bridle_audit-0.1.0-py3-none-any.whl
Size 7.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d4e5432ae7a8aedfd2e662578d8ebab1d2a95b82f2749117b6221e10f14403e9
BLAKE2b-256 checksum
How to use checksums
5c604d140c438b7026ffbec7a2a4d38974707e915f10c0da5e3304927b83af6b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page