the tool that drew this, drawn by itself
| Repository | show-me |
| Revision | main @ af7d5f27 |
| Structures | 19 in 6 districts |
| Connections | 28 |
| Measured | 19 source files, 6,046 lines |
| Scope coverage | 19/19 files claimed |
| Chapters | 7 |
| Traced flows | 3 |
Open the interactive map — the same content, explorable.
Generated from
system-map.json. Do not edit this file — edit the map and regenerate, or the two views will disagree. Every citation below was verified against the revision named above at generation time.
This skill turns a codebase into a picture you can trust. The design is one idea: an agent reads the code and writes down what it found, and scripts do only the things a careful reader reliably gets wrong.
Nothing here parses source. That is deliberate, and it is what makes the skill work on any language without configuration. An earlier version shipped detectors that extracted relations with regular expressions; every false relation it produced came from a pattern misreading code, it needed new rules for every stack, and the one genuinely valuable thing it did turned out to need no language knowledge at all.
What the scripts keep is the work reading cannot do. Opening ninety cited files to check every quotation is exactly the tedium a reader skims. Counting lines is arithmetic, and the moment a building size is estimated the picture becomes decoration. Placing buildings so that no connection ever crosses a footprint is a geometric invariant with a test behind it.
The sharpest of them is the coverage check, because it catches the failure a reader cannot catch in themselves: reading a directory, feeling finished, and moving on. That feels identical to having finished. Subtracting claimed files from files in scope has no such blind spot, and on this project it surfaced a whole subsystem in a directory the author had already read.
Scope. The whole skill, read from its own directory: the instructions an agent follows, the citation gate, the measuring and drawing pipeline, the published page runtime, and everything the pipeline emits.
The map reveals the system a few structures at a time. This is that order, so the document can be read the same way.
The skill begins as prose, not code.
Everything else here serves one document. It states the steps and the two rules that cannot be bent. It also points at three companions: the shape of the data file, how to find structure by reading code, and what each shape on the finished map means.
Nothing in this district reads code itself.
Introduces. The instructions, The contract, How to read, The visual language
A claim that cannot be checked is decoration.
The agent writes a map; the gate opens every file it cites and confirms the quoted line is really there. That is the whole trust model, and it is why someone who has not read the code can believe the picture.
Its own tests mutate a good map into eleven specific lies and assert each is caught.
Introduces. The citation gate, The gate self-test, The citation helper
Building sizes are counted, never chosen.
Metrics resolves the globs a structure claims and counts files and lines. Geometry turns those counts into shape: height is lines of code on a square-root scale, footprint is file count.
There is no field an author could use to make a building bigger than its code.
Introduces. Measuring, Projection and mass, The scaffold
Placement is deterministic, and edges provably never cross a footprint.
Each district gets a band of rows, ordered inside by how deep a thing sits in the dependency chain. Connections travel only in the reserved gaps between buildings.
That is the single reason the picture can draw every line before every building and never work out which is in front. A test checks that rule holds rather than trusting the argument for it.
Introduces. Placement and routing, The scene, The layout invariants
The output is one file with nothing to install.
The renderer runs the gate again, measures, lays out, emits the scene, and inlines the theme and the interaction layer into a single ASCII-only file. Same map in, same coordinates out, so two renders are diffable.
The page you are reading is that output.
Introduces. The assembler, The interaction layer, The theme
Flow shown. From map to page — A validated map becomes one self-contained HTML file: gated, measured, placed, drawn, then inlined.
Read the code, verify the claim, measure it, draw it.
Three things come out of one data file. The page you are looking at, the same map written as a document, and a short animation of one path for a README. All generated, so none can drift from the others.
The example maps close the loop: they are what the pipeline produces, and one of them is this map of the tool itself. The guard scripts run against them, so the artifacts are also the fixtures.
Introduces. The example maps, The text twin, The flow preview
Flow shown. Rejecting a fabricated map — A real map is corrupted eleven ways and the gate must catch every one of them.
One claim is checked by a machine, not by a reader.
Most of what a map claims is checked by a person reading it. One claim is checked by a machine, every time: no connection ever crosses a building. Watch it being proven over the finished field.
Introduces. Nothing new — this is the whole system at once.
Flow shown. Proving edges never cross — Every shipped map is re-laid-out and checked: no connection may enter a building footprint.
| Structure | Kind | Files | Lines | Depended on by | |
|---|---|---|---|---|---|
INS |
The instructions | types and constants | 1 | 284 | 0 |
SCH |
The contract | types and constants | 1 | 250 | 1 |
EXT |
How to read | types and constants | 1 | 137 | 1 |
VIS |
The visual language | types and constants | 1 | 93 | 1 |
| Structure | Kind | Files | Lines | Depended on by | |
|---|---|---|---|---|---|
VAL |
The citation gate | entry point | 1 | 637 | 6 |
GT |
The gate self-test | entry point | 1 | 193 | 0 |
CIT |
The citation helper | entry point | 1 | 102 | 0 |
| Structure | Kind | Files | Lines | Depended on by | |
|---|---|---|---|---|---|
MET |
Measuring | service | 1 | 213 | 3 |
GEO |
Projection and mass | service | 1 | 159 | 6 |
SCA |
The scaffold | entry point | 1 | 162 | 0 |
| Structure | Kind | Files | Lines | Depended on by | |
|---|---|---|---|---|---|
LAY |
Placement and routing | service | 1 | 375 | 3 |
SVG |
The scene | service | 1 | 210 | 2 |
LT |
The layout invariants | entry point | 1 | 143 | 0 |
| Structure | Kind | Files | Lines | Depended on by | |
|---|---|---|---|---|---|
RND |
The assembler | entry point | 1 | 315 | 1 |
APP |
The interaction layer | client | 1 | 792 | 1 |
CSS |
The theme | types and constants | 1 | 523 | 1 |
| Structure | Kind | Files | Lines | Depended on by | |
|---|---|---|---|---|---|
EXM |
The example maps | store | 1 | 1,054 | 2 |
TWN |
The text twin | service | 1 | 233 | 0 |
PRV |
The flow preview | service | 1 | 171 | 0 |
types and constants · 1 files · 284 lines
The whole method, written for an agent about to map something. It sets out the seven steps, the two rules that cannot be bent, and the division of labour that everything else follows.
How it's built. A single Markdown file with YAML frontmatter naming the skill and describing when to reach for it. It states the pipeline as shell commands and delegates the detail to three reference documents rather than restating it.
Connections.
- imports types from The contract (the contract)
SKILL.md:62—Read 'references/schema.md' before writing any JSON - imports types from How to read (how to read)
SKILL.md:63—Read 'references/extraction.md' for how to find structure by reading - imports types from The visual language
SKILL.md:65—Read 'references/visual-language.md' for what each shape and channel means - calls The citation gate (step 5)
SKILL.md:276—node scripts/validate.mjs <map>.json --repo <worktree> - calls The assembler (step 6)
SKILL.md:279—node scripts/render.mjs <map>.json --repo <worktree> --out <out>.html
Evidence.
SKILL.md:276—node scripts/validate.mjs <map>.json --repo <worktree>
Files. SKILL.md
types and constants · 1 files · 250 lines
The exact shape of the file an agent writes. Everything the picture shows must be derivable from that document, so this is the one place where the format is defined.
How it's built. Annotated JSON with the required fields, the kinds a structure may take, the line styles each connection kind renders as, and the rules that keep a traced flow honest.
Connections.
- ← The instructions imports types from this
Evidence.
references/schema.md:1—# 'system-map.json' contract (v1)
Files. references/schema.md
types and constants · 1 files · 137 lines
The reading recipes. How to find what depends on what without guessing, how to cross an async boundary, and how to get a citation without ever typing a line number.
How it's built. Ranks evidence from strongest to weakest, gives the ripgrep invocations that produce file, line and literal text in one step, and explains why queue names in particular must be read rather than matched.
Connections.
- imports types from Measuring
references/extraction.md:96—REPO=/path/to/worktree node -e "import('./scripts/lib/metrics.mjs') - ← The instructions imports types from this
Evidence.
references/extraction.md:1—# Finding structure by reading
Files. references/extraction.md
types and constants · 1 files · 93 lines
What the picture means. Which shape says a thing runs versus stores versus buffers, what makes one building taller than another, and why a hollow outline means the code is not ours.
How it's built. Binds every visual property to a measured number and records the formulas alongside a note to keep them in step with the geometry module, because a document that misstates the measurement undoes the promise it describes.
Connections.
- imports types from Projection and mass
references/visual-language.md:37—These formulas live in 'scripts/lib/geometry.mjs' - ← The instructions imports types from this
Evidence.
references/visual-language.md:37—These formulas live in 'scripts/lib/geometry.mjs'. If you change them there,
Files. references/visual-language.md
entry point · 1 files · 637 lines
The reason a map can be trusted. It opens every cited file and proves the quoted text is really there, and it reports which files in the declared region no structure claims. Nothing renders until it passes.
How it's built. Structural checks, then for each citation it reads the file and searches a few lines either side for the literal evidence string. Also holds the coverage report and a relocate mode that repairs citations whose lines drifted while the code moved.
Concerns.
- Proves a cited line exists and says what was quoted, never that it was read correctly, so a misreading passes the gate.
Connections.
- calls Measuring (measure globs)
scripts/validate.mjs:429—const { expandGlobs, fileMetrics, discoverTestSiblings } = await import('./lib/metrics.mjs') - ← The instructions calls this
- ← The assembler calls this
- ← The gate self-test calls this
- ← The text twin calls this
- ← The flow preview calls this
- ← The citation helper imports types from this
Evidence.
scripts/validate.mjs:62—if (!window.includes(evidence)) {scripts/validate.mjs:402—export async function scopeCoverage(map, repoRoot) {
Files. scripts/validate.mjs
entry point · 1 files · 193 lines
Proof that the gate actually rejects lies. It takes a real map, corrupts it eleven different ways, and checks that each corruption is caught.
How it's built. Picks whichever shipped example resolves against the repo, clones it per case, and mutates one thing: a fabricated quotation, a real string cited at the wrong line, a flow that teleports, a branch step misdeclared as a hop.
Connections.
- calls The citation gate (eleven lies)
scripts/self-test.mjs:14—import { validateMap, resolveNodeFiles } from './validate.mjs' - reads from The example maps (fixture)
scripts/self-test.mjs:26—for (const name of readdirSync(examples).filter((f) => f.endsWith('.system-map.json')).sort())
Evidence.
scripts/self-test.mjs:14—import { validateMap, resolveNodeFiles } from './validate.mjs'
Files. scripts/self-test.mjs
service · 1 files · 213 lines
Counts. How many files a structure holds and how many lines they run to, plus which of them are tests. Building size comes from here and nowhere else.
How it's built. A dependency-free glob matcher over a directory walk, line counting that ignores blanks, and sibling discovery that finds a test file next to its subject whatever the language calls it.
Connections.
- ← The citation gate calls this
- ← How to read imports types from this
- ← The scaffold calls this
Evidence.
scripts/lib/metrics.mjs:96—export function expandGlobs(repoRoot, patterns) {scripts/lib/metrics.mjs:28—const TEST_PATTERN = new RegExp([
Files. scripts/lib/metrics.mjs
service · 1 files · 159 lines
Turns measurements into shapes. It decides how wide and how tall a structure is from its file count and line count, and produces the three visible faces of every building.
How it's built. A two-to-one isometric projection, a square-root height scale so a range spanning three orders of magnitude stays legible, and one branch per shape returning its own mesh.
Connections.
- ← The assembler calls this
- ← Placement and routing calls this
- ← The scene calls this
- ← The visual language imports types from this
- ← The text twin imports types from this
- ← The flow preview calls this
Evidence.
scripts/lib/geometry.mjs:32—export function massOf({ fileCount, loc }) {scripts/lib/geometry.mjs:12—export function project(gx, gy, z = 0) {
Files. scripts/lib/geometry.mjs
service · 1 files · 375 lines
Decides where everything sits. Each group becomes a raised band of its own. Every connection travels only through the gaps between buildings, which is why no line is ever ambiguously in front of or behind one.
How it's built. Groups become contiguous row bands, columns and rows size to their own contents, and connections route through reserved corridors with lanes assigned by interval colouring so two routes contend only where they actually overlap.
Connections.
- calls Projection and mass
scripts/lib/layout.mjs:16—import { massOf, project } from './geometry.mjs' - ← The assembler calls this
- ← The layout invariants calls this
- ← The flow preview calls this
Evidence.
scripts/lib/layout.mjs:16—import { massOf, project } from './geometry.mjs'
Files. scripts/lib/layout.mjs
service · 1 files · 210 lines
Draws the field: the ground, the raised district platforms, the connections, the buildings painted far to near, and the labels that appear only when a connection is highlighted.
How it's built. Emits inline SVG from coordinates already computed, so the browser does no layout work and the markup is diffable between runs. Hatch density on a roof encodes how many other structures depend on it.
Connections.
- calls Projection and mass
scripts/lib/svg.mjs:4—import { buildMesh, groundGrid, project } from './geometry.mjs' - ← The assembler calls this
- ← The flow preview imports types from this
Evidence.
scripts/lib/svg.mjs:4—import { buildMesh, groundGrid, project } from './geometry.mjs'
Files. scripts/lib/svg.mjs
entry point · 1 files · 315 lines
Puts the page together. It refuses to run on a map that has not passed the gate. Then it measures, places, draws, and folds everything into one file that needs no server and no build step.
How it's built. Runs the gate first, resolves globs to measurements, calls layout and the scene emitter, then inlines the stylesheet, the interaction layer and the map itself as pure ASCII so no host charset can corrupt it.
Connections.
- calls The citation gate (gate first)
scripts/render.mjs:16—import { validateMap, resolveNodeFiles } from './validate.mjs' - calls Placement and routing
scripts/render.mjs:17—import { layout } from './lib/layout.mjs' - calls The scene
scripts/render.mjs:18—import { renderScene, escapeHtml as esc, DEFAULT_SHAPE } - calls Projection and mass
scripts/render.mjs:19—import { massOf } from './lib/geometry.mjs' - reads from The theme (inlined)
scripts/render.mjs:218—const css = readFileSync(join(assets, 'app.css'), 'utf8') - reads from The interaction layer (inlined)
scripts/render.mjs:219—const js = readFileSync(join(assets, 'app.js'), 'utf8') - ← The instructions calls this
Evidence.
scripts/render.mjs:16—import { validateMap, resolveNodeFiles } from './validate.mjs'scripts/render.mjs:218—const css = readFileSync(join(assets, 'app.css'), 'utf8')
Files. scripts/render.mjs
entry point · 1 files · 143 lines
Proof that a connection never enters a building. That single property is the only reason the scene can draw every line before every building without sorting them by depth.
How it's built. Recomputes the layout for every shipped map and asserts no route enters a footprint, no footprints overlap, everything falls inside the frame, districts are contiguous, and two runs agree exactly.
Connections.
- calls Placement and routing
scripts/layout-test.mjs:16—import { layout } from './lib/layout.mjs' - reads from The example maps
scripts/layout-test.mjs:19—const examples = join(here, '..', 'examples')
Evidence.
scripts/layout-test.mjs:16—import { layout } from './lib/layout.mjs'
Files. scripts/layout-test.mjs
client · 1 files · 792 lines
Everything the page does once it is open. Panning and zooming, clicking a structure to read about it, and playing a traced path one step at a time. The pace is set by how long each step takes to read.
How it's built. Vanilla JavaScript over the pre-computed scene. Flow playback gives each step a travel time from its path length and a dwell from its own note, and scrolls the panel so the sentence explaining a hop is on screen while that hop is lit.
Connections.
- ← The assembler reads from this
Evidence.
assets/app.js:192—const READING_WORDS_PER_SECOND = 3.2; // unhurried prose, not skimmingassets/app.js:292—function scrollStepIntoView(el) {
Files. assets/app.js
types and constants · 1 files · 523 lines
How the page looks in either colour scheme, and the panel layout around the map. Colour never encodes a category, so the picture survives being printed or read by someone colour-blind.
How it's built. One complete palette as custom properties, redefined for dark under both a media query and an explicit attribute so every combination of viewer preference resolves. Components only ever read tokens.
Concerns.
- Pulls a webfont from Google Fonts, the one external host an artifact may reach; every face declares a fallback stack behind it.
Connections.
- ← The assembler reads from this
Evidence.
assets/app.css:1—@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono
Files. assets/app.css
store · 1 files · 1,054 lines
Three finished maps, which double as the fixtures both guard scripts run against. One of them is this map: the skill described by itself.
How it's built. Plain JSON conforming to the contract. Each cites paths in the repository it was built from, so a guard pointed at a different checkout skips it with a note rather than failing.
Concerns.
- Citations are repo-relative, so extracting the skill on its own leaves the example maps unresolvable.
Connections.
- ← The gate self-test reads from this
- ← The layout invariants reads from this
Evidence.
examples/show-me.system-map.json:2—"schema": "system-map/v1"
Files. examples/*.system-map.json
service · 1 files · 233 lines
Writes the same map out as a document instead of a picture. The picture is better for grasping shape; the words are better for everything afterwards. They can be searched, compared between two versions, reviewed alongside a code change, and read where there is no browser.
How it's built. Takes the same data file the page is drawn from, re-runs the gate, resolves the file globs for their counts, and emits Markdown: a header table, the reading order, one section per structure with its connections and the citation behind each, then the traced flows and a provenance note.
Connections.
- calls The citation gate (gate first)
scripts/twin.mjs:18—import { validateMap, resolveNodeFiles, scopeCoverage } from './validate.mjs' - imports types from Projection and mass
scripts/twin.mjs:19—import { massOf } from './lib/geometry.mjs'
Evidence.
scripts/twin.mjs:33—export async function twin(map, repoRoot) {scripts/twin.mjs:243—writeFileSync(resolve(flags.get('out')), text, 'utf8')
Files. scripts/twin.mjs
service · 1 files · 171 lines
Makes a small moving picture of one traced path, for a README or a message. A still image cannot show what this tool is for. The interesting part is a payload walking a real route, so the preview moves.
How it's built. Runs the same placement the page uses, frames only the structures the chosen flow touches, and emits an animated SVG. Each hop gets a lit copy of its route and a token timed to arrive in turn. Vector rather than a recording, so it needs no browser to capture and cannot drift from the map.
Connections.
- calls The citation gate (gate first)
scripts/preview.mjs:18—import { validateMap, resolveNodeFiles } from './validate.mjs' - calls Placement and routing (same placement)
scripts/preview.mjs:19—import { layout } from './lib/layout.mjs' - calls Projection and mass
scripts/preview.mjs:20—import { buildMesh, project } from './lib/geometry.mjs' - imports types from The scene
scripts/preview.mjs:21—import { tagText, DEFAULT_SHAPE, escapeHtml as esc } from './lib/svg.mjs'
Evidence.
scripts/preview.mjs:34—export async function preview(map, repoRoot, flowId, { step = 1200 } = {}) {scripts/preview.mjs:53—const travel = round((step * 0.62) / cycle)
Files. scripts/preview.mjs
entry point · 1 files · 162 lines
Does the clerical half of starting a map. It reads which revision you are on, counts what is there, finds the manifests, and writes one empty shell per directory. It decides nothing about what anything is.
How it's built. Rolls the file list up by directory with line counts, reports likely doorways by filename, and emits a skeleton whose every prose field is a placeholder the gate rejects. That refusal is the point: a scaffold cannot be mistaken for a finished map.
Connections.
- calls Measuring (count the files)
scripts/scaffold.mjs:23—import { expandGlobs, fileMetrics, TEST_PATTERN } from './lib/metrics.mjs'
Evidence.
scripts/scaffold.mjs:25—const BUDGET = {scripts/scaffold.mjs:54—export function scaffold(repoRoot, { branch = null, scope = [], mode = 'system' } = {}) {
Files. scripts/scaffold.mjs
entry point · 1 files · 102 lines
Turns a search result into a citation. Copying a path, a line number and a quote by hand dozens of times is the grindiest part of writing a map, and it is the part most likely to go wrong.
How it's built. Reads ripgrep output from a pipe or an argument, handles both of the shapes ripgrep emits, and checks each quote really sits at the line named before printing it. A bad paste is caught here rather than at the gate.
Concerns.
- It re-implements the gate's window check instead of importing it, so the two could drift apart.
Connections.
- imports types from The citation gate (same check, copied) — inferred
scripts/cite.mjs:46—export function verify(citation, repoRoot, window = 4) {
Evidence.
scripts/cite.mjs:24—export function parseHit(line, fallbackFile = null) {scripts/cite.mjs:46—export function verify(citation, repoRoot, window = 4) {
Files. scripts/cite.mjs
A validated map becomes one self-contained HTML file: gated, measured, placed, drawn, then inlined.
Trigger. The author runs render.mjs on a map that has passed the gate
Payload. system-map.json
- The instructions → The assembler
The pipeline hands the map to the assembler, which is the only step that produces a file anyone looks at.
SKILL.md:279—node scripts/render.mjs <map>.json --repo <worktree> --out <out>.html - The assembler → The citation gate (side effect; the path does not advance)
The gate runs again first, so a map that fails verification cannot be rendered even by accident.
scripts/render.mjs:16—import { validateMap, resolveNodeFiles } from './validate.mjs' - The assembler → Projection and mass (side effect; the path does not advance)
Measured file counts and line counts become a footprint and a height, which is why no field can inflate a building.
scripts/render.mjs:19—import { massOf } from './lib/geometry.mjs' - The assembler → Placement and routing (side effect; the path does not advance)
Groups become raised bands and every connection is routed through the corridors between buildings.
scripts/render.mjs:17—import { layout } from './lib/layout.mjs' - The assembler → The scene (side effect; the path does not advance)
Final coordinates are emitted as inline SVG, so the browser does no layout work and two runs are diffable.
scripts/render.mjs:18—import { renderScene, escapeHtml as esc, DEFAULT_SHAPE } - The assembler → The interaction layer (side effect; the path does not advance)
The stylesheet, the interaction layer and the map itself are inlined as pure ASCII, leaving one portable file.
scripts/render.mjs:219—const js = readFileSync(join(assets, 'app.js'), 'utf8')
A real map is corrupted eleven ways and the gate must catch every one of them.
Trigger. Anyone changes the validator or the schema
Payload. a mutated clone of a real map
- The gate self-test → The example maps (side effect; the path does not advance)
It picks whichever shipped example resolves here, so the gate can still be tested from a checkout missing the others.
scripts/self-test.mjs:26—for (const name of readdirSync(examples).filter((f) => f.endsWith('.system-map.json')).sort()) - The gate self-test → The citation gate
Each case clones that map, breaks exactly one thing, and asserts the gate rejects it for the expected reason.
scripts/self-test.mjs:14—import { validateMap, resolveNodeFiles } from './validate.mjs' - The citation gate → Measuring (side effect; the path does not advance)
Glob resolution is checked too, because a structure pointing at no files cannot be drawn or measured at all.
scripts/validate.mjs:429—const { expandGlobs, fileMetrics, discoverTestSiblings } = await import('./lib/metrics.mjs')
Every shipped map is re-laid-out and checked: no connection may enter a building footprint.
Trigger. Anyone changes placement, routing or projection
Payload. routed grid points
- The layout invariants → The example maps (side effect; the path does not advance)
It runs over every shipped map, skipping any whose citations do not resolve against the repository given.
scripts/layout-test.mjs:19—const examples = join(here, '..', 'examples') - The layout invariants → Placement and routing
Placement and routing are recomputed, then every segment is tested against every footprint for intersection.
scripts/layout-test.mjs:16—import { layout } from './lib/layout.mjs' - Placement and routing → Projection and mass (side effect; the path does not advance)
Projection and mass come from geometry, so a change to the height scale is caught by this test as well.
scripts/lib/layout.mjs:16—import { massOf, project } from './geometry.mjs'
Every structure, connection and flow step above cites a file, a line, and a literal string found at that line. The map is rejected at build time until all of them resolve, so this document cannot drift from the code silently — it can only fail to build.
What the check does not cover: it proves a cited line exists and says what is quoted, not that it was read correctly. Interpretation is human.
Marked inferred (real, but not pinnable to one line):
CIT→VAL