Skip to main content

Grade your AI agent against your own CLAUDE.md, with receipts.

Project description

housebroken

Grade your AI coding agent against your own CLAUDE.md — with receipts.

housebroken replays your real Claude Code transcripts against your rules files and tells you, rule by rule, which ones your agent violated (quoting the exact transcript evidence), which fired and passed, and which have been asleep for weeks — burning context tokens for nothing.

housebroken report card

Install

uvx housebroken          # zero-install, run it now
pipx install housebroken # keep it

Then just:

housebroken              # grade your real ~/.claude history
housebroken demo         # 30-second showcase, no history or setup needed

housebroken demo runs against a bundled synthetic transcript, so you get the full report card even on a fresh machine with no Claude Code history.

From source (before the PyPI release)

Until housebroken is published to PyPI, run it straight from a clone with uv:

git clone <this-repo> && cd housebroken
uv run --with-editable . housebroken demo    # the showcase
uv run --with-editable . housebroken         # grade your real ~/.claude

Discovery is automatic (rules under ~/.claude/CLAUDE.md and ~/.claude/rules/, transcripts under ~/.claude/projects/). Point it elsewhere with --claude-dir DIR, or override with --rules PATH / --transcripts PATH.

The flip

CLAUDE.md is unfalsifiable prose. You edit it on a hunch and hope the agent reads it. housebroken flips that: every rule becomes an assertion, checked against what the agent actually did, and each rule gets a performance review. You've been training a dog by leaving it notes — this tells you which notes it ignored.

What a run looks like

  HOUSEBROKEN REPORT ── score 40%

  ✗ VIOLATED       "Run the test suite before committing."           3×  [required-sequence]
      └ 2026-07-08T23:12:00Z session.jsonl:7
        commit with no prior test run in session: git commit -m 'stuff'
  ✗ VIOLATED       "Never use the --force flag when pushing ..."      1×  [forbidden-action]
      └ git push --force origin main
  ! SUSPECTED      "Write clean, readable code."             unverified  [judge 2/2]
      └ judge: claims cleanliness but shows no verifiable evidence
  ~ ASLEEP         "Never use --no-cache against staging."   ~14 tokens wasted
  ✓ PASSED         "Never use --hard with git reset."       (applicable 1×)
  ✓ PASSED-JUDGED  "Prefer small, surgical changes ..."     (judged 2/2 spans)
  ? UNENFORCEABLE  "Always be excellent."                   (prose — rewrite or delete)

  Verdicts: KEEP 6 · REWRITE 1 · DELETE 1

The beat that sells it is the receipt: your own rule, quoted back, next to timestamped proof the agent ignored it.

How it works

Each rule is sorted into a checkability class, shown next to its grade so you always know whether a verdict is mechanical or judged:

  • forbidden-action ("never use --force", "no emojis") — deterministic checks over tool calls and assistant text.
  • required-sequence ("run tests before committing") — ordering checks over the events within a session.
  • output-format ("use conventional commits") — pattern checks on the produced artifact (e.g. commit messages).
  • behavioral-prose ("prefer small, surgical changes") — judged by your own claude CLI, and only when the judge can quote concrete evidence.
  • unenforceable ("always be excellent") — surfaced as its own finding, with a suggestion to rewrite or delete.

Receipts, or it didn't happen. A VIOLATED verdict always quotes the exact transcript span — session file, line, timestamp, and the offending command or text. No receipt, no accusation.

Applicability is tracked. A git rule in a session with no git activity didn't "pass" — it was irrelevant. PASSED means applicable and clean; ASLEEP means it never came up in the window (with an estimate of the context tokens it cost you anyway).

The judge is conservative by design. Behavioral-prose rules are judged against windows of concrete activity, and the judge returns "no verdict" unless it can cite evidence in the span. If it sampled spans and none cleared that bar, the report says so plainly — housebroken never accuses without a receipt. That is the point, not a limitation.

Privacy

Local-first. No accounts, no telemetry, nothing leaves your machine. The only network-shaped step is the optional Tier-2 judge, which rides your existing claude CLI — your transcripts already live in that trust boundary, so housebroken adds no new data flow. Every span is scrubbed for secrets (API keys, tokens, bearer headers, emails) before it reaches a report or a judge prompt. Pass --no-judge to skip Tier-2 entirely. Bundled demo fixtures are 100% synthetic.

What's next (v2)

A replayable scenario-fixture suite: rule edits go red/green like code, you can bisect which rule change altered behavior, and a silent model upgrade that changes your agent's behavior trips an alarm. The linter becomes a regression suite for the newest config file in your repo.

Authorship

Built by one person (Turni Saha, author and maintainer) together with a frontier model (Claude) pushed hard. The commit history is what it looks like when you treat a language model as a real collaborator on a real tool.

Contributing

Issues and PRs welcome — the rule-compiler heuristics and the check classes are where most of the interesting work is. See LICENSE (MIT).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

housebroken-0.1.0.tar.gz (268.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

housebroken-0.1.0-py3-none-any.whl (49.4 kB view details)

Uploaded Python 3

File details

Details for the file housebroken-0.1.0.tar.gz.

File metadata

  • Download URL: housebroken-0.1.0.tar.gz
  • Upload date:
  • Size: 268.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for housebroken-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6b0d44836506b523a955a7fc448110b5b51d375755ab4f4cc2ea203dba54fda2
MD5 d99c011cb4f71d1d1ec3df84a43edcfb
BLAKE2b-256 04f84443a062fb2251f2ac3c7e32ed6e3ff2b12e7a3495fe80241496352a3019

See more details on using hashes here.

File details

Details for the file housebroken-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: housebroken-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 49.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for housebroken-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2ee7a1b51dc15f2253e0548109c2aa048b6f16555a4fdc972cc2402464a0ff28
MD5 3bb4ecb519ebeeb9a5b55f249e505cd0
BLAKE2b-256 0d299cc788de8f043afd0b7cf5c310b824894c4c7ca3d888c88d075d99f9659a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page