Refresh docs/CODE-MAP.md, the lines-of-code-by-area snapshot of the repository — regenerate its tables with `npm run gen:code-map`, teach the counting rules about new areas and misplaced files, rewrite the prose to match the new numbers, and flag areas whose growth deserves an issue. Use when asked to refresh, update, or reconcile the code map, before an exhaustive whole-repo audit-code pass that shards by map area, or when the map's snapshot commit is weeks behind main.
Installs into .claude/skills of the current project.
Are you the author of Reconcile Code Map?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/kylemit-reconcile-code-map)
---
name: reconcile-code-map
description: Refresh docs/CODE-MAP.md, the lines-of-code-by-area snapshot of the repository — regenerate its tables with `npm run gen:code-map`, teach the counting rules about new areas and misplaced files, rewrite the prose to match the new numbers, and flag areas whose growth deserves an issue. Use when asked to refresh, update, or reconcile the code map, before an exhaustive whole-repo audit-code pass that shards by map area, or when the map's snapshot commit is weeks behind main.
---
# Reconcile the code map
`docs/CODE-MAP.md` has two halves. The tables are generated by `npm run gen:code-map` from the rules
in `tools/code-map/lib/code-map-rules.mjs`; never edit them by hand. The prose around them — the
Method section and the notes — is this skill's job. The run is: regenerate, check where new files
landed, fix the rules, regenerate again, then rewrite the prose.
## 1. Start from committed main
1. Work on a fresh branch from the latest `origin/main`. The generator reads file contents from a
commit, not the working tree, but runs the rules from the checkout — so it refuses to write the
map while `tools/code-map/` differs from the counted commit. Commit rule edits before generating
the map that uses them.
2. Record the previous snapshot commit from the map's header line (`Snapshot of <sha> (<date>)`).
Every comparison below is against that commit.
## 2. Regenerate and catch unmapped paths
Run `npm run gen:code-map`. If it throws `UnmappedPathError`, a new top-level directory appeared
(this is also what fails `tools/code-map/tests/code-map-rules.test.mjs`). Decide what the directory
is before writing the rule:
* **Authored source, docs, or config:** a new entry in `AREAS`. Give it a sub-bucket function so it
splits once it passes the threshold.
* **Captured output, media, or generated data:** an entry in `EXCLUSION_CLASSES`, or add its root to
`EVIDENCE_ROOTS` / `VECTOR_ART_ROOTS` if it matches an existing class. A tree that mixes both,
like `perf-profiles/`, is an area whose data files are excluded by extension.
## 3. Review where new files landed
List the files added since the previous snapshot and their placement:
```bash
npm run --silent gen:code-map -- --assignments > /tmp/code-map.tsv
git diff --name-only --diff-filter=A <previous-sha> HEAD > /tmp/code-map-new.txt
awk -F'\t' 'NR==FNR{added[$1]=1;next} added[$1]' /tmp/code-map-new.txt /tmp/code-map.tsv
```
Read the new rows, not the whole inventory. What drifts between runs:
* **`web/src` files caught by a fallback rule.** The TSV's last column is the rule that placed the
file. The four directory-wide fallbacks (`lib/components/*` → Core UI controls, `lib/state/*` →
App state, `lib/*` → Focused utilities, and the `^/` catch-all → Routes / app shell) are
deliberately broad. A file whose feature owns it — a new AI component, a coloring-book state
module — gets a precise rule above the fallback. A generic control or state module where the
fallback is right needs no rule.
* **Large measured files that are data.** Sort the new rows by the `lines` column. A measured file
of thousands of lines is usually captured output, a traced SVG, or a recorded fixture that an
exclusion should cover. Hand-written code and specs of that size are real and stay.
* **New sub-buckets.** A new `tools/` or `docs/` subtree appears on its own; it needs a label only
when the directory name alone would mislead.
* **Dead rules.** The generator warns about any `web/src` domain rule that matched no file. Delete
or retarget it — a rename usually means the pattern needs the new name.
Leave alone: a co-located test follows its subject automatically; the `.ruler/` instruction source
nested in an area is counted there on purpose; and moving an existing file between domains because
the number looks better is not a fix.
A rule change that alters *what counts* (a new exclusion, a new evidence root) is a Method change:
record it in the Method section in step 5. A change that only alters *where* a file counts belongs
in the rules module alone.
## 4. Commit the rules, then regenerate from that commit
Run `npm run test:tools -- code-map`, commit the rule changes, then run `npm run gen:code-map` again
so the snapshot line names a commit that contains the rules that produced it. Re-run the generator
on that commit after any further rule edit.
## 5. Rewrite the prose
Diff the tables against the previous snapshot (`git diff <previous-sha> -- docs/CODE-MAP.md`) and
update the prose around them:
* **Method** — every exclusion class and measured category the rules now apply. The coverage table
names the classes; the prose says what each covers.
* **Notes worth carrying forward** — rewrite them against the new numbers: the headline growth,
which areas moved sharply and why (name the subtree or domain that drove it), which areas and
sub-buckets are new or gone. Say which snapshot the comparison is against. Drop notes the numbers
no longer support rather than letting stale figures ride along.
* The drawing and AI subdomain definitions are generated from `DOMAIN_SUBDIVISIONS`; edit them
there.
Run `npm run format:check` after editing the Markdown.
## 6. Flag growth that deserves an issue
The map finds work; it does not do it. For an area or domain that grew sharply, check whether the
growth is intended before filing anything:
* Intended and already explained (a campaign's evidence, a planned subsystem): a note in the map is
enough.
* Unexplained or accidental — generated output committed as source, a scratch tree nobody prunes, a
domain growing past what its feature justifies: open an issue per `docs/ISSUE-WORKFLOW.md` with
the numbers and the snapshot commits, or list it in the PR for the user to file.
## 7. Ship
One PR: the rule changes, the tests if a rule's contract changed, and the regenerated map. The body
lists the unmapped paths resolved, the fallback placements you overrode, any Method change, and the
growth flagged in step 6.