Code Archaeology skill for Codex
Find the commit, PR and reason behind any line. Codex answers 'why is this here?' with evidence instead of guesses. It blames past reformatting and moved code, uses pickaxe and function-history searches to find the introducing commit, follows it to the pull request, review thread and issue, and reads the tests added alongside. The answer separates stated intent from inference and checks whether the original reason still applies before suggesting removal.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- code-archaeology Installs to ~/.agents/skills/code-archaeology/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install code-archaeology The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project code-archaeology Installs to .agents/skills/code-archaeology/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/code-archaeology.zipunzip -o code-archaeology.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) code-archaeology PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $code-archaeology, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Finds out why code is the way it is from version control evidence - git blame that skips formatting commits and follows moved code, pickaxe searches with git log -S and -G, function history with git log -L, reverse blame for deleted lines, rename-following, and tracing commits to pull requests, issues and releases with gh. Separates proven intent from inference and judges whether the original reason still holds before anyone removes the code. Use when asked why a line, check or workaround exists, when code was added or removed, which release shipped a change, or whether a strange guard is safe to delete.
Use it when
- Someone asks why a line, guard or workaround exists
- You are about to delete code you do not understand
- You need the release or PR that introduced or removed a change
- Blame points at a reformat or file move instead of the real origin
Use something else when
- You need the exact commit that broke a test: use git-bisect
- You want a whole-repo orientation rather than one line's history: use codebase-onboarding
- You are rewriting or cleaning up commit history: use git-history-surgery
How to check the result
Each claim in the answer cites a commit SHA, PR or issue, inferences are labelled as such, and the repository was confirmed not to be a shallow clone before trusting blame.
The mistake it prevents
Trusting the first git blame result, which usually points at a formatter run or file move rather than the commit that actually introduced the logic.
An answer is done when it names the commit, pull request and (if any) issue that introduced the code, quotes the stated reason, says how confident you are and what is inference, and judges whether that reason still applies today. It describes decisions, not people: “the 2023 retry change” rather than “Sam’s hack”.
Check the history is complete
git rev-parse --is-shallow-repository # true in many CI and cloud checkouts
git fetch --unshallow # needs network; ask in an offline sandbox
git log --oneline | wc -l
A shallow clone makes blame stop at the graft point and attribute everything to one commit. Say so instead of drawing conclusions from it.
Workflow
- [ ] 1. Pin the exact lines and the question being asked
- [ ] 2. Blame, skipping whitespace, formatting and moves
- [ ] 3. Read the whole introducing commit, not only the line
- [ ] 4. Find the PR, review discussion and linked issue
- [ ] 5. Walk further back if the commit only moved or refactored the code
- [ ] 6. Check the tests added with it: they encode the intent
- [ ] 7. Decide whether the reason still holds; write the answer with evidence
Tool by question
| Question | Command |
|---|---|
| Who last changed these lines, ignoring noise? | git blame -w -C -C -C -L 120,140 -- src/http/client.py |
| Step past a commit that only reformatted | git blame <sha>^ -L 120,140 -- src/http/client.py |
| When did this string or constant appear or disappear? | git log -S'MAX_RETRIES = 3' --oneline -- src/ |
| When did lines matching a pattern change at all? | `git log -G’retry_(after |
| Full history of one function | git log -L :fetch_with_retry:src/http/client.py |
| History of a line range | git log -L 120,140:src/http/client.py |
| History across renames | git log --follow --oneline -- src/http/client.py |
| When was this file deleted? | git log --diff-filter=D --oneline -- '**/legacy_auth.py' then git show <sha>^:path |
| Where did a deleted line go (last commit it existed in)? | git blame --reverse <old-sha>..HEAD -L 50,60 -- path |
| Commits mentioning a ticket | git log --grep='PAY-1432' -i --oneline |
| Mainline story only (skip feature-branch noise) | git log --first-parent --oneline main -- path |
| Which releases contain a commit? | git tag --contains <sha> | head, git describe --contains <sha> |
| Is it on a given branch? | git merge-base --is-ancestor <sha> origin/release/2.4 && echo yes |
Notes:
-Sfinds commits where the number of occurrences changed (added or removed); it misses commits that edited a line but kept the string.-Gmatches any added or removed line matching the regex. Add-pto see the hunks; restrict to paths on big repos for speed.-C -C -Cmakes blame look for lines moved or copied from other files in any commit, so the original author of moved code shows up instead of the mover.- Configure the repo’s formatting commits to be skipped automatically:
git config blame.ignoreRevsFile .git-blame-ignore-revs(the file lists full SHAs; GitHub’s blame view honours it too).
From commit to discussion
git show --stat --format=fuller <sha> # full message, date, files
gh api repos/{owner}/{repo}/commits/<sha>/pulls --jq '.[] | "\(.number) \(.title) \(.html_url)"'
gh pr view <number> --comments # description and review thread
gh pr view <number> --json closingIssuesReferences --jq '.closingIssuesReferences[].url'
These need network and gh auth. Squash-merged commits usually end with (#123) in the
subject, which is a faster route to the PR. For tickets in Jira or Linear referenced by
ID, ask the user for the content rather than guessing it from the ID.
Other sources worth checking: ADRs (docs/adr/, docs/decisions/), CHANGELOG.md
around the release that shipped it, code comments containing ticket IDs, and the test
added in the same commit. A regression test named after a bug is the strongest evidence
of why a guard exists.
Weighing the evidence
| Evidence | Confidence |
|---|---|
| Commit message or PR description states the reason | High |
| Regression test added in the same commit reproduces a specific failure | High |
| Linked issue describes an incident or bug | High |
| Review comment requested the change | Medium-high |
| Only the diff, no message (e.g. “fix”) | Low: you are inferring from code |
| Commit is a move, rename or reformat | None yet: keep digging past it |
Label inferences explicitly: “Inferred: the 30-second timeout matches the upstream gateway’s limit at the time; no commit or PR states this.”
Does the reason still hold?
Before recommending removal (a fence you do not understand stays up):
| Original reason | Check today |
|---|---|
| Workaround for a library bug | Is the library version now past the fix? Find the upstream issue status and changelog |
| Guard against bad data from a source | Does the source still exist? Query or ask whether such data still arrives |
| Performance hack | Re-measure; the bottleneck may have moved |
| Compatibility with old clients or API versions | Check usage metrics or logs for those clients |
| Incident fix | Read the postmortem; is the root cause addressed elsewhere? |
If the evidence is low-confidence, recommend a safe removal path (feature flag, logging when the branch is hit, staged rollout) rather than a direct delete.
Gotchas
- Blame shows the last change, not the origin. The interesting commit is often three steps back behind a reformat and a file move.
- Rebased or cherry-picked commits carry new SHAs;
git log --grepon the subject orgit log --cherry-markhelps find the twins on other branches. - Merge commits hide changes from
git log -pby default; use--diff-merges=first-parentwhen a conflict resolution introduced the line. - Do not rewrite history to “clean up” what you find. Archaeology is read-only.
- Author names are for finding context, not for blame. If the person is still around, suggest the user ask them; do not contact anyone yourself.
Output
## Why does `fetch_with_retry` sleep 2.5 s before the third attempt?
**Answer:** Added to stay under the payment provider's rate limit after the
2024-03-14 incident (high confidence).
**Evidence**
1. `a1b2c3d` (2024-03-15) "Back off before third retry to avoid provider 429 storm" - PR #2211
2. PR #2211 links issue #2198 (incident: 40k 429 responses in 6 minutes)
3. Same commit adds `test_third_retry_waits_for_rate_limit_window`
4. `e4f5a6b` (2025-01) only moved the function to `http/client.py` (blame -C confirms)
**Still valid?** Partly: provider docs now return `Retry-After`; honouring that header would
replace the fixed sleep. Recommend changing the sleep to read `Retry-After`, keeping 2.5 s as fallback.
**Unknowns:** Why 2.5 s specifically; nothing in the PR explains the number (inferred from limit window). What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Code Archaeology"
short_description: "Find the commit, PR and reason behind any line"
default_prompt: "$code-archaeology Why does this function sleep before the third retry? Find the commit and PR that added it" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.