| name | map-explain |
| description | Deep walkthrough that builds a mental model of code, a diff, or the project — flow, side effects, assumptions, breakage. Use when learning unfamiliar code or auditing a diff. Do NOT use to plan or implement; use map-plan or map-efficient.
|
| effort | medium |
| disable-model-invocation | true |
| argument-hint | [file path | symbol | PR ref | code snippet | empty for branch diff vs origin/main (fallback origin/master), or project overview on main/master] |
MAP Explain
Target: $ARGUMENTS
Output language
Write the explanation in the user's established language — honor the language already set in context (the conversation's language and the host/global CLAUDE.md language convention) rather than defaulting to English. Translate only the prose. Keep code, identifiers, commands, error messages, and file:line references in English.
Effort and Parallelism Policy
thinking_policy: medium/adaptive
parallel_tool_policy: independent_reads_only
- Use adaptive reasoning to build the requested mental model, but stop at explanation: do not plan or implement changes from this skill.
- Parallelize independent file reads, diffs, and searches when they do not require immediate synthesis.
- Keep final synthesis sequential so the explanation is coherent and does not mix unrelated targets.
Default target (when $ARGUMENTS is empty)
Pick mode by inspecting the current branch and its relation to the upstream base:
BASE=$(git rev-parse --verify --quiet origin/main >/dev/null && echo origin/main \
|| (git rev-parse --verify --quiet origin/master >/dev/null && echo origin/master))
if [ -z "$BASE" ]; then
echo "map-explain: neither origin/main nor origin/master exists; aborting." >&2
exit 1
fi
git fetch origin "${BASE#origin/}" --quiet
CURRENT=$(git rev-parse --abbrev-ref HEAD)
Then choose one of the two modes below and follow it.
Mode A — Project overview (current branch is main or master, OR HEAD == $BASE)
There is no branch diff to explain — explain the project as a whole. Apply the output spec below at the repository level instead of a single-file level:
- Mental model in 60 seconds: what this repository exists to do — derive from
README.md, then top-level docs (docs/ARCHITECTURE.md, docs/USAGE.md, CLAUDE.md).
- Decomposition: the top-level modules / packages / services and the responsibility boundary between them — read the directory listing, primary entry points, and manifests (
pyproject.toml, package.json, go.mod, Cargo.toml).
- Execution flow: what happens when the primary entry point runs (CLI invocation, server startup, request lifecycle).
- Load-bearing lines: do NOT cover every line in the repo. Pick the 3–6 most architecturally load-bearing files/functions and walk only those.
- Assumptions & breakage: runtime, OS, language version, external services, secrets, env vars, plus the kinds of changes that routinely break this project (derive from
CONTRIBUTING.md, CHANGELOG.md, recent commits, learned-patterns docs).
There is no diff, so skip the before→after block.
Useful commands to bootstrap:
ls -la
git --no-pager log --oneline -n 20
Mode B — Branch diff (current branch is NOT main/master and HEAD != $BASE)
The target is the current branch's diff against the upstream base. Treat the resulting diff exactly like a PR target — lead with the before→after block.
git --no-pager diff --stat "$BASE"...HEAD
git --no-pager log --oneline "$BASE"..HEAD
git --no-pager diff "$BASE"...HEAD
Edge cases (apply to both modes)
- If the working tree has uncommitted changes you also want explained, say so and include
git diff (unstaged) and git diff --cached (staged) on top of whatever the chosen mode produced.
Size the explanation first
Classify the target by size and set a word budget. Budgets are ceilings, not targets — when in doubt, cut.
| Tier | Trigger | Word budget | Load-bearing line cap |
|---|
| Tiny | ≤50 lines / single symbol | 300–700 | full line detail OK |
| Small | 31–150 lines | 600–1,200 | ≤10 |
| Medium | 151–300 lines | 900–1,600 | ≤12 |
| Large | 301–600 lines / multi-file | 1,200–2,200 | ≤18 |
| Huge | >600 lines | 1,800–2,800 | ≤25 |
Snippet caps: never quote more than 3 lines at once; ~20 quoted lines total across the whole explanation. Summarize the rest by reference (file:line) rather than pasting it.
Output spec
Open with one framing line, then the blocks below in order. Tag each header with a read-tier so the reader can decide what to skip: [MUST READ], [READ IF MODIFYING], [SKIM]. Emit a block only when it applies (see "Adaptive sections").
Target: <type> · Size: <tier> · Budget: <range> words
-
Mental model in 60 seconds [MUST READ] — ≤100 words / ≤5 sentences: what it is, its job, the one thing you most need to know, and the one thing most likely to surprise you.
-
Before → after [MUST READ] — PR/diff targets only; this goes first because the delta is the most important context for a diff. A small table:
| Aspect | Before | After | Runtime effect |
|---|
-
Execution flow [MUST READ] — entry point → branches → where they converge.
-
Decomposition [SKIM] — a small table of the entities/responsibilities: what each owns and what it explicitly does NOT do. Skip for a single function.
-
Load-bearing lines [READ IF MODIFYING] — the one table defined below.
-
Assumptions & breakage [SKIM] — what the code relies on (runtime, services, invariants) and what changes routinely break it.
-
Key insights — plus common misunderstandings.
Close with a single line — not a "Skipped" header: Omitted: <list> — irrelevant for <reason>. Then offer 2–3 natural-language follow-ups (e.g. "Explain the authorization path line by line", "Focus only on the data flow"). Do NOT print fake CLI flags like --focus flow — the CLI cannot honor them.
Load-bearing lines (replaces line-by-line)
A line is load-bearing — and earns a row — only if it:
- mutates external/system state;
- branches on a non-trivial condition;
- crosses an abstraction boundary or public contract;
- does validation, authorization, normalization, or parsing;
- handles an error, retry, fallback, or edge case;
- encodes a non-obvious invariant;
- would silently change behavior if removed.
Skip (do not quote or explain): type annotations, logging, trivial assignments, boilerplate imports, standard decorators, getters/setters whose name equals their behavior.
Worked filter: in if user.is_admin or has_scope(token, "write"): the condition is load-bearing (an authorization branch); a neighboring logger.debug(f"checking {user.id}") is not.
Emit them as one table — this merges the old "what every line does" and "why each line" into a single pass so the same code is never explained twice:
| Where (file:line) | What it does | Why it matters / what breaks if changed |
|---|
- Repeated shapes once. When the target repeats a pattern (N handlers, routes, switch cases, validators, mappers), explain the shared shape once, then list only the meaningful exceptions. Never re-explain the same shape N times.
- Diffs: changed lines only. For a PR/branch diff, apply this table to changed lines, not the whole file.
- Density. One sentence for WHAT per row; add a second only when WHY is non-obvious.
Adaptive sections (menu, not checklist)
Emit a block only when it carries signal for this target:
- Single function → skip Decomposition.
- Pure function → skip side-effect discussion.
- PR diff → fold "what differs" into Before → after; do not also write a separate differences section.
- A category that is trivial for this target → compress to one sentence rather than a full block.
Never emit a header just to write "Skipped" — list everything omitted in the closing Omitted: line instead.
Rules
- Be dense. Prefer one precise sentence over three vague ones. Prefer statements of purpose and consequence over procedural description.
- Do not use a term before explaining it; do not hide behind jargon.
- Separate intuition, exact mechanism, and practical meaning.
- Mark an inference with
Inferred: only when it required reading multiple files or guessing intent — not for direct observations any competent reader would make.
- No preamble, no apology, no closing pleasantries. Begin with the substance.
- Ban filler openers: "This line…", "Here we have…", "It is important to note…", "Essentially…", "In other words…", "Note that…".
How to apply
- Locate the target. If
$ARGUMENTS is empty, pick Mode A (project overview) or Mode B (branch diff) per the rules above. If it's a file path, read the whole file. If it's a symbol, grep the codebase for the definition and primary call sites. If it's a PR ref (#N, branch name, commit SHA), fetch the diff with git show / gh pr diff. If it's an inline snippet, treat the snippet itself as the target.
- Read enough context to answer "why this exists." Imports, callers, tests, and adjacent files often carry intent the target itself does not.
- Size it, then emit the output spec in order. Front-load the mental model; the structure is part of the teaching, but only emit blocks that apply.
- Quote, do not paraphrase, the load-bearing lines you explain. Use
file:line references so the reader can navigate, and respect the snippet caps.
- Stop at the target's boundary. Explain only what is needed to understand this target's behavior, not the whole codebase.
Examples
/map-explain # on a feature branch: explain its diff vs origin/main; on main/master: explain the project
/map-explain src/mapify_cli/orchestrator.py
/map-explain map_step_runner.create_review_bundle
/map-explain #108
/map-explain HEAD~1..HEAD
Troubleshooting
- "neither origin/main nor origin/master exists" — the repo has no upstream named
origin, or its default branch is not main/master. Either add an origin remote, or pass an explicit target (file path / symbol / PR ref) instead of running with no arguments.
- "HEAD == $BASE" — the current branch already matches the upstream base, so there is no diff. The skill falls into Mode A (project overview); if that is not what you wanted, check
git status and confirm your commits are on this branch.
- Diff is enormous and the walkthrough turns shallow — pass a narrower target (single file, single symbol, or
HEAD~1..HEAD) so the load-bearing table fits within the tier budget.
- Output mixes inference with source claims — every non-explicit assertion must be prefixed with
Inferred:. If you see unmarked guesses, ask the skill to re-emit with explicit confidence tags.