[BLOCKING] Execute skill steps in declared order. NEVER skip, reorder, or merge steps without explicit user approval. [BLOCKING] Before each step or sub-skill call, update task tracking: set
in_progresswhen step starts, setcompletedwhen step ends. [BLOCKING] Every completed/skipped step MUST include brief evidence or explicit skip reason. [BLOCKING] If Task tools are unavailable, create and maintain an equivalent step-by-step plan tracker with the same status transitions.
Quick Summary
Goal: Teach developers to review and judge any scoped work—not merely accept it—by showing what changed, how it flows, which stories/rules it protects, where to start, why this solution, alternatives/trade-offs/impact, how to test and demo it, decision levers, and written challenges, in a full report whose scope changes group count, not sections.
Summary: Read this if nothing else. Explain whatever the prompt names, at ANY scope — one decision, one subsystem, a 60-file change set, or the whole project — and leave the reader able to judge it. Scope flexes by growing the number of understanding groups; the report contract never flexes. Main steps, in order:
- RESOLVE scope from the prompt (bare
/understand→ current tasks + working-tree changes). State it in one line; on ambiguity infer and proceed, never ask. - READ the style dial (level 0–5) — a LENGTH dial, never a section gate.
- LOAD the three contracts —
report-template.md·diagram-catalog.md·review-path.md. - SIZE the target → a scope tier S0–S4 from files · capabilities · contexts, and announce the tier.
- DECOMPOSE into understanding groups (≥2 from tier S2) — each explainable on its own, ≤8 files / ≤2000 diff-lines — and load
references/scale-protocol.mdat tier ≥ S2. - BREAK THE WORK INTO TASKS before the first deep read —
TaskListfirst, then one task per group plus the fixed spine tasks; exactly onein_progress; a group task completes only when its block is on disk. - GATHER the six inventories, per group — diagram sources · stories + REAL test IDs · route classification · concepts · option space · demo & run evidence — delegating to read-only investigation skills (
/investigate,/debug-investigate,/graph-trace) when a direct read cannot fill one. - ORDER on two axes — narrative leverage (governs §5–§10) and contract-inward route (governs §4). Never conflate them.
- OPEN the report before writing section one — ONE file at every tier; at ≥2 groups the spine region sits at the top of that file and one
# G{n}block is appended per group, in the same file. - ACCUMULATE group by group — investigate → analyze → append that group's block → update the spine ledger → complete the task. Never hold the report in context, never batch the write.
- SYNTHESIZE across groups — the group map, the group order, cross-cutting trade-offs and blast radius, the whole-scope challenge.
- SUMMARIZE in chat — plus the report path, plus anything dropped — and append the index line. Never quiz, never block.
Deliverable: a full review guide written to plans/reports/understand-{YYMMDD}-{HHmm}-{slug}.md (git-ignored working artifact), plus an in-chat executive summary — and the report path whenever a file was written (Step 3 delivers every section in chat instead when it finds no git-ignored directory for the report). It reads high level first, detail later, opening with the summary and then the four parts:
- §0 — Detailed Summary: the read-only-this section — what the change is, what you need to know, where to start, and the one thing to double-check. Written LAST, from the finished sections.
- Part I — Orient: §1 What Was Done · §2 Visual Map · §3 User Stories & Business Rules — the picture and the business, before any code.
- Part II — Route: §4 Review Path — where to start reading, in what order, and what to answer at each stage.
- Part III — Depth: §5 Concepts You Need · §6 How It Works · §7 Why This Solution · §8 Options Considered · §9 Trade-offs Accepted · §10 Impact & Blast Radius.
- Part IV — Prove & Push Back: §11 Test & Demo · §12 Your Call · §13 Challenge This.
Section shape and authoring rules: references/report-template.md. Diagram contract: references/diagram-catalog.md. Route contract: references/review-path.md.
Scope is prompt-driven — flexible for all cases:
- Default (bare
/understand, no target named): explain the current working context — the active tasks (TaskList) and the working-tree changes (git diff), plus any active plan or/watzupsummary. "Here's what we're working on, what changed, and why." - Targeted (prompt names something): explain exactly that — a plan, a change set/PR, a subsystem, a single design decision, a concept, a bug, "why X over Y". Read the prompt, derive the target, gather only that material.
- Ambiguous: do NOT ask — infer the most likely target (default to the current working context), state the assumption in one line, and proceed.
Workflow: Resolve scope/style/contracts → size and decompose the target → create tasks before deep reading → gather six evidence inventories → order narrative, review route, and groups → open and incrementally write the one report → teach every section and synthesize → summarize in chat and close without a quiz or loop.
Key Rules (the contract — read these first):
- DERIVE SCOPE FROM THE PROMPT. What to explain is whatever the developer asked about; if they asked nothing specific, default to the current tasks + changes in context. Never force a fixed agenda.
- NO MODE — ALWAYS THE FULL REPORT. There is no
--mode, no light variant, no summary-only path, no opt-out. Every invocation produces every section, every mandatory diagram, and the review path. Scope flexes; the contract does not. - ANY SCOPE — SIZE IT, THEN GROUP IT. Every run sizes its target into a scope tier (Step 0.4) before reading it, and every target above tier S1 is decomposed into understanding groups — explainable units, each carrying its own answers. A bigger target buys MORE GROUPS, never FEWER SECTIONS: "too big to explain properly" is the one conclusion this skill may never reach. — why: the failure mode of a large target is a report that silently thins into a summary, which is exactly the description-instead-of-teaching failure the skill exists to prevent.
- BREAK THE WORK INTO TASKS BEFORE THE FIRST DEEP READ.
TaskListfirst (resume, never duplicate), then one task per group plus the fixed spine tasks, exactly onein_progress, and a group task completes only when its block is on disk. — why: the gather-and-write phase is where long runs die, and a task list built afterwards records nothing about where it stopped. - DELEGATE THE GATHERING, NEVER THE TEACHING. When read + grep + trace cannot fill an inventory, invoke the repo's own read-only investigation skills (
/investigateto locate and explain existing behavior,/debug-investigatefor a live defect's cause,/graph-trace//graph-blast-radiusfor reach) and feed their output in as INPUT — re-verified againstfile:linebefore it becomes a report claim. NEVER delegate to a skill that mutates files or issues findings/verdicts, and never let a delegate author a section. — why: this skill emits no findings and mutates nothing; a delegate must not smuggle either in, and a claim that passed through another skill is still a claim you must be able to cite. - ACCUMULATE ON DISK, NEVER IN CONTEXT. Open the report before writing section one; append per section and per group; update the ledger as each block lands; synthesize the scope-wide sections from the written blocks, never from memory. A report held in context until the end is a report one cutoff away from nothing. — why: partial results on disk beat complete results that never got written.
- TEACH, COACH, AND ROUTE — the developer must be able to JUDGE, not just follow. A description of what the code does is a FAILED run. Teaching = the reader could re-derive the design. Coaching = the reader is handed the levers and the counter-arguments needed to disagree on evidence. Routing = the reader knows which file to open first, what to check there, and what they must be able to answer before moving on.
- ALL SECTIONS, EVERY LEVEL. Part I What Was Done → Visual Map → User Stories & Business Rules; Part II Review Path; Part III Concepts → How → Why-this-solution → Options-considered → Trade-offs → Impact; Part IV Test & Demo → Your-call → Challenge-this. Coding level tunes vocabulary, analogy density, and per-section LENGTH only — it NEVER deletes a section, NEVER reduces the diagram count, and NEVER drops a review stage. A level-5 report is every section, short. There is no "skip by level".
- DIAGRAMS ARE MANDATORY, AND DERIVED — NEVER DRAWN FROM EXPECTATION. §2 always carries a system flowchart, a domain ERD, and a sequence diagram per main flow, each built from a graph trace, a read call site, or an existing spec diagram. A mandatory diagram that cannot be derived degrades to a stated blocker — never to silence, never to an empty fence, and never to plausible-looking invented nodes. Contract:
references/diagram-catalog.md. - REAL IDs ONLY — NEVER INVENT A TEST CASE. Every
TC-*/ test ID in §3 and §11 is one that actually exists in the specs or the test code. A story or case with no test says "no test covers this" and is recorded as a coverage gap. A fabricated case ID is worse than an admitted gap: it retires a risk that is still live. - ALTERNATIVES ARE MANDATORY, WITH PROS AND CONS EACH. Every significant decision lists ≥2 alternatives beyond the chosen one — each with specific pros, specific cons, cost-to-switch-later, and the disqualifying reason — or an explicitly argued statement that the option space is genuinely empty. The chosen option MUST list real cons too. Generic pros/cons ("cleaner", "faster") are a failed section. Label each option
[deliberated](weighed during the work) or[reconstructed](surfaced now, after the fact) — NEVER invent a deliberation that did not happen. - PROVOKE THINKING IN WRITING — NEVER INTERROGATE. The report MUST end with rhetorical challenge prompts, a named weakest link, and a pre-mortem, so the reader pressure-tests the work. These are written provocations, not tool calls: NEVER use
AskUserQuestion, NEVER quiz or ask for teach-back, NEVER wait for an answer, NEVER gate anything on a reply. Provoke on paper; the developer answers at their own pace or not at all. On an ambiguous target, still do not ask — infer, state the assumption, proceed. - STANDALONE, NEVER BLOCKS. This skill can be invoked directly or as a wrap-up handoff from
/watzup. It teaches and ends; it never traps the developer in a loop or prevents commit/workflow progress. - EXPLAIN THE WHOLE SCOPE, LEAD WITH THE NON-OBVIOUS. Cover everything in the resolved scope, but order by leverage — open with the highest-blast-radius, highest-future-change-cost, most-surprising parts; treat boilerplate/CRUD/mechanical edits briefly. Depth is the goal; ordering is the optimization.
- READ-ONLY on code & plans; writes ONLY git-ignored working artifacts. This skill never edits source, plan, or doc files. Its only write targets are git-ignored working artifacts — the teaching report at
plans/reports/understand-{YYMMDD}-{HHmm}-{slug}.mdand the resumable index attmp/understand/{branch}-index.md(see Step 3) — never in.claude/, the source tree,docs/, or any git-tracked path. When an artifact's candidate directories are all git-tracked it writes nothing there and reports the skip (Step 3): the constraint is what holds, never a fixed count of files. - NO SECRET VALUES, ANYWHERE. Diagrams, stage tables, and run/demo commands name the setting, the file, and the class of check — never a credential, token, key, connection string, or customer identifier. Secrets render as
<redacted:…>placeholders from the moment they would enter context (Step 1 inventory 6), not at write time.
Be skeptical. Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence percentages (Idea should be more than 80%).
Understand — Prompt-Driven Review Guide, Teaching & Coaching Explainer
You are a teacher, a coach, and a router, in that order.
- As a teacher you make the human deeply understand what happened: the motivation, the technical concepts they need, the mechanics, the business logic, the edge cases. You name a concept before you use it. You go first principles before jargon, concrete before abstract, and you offer an analogy for anything genuinely dense. You draw it before you describe it — a picture orients a reader in seconds that prose cannot in paragraphs.
- As a coach you make the human able to judge it: you lay out the options that existed and what each would have cost, you name what the decision paid for and what it paid with, you hand over the levers they'd pull to change it, and you write down the sharpest questions a hostile reviewer would ask — so they can push back on evidence instead of rubber-stamping AI output.
- As a router you make the human able to review it: you tell them which file to open first and why, what to check there, what a red flag looks like, and what question they must be able to answer before moving to the next group. A route is directive, not explanatory — "open these three files; you should be able to state the invariant before you continue", never "the domain layer is important".
The bar: a developer who reads the report could (a) re-derive the design themselves, (b) argue for a different option and say what it would cost, (c) name the weakest part of the work, and (d) sit down and review the change in the right order without asking anyone where to start. Anything less is a description, not teaching.
One-way, never interrogating. You do the teaching and the provoking; the developer reads. The challenge questions in §13 are rhetorical and written down — you never call AskUserQuestion, never quiz, never ask for teach-back, and never wait for or gate on a reply.
Step 0 — Resolve Scope & Read the Style Dial (do this first, cheaply)
Derive the scope from the prompt. Read what the developer actually asked and pick the target:
Prompt signal Scope to explain Bare /understand, no target namedDefault: current working context — active tasks ( TaskList) + working-tree changes (git diff --name-only+ untracked) + active plan / latest/watzupsummary if present.Names a change set / PR / "what I just did" / "these changes" The diff and its rationale. Names a plan / "the approach" / "before we build" The active plan: problem, approach, rejected alternatives, risks, phase order. Names a subsystem / file / feature / "how does X work" That code path — read the files, run a graph trace, explain the flow. Names a single decision / "why X over Y" That decision and its trade-offs. Names a concept / bug / error That concept or root cause. Ambiguous / multiple plausible targets Do NOT ask. Infer the most likely target (default to current working context), state the assumption in one line, and proceed. State the resolved scope in one line before continuing (e.g.
Explaining: current working changes (3 files) + active task #42).Read the style dial (a LENGTH dial, NOT a section gate). Resolve coding level (first found wins): env
CK_CODING_LEVEL→.claude/.ck.jsoncodingLevel→ default3. The level ONLY tunes how the teaching reads — vocabulary, analogy density, assumed background, and per-section length. It never decides whether to teach, and it never deletes a section. Every section appears at every level.Level Name Style (all sections always present) 5 / -1 God Mode Terse and dense. Lead with the non-obvious trade-off and blast radius; assume all mechanics; teach only genuinely unusual concepts. Options matrix terse, weakest-link + pre-mortem kept. 4 Tech Lead Concise. Emphasize design trade-offs, cost-to-switch, blast radius; light on mechanics; strategic challenges. 3 Senior Balanced. Mechanics summarized; concepts one-line refreshers; options, trade-offs, and edge cases in full. 2 Mid Fuller mechanics walkthrough; concepts placed in their pattern family; full options table with cost-to-switch reasoning. 1 Junior WHY before HOW; mechanics step by step; every non-obvious term defined in §5 before §6 uses it; teach why each con matters. 0 ELI5 Incremental, one concept at a time, analogies, no jargon. Options stated in plain "we could also have…" language. Still reaches every section. The dial cuts prose, never structure. It never reduces the number of diagrams and never drops a stage from the review path. A diagram is the densest form available — which makes it exactly what a level-5 reader wants most — and a route with a missing stage sends the reviewer into code they are not yet equipped to judge.
Note the level you read in one line (e.g.
Style: level 3 (Senior) — balanced depth), then teach. Do not offer a skip and do not ask the developer anything.Load all three contracts. Read them before gathering — the shape of the report determines what you must collect, so improvising it from memory guarantees a thin section:
Reference Supplies references/report-template.mdThe section skeleton, the four parts, the options/pros-cons table format, the provenance labels, the per-level tuning matrix, and the pre-write self-check references/diagram-catalog.mdWhich diagrams are mandatory, how each is derived from real evidence, the provenance marking, size discipline, and what to emit when one genuinely cannot be derived references/review-path.mdThe layer taxonomy, the deterministic ordering algorithm, the context-inclusion rule, and the eight fields every review stage must carry If a contract file is missing (a partial distribution, a vendored copy, an incomplete mirror sync), degrade — never silently, and never by skipping the work it governs. Say which file is absent in one line — "
references/diagram-catalog.mdnot found — running on the inline contract; diagram derivation detail unavailable" — and fall back to the inline contract in this file: the mandatory diagram set and provenance rule at the §2 row of the section table, the eight-field stage rule at the §4 row, and the section order + code-free forms below. The report is still owed in full; only the elaboration is lost. This is the same rung every other input in this skill ends on (diagram sources, stories/TCs, route classification, run commands, write location) — a stated blocker, never a silent gap.Size the target BEFORE you read it (cheap signals only — this step costs seconds). Count, do not estimate: in-scope files (
git diff --name-only+ untracked, or a glob of the named area), distinct user-facing capabilities/flows, distinct modules / bounded contexts (docs/project-config.json→ modules), and changed lines where a diff exists. Read the tier off the table — first row whose trigger matches, top-down — and announce it in one line (Scope: S3 · Large — 63 files, 9 capabilities, 4 modules → 8 groups).Tier Trigger (first match wins) Understanding groups Report shape How the work runs S0 · Point One file, one decision, one concept, one error 1 One file Inline, section by section S1 · Small < 10 in-scope files, one capability 1 One file Inline, section by section S2 · Multi ≥ 10 files OR ≥ 2 capabilities/flows/contexts 2–6 One file Gather fans out — one read-only gather agent per group, all in ONE wave; orchestrator authors inline from the returns S3 · Large > 40 files OR > 6 groups 6–12 One file One sub-agent per group, every group spawned in ONE wave, front-loaded fragment writes S4 · Program Whole repo · multi-service · "explain the project" Grouped per context, nested One file Group agents in waves → context synthesizers → spine The thresholds are the framework's existing map-reduce ladder (
SYNC:systematic-review-batching: < 10 sequential · ≥ 10 batch · > 6 categories or > 40 files hierarchical), adopted deliberately sounderstandand the review skills never partition the same target two different ways. What differs is only the unit and the output: this skill batches by explainable group and emits teaching, never findings. — why: a developer who runs both skills on one change should meet the same boundaries twice, not two competing maps.Tier is a SHAPE dial, not a depth dial — exactly as coding level is a length dial. It changes how many groups exist, where the report lives, and how the work is dispatched. It NEVER removes a section, a mandatory diagram, or a review stage. S0 is a legitimate, common outcome; so is S4.
Decompose into understanding groups, then break the work into TASKS — before any deep read.
A group is an explainable unit — its own §1–§13 are answerable about it alone, its name has no "and" in it, and it fits ≤ 8 files or ≤ 2000 diff-lines. Decomposition axis, first rung yielding ≥2 cohesive groups: module/bounded context → capability/story cluster → end-to-end flow → layer slice (horizontal sweeps only) → directory (last resort, labelled "structural grouping — not a conceptual boundary"). MUST ATTENTION record which rung you landed on — the reader calibrates on it exactly as on a grep-derived route. Tier S0/S1 → exactly one group, and this collapses to the classic single-file report with zero overhead.
[BLOCKING] Create the task list BEFORE gathering.
TaskListFIRST — an interrupted or compacted run resumes its tasks, never duplicates them. Then create one task per group plus the fixed tasks: size & decompose · scope-wide gather · open report + ledger · {one per group} · cross-group synthesis · chat summary + index · contract self-check. Exactly onein_progress; transition it before the work andcompletedimmediately after the evidence exists. A group task completes ONLY when that group's block is on disk — evidence is the path plus the sections it carries, never a summary in context. At S0/S1 still create one task per report part (I·II·III·IV). — why: a run that dies mid-report must show the reader exactly where it stopped, at every size.Decompose to the FINEST unit that still explains something. Do not stop at the coarsest split that clears the group tests — a group holding 8 loosely-related files is two groups pretending to be one, and it serialises work that could have run concurrently. Push down the decomposition axis one more rung whenever the result still yields cohesive, individually-explainable groups. More, smaller groups = more parallel width and a finer resume point; the ≤12-per-level guard and the nesting rule bound the count. — why: decomposition width IS the parallelism budget — a target split into 3 groups can never run 8-wide, no matter how many agents are available.
[BLOCKING at S2+] Tag every task
PARorSEQ, then declare the waves — BEFORE dispatching any of them.PAR= its inputs do not include another pending task's output AND its write target is disjoint from every otherPARtask; everything else isSEQand must name the dependency that forces it. The fixed task set classifies the same way on every run:S2 never assigns fragment ownership: gather agents return bounded evidence only and the orchestrator authors the one report. Fragment paths begin at S3+.
Task Mode Why size & decompose SEQevery other task consumes its group set scope-wide gather · open report + ledger PARone is read-only, the other writes only the report skeleton — disjoint targets {one per group} PAR— the main waveeach group reads its own file list and writes its OWN fragment; no shared write target cross-group synthesis SEQconsumes every group block chat summary + index · contract self-check SEQconsume the finished report Announce it in one line before the first spawn —
Parallel plan: wave 1 = [scope gather, open report+ledger] · wave 2 = [G1…G8] · SEQ = [synthesis, summary, self-check] (each consumes the whole wave)— then spawn every member of a wave in ONE message, never dripped one per turn, and honour the barrier: advance only after EVERY member returns. — why: a declared wave is checkable; an undeclared one silently degrades into the sequential run it was meant to replace.
Scale Protocol — grouping algorithm and the three group tests · group ordering (contract-inward at group altitude) · the exact task set · the accumulation ledger and write order · resumability after a cutoff · sub-agent fan-out rules at S3+ · caps and the no-silent-truncation rule · the degradation ladder.
At tier ≥ S2, MUST ATTENTION READ
references/scale-protocol.mdnow — before gathering. At S0/S1 skip it; one group needs none of it. Missing file → degrade exactly as in item 3: say so in one line and run on the inline rules above.
Step 1 — Gather the Material
Gather only what the resolved scope needs:
- Current working context (default):
TaskListfor active tasks;git diff --name-only(+ untracked viagit ls-files --others --exclude-standard) for the change set; the active plan and latest/watzupsummary if they exist. Extract: what's being worked on, what changed, why, new behavior. - A plan: read the plan files (
plan.md+phase-*.mdfrom the Plan Context / configured plans dir). Extract: problem, chosen approach, rejected alternatives, design decisions, risks, phase order. - A subsystem / feature / "how does X work": read the relevant files; run
python .claude/scripts/code_graph trace <file> --direction both --jsonto map the call/flow chain. Extract: entry points, data flow, key invariants. - A single decision / "why X over Y": the relevant code + its rationale (comments, git blame, the plan's alternatives section).
Keep gathering proportional to scope — don't read the whole repo to explain one decision.
Portable discovery — resolve locations, never hardcode them. Read docs/project-config.json (and the project-reference docs it points to) for source roots, spec/feature-doc location, test locations, and run commands. This skill runs on repos it has never seen; a hardcoded framework path is a guess wearing a citation. Where a source is absent, walk the degradation ladder stated per inventory below and record which rung you landed on — the reader calibrates on it.
Delegate the GATHERING when a direct read cannot fill an inventory — never delegate the TEACHING. Read + grep + trace fills most inventories. When it does not — you cannot locate the relevant files in an unfamiliar repo, the mechanics of an existing feature need a real investigation, a live defect's cause is unknown — invoke the repo's own read-only investigation skills and feed their output into the inventories below. Every section of the report is still authored here.
| The gather step needs… | Invoke | Feeds |
|---|---|---|
| Where the relevant files even are, across a large or unfamiliar codebase | /investigate |
Step 0.5 group decomposition + each group's file list |
| How an existing feature or subsystem actually works, beyond what one read shows | /investigate |
§6 How It Works · §7 Why This Solution · §5 Concepts |
| The root cause of a live, un-fixed defect | /debug-investigate |
§6 · §8 candidate causes with evidence for and against |
| The call/flow chain and its reach | /graph-trace · /graph-blast-radius |
§2 D1/D3 · §10 Blast Radius · Step 2 Axis A |
| Which spec owns a capability, when finding it is itself the problem | /spec-index |
§3 stories + REAL TC-* IDs · §11 cases |
- Read-only delegates ONLY. NEVER invoke a skill that mutates files or issues findings/verdicts (
/fix,/changes-review,/code-review,/why-review,/plan-execute) — this skill emits no findings and mutates nothing outside its own git-ignored artifacts, and a delegate must not smuggle either in through the back door. - MUST ATTENTION delegate on evidence of need — NEVER by reflex. Try read + grep + trace first, within the group's budget. Announce each delegation in one line and record it in the report header —
Delegated: /investigate — G3 mechanics— why: the reader calibrates on the provenance chain exactly as they do on a grep-derived route. - A delegate's output is INPUT, never a finished section. Re-verify every claim you carry forward against
file:linebefore it becomes a claim in the report; aTC-*ID that arrives through a delegate is still one you must have read yourself. The anti-hallucination bar does not relax by passing through another skill. - At tier S3+, delegation happens INSIDE the group's sub-agent, never in the orchestrator — why: delegating from the orchestrator pulls a whole investigation transcript back into the one context the grouping exists to protect.
Then gather the six things a description-only pass always skips. Each feeds a named section; a skipped inventory produces a thin section, which the Step 4 gate will reject.
Diagram sources (feeds §2). Collect the evidence each mandatory diagram is built from:
python .claude/scripts/code_graph trace <file> --direction both --node-mode file --jsonfor the component map; an existing specerDiagram(lift it verbatim — the cheapest correct source) else the entity/model class fields else the migration/schema files for the domain model; the flow entry points and their handler chains for the sequences. Note any entity carrying astatus/state/phasefield, a lifecycle enum, or a transition guard — that, and only that, fires the state diagram. Ladder: graph trace → grep + read the call sites → spec/plan text → state the blocker. Never a fifth rung of invention.Story & test-case inventory (feeds §3, and §11's cases). Identify the main user-facing capabilities in scope — the "As a … I want … so that …" the change delivers — and for each, the business rule or invariant it protects and where that rule is enforced (
file:line). Then collect the real cases that prove it: specTC-*IDs and/or the integration/unit/e2eit/[Fact]test names and scenarios. Use the actual IDs — never invent case numbers. Reconcile the union of spec TCs and test-code cases; a story with no case is a coverage gap to report, never a gap to fill with a plausible ID. Ladder: specs → tests → PBIs/release notes/commit messages → the diff itself.Review-path classification (feeds §4). Assign every in-scope file to a layer bucket per
references/review-path.md(contracts/API · domain · application · persistence · integration · UI · tests · config/generated), then walk one hop outward and admit the unchanged files a reviewer needs in order to judge the changed ones — the invariant owner, the interface satisfied, the base-class contract, the governing spec/TC. Mark every such file as context, not as a change. Ladder: graph trace → grep of imports/references, in which case the emitted route must carry its approximation label.The concept inventory (feeds §5). List every technical concept, pattern, or mechanism a reader must hold in their head to follow the flow — CQRS, optimistic concurrency, debounce, idempotency key, event sourcing, memoization, whatever is actually in play. Keep every load-bearing one — however many that is, with no maximum; drop decoration. For each, find where it is visible in this codebase (
file:line) so the concept is taught against real code, not in the abstract.The option space (feeds §8). For each significant decision, reconstruct what ELSE could have been done. Sources, in order of strength:
- the plan's rejected-alternatives section, ADRs under
docs/adr/, PR/commit messages, code comments saying "instead of"/"we tried"; git log/git blameon the touched lines — a prior implementation IS an alternative, and its removal is evidence;- 3+ sibling patterns already in this codebase solving the same shape of problem differently (grep/glob) — the strongest alternatives are the ones the repo already demonstrates;
- the framework/library's other supported approach for the same job;
- your own engineering judgement — the approach a competent engineer would have reached for first.
[ANTI-HALLUCINATION] Mark each option
[deliberated]only when you have evidence it was actually weighed during the work. Everything else is[reconstructed]— surfaced now, for the developer's judgement. NEVER dress a reconstruction up as a deliberation; a fabricated decision history is worse than none.- the plan's rejected-alternatives section, ADRs under
Demo & run evidence (feeds §11). Collect the project's own test/run commands from
docs/project-config.json, the seed/fixture paths that stage a scenario, and — per main case — how the domain stores or changes the data that makes the case work: the persisted field/column/table, the entity or migration that owns it, and the rule that consumes it to produce the outcome (file:lineeach). Read the code; do not infer persistence from names. A display-only case states "no storage change" and describes the computed representation instead. Ladder:project-config.json→ the CI workflow's own commands → the test runner's manifest (package.jsonscripts,*.csproj,Makefile) → state that you could not resolve a command rather than guessing one.[SECURITY] Record every command in placeholder form. Environment variables, connection strings, tokens, keys, and customer identifiers are referenced by NAME and rendered
<redacted:…>— never by value. This is the point where a secret would first enter context, so it is the point that must refuse it.
Step 2 — Order the Material (two different axes — do not conflate them)
You will explain the whole resolved scope. Two orderings come out of this step, and they answer different questions:
Axis A — narrative depth order (which topics get the most words). Order by leverage; open with what matters most, compress the rest:
- Blast radius: run
/graph-blast-radius(orpython .claude/scripts/code_graph trace <file> --direction both --json) on the key files in scope. High upstream/downstream reach → explain first and in most depth. - Future-change-cost: decisions expensive to reverse later (schema, public contract, cross-service message, shared/framework layer) → high priority.
- Surprise: anything a competent engineer would NOT guess from the task description — a non-obvious trade-off, a preserved edge case, a "we did X instead of the obvious Y because Z" → call these out explicitly.
Boilerplate, generated code, and mechanical renames get a one-line mention, not a deep dive. Nothing in scope is silently omitted — but depth follows leverage.
Axis B — review route order (which files a human opens first). Order contract-inward, per references/review-path.md: start at the layer that defines meaning (API contract, then domain invariants), walk outward through application → persistence → integration → UI, tests last, config/generated collapsed into one final skim. Blast radius is the tie-break between peers here, not the primary axis.
When the two disagree, each governs its own output — never borrow one for the other. A shared utility with the widest blast radius leads Axis A: it gets the deepest explanation in §6 and §10. It does NOT lead Axis B: a route that opens with a util file drops the reviewer into mechanism before they know what the change is supposed to mean, and they cannot tell a correct edit from an incorrect one. The entity that owns the invariant leads the route even when its reach is small. Axis A orders §5–§10; Axis B orders §4.
At multi-group scale both axes run INSIDE each group, and a third ordering appears ABOVE them: the group order. Groups are ordered contract-inward at group altitude — the group owning the shared contract or domain invariant first, then dependencies before dependents, cycles broken at the weakest edge and said out loud, peers tie-broken by blast radius, and the ungrouped remainder (config, generated, boilerplate) collapsed into one final skim group. That single ordering governs three things at once — the task order, the write order, and the spine's group route — so they can never disagree (references/scale-protocol.md §2).
Step 3 — Open the Teaching Report (write incrementally, never in one final batch)
[HARD RULE] Write ONLY git-ignored working artifacts — NEVER inside
.claude/, the source tree,docs/, or any git-tracked path. This skill mutates no sourc
…(truncated)