Generate a Review Walkthrough Guide
Analyze a git diff and produce a guide XML sidecar that self-review discovers next to its output file. The guide reorganizes the file tree from alphabetical order into named, ordered groups with rationales, gives each file a one-line description of its role in the change, and provides a review-level overview shown before the first file.
The guide asserts reading order, never review verdicts. It carries no severity, no confidence,
no findings, and no comments — that is self-review-critique's job. This skill only answers one
question: in what order, and with what orientation, should a human read this diff?
XML Reference
Non-obvious semantics (keep in sync with assets/self-review-guide-v1.xsd):
- Document order IS reading order. Groups are presented in the order they appear, and files within a group in the order they appear. There are no ordering attributes; to reorder, reorder the elements.
- Presentation only, never suppression. The vocabulary has no way to hide, collapse, or mark a file as skippable, and the consumer shows every file regardless. Files you omit from every group are not hidden — self-review shows them in an implicit trailing "Everything else" group.
- Each diff file appears in at most one group. Duplicating a path across groups is invalid authoring; the first mention would win and the rest would be noise.
- Stale entries degrade silently. A
<file>whosepathmatches nothing in the diff is silently dropped by the consumer. Paths are repository-relative, same convention asreview.xml; for renamed files, use the new path. rationaleanddescriptionare single plain-text sentences. No Markdown, no line breaks.overviewis Markdown. Fenced code blocks are allowed, including a```mermaidfence for a diagram of the change.- Provenance attributes are optional.
timestamp,git-diff-args, andrepositorymirror the review schema's provenance; they help a consumer sanity-check freshness but never affect presentation.
Hard Rules
These are invariants, not style preferences. A guide that breaks them is wrong even if it validates:
- Account for every file. Every file in the diff either appears in exactly one group or is knowingly left to the implicit "Everything else" group. Never lose track of a file; before writing the XML, reconcile your group lists against the full diff file list.
- Describe and order, never judge skippable. You may say a group is mechanical churn and place it last; you may never say or imply it need not be read. Words like "skip", "ignore", "can be skimmed", "no need to review", "safe to ignore" are forbidden in rationales, descriptions, and the overview.
- No review verdicts. No bug claims, no severity language, no "looks correct", no "needs attention because it is risky code". The guide orients; critique judges.
1. Parse Arguments
Read $ARGUMENTS for git diff args. If empty, default to unstaged changes (plain git diff).
The arguments support the same format as self-review CLI: --staged, HEAD~3,
main..feature-branch, -- path/to/file, etc.
If the argument is a GitHub PR URL (https://<host>/<owner>/<repo>/pull/<N>) or a GitLab MR
URL (https://<host>/<namespace>/<repo>/-/merge_requests/<N>, any host — self-hosted GitLab
included), this is a URL source: follow the "URL source" recipe in step 3 to materialize
the diff, then continue with the remaining steps unchanged.
2. Load Configuration
Check if .self-review.yaml exists in the current directory. If it does, read it to extract:
output-file: The review output path (default./review.xml)guide-file: Explicit guide output path, if set
Determine the guide output path:
- If
guide-fileis set, use it. - Otherwise derive it from the review output path by stripping the last extension (whatever it
is) and appending
.guide.xml:review.xml→review.guide.xml,out/my-review.xml→out/my-review.guide.xml,review.out→review.guide.xml. An output filename with no extension gets.guide.xmlappended verbatim.
This pairing is how self-review discovers the guide at launch — it looks for
<output-basename>.guide.xml next to its configured output path, with no CLI flag.
3. Get the Diff
Use the Bash tool to run:
git diff $ARGUMENTS
If the diff output is empty, report "No changes to guide." and stop.
URL source: materialize the PR/MR first
For a PR/MR URL, materialize the diff through the same clone-aware model the self-review app uses, so steps 4–5 can read surrounding code from a real checkout instead of the bare diff:
- Head ref. From the URL:
refs/pull/N/head(GitHub) orrefs/merge-requests/N/head(GitLab). - Base branch. Ask the forge CLI:
gh pr view N --repo <host>/<owner>/<repo> --json baseRefName -q .baseRefName(GitHub) orglab mr view N --repo <host>/<namespace>/<repo> --output jsonand readtarget_branch(GitLab). If the CLI is unavailable, fall back to the remote default branch:git ls-remote --symref https://<host>/<owner>/<repo>.git HEAD(theref:line names it). - Materialize. If the current directory is inside a clone whose remote matches the URL's
host and owner/repo (check
git remote -v), fetch into it — read-only for the working tree:git fetch <remote> "+refs/heads/<base>:refs/self-review/base" "+<head-ref>:refs/self-review/head". Otherwise create a temporary blobless clone (never--depth, which breaks merge-base computation):git clone --filter=blob:none https://<host>/<owner>/<repo>.git <tmpdir>, thengit -C <tmpdir> fetch origin "+<head-ref>:refs/self-review/head"; the base isorigin/<base>. Private repositories rely on git's own credentials (gh auth setup-git/glab auth git-credentialwire the forge CLI login into git). - Diff. Run the three-dot diff (from the merge base, matching how the forge presents the
PR/MR) inside the checkout:
git -C <repo> diff <base-ref>...refs/self-review/head. - Read file content with
git -C <repo> show refs/self-review/head:<path>— in a temporary clone the working tree is the default branch, not the PR head, and blobs fetch lazily on demand.
Set git-diff-args to the <base-ref>...refs/self-review/head range you diffed, and leave the
optional repository attribute unset. The checkout is often a temporary clone under the OS
temp directory, and even a reused local clone's path is specific to this machine; recording it
would mislead anyone opening the guide from a different checkout. Remove a temporary clone
when the whole run is finished — when invoked from self-review-critique, leave it in place so
the critique steps can reuse the same checkout, and let the outer run clean it up.
4. Understand the Change
You need enough context to say what role each file plays, not to judge its correctness:
- Read the diff hunks of every file. For most files this is sufficient.
- When a file's role is unclear from its hunks alone (e.g., a small edit whose purpose depends on its callers), use the Read tool on the relevant region of the file.
- Binary files and generated/lockfile churn rarely need reading beyond their paths and stats.
Identify the center of gravity: which file(s) contain the change everything else exists for? Which files are consequences (call-site updates, type fallout)? Which are verification (tests, fixtures)? Which are mechanical (lockfiles, generated output, formatting)?
5. Group and Order
Build the reading path:
- Aim for 2–5 groups. One group means you found no structure; more than five means the structure is noise.
- Lead with the core. The first group holds the files the reviewer must understand first — the "Core change" — with a rationale saying why they anchor everything else.
- Mechanical churn goes late, labeled honestly. Lockfiles, generated code, and formatting fallout belong in a later group whose rationale says what produced them (e.g., "Lockfile and generated types regenerated by the dependency bump") — an honest label, never a dismissal.
- When unsure, promote. A file you cannot confidently classify goes in an earlier group, not a later one. Bias toward attention: the cost of over-promoting a boring file is seconds; the cost of demoting a load-bearing one is a missed defect.
- One-liners describe the file's role in this change, not what the file is in general. "Adds the retry wrapper the other files call" — not "Utility module for HTTP retries".
- Overview orients, then stops. A few sentences: what the change does, where to start
reading, how the groups relate. Include a
```mermaiddiagram only when a picture genuinely orients — a dependency direction, a before/after flow — not as decoration. Do not restate every file.
6. Build the Guide XML
Read the XSD schema at assets/self-review-guide-v1.xsd (relative to this skill's directory) for
the complete structure and validation rules. The <xs:documentation> annotations describe all
element and attribute semantics.
Construct the XML using the Write tool at the output path from step 2. Minimal example:
<?xml version="1.0" encoding="UTF-8"?>
<guide xmlns="urn:self-review-guide:v1" timestamp="2026-08-01T14:30:00.000Z" git-diff-args="--staged">
<overview>Adds retry-with-backoff to the HTTP client. Start with the wrapper in `src/retry.ts`; everything else adopts it.
```mermaid
graph LR
client[src/client.ts] --> retry[src/retry.ts]
jobs[src/jobs.ts] --> retry
```</overview>
<group name="Core change">
<rationale>The retry wrapper everything else calls; read this first.</rationale>
<file path="src/retry.ts"><description>Adds the retry wrapper the other files call.</description></file>
<file path="src/client.ts"><description>Switches the HTTP client onto the wrapper.</description></file>
</group>
<group name="Tests">
<rationale>Coverage for the new wrapper and the migrated call sites.</rationale>
<file path="src/retry.test.ts"><description>Unit tests for backoff timing and give-up behavior.</description></file>
</group>
</guide>
Additional notes not in the schema:
timestamp: Get current time withnode -e "console.log(new Date().toISOString())"repository: Optional; normally omit it. It records an absolute checkout path, which is stale or misleading once the guide moves to a different checkout (a teammate's clone, the host machine, CI). Set it only when the guide stays in this exact checkout. Get the value withgit rev-parse --show-toplevel.git-diff-args: The same arguments from step 1 (empty string if none)- XML-escape all text content:
&→&,<→<,>→>,"→",'→'
7. Validate the XML
Use the Bash tool to run:
xmllint --schema .agents/skills/self-review-guide/assets/self-review-guide-v1.xsd GUIDE_XML_PATH --noout
Where GUIDE_XML_PATH is the output path from step 2.
- If validation passes: proceed to step 8.
- If validation fails: read the xmllint errors, fix the XML, and re-validate. An invalid guide is silently ignored by self-review (it degrades to the flat view with only a stderr warning), so an unvalidated guide risks being a no-op.
- If
xmllintis not installed: warn the user and continue without validation.
8. Output Summary
After writing the file, print a summary:
- Number of files in the diff, and how many were placed in explicit groups vs. left to "Everything else"
- The group names in reading order
- Output file path
Then remind the user how the guide is picked up:
self-review discovers the guide automatically:
self-review <same-diff-args>
(the guide is loaded when GUIDE_XML_PATH sits next to the review output path)