codemap — read the whole plot before translating a line
A translator does not translate sequentially. They read the whole work first: the plot, the scheme, the correlations, the ramifications. They build a map. Then they translate, clinging to the map. Doing it the other way round produces fluent sentences that get the book wrong.
The same is true of code. Working without a map produces the signature failure: you port a function, trip over its caller, stop, instrument, diagnose, and rediscover a rule that was written down in the source all along. Every hour of that is an hour spent re-deriving what you could have read.
This skill is a gate. Complete the map before making the first behavioural change.
When it applies
- Porting or translating an implementation to another language.
- Reproducing another implementation's output exactly (parity work, golden fixtures).
- Any substantial change in a codebase you cannot already draw from memory.
Not for a one-line fix in code you know.
The map is a written artifact
Not notes in your head, not a summary in a reply that scrolls away. A file in the repo —
docs/PORT-MAP.md, docs/CODEMAP.md — that you re-read and update as you work. If it is
not on disk, you do not have a map.
Procedure
1. Read what the authors already wrote about their own code
Do this FIRST, before any source file. It is the cheapest and most concentrated information in the repository, and it is the step most often skipped.
ls README* ARCHITECTURE* CONTRIBUTING* AGENTS* CLAUDE* docs/ adr/ rfc/ 2>/dev/null
find . -maxdepth 2 -iname "FINDINGS*" -o -iname "*DESIGN*" -o -iname "*METHOD*" \
-o -iname "KNOWN*" -o -iname "*NOTES*" | head -40
git log --oneline -40 # the authors' own account of what changed and why
Engineering logs, design docs, findings reports and ADRs tell you why the code is shaped as it is, which no amount of reading the source will give you. They also list the known gaps (§5), so you do not chase targets the reference itself never reached.
2. Find the spine
The entry point and the sequencing function — often small, often the highest-value file in the repo. It names every stage in order and shows what mutates the parameters before the stages run. Read it completely.
3. Enumerate the ROUTES, not just the steps
The failure this catches: assuming there is one path through the system. Ask what distinct routes an input can take, and what decides between them. A system with a "general path" and a "special-cased fast path" will have you optimising the general one for an input that never takes it.
For each route: what triggers it, what it produces, and where its outputs are counted.
4. Determine empirically which route each input takes
The docs tell you routes exist; measurement tells you which one your case uses. Use the
reference's own diagnostics — most mature codebases have env-var or flag-gated tracing;
grep for getenv, --verbose, DIAG, --debug.
Build a table: input → route → why. This one table prevents the most expensive class of mistake.
5. Decode where every observable output comes from
For parity work especially: each number you must match has exactly one producer. Trace it. A counter that will not move under any local change is a routing error, not a tuning problem.
6. Record the known gaps
What the reference itself does not achieve — documented limitations, partial support, targets it misses. Without this you will burn days trying to exceed the thing you are copying.
7. Only now, plan and verticalize
With the map written, run ai-intuition before choosing the first task: it compresses
the map into one claim plus a few arms and makes them predict, which is what turns the map
from something you consult into something you can derive from. Then pick the order of work
from the dependency structure rather than from where you happened to trip.
Rules that follow from having a map
- Translate, do not paraphrase. A faithful translation of a deterministic reference reproduces it exactly. A paraphrase of what a function "seems to do" is a new implementation with new bugs. If you cannot translate a function, read its caller — do not guess its contract.
- Read before instrumenting. Instrumentation tells you that something is wrong; the source tells you why, and usually says so in a comment.
- Milestones are a delegation unit, not a porting unit. Slice work for gating and review; do not let the slices dictate what you read.
- The map is maintained. When a measurement contradicts it, fix the map in the same breath as the code, or the next session inherits your wrong model.
Cost
Reading a few thousand lines of docs and a spine file costs far less than one wrong verticalization. On the mesh2step port, the map — once built — showed in a single table that the fixture under repair took an entirely different route through the engine than the code being repaired, after hours had gone into the wrong path.