Map an Unfamiliar Codebase
Activated Cloud✓ Officialactivated/map-unfamiliar-codebase
Free · MIT
About
Builds a working map of a repository you have not worked in: what it does, how it is laid out, the exact commands to install, run, test, lint, type-check and build it, a baseline of what already passes, the entry points, one traced request, and the conventions to copy. Use before your first change in a repo, when asked how something works, or when picking up a project. Not for planning a specific change (use plan-code-change) or chasing a bug (use debug-root-cause).
Documentation
Map an Unfamiliar Codebase
Before you change code you have never seen, learn how the project builds, tests and hangs together, and record it so neither you nor a teammate has to rediscover it. The standard: every command in your map has been run by you with its exit code noted, every claim about the code cites a file path, and the baseline test result is written down before you touch anything.
When to use
- "Take a look at this repo", "get familiar with the codebase", "how does checkout work in here?"
- You are about to make your first change in a repository.
- A teammate hands you a project and you do not yet know its test command.
- You came back to a repo after a long gap and the tooling may have changed.
What you need
- The code. Repository access comes from the owner's GitHub or GitLab connected app (Connections page) or a git credential the owner set up on your computer. If neither is there, ask the owner with
clarifyto connect one or to send an archive of the code. Never paste tokens into commands, URLs or notes. - Somewhere safe to run it: your own computer, never a production server.
- Any notes from earlier work: check
memoryandsession_searchfor this repo's name first.
Method
Get a clean checkout and its state.
git clone <url> && cd <repo> # or cd into the existing checkout git status --short; git branch --show-current; git log --oneline -15; git remote -vIf the working tree is dirty and the changes are not yours, stop and ask before touching it.
Read the house rules first.
read_filethe README, CONTRIBUTING, any agent or contributor instructions file at the root (for exampleAGENTS.md),docs/development*, and the pull request template. These often name the one true test command and things you must never do.Identify the stack from manifests. Use
search_fileswithtarget='files'forpyproject.toml,requirements*.txt,package.json, lockfiles,go.mod,Cargo.toml,pom.xml,build.gradle*,Gemfile,composer.json,Makefile,justfile,Taskfile.yml,Dockerfile,compose*.yml,.tool-versions,.nvmrc,.python-version. The lockfile tells you the package manager (package-lock.jsonnpm,pnpm-lock.yamlpnpm,yarn.lockyarn,bun.lockbbun,uv.lockuv,poetry.lockpoetry). A monorepo has several manifests: note which directory each command must run from.Find the real commands, in this order of trust.
- CI config (
.github/workflows/*.yml,.gitlab-ci.yml,.circleci/config.yml): what CI runs is what counts. - Task runners:
Makefiletargets,package.json"scripts",tox.ini,noxfile.py,justfile,[tool.*]tables inpyproject.toml. - Contributor docs.
- Stack conventions from
references/stack-commands.md. Write down install, run, test-all, test-one, lint, format-check, type-check and build. Include how to run a single test: you will need it constantly.
- CI config (
Check before you run. Look at
.env*, config files and test settings for real credentials or production URLs. Tests must point at local or throwaway services. If a test suite would touch a real database, payment provider or email sender, stop and ask.Establish the baseline. Install dependencies in a project-local environment (
uv sync,python -m venv .venv,npm ci,go mod download,cargo fetch), then run the full test suite, linter and type checker once:<test command>; echo "exit=$?"Record pass and fail counts, duration and every pre-existing failure by name. Later you will compare against this, so a failure that was already there is never blamed on your change. Long suites: run with
terminal(background=true, notify_on_complete=true)and keep reading code meanwhile.Map the layout. List top-level directories and give each a one-line job.
git ls-files | awk -F/ '{print $1}' | sort | uniq -c | sort -rn | head -20 git ls-files | sed -n 's/.*\.//p' | sort | uniq -c | sort -rn | head -10Skip generated and vendored trees (
node_modules,vendor,dist,build,.venv,target) in every search.Find the entry points.
mainfunctions,cmd/folders,[project.scripts]inpyproject.toml,"bin"/"main"inpackage.json, app factories, route tables, job and queue workers, cron definitions, CLI parsers.search_filesfor patterns such asif __name__ == "__main__",func main(),app =,createServer,@app.route|router\.,fn main().Trace one real flow end to end. Pick one user-visible action and follow it from entry point to storage and back with
read_file, writing down each hop asfile:function. One honest trace teaches more than skimming fifty files.Learn the conventions to copy. Error handling, logging, config loading, naming, test layout and fixtures, formatter and linter settings (
.editorconfig,ruff.toml,.eslintrc*,.prettierrc*,rustfmt.toml). Read the last three meaningful commits to see what a normal change looks like:git log -3 --stat --no-merges git show <sha> --statDo changes ship with tests? With changelog entries? With migrations?
Find the risky ground. Hot files and owners:
git log --since=6.months --name-only --format= | sort | uniq -c | sort -rn | head -15 git shortlog -sn --since=1.year -- <path>Read
CODEOWNERSif present. Hot, large, untested files are where changes break things.Split big repos. For a large monorepo,
delegate_taskone subsystem per subagent with explicit questions ("What are the entry points of services/billing, how are its tests run, what does it depend on? Cite file paths."). Then spot-check their claims by reading the cited lines before you put them in your map.Save what lasts. Write durable facts (commands, quirks, pre-existing failures, where things live) to
memoryunder the repo's name. Do not store secrets or anything that will be stale next week.
Output
A code map in the shape of references/codemap-template.md: purpose, stack and versions, a commands table with exit codes, the baseline, layout, entry points, one traced flow, conventions, risky areas and open questions. Keep it under two screens. If the owner asked a specific question ("how does checkout work?"), answer that first in a few sentences with file paths, then attach the map. Use show_card for the commands table when the owner is watching.
Checks before you finish
- Every command in the map was run by you, and its exit code is recorded.
- The baseline lists pre-existing failures by name, or says "none".
- Every statement about behaviour cites at least one file path.
- Tests did not touch any real external service.
- Durable facts are saved to
memory; secrets are not.
Pitfalls
- Trusting the README over CI. READMEs rot; workflows run on every push. When they disagree, CI wins, and note the drift.
- Running the suite against real services. Read the test config first. One test that sends real email or charges a real card is one too many.
- Installing globally. Use a virtualenv,
npm ciinto the project, or the version the project pins. Global installs make "works on my machine" bugs. - Searching vendored code. Results from
node_modulesorvendordrown the real answer. Exclude them. - Assuming the framework from one file. Confirm with the manifest and an entry point.
- Skimming instead of tracing. A list of directories is not understanding. Trace one flow.
- Forgetting the monorepo root. A command that works in one package may fail at the root, or vice versa. Note the working directory for each command.
Versions
Listed from the source repository.
Reviews
No reviews yet. Be the first.
