Cut tokens on AI code reviews with code-review-graph
When you ask Claude Code, Codex or Cursor to review a change in a big repo, the agent usually does one of two things. It reads far too many files and burns your context window, or it reads too few and misses the caller your change breaks. Neither is a great way to spend tokens.
code-review-graph takes a different route. It parses your codebase with Tree-sitter into a local graph of functions, classes, imports, calls and test coverage, then serves a small slice of that graph to your assistant over MCP. The assistant reads only the files a change actually touches. The README reports about 63x fewer tokens per question at the median across six repos. We have not reproduced that number ourselves, so treat it as the author's benchmark.
What you need
- Python 3.10 or newer
- One of the supported AI coding tools: Claude Code, Codex, Cursor, Windsurf, Zed, Continue, OpenCode, Gemini CLI, Copilot and several others
- A repository you want reviewed, ideally a large one where context fills up fast
Install and build
pip install code-review-graph # or: pipx install code-review-graph
code-review-graph install # detect installed AI coding tools and configure each one
code-review-graph build # parse the codebase
The install step detects which AI coding tools you have, writes an MCP server entry for each one, installs hooks and skills where the platform supports them, and adds graph instructions to the platform's rules file. Restart your editor or tool afterwards.
To configure only one tool, pass a platform:
code-review-graph install --platform claude-code
code-review-graph install --platform cursor
A cold build of a roughly 3,000 file repository took about 40 seconds in the README's measurement. After that, hooks and watch mode keep the graph updated as files change. If some files fail to parse, the build reports a partial status and names them, and those files keep their previous graph rows.
Run a review
Open the project in your assistant and ask:
Build the code review graph for this project
Then ask for a review of a branch or diff. The assistant calls the graph's MCP tools to get the blast radius of the change: callers, dependents and the tests that cover it, plus risk scores. That is the "smallest set of files the assistant needs to read."
A prompt you can paste
"Install tirth8205/code-review-graph in this repo, build the graph, and review my current branch through its MCP tools. List which files the review context included, the blast radius of the change, and any tests that cover it."
Removing it cleanly
code-review-graph uninstall --dry-run # preview only
code-review-graph uninstall # preview, confirm, apply
Uninstall removes only the files and entries it created and leaves your other MCP servers and hooks alone.
Tips
- Check the "files included" list in the review. If the blast radius looks wrong, rebuild the graph before trusting the result.
- Keep watch mode or hooks on, so a stale graph does not hide a new caller.
- This walkthrough follows the README and has not been run end to end by us.
More
Step-by-step card: Give your AI reviewer only the code that matters. More on the repo: code-review-graph use cases.
Source repo: tirth8205/code-review-graph.
Want the setup commands for 50 AI repos people actually ship with? Get the free AI Repos That Actually Ship pack: dedupedai.com
---
Get one email every Monday with the week's hottest AI repos and exactly how to use them: subscribe free at dedupedai.com
Dev OS v2: gates, a learning loop, and agents that check agents
In v1 I treated ~/.claude as an operating system around the model: a kernel (one rulebook), a scheduler (lanes), interrupts (hooks), a package manager (pinned skills). I asked you to run the starter kit for a week and tell me what broke.
I ran it too, every day. 213 commits later, this is the v2 release, and its main change fits on one line:
> A rule the agent reads is a request. A rule something runs is a gate.
Both commenters on v1 had said the same thing. Here is what that changed, in order of how much it helped. The gates, hooks, agents and tests below ship in the kit (135 checks, bash tests/run.sh); the rest is how I run my own setup. The kit works with any agent that reads AGENTS.md (Codex, Cursor, Copilot), not only Claude Code.
1. One rulebook, every agent
The kernel is the same: one CLAUDE.md whose first section says it overrides every skill, plugin and repo file. What's new is that AGENTS.md is a symlink to it.
ln -s ~/.claude/CLAUDE.md ~/.codex/AGENTS.md # Codex reads ~/.codex/AGENTS.md, then one per folder, root → cwd
I checked how each tool loads it on 2026-11-01:
- Codex concatenates AGENTS.md files up to 32 KiB by default. A long global rulebook steals room from repo rules. Mine is capped at 136 lines by a test.
- Claude Code reads AGENTS.md only in a repo with no CLAUDE.md, so CLAUDE.md stays the source.
- @lessons.md imports are Claude-only. Through the link, Codex gets the rulebook but not its imports.
2. Gates beat reminders
A test gate in plain git. v1's pre-commit hook only guarded ~/.claude itself. v2 installs one per project:
echo 'npm test' > .dev-os-test && ~/.claude/bin/gate-install
The hook it writes (condensed from bin/gate-install):
TOP=$(git rev-parse --show-toplevel)
unset GIT_INDEX_FILE GIT_DIR GIT_WORK_TREE GIT_PREFIX
CMD=$(cat "$TOP/.dev-os-test" 2>/dev/null)
if ! printf '%s' "$CMD" | grep -q '[^[:space:]]'; then
echo "dev-os test gate: .dev-os-test is missing or empty; commit refused" >&2; exit 1
fi
(cd "$TOP" && bash -o pipefail -c "$CMD") || { echo "dev-os test gate: commit refused" >&2; exit 1; }
Every line there is a bug I hit:
- pipefail: npm test | tail -5 exits with tail's 0, so a red suite commits.
- Empty means refuse: a missing or empty test command fails loudly instead of passing quietly.
- unset GIT_INDEX_FILE: git runs pre-commit with a temporary index during commit -a. A test suite that runs git add in a temp repo writes into your commit and breaks it with "Error building trees".
- No global hooks: the installer refuses when a global core.hooksPath would turn one repo's gate into every repo's gate.
Permissions the agent can't talk past. permissions.ask rules still prompt under --dangerously-skip-permissions, and compound commands are split before matching:
"permissions": { "ask": ["Bash(git push:*)", "Bash(gh pr create:*)"] }
One catch: rules match the command text, so git -C . push slips past Bash(git push:*). I add Bash(git -C * push *) in my own settings. Keep branch protection on the remote as the backstop.
A Stop hook for the cheap way out. v1's Stop hook sent the agent back when source changed with no test. v2 adds one more case: a weakened test. That means fewer assertions, a new .skip/.only, or a deleted test file.
ASSERT = re.compile(r"\bassert\w*\s*\(|\bexpect\s*\(|->assert\w*\(|\$this->assert|^[-+]\s*assert(_\w+)?\s")
SKIP = re.compile(r"markTestSkipped|markTestIncomplete|->skip\(|\.(skip|only|fixme)\s*\(|\bx(it|describe|test)\s*\(")
if removed_asserts > added_asserts or any(SKIP.search(l) for l in added):
weakened.append(path) # → {"decision": "block", "reason": "TEST WEAKENED: …"}
Codex hooks use the same Stop → {"decision":"block"} shape.
3. It learns by itself
In v1, "add a line to lessons.md" depended on me remembering to do it. Now the setup logs its own mistakes:
prompt starts "no, …" / "I said …" ─┐
stop-check or test gate blocks ─┼─▶ state/learn-<session>.jsonl
│
Stop: learn.sh → any entry newer than the last `reflect`? → block once: "run reflect"
reflect routes each mistake to the lowest layer that would have caught it: first a test or hook, then one line in the skill that owns the job, and only last a line in lessons.md. lessons.md has a 60-line budget. When it fills up, meditate audits the rules for stale, duplicate and contradicting lines, and deletes nothing without my yes. 59 of the 213 commits are Lesson: commits, and many of them removed a lesson by turning it into a check.
The loop gets tested like everything else. A cold review caught the correction detector flagging "No tests exist for the parser yet" as a correction. Now no counts only when followed by punctuation, and only the first line of a prompt is read.
4. Agents check agents
One agent reviewing its own diff is a student grading their own exam. The kit ships two read-only agent shapes:
- scout: one angle per scout (callers, tests, history, config). Each returns file:line facts and what it couldn't check.
- review-lens: Skeptic always, Architect at 50+ changed lines, Minimalist at 200+. Then one verifier per finding that starts from "false positive".
Two skills run them. pre-merge-review is relay step 7 on your own branch: lenses sized by the diff, a verifier per finding, one saved report. post-pr-review is for someone else's PR: each finding must reproduce on both the base and the PR branch before it goes in a draft, and nothing is posted without a yes. /code-review stays the per-slice check inside build-check, and it never posts on other people's PRs.
Every subagent brief has the same fields: goal, scope, what's known, what's been ruled out, the exact ask, the output format, what's out of scope. Parallel builders get one git worktree each, and only for plan slices that share no files.
How well does this work? On the v2 kit itself, which already passed all its own tests:
| Pass | Found |
|---|---|
| /code-review | 9 (6 fixed, 3 left with reasons) |
| 3 lenses, each reproducing its findings in a temp dir | 14 more |
| a cold reviewer that saw none of the above | 4 more |
Every behaviour fix got a red test first.
5. Prove it by running it
9. A bug or security claim counts only when reproduced by running it. No repro, no fix.
For bugs, the first job is a red-capable feedback loop, in the order from Matt Pocock's diagnosing-bugs: failing test → curl script → CLI snapshot diff → headless browser → replayed payload → harness → fuzz → git bisect run. Hypotheses come after.
I also break every gate on purpose before I trust it. That caught a test that passed before the code existed. My helper matched substrings, so rc=127 ("command not found") satisfied a check for rc=1.
6. Project memory: graph first
Rule 8: before grep, ask a code graph "who calls this, and what breaks if I change it?"
| Tool | Used for |
|---|---|
| graphify query / explain / path / merge-graphs | Finding code, explaining a node, call paths, one graph across repos |
| code-review-graph get_impact_radius_tool | Who else a fix reaches (the no-regressions rule) |
| get_review_context_tool, get_affected_flows_tool | Review context; which E2E flows a diff touches |
The scouts, review lenses and review-reply step all start there. The graph holds structure. What the project taught lives in lessons.md and in plan folders kept outside the repo.
7. Stay lean
- A context budget test: rulebook plus skill descriptions, measured in bytes, against a baseline. It went from 59,287 to 46,927 while the setup grew.
- Routing is tested: one rulebook sentence ("call the owner skill before any other tool") took my routing eval from 0-1 to 7-8 of 11 prompts.
- Effort is a budget too: "effortLevel": "medium" by default, in every modelSettings entry as well, since a per-model value wins. High effort lives in skill frontmatter only where a wrong answer is expensive: grilling, writing and checking the plan, whole-plugin bug hunts. Hooks can read the effort level but not set it, so serious cases are handled by a rule: payment or refund, data loss, auth or a security finding mean the verifiers are spawned with effort: "high".
- Smaller output: RTK trims git/gh/test output before the agent reads it. Compressed output can hide the one line you need, so "never report a result you couldn't see" is a rule.
The userland
Most of my 103 skills are other people's work: 39 are pinned to an upstream commit in skills.lock, with local edits in overlays that a sync script re-applies.
- ponytail by Dietrich Gebert: the smallest-change ladder (YAGNI → reuse → stdlib → platform → installed dep → one line). It's rule 3 in the kit.
- Matt Pocock's skills: tdd, grill-me, handoff, domain-modeling.
- obra/superpowers: brainstorming and systematic-debugging.
- Trail of Bits: fp-check, variant-analysis and differential-review, for security claims.
- e2e-reviewer: catches E2E tests that pass while the feature is broken.
Skills use the Agent Skills format. Codex reads them from .agents/skills, and Claude Code from .claude/skills, so one folder with two symlinks serves both.
Upgrade or start
New: follow the kit's README "Start here". The core (rulebook, test gate, plan template) takes about 10 minutes, and the Claude Code layer is optional.
From v1: the README has an "Upgrading from v1" block. Nothing was renamed. Two hooks and two skills get replaced after a "Before v2" commit, so it's one git revert to undo.
Same ask as v1: run it for a week and tell me what broke. And what's the one rule your agent keeps breaking? I'll tell you which gate I'd put behind it.
Mentions
Cut tokens on AI code reviews with code-review-graph When you ask Claude Code, Codex or Cursor to review a change in a big repo, the agent usually does one of two things. It reads far too many files and burns your context window, or it reads too few and misses the caller your change breaks. Neither is a great way to spend tokens. code-review-graph takes a different route. It parses your codebase with Tree-sitter into a local graph of functions, classes, imports, calls and test coverage, then serves a small slice of that graph to your assistant over MCP. The assistant reads only the files a change actually touches. The README reports about 63x fewer tokens per question at the median across six repos. We have not reproduced that number ourselves, so treat it as the author's benchmark. What you need - Python 3.10 or newer - One of the supported AI coding tools: Claude Code, Codex, Cursor, Windsurf, Zed, Continue, OpenCode, Gemini CLI, Copilot and several others - A repository you want reviewed, ideally a large one where context fills up fast Install and build pip install code-review-graph # or: pipx install code-review-graph code-review-graph install # detect installed AI coding tools and configure each one code-review-graph build # parse the codebase The install step detects which AI coding tools you have, writes an MCP server entry for each one, installs hooks and skills where the platform supports them, and adds graph instructions to the platform's rules file. Restart your editor or tool afterwards. To configure only one tool, pass a platform: code-review-graph install --platform claude-code code-review-graph install --platform cursor A cold build of a roughly 3,000 file repository took about 40 seconds in the README's measurement. After that, hooks and watch mode keep the graph updated as files change. If some files fail to parse, the build reports a partial status and names them, and those files keep their previous graph rows. Run a review Open the project in your assistant and ask: Build the code review graph for this project Then ask for a review of a branch or diff. The assistant calls the graph's MCP tools to get the blast radius of the change: callers, dependents and the tests that cover it, plus risk scores. That is the "smallest set of files the assistant needs to read." A prompt you can paste "Install tirth8205/code-review-graph in this repo, build the graph, and review my current branch through its MCP tools. List which files the review context included, the blast radius of the change, and any tests that cover it." Removing it cleanly code-review-graph uninstall --dry-run # preview only code-review-graph uninstall # preview, confirm, apply Uninstall removes only the files and entries it created and leaves your other MCP servers and hooks alone. Tips - Check the "files included" list in the review. If the blast radius looks wrong, rebuild the graph before trusting the result. - Keep watch mode or hooks on, so a stale graph does not hide a new caller. - This walkthrough follows the README and has not been run end to end by us. More Step-by-step card: Give your AI reviewer only the code that matters. More on the repo: code-review-graph use cases. Source repo: tirth8205/code-review-graph. Want the setup commands for 50 AI repos people actually ship with? Get the free AI Repos That Actually Ship pack: dedupedai.com --- Get one email every Monday with the week's hottest AI repos and exactly how to use them: subscribe free at dedupedai.com
Dev OS v2: gates, a learning loop, and agents that check agents In v1 I treated ~/.claude as an operating system around the model: a kernel (one rulebook), a scheduler (lanes), interrupts (hooks), a package manager (pinned skills). I asked you to run the starter kit for a week and tell me what broke. I ran it too, every day. 213 commits later, this is the v2 release, and its main change fits on one line: > A rule the agent reads is a request. A rule something runs is a gate. Both commenters on v1 had said the same thing. Here is what that changed, in order of how much it helped. The gates, hooks, agents and tests below ship in the kit (135 checks, bash tests/run.sh); the rest is how I run my own setup. The kit works with any agent that reads AGENTS.md (Codex, Cursor, Copilot), not only Claude Code. 1. One rulebook, every agent The kernel is the same: one CLAUDE.md whose first section says it overrides every skill, plugin and repo file. What's new is that AGENTS.md is a symlink to it. ln -s ~/.claude/CLAUDE.md ~/.codex/AGENTS.md # Codex reads ~/.codex/AGENTS.md, then one per folder, root → cwd I checked how each tool loads it on 2026-11-01: - Codex concatenates AGENTS.md files up to 32 KiB by default. A long global rulebook steals room from repo rules. Mine is capped at 136 lines by a test. - Claude Code reads AGENTS.md only in a repo with no CLAUDE.md, so CLAUDE.md stays the source. - @lessons.md imports are Claude-only. Through the link, Codex gets the rulebook but not its imports. 2. Gates beat reminders A test gate in plain git. v1's pre-commit hook only guarded ~/.claude itself. v2 installs one per project: echo 'npm test' > .dev-os-test && ~/.claude/bin/gate-install The hook it writes (condensed from bin/gate-install): TOP=$(git rev-parse --show-toplevel) unset GIT_INDEX_FILE GIT_DIR GIT_WORK_TREE GIT_PREFIX CMD=$(cat "$TOP/.dev-os-test" 2>/dev/null) if ! printf '%s' "$CMD" | grep -q '[^[:space:]]'; then echo "dev-os test gate: .dev-os-test is missing or empty; commit refused" >&2; exit 1 fi (cd "$TOP" && bash -o pipefail -c "$CMD") || { echo "dev-os test gate: commit refused" >&2; exit 1; } Every line there is a bug I hit: - pipefail: npm test | tail -5 exits with tail's 0, so a red suite commits. - Empty means refuse: a missing or empty test command fails loudly instead of passing quietly. - unset GIT_INDEX_FILE: git runs pre-commit with a temporary index during commit -a. A test suite that runs git add in a temp repo writes into your commit and breaks it with "Error building trees". - No global hooks: the installer refuses when a global core.hooksPath would turn one repo's gate into every repo's gate. Permissions the agent can't talk past. permissions.ask rules still prompt under --dangerously-skip-permissions, and compound commands are split before matching: "permissions": { "ask": ["Bash(git push:*)", "Bash(gh pr create:*)"] } One catch: rules match the command text, so git -C . push slips past Bash(git push:*). I add Bash(git -C * push *) in my own settings. Keep branch protection on the remote as the backstop. A Stop hook for the cheap way out. v1's Stop hook sent the agent back when source changed with no test. v2 adds one more case: a weakened test. That means fewer assertions, a new .skip/.only, or a deleted test file. ASSERT = re.compile(r"\bassert\w*\s*\(|\bexpect\s*\(|->assert\w*\(|\$this->assert|^[-+]\s*assert(_\w+)?\s") SKIP = re.compile(r"markTestSkipped|markTestIncomplete|->skip\(|\.(skip|only|fixme)\s*\(|\bx(it|describe|test)\s*\(") if removed_asserts > added_asserts or any(SKIP.search(l) for l in added): weakened.append(path) # → {"decision": "block", "reason": "TEST WEAKENED: …"} Codex hooks use the same Stop → {"decision":"block"} shape. 3. It learns by itself In v1, "add a line to lessons.md" depended on me remembering to do it. Now the setup logs its own mistakes: prompt starts "no, …" / "I said …" ─┐ stop-check or test gate blocks ─┼─▶ state/learn-<session>.jsonl │ Stop: learn.sh → any entry newer than the last `reflect`? → block once: "run reflect" reflect routes each mistake to the lowest layer that would have caught it: first a test or hook, then one line in the skill that owns the job, and only last a line in lessons.md. lessons.md has a 60-line budget. When it fills up, meditate audits the rules for stale, duplicate and contradicting lines, and deletes nothing without my yes. 59 of the 213 commits are Lesson: commits, and many of them removed a lesson by turning it into a check. The loop gets tested like everything else. A cold review caught the correction detector flagging "No tests exist for the parser yet" as a correction. Now no counts only when followed by punctuation, and only the first line of a prompt is read. 4. Agents check agents One agent reviewing its own diff is a student grading their own exam. The kit ships two read-only agent shapes: - scout: one angle per scout (callers, tests, history, config). Each returns file:line facts and what it couldn't check. - review-lens: Skeptic always, Architect at 50+ changed lines, Minimalist at 200+. Then one verifier per finding that starts from "false positive". Two skills run them. pre-merge-review is relay step 7 on your own branch: lenses sized by the diff, a verifier per finding, one saved report. post-pr-review is for someone else's PR: each finding must reproduce on both the base and the PR branch before it goes in a draft, and nothing is posted without a yes. /code-review stays the per-slice check inside build-check, and it never posts on other people's PRs. Every subagent brief has the same fields: goal, scope, what's known, what's been ruled out, the exact ask, the output format, what's out of scope. Parallel builders get one git worktree each, and only for plan slices that share no files. How well does this work? On the v2 kit itself, which already passed all its own tests: | Pass | Found | |---|---| | /code-review | 9 (6 fixed, 3 left with reasons) | | 3 lenses, each reproducing its findings in a temp dir | 14 more | | a cold reviewer that saw none of the above | 4 more | Every behaviour fix got a red test first. 5. Prove it by running it 9. A bug or security claim counts only when reproduced by running it. No repro, no fix. For bugs, the first job is a red-capable feedback loop, in the order from Matt Pocock's diagnosing-bugs: failing test → curl script → CLI snapshot diff → headless browser → replayed payload → harness → fuzz → git bisect run. Hypotheses come after. I also break every gate on purpose before I trust it. That caught a test that passed before the code existed. My helper matched substrings, so rc=127 ("command not found") satisfied a check for rc=1. 6. Project memory: graph first Rule 8: before grep, ask a code graph "who calls this, and what breaks if I change it?" | Tool | Used for | |---|---| | graphify query / explain / path / merge-graphs | Finding code, explaining a node, call paths, one graph across repos | | code-review-graph get_impact_radius_tool | Who else a fix reaches (the no-regressions rule) | | get_review_context_tool, get_affected_flows_tool | Review context; which E2E flows a diff touches | The scouts, review lenses and review-reply step all start there. The graph holds structure. What the project taught lives in lessons.md and in plan folders kept outside the repo. 7. Stay lean - A context budget test: rulebook plus skill descriptions, measured in bytes, against a baseline. It went from 59,287 to 46,927 while the setup grew. - Routing is tested: one rulebook sentence ("call the owner skill before any other tool") took my routing eval from 0-1 to 7-8 of 11 prompts. - Effort is a budget too: "effortLevel": "medium" by default, in every modelSettings entry as well, since a per-model value wins. High effort lives in skill frontmatter only where a wrong answer is expensive: grilling, writing and checking the plan, whole-plugin bug hunts. Hooks can read the effort level but not set it, so serious cases are handled by a rule: payment or refund, data loss, auth or a security finding mean the verifiers are spawned with effort: "high". - Smaller output: RTK trims git/gh/test output before the agent reads it. Compressed output can hide the one line you need, so "never report a result you couldn't see" is a rule. The userland Most of my 103 skills are other people's work: 39 are pinned to an upstream commit in skills.lock, with local edits in overlays that a sync script re-applies. - ponytail by Dietrich Gebert: the smallest-change ladder (YAGNI → reuse → stdlib → platform → installed dep → one line). It's rule 3 in the kit. - Matt Pocock's skills: tdd, grill-me, handoff, domain-modeling. - obra/superpowers: brainstorming and systematic-debugging. - Trail of Bits: fp-check, variant-analysis and differential-review, for security claims. - e2e-reviewer: catches E2E tests that pass while the feature is broken. Skills use the Agent Skills format. Codex reads them from .agents/skills, and Claude Code from .claude/skills, so one folder with two symlinks serves both. Upgrade or start New: follow the kit's README "Start here". The core (rulebook, test gate, plan template) takes about 10 minutes, and the Claude Code layer is optional. From v1: the README has an "Upgrading from v1" block. Nothing was renamed. Two hooks and two skills get replaced after a "Before v2" commit, so it's one git revert to undo. Same ask as v1: run it for a week and tell me what broke. And what's the one rule your agent keeps breaking? I'll tell you which gate I'd put behind it.
code-review-graph: AI code reviews, 65x faster and cheaper. ⚡ Tech breakdowns, AI news, and future trends. Hit subscribe to stay ahead. This tool builds and incrementally updates a smart map of your codebase. It then feeds AI coding tools only the precise, relevant context needed for code reviews, rather than the entire project. By providing only compact, relevant code context, it drastically cuts down on the AI tokens consumed and speeds up review processes, making AI-powered code reviews significantly more cost-effective and efficient for businesses. 🔗 GitHub: tirth8205/code-review-graph 🌐 Website: letsmakeourworld.vercel.app 🎁 A 'Starter Guide: Optimizing AI Code Reviews for Cost & Speed.' 💬 Comment "DECODE03" below and we'll send you the link to try it yourself! 🔔 Subscribe for weekly deep dives on trending open source tools. #AI #Code Review #LLM Optimization #Developer Tools #Knowledge Graph #Productivity 🚀 Build with HyperAutomationLabs: Website: letsmakeourworld.vercel.app Source/demo repo: tirth8205/code-review-graph 🔔 Subscribe for more tech content from HyperAutomationLabs. 💬 Comment "CODE08" below to get A 'Starter Guide: Optimizing AI Code Reviews for Cost & Speed.' or tell us what use case you want us to build next. 📌 Timestamps: 0:00 Introduction #HyperAutomationLabs #tech #AI #Automation #BuildInPublic --- ⚠️ ARCHIVAL NOTICE & AGENT PRODUCTION DISCLAIMER: This video was researched, written, voiced, and edited autonomously by an AI documentary agent (ProjectNexus Autonomous Media Engine). Content is synthesized from public domain historical archives, declassified records, investigative news reports, and open cold case dossiers for educational, documentary, and historical preservation purposes. Living individuals mentioned are presumed innocent unless proven guilty in a court of law.