agentleFS
allemaarallemaar/open-skills/skills/diff-recap/SKILL.md

diff-recap

Skill15 starsChanged 13 days agoApache-2.0View on GitHub

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 --name-status` and `--numstat` (the model writes only the labels), emitted as a `diff-recap/1` record whose totals equal the sum of the rows, with a complete ASCII recap for human readers and an inline widget when the render-face contract permits it. 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.

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 2 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every call recomputes from the real diff.

    line 45
  2. Very specific:

    Fail closed: No git, or an empty diff → gate_status = barren, attested = false, and a NO DIFF card — never a fabricated recap.

    line 55
  3. Very specific:

    MUST be true by construction — transcribe path, status, added, removed verbatim from git diff --name-status/--numstat.

    line 125
  4. Very specific:

    MUST set total_files/total_added/total_removed to the exact count and sums of the rows, so the headline equals the sum of the attested rows.

    line 126
  5. Very specific:

    MUST fail closed — no git or an empty diff → gate_status = barren, attested = false, NO DIFF card.

    line 127
  6. Distinctive:

    MUST emit the information-complete ASCII twin on human-facing and indeterminate branches — it is the only human render in a no-SVG channel …

    line 128
  7. Very specific:

    MUST emit file rows as @CFG id=file.<n> and list fields (groups, provenance) as sidecar @MAP.

    line 130
  8. Very specific:

    MUST take intent as input and cap labels to descriptive when it's ungrounded — never fabricate a rationale.

    line 131

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

/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, backed by a diff-recap/1 record, with a complete ASCII recap for human readers and an inline widget when the render-face contract permits it. 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, which checks internal arithmetic; source fidelity still depends on the required Git capture and transcription. 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 @STAMP date.

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.

  1. Take range, repo, and intent as inputs — never prompt. range defaults to the working tree against HEAD (or a A..B range, or --staged); repo defaults 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.
  2. Gather from git, transcribe verbatim. Run git diff --name-status and git diff --numstat over the range. Hold the exact repository, range and rename/copy-detection settings constant across both captures. Before transcribing rows, inspect the status and path arity. Any rename/copy status (R, C, R100, C75, or another score) or two-path rename/copy form is UNSUPPORTED INPUT for the current single-path record: report the exact source case and stop without emitting a recap. Do not strip scores, collapse paths, drop rows, silently disable detection, or mislabel this as barren/NO DIFF. For ordinary single-path files, copy status (A/M/D) and added/removed exactly as git reports them. A binary file reports -/- in numstat → record 0/0 and mark the row binary in its label. The model never counts by hand — the numbers are git's.
  3. 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, removed are git-attested; label and group are the model's only freedom.
  4. Set the totals as the sum of the rows. total_files, total_added, total_removed are 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.
  5. Fail closed. No git, or an empty diff → gate_status = barren, attested = false, and a NO DIFF card — never a fabricated recap. A clean recap requires a real git source (attested = true); a partial source caps the verdict at partial.
  6. Emit the selected bundle. Emit the YON record (below); human-facing branches add the PR-pasteable markdown summary and selected visual face. 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_type gets the ASCII twin (fail-closed). See the bundled, self-contained render-face contract. diff-recap adopts only this branching, not the orient family's footer roster, "you are here" breadcrumb, or staleness short-circuit. Every human-facing or indeterminate branch emits the information-complete ASCII twin — it carries every file row, count, group, and total the widget does (worked trio at examples/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"]

Unsupported input is a separate diagnostic, not a diff-recap/1 record or a new gate enum. The legacy R schema enum does not provide an old/new-path encoding. Supporting scored renames/copies requires a separately selected compatible format. The value checker does not inspect --name-status; the emitter must perform this input boundary before value validation.

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 compares row paths and counts against the supplied capture. It does not compare statuses with --name-status or establish capture origin or freshness; an attested flag alone is not source evidence. The emitter still verifies the bound Git source and transcribes statuses. 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 human-facing and indeterminate output; an agent consumer receives only the record.

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-review for that.
  • Read-only. It runs git diff and 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, removed verbatim from git diff --name-status/--numstat; never count by hand. The model authors only label and group.
  • MUST set total_files/total_added/total_removed to 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; a clean verdict requires attested = true.
  • MUST emit the information-complete ASCII twin on human-facing and indeterminate branches — it is the only human render in a no-SVG channel and is PR-pasteable verbatim. The agent-only branch emits only the record.
  • MUST select the output per the render-face contract (the widget is Claude Code only, via mcp__visualize__show_widget): agent → YON record only; human + Claude + tool + explicit invocation → widget + ASCII twin; other runtime / no tool / indeterminate handler_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; never yon format an instance.
  • MUST take intent as 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 the next-skills recommendations 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): apply its signal taxonomy and threshold to this run; surface any surviving proposal for handler approval. Conservative — silent otherwise. Never auto-apply.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.