Diff recap
Readable agent skills with optional declarative YON protocols you can inspect and validate. A personal, field-used pack by Alexandru Mares.
npx -y skills add allemaar/open-skills --skill diff-recapAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Turn a git diff into a PR-pasteable recap — one row per changed file whose path, status, and line counts are transcribed verbatim from `git diff --numstat` (true by construction; the model writes only the labels), emitted as an inline annotated widget plus a mandatory ASCII twin and a `diff-recap/1` record whose totals equal the sum of the rows. Fills the PR-summary gap the orient- family does not cover. Not /orient-map (shape + delta of the work) or /orient-status (position + ETA) — diff-recap recaps a concrete change-set. Zero external dependency: it renders inline, never to a hosted service.
SKILL.md
12.1 KB, as published. Nobody here has run it
/diff-recap
Turns a git diff into a recap you can paste into a pull request — a per-file change table whose numbers are transcribed from git, grouped and labelled, rendered as an inline annotated widget with a mandatory ASCII twin, and backed by a diff-recap/1 record. It fills the gap the orient- family leaves open: orient-map shows the shape of the work and orient-status shows where you stand, but neither recaps what a concrete change-set contains for a reviewer. diff-recap does exactly that, and only that.
Its differentiator is true by construction: the structured numbers (per-file added/removed/status and the headline totals) come straight from git diff --numstat and --name-status — the model authors only the prose labels. A record whose totals don't equal the sum of its rows is rejected by a value gate before it can be shown, so the recap cannot quietly lie about the diff. And unlike a hosted recap renderer, it has zero external dependency — the ASCII twin is self-contained and PR-pasteable in any channel.
Structured execution spec:
protocol.yon. Read it for the canonical steps, rules, and gates; this file is the human-readable, self-sufficient explanation. The two must stay in sync — if you edit one, update the other and refresh the@STAMPdate.
When to use
- "Recap this diff / summarize these changes for a PR" — you want a reviewer-ready change summary, not a fresh read of the whole tree.
- "What changed in this branch" as a change-set, grouped by area with a one-line why per file.
- Right before opening a pull request, when you want a paste-able summary whose numbers you can trust.
How it works (self-sufficient — works without protocol.yon)
Every call recomputes from the real diff; nothing is stored.
-
Take
range,repo, andintentas inputs — never prompt.rangedefaults to the working tree againstHEAD(or aA..Brange, or--staged);repodefaults to the cwd.intent(the PR's goal) shapes the labels — if it's ungrounded, the recap still emits the mechanical facts but caps the labels to descriptive and never invents a rationale. -
Gather from git, transcribe verbatim. Run
git diff --name-statusandgit diff --numstatover the range. For each file, copy thestatus(A/M/D/R) and theadded/removedcounts exactly as git reports them. A binary file reports-/-in numstat → record0/0and mark the row binary in its label. The model never counts by hand — the numbers are git's. -
Group and label — the only model-written fields. Cluster the files by area (feature / tests / docs / config / …), and write one concise label per file and a one-line summary per group.
path,status,added,removedare git-attested;labelandgroupare the model's only freedom. -
Set the totals as the sum of the rows.
total_files,total_added,total_removedare the exact count and sums of the per-file rows — that is the true-by-construction invariant: the headline is, by definition, the sum of the attested rows. -
Fail closed. No git, or an empty diff →
gate_status = barren,attested = false, and a NO DIFF card — never a fabricated recap. Acleanrecap requires a real git source (attested = true); a partial source caps the verdict atpartial. -
Emit the triple bundle. The YON record (below), the PR-pasteable markdown summary, and the visual face (Claude Code only). diff-recap honors the three render-face branches: a human on Claude Code with the visualize tool present on an explicit invocation gets the widget + ASCII twin; an agent gets the YON record only; any other runtime / no tool / indeterminate
handler_typegets the ASCII twin (fail-closed). See the bundled, self-containedrender-face contract. diff-recap adopts only this branching, not the orient family's footer roster, "you are here" breadcrumb, or staleness short-circuit. The information-complete ASCII twin is always emitted — it carries every file row, count, group, and total the widget does (worked trio atexamples/diff-recap.{ascii.txt,widget.svg,example.yon}).
Record emission (the YON face — reserved tags only)
The record is a diff-recap/1 instance (recap-schema.yon). Reserved tags only. The envelope is @CFG id=recap; each changed file is one @CFG id=file.<n>; list fields (groups, provenance) go in a sidecar @MAP, never an in-set bracket-list (an in-set list corrupts the record silently and still validates). Never run yon format on an instance — CANON mode is destructive on set-internal lists. Validate with --profile exec, then run the value gate. Skeleton:
@CFG id=recap | set=[schema_version=diff-recap/1,computed_at:ts=…,ephemeral:bool=true,tool=diff-recap,range="HEAD",repo=".",total_files:int=4,total_added:int=155,total_removed:int=7,attested:bool=true,gate_status=clean,overall_trust=high]
@CFG id=subject | set=[name=…,kind=repo,purpose=…,intent_status=stated]
@CFG id=file.f1 | set=[path="src/rate-limit.ts",status=A,added:int=88,removed:int=0,group=feature,label="new token-bucket limiter"]
@CFG id=file.f2 | set=[path="src/server.ts",status=M,added:int=24,removed:int=6,group=feature,label="wire the limiter in"]
@MAP name=groups | pairs=["feature"->"limiter + wiring (2 files, +112/-6)"]
@MAP name=provenance | pairs=["recap.total_added"->"git-attested:high:git diff --numstat"]
On barren evidence the envelope degrades honestly: gate_status=barren, attested:bool=false, no file rows, and the visual is the NO DIFF card. A full worked instance ships at examples/diff-recap.example.yon.
The value gate — why the recap can't lie
yon validate checks structure, not values: a record can be valid YON yet state total_added=999 while its rows sum to 155. references/tools/diff-recap-check.mjs travels inside this skill folder and is the missing half — it asserts Σ per-file == totals, enum membership, and the fail-closed/attested gates, and with --numstat it checks every row against the real git numstat. An emitter runs it before emit; the source repository additionally exercises the worked and deliberately broken fixtures as release evidence.
node <skill-dir>/references/tools/diff-recap-check.mjs <skill-dir>/examples/diff-recap.example.yon --numstat <skill-dir>/examples/diff-recap.numstat
Output — worked examples (markdown / ASCII face)
📋 acme-api — add per-route rate limiting. range: HEAD [counts: ◆ git --numstat]
## 4 files · +155 / −7 ◆ git diff --numstat
feature +112 / −6
+ src/rate-limit.ts +88 / −0 new token-bucket limiter (per-route) ◆ A
~ src/server.ts +24 / −6 wire limiter in; drop old fixed counter ◆ M
tests +40 / −0
+ test/rate-limit.test.ts +40 / −0 burst, refill, per-route isolation ◆ A
docs +3 / −1
~ README.md +3 / −1 document the RATE_LIMIT env var ◆ M
Σ rows = +155 / −7 == headline ✓ (true by construction)
**→ PR summary:** per-route token-bucket rate limiter + unit tests + env-var doc.
Trust: ◆◆◆ every count git-attested · the model wrote only the labels · gate: clean
Barren (honest degradation is the success case):
📋 ToDo — no git, or an empty diff.
┌───────────────────────────────┐
│ NO DIFF │ nothing to recap — no commits, no changes.
└───────────────────────────────┘
**→ Next:** stage or commit a change, and the recap becomes visible.
Trust: ◌◌◌ · [gate: barren · attested: false]
The ASCII twin + the Σ rows == headline line + the trust trailer are mandatory on every output.
Boundaries
- Not
/orient-map— that shows the shape + delta of the work (done → here → next); diff-recap recaps a concrete change-set for a reviewer. They never overlap: orient-map is trajectory, diff-recap is a PR table. - Not
/orient-status— that reports position + remaining + ETA; diff-recap reports what a diff contains. - Not a code review — it summarizes what changed, it does not judge whether the change is good. Pipe it into
/cold-reviewfor that. - Read-only. It runs
git diffand reads the tree; it never mutates state. - No hosted dependency. Unlike a hosted recap renderer, the ASCII twin is the floor and is self-contained — the recap works with no visualize tool, no server, no account.
Rules
- MUST be true by construction — transcribe
path,status,added,removedverbatim fromgit diff --name-status/--numstat; never count by hand. The model authors onlylabelandgroup. - MUST set
total_files/total_added/total_removedto the exact count and sums of the rows, so the headline equals the sum of the attested rows; the value gate rejects any record where they drift. - MUST fail closed — no git or an empty diff →
gate_status = barren,attested = false, NO DIFF card; acleanverdict requiresattested = true. - MUST always emit the information-complete ASCII twin — it is the only render in a no-SVG channel and is PR-pasteable verbatim.
- MUST render the visual face per the render-face contract (Claude Code only, via
mcp__visualize__show_widget): agent → YON record only; human + Claude + tool + explicit invocation → widget + ASCII twin; other runtime / no tool / indeterminatehandler_type→ ASCII twin (fail-closed). Widget and ASCII twin are projections of one row-structure (same rows + totals), chrome-compliant (no hardcoded color,role="img"with non-empty title/desc, fixed 680 viewBox). - MUST emit file rows as
@CFG id=file.<n>and list fields (groups,provenance) as sidecar@MAP; never a bare in-set bracket-list; neveryon formatan instance. - MUST take
intentas input and cap labels to descriptive when it's ungrounded — never fabricate a rationale.
Next skills. On completion, run the Next Skills protocol (
next-skills/SKILL.md): surface thenext-skillsrecommendations from front-matter for the caller to pick. Offer only — never auto-invoke.
Self-improvement. On completion, run the Self-Improvement Protocol (
self-improve/SKILL.md): if this run surfaced a concrete, blocking-or-recurring weakness in this skill, propose a specific fix for the handler to approve. Conservative — silent otherwise. Never auto-apply.