bridle-audit
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)
| File | Size | Uploaded | |
|---|---|---|---|
| bridle_audit-0.1.0.tar.gz | 9.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|