Skip to content
shanchen97Public

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

reviewtax

Track and analyze the delta between "the code an AI agent first wrote" and "what you actually committed after human review". Every review is recorded automatically: the diff is archived, each change is AI-classified (necessary fix / design gap / overengineering / convention...), and attributed (hand-edited vs. reworked-by-agent-under-direction). Later, export an aggregate report showing which problems recur most and which could have been avoided via prompt changes, CLAUDE.md entries, lint, or tests.

Single-file Python CLI, zero third-party dependencies. Requires git and the claude CLI.

How it works

SessionStart hook ──── join the worktree's chain (task base = HEAD)
Stop hook ──────────── snapshot the worktree when the agent stops and the
                       tree changed (first snapshot = "agent's first version")
UserPromptSubmit hook ─ detect hand edits between agent turns, snapshot them
post-commit hook ───── settle on every commit: diff, archive, AI-classify,
                       then re-anchor a fresh chain at the new HEAD
SessionEnd hook ─────── sweep stale unfinished chains

Tracking is per worktree, not per session: snapshots capture the whole worktree, so all uncommitted work between two commits — agent turns from any Claude session, hand edits, manual marks — is one stream and one chain. A chain can span several Claude sessions; feedback is collected from each session's transcript from the moment the agent's first version exists.

Snapshots are real commit objects created with plumbing commands (commit-tree + update-ref) under refs/reviewtax/:

  • not on any branch — invisible to git log / git status / GitHub;
  • never touch your staging area (a temp index is used);
  • protected from git gc because a ref points at them;
  • plumbing never fires git hooks, so snapshots can never trigger a settle;
  • once archived as patch text they can be cleaned up, leaving no trace.

Every commit settles the current chain into one record and starts the next cycle, so records line up 1:1 with commits that contain agent work (commits with no agent snapshots since the last one settle nothing). If the agent stopped and a commit landed with no feedback and no hand edits in between, the record is flagged pass_through (not reviewed) and counted separately.

Install

# 1. Install the Claude Code hooks (user-level, merged into
#    <claude_dir>/settings.json with a backup)
python3 reviewtax.py setup

# 2. Opt in each repo you want tracked (git config flag + post-commit hook)
cd /path/to/repo && python3 reviewtax.py enable

# Optional: a shim for convenience
ln -s "$(pwd)/reviewtax.py" ~/.local/bin/reviewtax

# Optional: an agent skill so AI agents know how to drive the CLI
# (SKILL.md at the repo root; the repo itself acts as the skill directory)
ln -s "$(pwd)" ~/.claude/skills/reviewtax

The hooks silently no-op (a few ms) in repos without enable, and never interfere with a Claude session — all errors are swallowed and logged. Restart any running Claude Code sessions to pick up the hooks.

Daily use

Just work normally: the agent writes code, you review (send feedback or hand-edit), the agent commits. Collection is fully passive. One habit worth keeping: when the agent needs more than one turn to finish, run reviewtax mark at the moment it's done — see the next section.

reviewtax status                 # per-worktree review state, recent records
reviewtax report                 # records settled since the previous report
reviewtax report --all           # full history instead of the increment
reviewtax report --since 2026-07-01 --out report.md
reviewtax report --no-ai         # stats tables only, no model calls

Marking the review start

Passive tracking anchors "the agent's first version" at the first snapshot after the task base. That is right for one-shot tasks: everything after the first version is review. But when the agent needs several turns — or several sessions — to finish the code, the later turns are still development, not review, and would be miscounted as review delta. Declare the boundary yourself: the moment the agent is done and you start reviewing, run reviewtax mark.

A record is built from two points, and mark controls both:

  • Review start — mark snapshots the current worktree as "the agent's first version", discarding any earlier snapshots in the cycle. Everything from this moment to the next git commit (feedback-driven rework and hand edits) is the review delta, and messages from now on count as review feedback.
  • Task base — the state before the agent touched anything. This is an existing commit, not a snapshot: by default, the commit the current cycle started from (normally the last commit), and base → mark is recorded as the agent's work. If the agent committed mid-task, the cycle was re-anchored at that commit, so pass --base <commit> to point the base back at the true task start.
reviewtax mark                   # review starts now
reviewtax mark --base <commit>   # ...and agent work started from <commit>

mark is also the repair tool when hooks missed the session or the automatic anchor landed on the wrong turn.

Other manual entry points

# Fully retroactive (the agent's version is already a historical commit):
reviewtax record --base <base> --agent <agent-version> [--final HEAD] \
                [--transcript x.jsonl]

# Re-run a failed/updated AI analysis for one record:
reviewtax analyze ~/.reviewtax/records/<repo>/<record-id>

reviewtax settle                 # trigger a settle manually (same as post-commit)
reviewtax disable                # stop tracking this repo (hook becomes a no-op)
reviewtax sweep                  # remove chains idle beyond stale_days

Data layout

~/.reviewtax/                          # override with REVIEWTAX_HOME
  chains/<repo-key>.json              # per-worktree in-flight chain state
  records/<repo>/<record-id>/
    meta.json                         # stats, tree hashes, pass_through flag
    agent.patch                       # task base -> agent's first version
    review.patch                      # agent's first version -> final commit
    hand-edit.patch                   # hand-edit segments (for attribution)
    feedback.md                       # your verbatim review feedback
    analysis.json                     # AI classification results
  reports/                            # exported reports
  logs/reviewtax.log                   # diagnostics

Classification

correctness (necessary fix) / design-gap (requirement never stated) / churn (reverts or redoes what the review itself asked for earlier — a direction change, not an agent defect) / overengineering / simplification / convention / security / cosmetic. Each entry carries evidence (code-level facts backing the judgment), a root cause, and avoidable_by (prompt / claude_md / lint / test / none). The analyzer runs inside the target repository so it can read the real code to verify its conclusions instead of judging from diff hunks alone, and it must check the feedback history before blaming the agent's first version for a change the review itself directed.

Configuration

All machine-specific settings live in ~/.reviewtax/config.json — the repository itself contains no absolute paths or personal information. Precedence: env var REVIEWTAX_<KEY> > config.json > default. reviewtax config shows the effective values.

{
  "model": "sonnet",          // model for analysis calls; "" = claude CLI default
  "no_ai": false,             // disable all AI calls (record only)
  "claude_dir": "~/.claude",  // Claude Code config dir (settings, transcripts)
  "patch_limit": 60000,       // truncation for each patch fed to the analyzer
  "feedback_limit": 20000,    // truncation for feedback fed to the analyzer
  "stale_days": 7             // sweep chains idle longer than this
}

The data root is set via the REVIEWTAX_HOME env var (default ~/.reviewtax; it can't live in the config file that sits inside it).

Note: setup / enable write your local interpreter and script paths into <claude_dir>/settings.json and each repo's .git/hooks/post-commit. Those files live outside this repository and are never committed; after moving the script or switching machines, just re-run setup / enable.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages