Code archaeology
A comprehensive SWE workflow, encoded. Might be useful to you too.
npx -y skills add SWEStash/swe-workflow-skills --skill code-archaeologyAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Understand unfamiliar or legacy code before changing it — map entry points, mine git history (blame, churn, log -S), trace data flow, recover the why behind odd code, pin current behavior with characterization tests, find seams for safe change. Triggers: understand this codebase, legacy code, inherited this project, what does this code do, why is it written this way, nobody knows how this works, onboard to this repo, is it safe to change this. Prioritizing debt → technical-debt-review; improving code you already understand → refactoring.
SKILL.md
5.5 KB, as published. Nobody here has run it
Code Archaeology
Build a working model of code nobody fully understands — before changing it.
The cardinal rule: the code is the way it is for reasons; find them before
overriding them. Chesterton's fence applies — weird code is usually a bug fix
whose bug report is lost, and "cleaning it up" reintroduces the bug. Boundary
with siblings: technical-debt-review assesses and prioritizes what to fix;
refactoring improves code you already understand; this skill produces the
understanding both depend on.
Workflow
Step 1: Survey Before Digging
Get the shape of the territory without reading line-by-line: entry points (main, routes, handlers, cron, consumers), the dependency skeleton (what are the load-bearing modules — imported by everything), build/run/test commands (does the test suite even pass? that's data), and the directory map with sizes. Resist starting at file one and reading forward — comprehension follows the call graph, not the alphabet.
Step 2: Mine the History — the Code's Memory
Git knows what the docs forgot. The high-yield digs:
git log --follow -p -- <file>— a file's life story; the commit that introduced the odd code usually says why (and links a ticket).git log -S '<string>'(pickaxe) — when a magic value or weird guard appeared, and what else changed with it.- Churn analysis — files with the most commits are the active organs
(
git log --format= --name-only | sort | uniq -c | sort -rn | head); high-churn + large = where understanding pays most (same hotspot logic astechnical-debt-review). git blame -w -C(ignore whitespace, follow copies) — who last touched this line and in what commit context; blame the commit, then read its message and siblings.- Merge/PR references in messages — the review thread often holds the design discussion that never made it into the code.
Step 3: Trace, Don't Guess
For the specific behavior you need to understand, follow the data: pick one concrete input (a request, an event, a row) and trace it end to end — through handlers, transformations, side effects, and persistence. Use the debugger or strategic log statements over static reading when the control flow is dynamic (dispatch tables, DI containers, metaprogramming). Write the trace down as you go; a data-flow narrative ("the order enters here, gets enriched here, forks here") is worth ten class diagrams.
Step 4: Interrogate the Oddities
For each "why on earth" you hit, run the checklist before concluding it's senseless: What does history say (Step 2)? Does a test encode it as intended behavior? Do comments/tickets/ADRs reference it? Does production data depend on it (that dead-looking branch may handle the 2019 records)? Only after all four come up empty may you suspect it's vestigial — and even then you prove it (logging/telemetry on the branch) rather than assume it.
Step 5: Pin Behavior with Characterization Tests
Before changing anything you don't fully understand, write tests that capture
what the code currently does — not what it should do. Feed it
representative inputs (including the weird ones from production), assert the
observed outputs, and lock in today's behavior as the baseline. These tests
are your tripwire: if a "safe cleanup" changes an output, you learn it in CI,
not in production. Golden-master/snapshot testing works well when outputs are
large or numerous. (For designing the suite around them long-term:
test-suite-design.)
Step 6: Leave the Map Better Than You Found It
Record what you learned where the next archaeologist will find it: a short
architecture note or README-in-the-directory (the data-flow narrative from
Step 3, the load-bearing oddities from Step 4 and why they exist), backfilled
ADRs for the big recovered decisions (architecture-design), and comments only
on the genuinely non-obvious constraints. Then, with understanding and
characterization tests in place, changes proceed via refactoring (seams,
safe transformations) or dependency-impact-analysis (blast radius) as normal.
Principles Applied
- Chesterton's fence: understand why the fence is there before removing it; lost context is not absent context.
- Evidence over inference: history, traces, and tests beat reading-and- guessing — the code's actual behavior outranks anyone's model of it.
- Capture as you go: understanding that lives in one head (or one session) is re-excavated at full cost next time.
Cross-Skill References
technical-debt-review— assess and prioritize what to fix once understoodrefactoring— the safe-change patterns applied after comprehensiontest-suite-design— growing characterization tests into a real suitedependency-impact-analysis— blast radius before changing a shared piecearchitecture-documentation— recording the recovered architecture (C4, flows)bug-investigating— when the goal narrows to one specific misbehavior
Gives 0 of the 12 instructions most refactoring skills give
Counted across 521 of the 525 authors here whose files we hold, read 2026-08-06
- run tests after each changein 59 of 521, across 56 files
- write tests before refactoringin 27 of 521, across 24 files
- preserve external behaviorin 26 of 521, across 22 files
- remove dead codein 25 of 521, across 24 files
- make small incremental changesin 20 of 521, across 17 files
- break the implementation into tiny commitsin 18 of 521, across 5 files
- ask the user about alternative optionsin 17 of 521, across 4 files
- create a GitHub issue with the planin 17 of 521, across 4 files
- explore the repository to verify assertionsin 17 of 521, across 4 files
- interview the user about the refactorin 16 of 521, across 3 files
- check the codebase for test coveragein 16 of 521, across 3 files
- refactor one thing at a timein 16 of 521, across 12 files
Said here and by no other author read
- trace one concrete input end to end
- write down the data-flow narrative as you trace
- investigate the history of odd code before removing it
- record recovered context in architecture notes
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once.