Deterministic triage of an AI agent's changes — see what it actually touched before you merge.
Project description
agentdiff
See what the agent actually changed — before you merge.
An AI coding agent just edited your repo. Before you accept the diff you want to know, without reading every line: did it touch anything outside what you asked for? Did it add a dependency, modify a CI pipeline, or leave a high-entropy string in a config file?
agentdiff answers those questions in under a second, deterministically, with no LLM call and nothing leaving your machine.
Part of a small family of zero-dependency tools for working with coding agents — see stillworks for behavior-lock / characterization testing.
30-second quickstart
pip install 'stillworks[all]' # all four agent tools, including this one
pip install agentdiff-cli # or just this one (the command is `agentdiff`)
# Inside any git repo, after an agent session:
agentdiff review
# Tell it what the agent was supposed to touch:
agentdiff scope "src/**" "tests/**"
agentdiff review # now flags files outside that scope
# See exactly what every rule flags (and which tools go deeper):
agentdiff rules
# Machine-readable output for CI:
agentdiff review --json
Real example output
A repo where an agent was scoped to src/* and tests/* but also
created a Dockerfile, a requirements.txt, and added a TODO comment:
$ agentdiff review --scope "src/*" --scope "tests/*"
HIGH (2)
HIGH Dockerfile CI/release file modified: Dockerfile
HIGH requirements.txt:1 dependency added/changed: requests
MED (2)
MED Dockerfile changed outside declared scope (src/*, tests/*)
MED requirements.txt changed outside declared scope (src/*, tests/*)
LOW (1)
LOW src/main.py:1 TODO/FIXME added
5 finding(s): 2 HIGH, 2 MED, 1 LOW — review before merge
Exit code is 1 (findings at HIGH or MED). With --json:
{
"findings": [
{"severity": "HIGH", "file": "Dockerfile", "line": 0, "reason": "CI/release file modified: Dockerfile", "rule": "ci-release"},
{"severity": "HIGH", "file": "requirements.txt", "line": 1, "reason": "dependency added/changed: requests", "rule": "dependencies"},
{"severity": "MED", "file": "Dockerfile", "line": 0, "reason": "changed outside declared scope (src/*, tests/*)", "rule": "out-of-scope"},
{"severity": "MED", "file": "requirements.txt", "line": 0, "reason": "changed outside declared scope (src/*, tests/*)", "rule": "out-of-scope"},
{"severity": "LOW", "file": "src/main.py", "line": 1, "reason": "TODO/FIXME added", "rule": "test-quality"}
],
"files_changed": 3,
"clean": false,
"gate_triggered": true,
"counts": {"HIGH": 2, "MED": 2, "LOW": 1}
}
CLI reference
agentdiff review [--since GIT_REF] [--scope GLOB]... [--json] [--report FILE]
[--strict] [--staged-only | --pre-commit]
agentdiff scope GLOB... # save the intended scope to .agentdiff/scope
agentdiff rules # print every rule and what it flags
--since GIT_REF Compare the working tree against that ref instead of
HEAD. Useful when the agent was handed a feature branch and you want to see
only what changed since that branch was cut.
--scope GLOB Repeatable. Overrides .agentdiff/scope for this run.
Files not matching any glob produce MED findings.
--strict LOW findings also set exit code 1.
--staged-only / --pre-commit Only inspect staged (git-indexed) files.
Clean pre-commit hook integration:
# .git/hooks/pre-commit
agentdiff review --staged-only || exit 1
--report FILE Write a markdown evidence document to FILE, suitable for
pasting into a PR description or issue comment.
Exit codes: 0 = nothing flagged at gating severity. 1 = one or more findings at HIGH or MED (or LOW under --strict). 2 = usage error (not a git repo, unknown ref).
Rules
Run agentdiff rules to see all rules and which specialist tools cover
each domain more deeply.
| Severity | Rule | What it catches |
|---|---|---|
| HIGH | secrets | PEM private key blocks, AWS access key ID patterns, high-entropy tokens assigned to names containing key/token/secret/password |
| HIGH | ci-release | .github/workflows/, Dockerfiles, *.tf, .circleci/, Jenkinsfile, Makefile release targets, deploy scripts (shell/Python/Ruby/PowerShell — not YAML/JSON data files) |
| HIGH | dependencies | Added or version-changed packages in requirements.txt, pyproject.toml, package.json, go.mod, Cargo.toml (section-aware), Gemfile, Pipfile. Lock files flagged as modified: package-lock.json, Gemfile.lock, poetry.lock, yarn.lock, pnpm-lock.yaml, Pipfile.lock, composer.lock |
| MED | ignore-config | .agentdiff/ignore added or modified. The ignore file is never suppressed by its own patterns — an agent silencing its reviewer is always flagged |
| MED | out-of-scope | Files changed outside the declared scope (only when scope is set) |
| MED | deletion | File deleted or more than 50 lines removed from a file |
| MED | executable | Executable bit added, or a new binary file added |
| LOW | test-quality | Test files deleted or renamed out of the test tree, assertions removed, TODO/FIXME added, large (>1000 line) or minified-looking files added |
LOW findings only affect the exit code under --strict.
Config files
Both live in .agentdiff/ at the repo root.
.agentdiff/scope — one glob per line, # comments. Written by
agentdiff scope. Lists the paths the agent was authorized to touch.
.agentdiff/ignore — one glob per line, # comments. Files matching
these globs are skipped by all rules. Useful for vendored code, test fixtures,
or generated files you don't want reviewed.
Neither file is required. Without .agentdiff/scope, the out-of-scope rule
does not run.
Why not just ask your AI to review the diff?
Because the answer changes every time, you cannot automate it, and the model
can be wrong in ways that are hard to catch. agentdiff produces the same output
for the same diff, every time, with no API key. It composes cleanly with
grep, jq, and CI pipelines. And because it is small enough to read in an
afternoon, you can decide whether to trust it.
Prior art (and what's different)
agentdiff is not the only tool covering this space. Here is an honest map:
Secrets detection
- gitleaks (gitleaks/gitleaks) — 18k+ stars. Scans git history, staged files, and diffs using 150+ regex rules plus entropy analysis. Runs as a pre-commit hook or in CI. Supports custom TOML rule files and allowlists. agentdiff's secret rule is a fast first pass; for comprehensive scanning, run gitleaks alongside.
- TruffleHog (trufflesecurity/trufflehog) — scans 800+ credential types with live provider verification (it actually tests whether an AWS key is still active). Covers git history, diffs, S3, Slack. agentdiff will miss secrets that TruffleHog catches.
- detect-secrets (Yelp/detect-secrets) — baseline-driven scanner with 27 detectors, regex + entropy + keyword. Scans staged files. agentdiff is not a replacement.
Dependency review
- GitHub dependency-review action — scans lock-file diffs in pull requests, reports CVE severity, blocks merges. Requires an open GitHub pull request. agentdiff runs on the raw working tree before a PR exists, but provides no vulnerability data.
- socket.dev — supply-chain security: detects typosquatting, dependency confusion, compromised maintainers. agentdiff only reports the package name.
- e18e/action-dependency-diff — trust levels, install size, duplicates, module replacements. PR-native.
CI/CD change detection
- Elastic cicd-abuse-detector — uses regex plus Claude LLM to detect suspicious CI changes. LLM-based, not deterministic.
Review frameworks
- Danger (danger.systems) — scripting framework that runs a Dangerfile in CI. Every agentdiff rule could be a Dangerfile, but Danger provides no opinionated rules and requires a PR on GitHub/GitLab.
- reviewdog (reviewdog/reviewdog) — routes linter output to PR annotations. Infrastructure, not rules.
- Semgrep (semgrep/semgrep) — full SAST with diff-aware mode, not zero-config.
Agent-specific tools (name collisions)
Three repos already occupy the "agentdiff" name: sunilmallya/agentdiff (Claude Code audit trail, LLM-based), agentdiff-ai/agentdiff (TypeScript agent behavioral escalation detector, LLM-based), codeprakhar25/agentdiff (git-native AI code attribution with ed25519 signing). None of these are this tool; none are pip-installable as of this writing.
What agentdiff does differently
The one thing no surveyed tool does: the scope subcommand persists what the
agent was authorized to touch and flags deviations as MED findings. Existing
tools can detect what changed; none track whether it was authorized to change.
agentdiff also operates on the raw working tree (staged + unstaged + untracked)
before a commit or PR exists, with zero configuration and zero dependencies.
Honest limits (v0.1)
-
The secrets rule is a narrow first pass. It covers PEM private key blocks, AWS access key ID patterns, and high-entropy token assignments. It does not use entropy analysis over whole files, does not scan git history, and will miss many credential types that gitleaks or TruffleHog catch. The tradeoff is near-zero false positives; do not rely on this rule alone for secrets hygiene.
-
Scope globs use Python fnmatch, not gitignore semantics. A glob like
src/**matches files with a literalsrc/prefix in fnmatch but may not behave identically to gitignore patterns in all cases. Test your globs withagentdiff review --scope YOUR_GLOBon a known set of files. -
Binary files are flagged but not inspected. A new binary whose content looks benign (a PNG icon) gets the same MED finding as a compiled payload. Use
.agentdiff/ignoreto suppress expected binary additions. -
No diff of diffs. agentdiff compares the working tree against a ref. If the agent made a large refactor that deletes 200 lines and adds 200 different ones, it flags the deletion (>50 lines removed) but has no opinion about whether the replacement is equivalent.
-
The dependency rule reads added lines only. It does not resolve package metadata, check for vulnerabilities, or detect transitive changes via lock files. All lock files are flagged as "lock file modified" without line-level parsing (too noisy to parse per-package). Use dependency-review-action for CVE context. For per-package change detection in lock files, use socket.dev or the GitHub dependency review action.
-
Cargo.toml target-specific dependency sections are best-effort. The Cargo.toml parser is section-aware and correctly ignores
[package],[profile.*], and[features]keys. Standard sections ([dependencies],[dev-dependencies],[build-dependencies],[workspace.dependencies]) are well-covered. Complex[target.'cfg(...)'.dependencies]expressions may have edge cases in multi-hunk diffs where a section header is not visible as a context line. -
.agentdiff/ignorebypass is detected, not prevented. When an agent overwrites.agentdiff/ignorewith**, the tool emits a MED finding for the ignore config change and exits 1 — it does not exit 0. However, other files in the same changeset that match**are still suppressed by the updated ignore list. The MED finding is the signal to investigate manually. -
No Windows path support. The tool assumes POSIX paths throughout. Contributions welcome.
Installation
pip install agentdiff-cli
(The PyPI name is agentdiff-cli because agent-diff was already taken. The
command, the module, and the repo are all just agentdiff.)
Or run it straight from a checkout, no install needed — it is stdlib only:
git clone https://github.com/iselur/agentdiff
cd agentdiff && python3 -m agentdiff --help
Requires Python 3.9+, git in PATH. Zero third-party dependencies.
Part of a small family
Four tools for working with coding agents, same house style: zero dependencies, MIT, no API key, nothing leaves your machine. None of them call a model — that is the point, since the thing being checked already is one.
- stillworks — record what your code does now, catch when it changes later
- agentdiff — see what the agent actually changed, before you merge ← you are here
- agentlog — what did your coding agent actually do today?
- unedit — a safety net for letting an agent loose on your files
One install gets all four, and stillworks tools says which ones you have:
pip install 'stillworks[all]'
stillworks tools
License
MIT. Copyright (c) 2026 stillworks contributors.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agentdiff_cli-0.1.2.tar.gz.
File metadata
- Download URL: agentdiff_cli-0.1.2.tar.gz
- Upload date:
- Size: 37.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ab0aed2e2fde58406134b0866a58fce6727693e4bf422c08a779b3248864b98
|
|
| MD5 |
33cf421ee4a862e3c638168a5a5f5c14
|
|
| BLAKE2b-256 |
dabb04d9ff4cf85fceafc1e683e0770c4a775fbf8243525783e1cd3aadc942d9
|
File details
Details for the file agentdiff_cli-0.1.2-py3-none-any.whl.
File metadata
- Download URL: agentdiff_cli-0.1.2-py3-none-any.whl
- Upload date:
- Size: 22.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
99f724c08c6ee9d413e2d8b82afd54b6ad8c7db83e8546545381bb3c08fe10d6
|
|
| MD5 |
01634c3231b2d05bfa8a028e2b42b576
|
|
| BLAKE2b-256 |
17296186ecad9d5711a9c06489493f98c708d4ef7181200540a1fb5af5ee1fc8
|