rich-html.branch-review

Branch review — skills #20

main…moacyrricardo/spec-002-branch-review · 10 files · +303 −52

The PR that added the branch-review command, reviewed by the command itself. Slice the diff two ways with the filters below — by change type (why a cluster exists) or by file type — they combine and intersect. The file navigator (left) jumps to any file; each change-type leads with its reasoning, the real diff underneath.

change type
file type showing 10 files · +303 −52
☰ files

why these change-types How this diff is organized

This PR sorts into four change-types — clusters named by what each group of changes is for, not by which folder it touches. branch-review-command is the headline: the single new file that defines the command's behaviour. The other three exist only to land it — promote-to-third-command registers it across the plugin's shared contract and public manifests; docs-propagation threads it through every human-facing page; spec-002-record closes the repo's spec-workflow loop.

The split is deliberate: the one cluster carrying real behaviour is isolated from the mechanical support work, so you spend attention where the risk is and skim the rest. Because each name states an intent, “which part actually matters?” is answerable from the cluster list alone — the headline is the untagged one.

branch-review-commandchange-specific · headline +139 −0 · 1 file

The point of the PR — one file that is the command. Defines the whole content model (diff resolution, the two filter axes, the filter-driven summary) and delegates every format concern to html-doc. It fits no seed word because it is the change — the one untagged cluster.

plugins/rich-html/commands/branch-review.md newcode+139 −0
@@ -0,0 +1,139 @@+---+description: Turn a branch or PR diff into a self-contained, filterable HTML review — the full diff narrowed by facet (code/tests/docs/spec) and regrouped by change-type (why each cluster of changes exists), with a summary that recomputes as you filter. Asks nothing it can infer; reads the diff and its intent, then emits one theme-aware file. Read-only — it never touches the branch it reviews.+argument-hint: <branch | PR#/URL | range> [angle/audience notes]+---++Build a rich HTML **branch review** of **$ARGUMENTS**.++A branch review turns a diff into **one readable, filterable document** — not a wall of hunks. It+reads the change and *why each part of it exists*, then lets a reviewer slice the full diff two+ways: by **facet** (is this code, tests, docs, or spec?) and by **change-type** (what is this+cluster of changes *for*?). It is a document *about* a diff — it **never mutates** what it reviews+(no commits, no pushes, no PR edits, no branch changes). The output is a single self-contained+interactive HTML file.++**Format contract:** the *how* of the file — self-containment / Artifact CSP, theme-awareness,+progressive disclosure, and the **Visual evidence** vocabulary (the diff hunks and the summary+chart are exactly that) — comes from the **`html-doc`** skill. Read+`${CLAUDE_PLUGIN_ROOT}/skills/html-doc/SKILL.md` first and conform to it. This command owns only+the *what*: resolving the diff, classifying it, and structuring the review.++## 1. Resolve the diff — pin exactly what is under review++Work out the change set from `$ARGUMENTS`, in priority order:++- **PR number / URL** (`#662`, a GitHub URL) → `gh pr diff <n>` for the diff and `gh pr view <n>`+  for title, body, and threads (the *intent* behind the change). Base = the PR's base branch.+- **A range** (`main...feature`, `a1b2..c3d4`) → use it verbatim.+- **A branch name** → `git merge-base` against the repo's default branch, then diff `base...branch`.+- **Bare / no argument** → the current branch against its merge-base with the default branch.++The diff is the **net** `base...head`. Pin the resolved base and totals in the report header+(`main…feature · 42 files · +1,013 −287`) so the reader knows exactly what they are looking at.+`gh` is only needed for the PR path — a range or branch needs nothing but `git`.++## 2. Classify by facet — the mechanical axis++Tag every change with a **facet**; the filter is `[all] [code] [tests] [docs] [spec]`, combinable:++- **`code`** — non-test source files.+- **`tests`** — test paths and suffixes (`*test*`, `*spec*`, `__tests__`, `*_test.*`, test dirs).+- **`docs`** — comment-only / javadoc-only hunks, `*.md`, doc dirs. **Classify this at the hunk+  level, not the file level:** a code file whose change is a big comment or javadoc block is `docs`,+  not `code` — otherwise prose-heavy diffs read as pure code. A single hunk can **mix facets**: tag+  it by its dominant facet, and where a block inside it is cleanly one facet (a whole javadoc+  paragraph beside code) you may split it into presentational sub-hunks so each carries one tag.+  Don't over-split — this is for legibility, not partition purity.+- **`spec`** — files under a `specs/` catalog (or the project's documented spec location).++This axis is heuristics, not judgment — the lowest-risk part. Let the target project's `CLAUDE.md`+override the path rules if it documents its own layout.++## 3. Cluster by change-type — name each cluster by its intent++This is the axis that makes the review worth more than a diff viewer, and the one that degrades+into a generic dump if you get it wrong. Group the diff by **change-type = why a cluster of+changes exists**, and follow these rules exactly:++- **Name every cluster by what *this* change does** — `jul2026-sync-replay`,+  `java-opts-expansion-fix`, `pipeline-revert` — **never a bare layer word** like `service`,+  `config`, or `migration`. The name is the reasoning in miniature.+- **Treat this vocabulary as a prompt list and an optional tag, not buckets to sort into:**+  `model/repository`, `config`, `service`, `api-surface`, `migration`, `test-scaffolding`,+  `process/convention` (spec records, catalog/changelog, lint config). Use it to *prompt* yourself+  to look, and to *tag* a cluster for filtering — **never make "is this seed or emergent?" a+  question you have to answer.** A cluster can carry a tag *and* be named by its intent.+- **The smell to watch for is generic-layer naming.** If a cluster's *name* is a bare layer word+  instead of a phrase describing what the change does, you have probably missed the point of the+  change — re-read the diff. (Checkable from the names alone, which is the whole point.)+- **All-emergent is fine.** A revert or consolidation has no forward-feature clusters and every+  cluster is change-specific — that is correct, not a gap. Too few tags is never the problem;+  generic names are.+- **The headline change is often the untagged one.** The cluster that is the *actual point* of the+  PR frequently fits no seed word and stays change-specific, while the peripheral clusters (a+  migration, test scaffolding, the spec record) carry seed tags. That asymmetry is expected.+- **Cluster tests by the intent they serve.** When test files back two genuinely different+  production changes, split them into separate clusters named for each; when splitting would force a+  generic name, keep them one. ("Too few tags is never the problem" governs the seed tags — not how+  finely you cluster by intent.)+- **Each cluster carries its reasoning** — one short paragraph on *why* it exists — sitting **above+  the actual hunks** it draws on, in `<details>` (the `html-doc` Visual-evidence rule: the claim in+  prose, the real diff one expand below it, escaped). Those hunks **may overlap** another cluster's+  — two change-types can live on one physical line. Intents partition cleanly; hunks need not.++If the diff has a `specs/` catalog (or the project's documented spec location), read the relevant+spec/concern for the *intent* and link it. If it has none, the review works identically without the+`spec` facet — **never require one.**++## 4. Summarize — a summary that moves with the filter++A **summary block**, directly under the filter controls, that recomputes as facets and change-types+are toggled. It reflects the **currently visible** (filtered) changes: files touched (each distinct+file counted once), ± lines, and per-change-type line counts over the hunks still shown. Render the+per-change-type line distribution as a **single-series bar chart** — inline SVG, no chart library.+**Load the `dataviz` skill first** for palette and light/dark-safe form; a review's line+distribution *is* a distribution. **Pin the chart's axis to the full-diff maximum** so toggling a+filter shortens bars in place without rescaling the axis — the bars stay comparable to the whole+change rather than jumping.++## 5. Build the surface (per `html-doc`)++One self-contained, theme-aware file:++- **Layout order:** the filter controls sit at the **top** — they govern the whole document — then+  the summary block and its chart, then the change-type clusters. Filters are the control surface;+  everything below reflects the current selection.+- **Two filter axes** — facet and change-type — as combinable checkbox rows with **live counts**.+  The full diff renders filtered by the active selection.+- **Change-type clusters are the primary structure**; the facet filter narrows within and across+  them. Each cluster is its reasoning paragraph + the hunks one expand away.+- Hunks in `<pre>` with add/del styling, every interpolated line **escaped** (`<`, `>`, `&`) so a+  diff can't break the layout or inject markup.+- **Selection state in small vanilla JS.** The document must be **fully readable with JS disabled**+  — clusters, reasoning, and diffs are all present; filtering is the enhancement, never the gate.++## 6. Deliver++Write the `.html` to a sensible path (the user's scratchpad unless they name a location) and hand+it back with the file tools; offer to publish it as an Artifact for a shareable link. Give a+one-or-two-line summary of what the change *is* — don't restate the review in chat; the file is the+deliverable.++## Notes++- **Read-only** is a hard guarantee: this command resolves a diff and writes exactly one output+  file. It never commits, pushes, edits a PR/issue, or changes the branch it reviews.+- Project-agnostic: the tracker, the default branch, the spec location, and any path overrides come+  from the target project's `CLAUDE.md`, never hardcoded here.+- **Known gap — net-diff blindness:** the review reads the net `base...head` diff, so on a+  build-then-revert branch, work the PR body centers on can net to zero and not appear. When the PR+  body describes a path as *changed by this PR* but that path is absent from the net diff, **flag+  it**. A path the body merely *references* for context — an unchanged file, a line number in+  existing code — is not a gap; don't flag those.+- **The two axes are lenses, not a partition.** Facet and change-type can overlap — spec content+  shows up under the `spec` facet *and* a `process/convention` change-type, and on a small PR the two+  axes can nearly coincide. That's fine: each axis is a way to slice the same diff, not a claim that+  they carve disjoint sets.+- Complements `report` (facts *about* heterogeneous sources) and `decide` (the forks *between*+  things). A branch review is the third shape: one diff, read and organized. If the change hides a+  decision that still needs making, point at `decide`.
promote-to-third-commandapi-surface +13 −12 · 3 files

Makes branch-review a first-class sibling, not a loose file. Widens the shared html-doc contract from two commands to three and bumps the plugin's public surface — description, 0.2.0 → 0.3.0, marketplace entry. No behaviour; registration.

plugins/rich-html/skills/html-doc/SKILL.mdcode+9 −8
@@ -1,12 +1,13 @@ --- name: html-doc-description: The shared authoring contract for the rich-html plugin's document tools (report and decide) — how to build a single self-contained, theme-aware, interactive HTML file that renders anywhere (browser or Claude Artifact under a strict CSP) and uses progressive disclosure / expandable context to keep a dense document readable. Load this when generating a rich-html report or decision surface so the two feel like one system. This is the single source of truth those commands build on — prefer it over any inline restatement.+description: The shared authoring contract for the rich-html plugin's document tools (report, decide, and branch-review) — how to build a single self-contained, theme-aware, interactive HTML file that renders anywhere (browser or Claude Artifact under a strict CSP) and uses progressive disclosure / expandable context to keep a dense document readable. Load this when generating a rich-html report, decision surface, or branch review so they feel like one system. This is the single source of truth those commands build on — prefer it over any inline restatement. ---  # Authoring a self-contained interactive HTML document -`report` and `decide` both emit **one HTML file** that a person opens and interacts with. This-skill is the format contract they share so their output feels like one system. It is *not* about+`report`, `decide`, and `branch-review` each emit **one HTML file** that a person opens and+interacts with. This skill is the format contract they share so their output feels like one system.+It is *not* about what to put in the document (each command owns its content) — only *how the file is built*.  The three non-obvious constraints below are the whole point of the skill; a capable model will get@@ -64,7 +65,7 @@ Every piece of evidence is **text plus, when it helps, a supporting artifact — alone.** The prose states the claim or the fork and carries the reader; a code snippet, chart, diagram, or sketch sits *under* it, inside the expandable context, as substantiation the reader can check. So the question is never "text or visual" — it is whether a supporting artifact earns its-place beside the text. Both commands draw from the same small vocabulary of supporting forms so+place beside the text. All three commands draw from the same small vocabulary of supporting forms so their output stays one system; each command owns *when* a piece of its content warrants one, this skill owns *how* each is built (and every form here is inline and CSP-safe — SVG and divs inline, images as `data:` URIs):@@ -80,7 +81,7 @@ images as `data:` URIs):   than hand-rolling a bar — a report synthesizing history or logs is often *itself* a trend, so this   is the form `report` reaches for most. - **UI appearance → show it.** Embed the screenshot as a `data:` URI rather than describing how a-  screen looks. **Read-only caveat:** both commands only inspect — use an image the source already+  screen looks. **Read-only caveat:** all three commands only inspect — use an image the source already   has (a PR, an issue, a thread); never spin up the app just to capture one. With no existing image,   fall back to a layout sketch or plain description. - **Page layout → rough it in divs+CSS.** A few styled divs sketching each option's arrangement,@@ -107,7 +108,7 @@ is off.  ## The house skeleton -Both commands start from the same shape — a fixed header with the theme toggle, then content:+All three commands start from the same shape — a fixed header with the theme toggle, then content:  ```html <!doctype html><html lang="en"><head><meta charset="utf-8">@@ -131,7 +132,7 @@ Both commands start from the same shape — a fixed header with the theme toggle ## Delivering the file  - Write the `.html` to disk and hand it back with the file tools (or publish as an Artifact when-  the user wants a shareable link — Artifacts render this format natively). Both commands say where-  their output lands.+  the user wants a shareable link — Artifacts render this format natively). Each command says where+  its output lands. - One document = one file. If a command produces a companion machine payload (e.g. `decide`'s   emitted prompt), that is separate from this HTML, not embedded chrome inside it.
plugins/rich-html/.claude-plugin/plugin.jsoncode+2 −2
@@ -1,7 +1,7 @@ {   "name": "rich-html",-  "description": "Turn your work into rich, self-contained interactive HTML deliverables. report synthesizes heterogeneous sources (docs, trackers, PRs, git, code) into a readable document; decide aggregates pending decisions into an expandable-context surface that emits one prompt to execute them. General-purpose — no spec or tracker coupling.",-  "version": "0.2.0",+  "description": "Turn your work into rich, self-contained interactive HTML deliverables. report synthesizes heterogeneous sources (docs, trackers, PRs, git, code) into a readable document; decide aggregates pending decisions into an expandable-context surface that emits one prompt to execute them; branch-review turns a branch or PR diff into a filterable review, grouped by change-type. General-purpose — no spec or tracker coupling.",+  "version": "0.3.0",   "author": {     "name": "Moacyr Ricardo",     "email": "moacyr.ricardo@gmail.com"
.claude-plugin/marketplace.jsoncode+2 −2
@@ -30,9 +30,9 @@     {       "name": "rich-html",       "source": "./plugins/rich-html",-      "description": "Turn your work into rich, self-contained interactive HTML deliverables: report synthesizes heterogeneous sources into a readable document; decide aggregates pending decisions into an expandable-context surface that emits one prompt to execute them. General-purpose, no spec/tracker coupling.",+      "description": "Turn your work into rich, self-contained interactive HTML deliverables: report synthesizes heterogeneous sources into a readable document; decide aggregates pending decisions into an expandable-context surface that emits one prompt to execute them; branch-review turns a branch or PR diff into a filterable review grouped by change-type. General-purpose, no spec/tracker coupling.",       "category": "productivity",-      "tags": ["html", "report", "decisions", "synthesis", "interactive"]+      "tags": ["html", "report", "decisions", "branch-review", "diff", "synthesis", "interactive"]     },     {       "name": "prototype",
docs-propagationdocs +119 −39 · 4 files

Weaves the third command through every human-facing page. The guide gains a three-track diagram, a third tool card, a step group and a changelog entry; the landing page and README get it in their tables and blurbs. Mechanical, but load-bearing for discovery.

docs/rich-html-guide.htmldocs+58 −12
@@ -92,14 +92,14 @@   .term .cmd { color: var(--ink); font-weight: 600; }    /* two-tool table cards */-  .defs { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 8px; }+  .defs { display: grid; grid-template-columns: repeat(3,1fr); gap: 16px; margin-top: 8px; }   .def { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 22px; }   .def .tag { font-family: var(--mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-ink); margin: 0 0 8px; }   .def h3 { margin-bottom: 8px; }   .def p { margin: 0 0 10px; color: var(--ink-soft); font-size: 15.5px; }   .def .meta { font-family:var(--mono); font-size:12px; color:var(--muted); }   .def .meta b { color: var(--ink-soft); font-weight:600; }-  @media (max-width: 620px) { .defs { grid-template-columns: 1fr; } }+  @media (max-width: 780px) { .defs { grid-template-columns: 1fr; } }    /* two-track diagram */   .tracks { display:flex; flex-direction:column; gap:14px; margin-top:6px; }@@ -181,11 +181,12 @@    <div class="hero">     <p class="eyebrow reveal">Claude Code · interactive HTML deliverables</p>-    <h1 class="reveal">Turn your work into <span class="grad">documents you can read and act on.</span></h1>-    <p class="lede reveal">Two commands that take the scattered inputs of your work and produce one self-contained, interactive HTML file. <code>report</code> synthesizes sources into something to read; <code>decide</code> gathers pending choices into something to act on.</p>+    <h1 class="reveal">Turn your work into <span class="grad">documents you can read, act on, and review.</span></h1>+    <p class="lede reveal">Three commands that take the scattered inputs of your work and produce one self-contained, interactive HTML file. <code>report</code> synthesizes sources to read; <code>decide</code> gathers pending choices to act on; <code>branch-review</code> turns a diff into a filterable review.</p>     <div class="flowline reveal">       <div class="fl"><b>sources</b><span class="arw">→</span><b>report</b><span class="arw">→</span><b>a readable document</b></div>       <div class="fl"><b>decisions</b><span class="arw">→</span><b>decide</b><span class="arw">→</span><b>an expandable surface + one prompt</b></div>+      <div class="fl"><b>a diff</b><span class="arw">→</span><b>branch-review</b><span class="arw">→</span><b>a filterable review by change-type</b></div>     </div>   </div> @@ -205,14 +206,14 @@ <h2 class="reveal">One command to add it, one to install</h2> <span class="c"># 3 · activate in the current session</span> <span class="p">/</span><span class="cmd">reload-plugins</span></pre>     </div>-    <p class="read reveal" style="margin-top:16px; color:var(--muted); font-size:14.5px;">Once installed the commands are namespaced — <code>/rich-html:report</code>, <code>/rich-html:decide</code>.</p>+    <p class="read reveal" style="margin-top:16px; color:var(--muted); font-size:14.5px;">Once installed the commands are namespaced — <code>/rich-html:report</code>, <code>/rich-html:decide</code>, <code>/rich-html:branch-review</code>.</p>   </section> -  <!-- TWO TOOLS -->+  <!-- THREE TOOLS -->   <section>-    <p class="eyebrow reveal">Two tools, one system</p>-    <h2 class="reveal">One to read, one to act on</h2>-    <p class="sec-lede reveal">Both produce a <b>document about your work</b> — not the product itself (that's what the <code>prototype</code> plugin's <code>mockup</code> is for). They share a format contract, so the two feel like one system.</p>+    <p class="eyebrow reveal">Three tools, one system</p>+    <h2 class="reveal">One to read, one to act on, one to review</h2>+    <p class="sec-lede reveal">Each produces a <b>document about your work</b> — not the product itself (that's what the <code>prototype</code> plugin's <code>mockup</code> is for). They share a format contract, so the three feel like one system.</p>     <div class="defs">       <div class="def reveal">         <p class="tag">read</p>@@ -226,6 +227,12 @@ <h3>decide</h3>         <p>Gathers pending decisions into an interactive surface where each expands to its real context — then emits one prompt to execute your choices.</p>         <div class="meta"><b>for:</b> the forks <em>between</em> things</div>       </div>+      <div class="def reveal">+        <p class="tag">review</p>+        <h3>branch-review</h3>+        <p>Turns a branch or PR diff into a filterable review — the full diff sliced by facet and regrouped by change-type, named by intent. Read-only.</p>+        <div class="meta"><b>for:</b> what a change <em>does</em>, and why</div>+      </div>     </div>   </section> @@ -251,6 +258,14 @@ <h2 class="reveal">Scattered inputs in, one file out</h2>         <span class="arw">→</span>         <div class="box out"><div class="k">emit</div><div class="v">a surface + one prompt</div></div>       </div>+      <div class="track reveal">+        <span class="lbl">branch-review</span>+        <div class="box"><div class="k">collect</div><div class="v">a branch/PR diff</div></div>+        <span class="arw">→</span>+        <div class="box"><div class="k">structure</div><div class="v">facet + change-type</div></div>+        <span class="arw">→</span>+        <div class="box out"><div class="k">emit</div><div class="v">a filterable review</div></div>+      </div>     </div>   </section> @@ -258,7 +273,7 @@ <h2 class="reveal">Scattered inputs in, one file out</h2>   <section>     <p class="eyebrow reveal">The shared format · <span class="mono">html-doc</span></p>     <h2 class="reveal">Four rules that make one file work everywhere</h2>-    <p class="sec-lede reveal">Both commands build on the <code>html-doc</code> skill, which encodes the non-obvious constraints so the two outputs feel like one system.</p>+    <p class="sec-lede reveal">All three commands build on the <code>html-doc</code> skill, which encodes the non-obvious constraints so the outputs feel like one system.</p>     <div class="rules">       <div class="rule reveal"><div class="t">Self-contained</div><div class="d">Inline CSS/JS, no network, assets as <code>data:</code> URIs — renders as a local file, an email attachment, or a Claude Artifact under a strict CSP.</div></div>       <div class="rule reveal"><div class="t">Theme-aware</div><div class="d">Respects the reader's light/dark with a manual toggle. A document adapts to the reader — the opposite of a <code>mockup</code>.</div></div>@@ -319,15 +334,39 @@ <h3>Emit one prompt</h3>           <p>You choose per decision (or "accept all recommended"), and a <b>Copy prompt</b> button assembles a single, self-standing prompt — one line per decision with its choice and source — to hand straight back to an agent. It never degrades into chat Q&amp;A.</p>         </div>       </div>++      <p class="stepgroup-h reveal" style="margin-top:14px;">branch-review · a diff → a filterable review</p>+      <div class="step reveal">+        <div class="n">1</div>+        <div>+          <h3>Resolve the diff</h3>+          <p>From a PR number/URL, a <code>base...head</code> range, a branch name, or bare — the current branch vs. its merge-base. The exact base and totals are pinned in the header, so you know precisely what's under review. Read-only.</p>+        </div>+      </div>+      <div class="step reveal">+        <div class="n">2</div>+        <div>+          <h3>Two filter axes</h3>+          <p>Every change is tagged by <b>facet</b> (<code>code / tests / docs / spec</code>) and clustered by <b>change-type</b> — <em>why</em> each cluster exists, <b>named by its intent</b> (<code>jul2026-sync-replay</code>, not a bare <code>service</code>). The full diff slices both ways, and a summary — files, ± lines, a <code>dataviz</code> chart — recomputes as you filter.</p>+          <span class="cmdrow"><span class="p">/</span>rich-html:branch-review #662</span>+        </div>+      </div>+      <div class="step reveal">+        <div class="n">3</div>+        <div>+          <h3>Reasoning over hunks</h3>+          <p>Each cluster leads with one paragraph on why it exists; the real diff is one expand below it. The change-type rule was hardened by an adversarial redteam — the original seed-vs-emergent taxonomy became name-by-intent, with generic-layer naming as the checkable smell.</p>+        </div>+      </div>     </div>   </section>    <!-- WHEN TO USE -->   <section>     <p class="eyebrow reveal">Which one</p>-    <h2 class="reveal">Reading vs deciding</h2>+    <h2 class="reveal">Reading, deciding, reviewing</h2>     <div class="callout reveal">-      Reaching for the <b>state of something</b>, a synthesis, a briefing → <code>report</code>. Facing a pile of <b>unmade choices</b> you want to clear in one pass → <code>decide</code>. If <code>report</code> hits a decision that needs making it points at <code>decide</code>; if <code>decide</code> finds reportable state rather than a fork, it points back at <code>report</code>.+      Reaching for the <b>state of something</b>, a synthesis, a briefing → <code>report</code>. Facing a pile of <b>unmade choices</b> you want to clear in one pass → <code>decide</code>. Wanting to understand <b>what a branch or PR changed</b>, and why → <code>branch-review</code>. If <code>report</code> hits a decision that needs making it points at <code>decide</code>; if <code>decide</code> finds reportable state rather than a fork, it points back at <code>report</code>; and if a change hides an unmade decision, <code>branch-review</code> points at <code>decide</code> too.     </div>   </section> @@ -337,6 +376,13 @@ <h2 class="reveal">Reading vs deciding</h2>     <h2 class="reveal">What's changed</h2>     <p class="sec-lede reveal">Notable additions to the shared format, each backed by the evidence behind the call.</p>     <div class="clog">+      <div class="clog-item reveal">+        <div class="clog-when">2026-08-21</div>+        <div class="clog-body">+          <h3><span class="mono">branch-review</span> — a third command <span style="color:var(--muted); font-weight:400;">(plugin 0.3.0)</span></h3>+          <p>Turns a branch or PR diff into a filterable HTML review: the full diff sliced by <b>facet</b> (<code>code / tests / docs / spec</code>) and regrouped by <b>change-type</b>, each cluster <b>named by its intent</b> rather than a generic layer. The change-type rule was hardened by an adversarial redteam across three real PRs — the original seed-vs-emergent taxonomy was undecidable when a change fit both, so it became name-by-intent with <em>generic-layer naming</em> as the checkable smell.</p>+        </div>+      </div>       <div class="clog-item reveal">         <div class="clog-when">2026-08-20</div>         <div class="clog-body">
docs/rich-html-guide.mddocs+50 −18
@@ -1,16 +1,17 @@ # rich-html — turn your work into interactive HTML deliverables -A short guide to the `rich-html` plugin and its two commands, `report` and `decide`. Both take the-scattered inputs of your work and turn them into a single **self-contained, interactive HTML file** —-one to *read*, one to *act on*.+A short guide to the `rich-html` plugin and its three commands, `report`, `decide`, and+`branch-review`. Each takes the scattered inputs of your work and turns them into a single+**self-contained, interactive HTML file** — to *read*, to *act on*, or to *review*.  > 📖 **Prefer the visual version?** Open [`rich-html-guide.html`](./rich-html-guide.html) in a > browser for the same guide with the two-track diagram and nicer formatting. This Markdown page is > the quick, GitHub-readable companion.  ```-sources    → report → a readable document-decisions  → decide → an expandable surface + one prompt+sources    → report        → a readable document+decisions  → decide        → an expandable surface + one prompt+a diff     → branch-review → a filterable review, grouped by change-type ```  ## Install@@ -26,25 +27,27 @@ decisions  → decide → an expandable surface + one prompt /reload-plugins ``` -Once installed the commands are namespaced: `/rich-html:report`, `/rich-html:decide`.+Once installed the commands are namespaced: `/rich-html:report`, `/rich-html:decide`,+`/rich-html:branch-review`. -## Two tools, one system+## Three tools, one system -Both commands produce a **document about your work** — not the product itself (that's what the+Every command produces a **document about your work** — not the product itself (that's what the `prototype` plugin's `mockup` is for). They share a format contract, the `html-doc` skill, so the-two outputs feel like one system.+outputs feel like one system. -| | `report` | `decide` |-| :-- | :------- | :------- |-| **Turns** | heterogeneous sources | pending decisions |-| **Into** | a readable document | an interactive decision surface |-| **You** | read it | choose per decision, then run the emitted prompt |-| **For** | facts *about* things | the forks *between* things |+| | `report` | `decide` | `branch-review` |+| :-- | :------- | :------- | :-------------- |+| **Turns** | heterogeneous sources | pending decisions | a branch/PR diff |+| **Into** | a readable document | an interactive decision surface | a filterable diff review |+| **You** | read it | choose per decision, then run the emitted prompt | filter & read |+| **For** | facts *about* things | the forks *between* things | what a change *does*, and why |  ## The shared format — the `html-doc` skill -`report` and `decide` both build on `html-doc`, which encodes the non-obvious rules that make-one HTML file work everywhere, stay readable, and carry evidence in the form that reads fastest:+`report`, `decide`, and `branch-review` all build on `html-doc`, which encodes the non-obvious+rules that make one HTML file work everywhere, stay readable, and carry evidence in the form that+reads fastest:  - **Self-contained** — inline CSS/JS, no network, assets as `data:` URIs. Renders identically as a   local file, an email attachment, or a Claude Artifact (which enforces a strict CSP).@@ -93,16 +96,45 @@ agent can execute. Guardrail: `decide` always renders the rich surface — it **never** degrades into chat Q&A. The expandable-context format *is* the value. +## `branch-review` — a diff → a filterable review++Read-only. It never touches the branch it reviews.++1. **Resolve the diff** — from a PR number/URL, a `base...head` range, a branch name, or bare (the+   current branch vs. its merge-base). The exact base and totals are pinned in the header, so you+   know precisely what is under review.+2. **Two filter axes** — every change is tagged by **facet** (`code / tests / docs / spec`) and+   clustered by **change-type**: *why* each cluster of changes exists, **named by its intent**+   (`jul2026-sync-replay`, not a bare `service`). The full diff slices both ways, and a summary —+   files, ± lines, a `dataviz` bar chart of the line distribution — recomputes as you filter.+3. **Reasoning over hunks** — each cluster leads with one paragraph on *why* it exists; the real+   diff is one expand below it.++```+/rich-html:branch-review #662+```+ ## When to use which  - Reaching for the **state of something**, a synthesis, a briefing → **`report`**. - Facing a pile of **unmade choices** and want to clear them in one pass → **`decide`**.+- Wanting to **understand or review a diff** — what a branch or PR actually changed, and why →+  **`branch-review`**.  If `report` runs into a decision that needs making, it points at `decide`; if `decide` finds-reportable state rather than a fork, it points back at `report`.+reportable state rather than a fork, it points back at `report`; and if a change hides an unmade+decision, `branch-review` points at `decide` too.  ## Changelog +- **2026-08-21 · `branch-review` — a third command (plugin `0.3.0`).** Turns a branch or PR diff+  into a filterable HTML review: the full diff sliced by **facet** (`code / tests / docs / spec`)+  and regrouped by **change-type**, each cluster **named by its intent** rather than a generic+  layer. The change-type rule was hardened by an adversarial redteam across three real PRs — the+  original seed-vs-emergent taxonomy was undecidable when a change fit both, so it became+  name-by-intent with *generic-layer naming* as the checkable smell. Built from specs+  [`001`](../specs/001-concern-branch-review.md) (concern) and+  [`002`](../specs/002-doing-branch-review.md) (spec). - **2026-08-20 · Visual evidence — a fourth `html-doc` rule.** Evidence can now be carried in the   form that reads fastest — a code snippet, an inline-SVG flow diagram, a chart (via the `dataviz`   skill), an existing screenshot, or a schematic divs+CSS layout sketch — always *added under* the
README.mddocs+8 −6
@@ -17,7 +17,7 @@ This repo is itself a **plugin marketplace** (`moacyr-skills`). Each plugin live  # 2. Install the plugins /plugin install spec-workflow@moacyr-skills   # pulls live-verify automatically (it depends on it)-/plugin install rich-html@moacyr-skills       # report + decide (interactive HTML deliverables)+/plugin install rich-html@moacyr-skills       # report, decide, branch-review (interactive HTML deliverables) /plugin install prototype@moacyr-skills       # mockup — clickable HTML mocks in the product's own look /plugin install utils@moacyr-skills           # standalone helpers (currently: stacked-merge) # (live-verify installs with spec-workflow; grab it alone if that's all you want:@@ -93,16 +93,18 @@ Turn your work into rich, **self-contained interactive HTML** files. No spec or usable on any project; the tools just *point at* whatever sources are around.  > 📖 **Guide:** [`docs/rich-html-guide.md`](./docs/rich-html-guide.md) — the walkthrough, with the-> two-track diagram and the `html-doc` format rules in the [rich HTML version](./docs/rich-html-guide.html).+> three-track diagram and the `html-doc` format rules in the [rich HTML version](./docs/rich-html-guide.html).  | Command | What it does | | :------ | :----------- | | `report` | Synthesize a readable document from heterogeneous sources (docs, trackers, PRs, git, code, logs) after asking what angle/audience you need. Cross-checks sources; conclusion up top, evidence one expand away. **Read-only.** | | `decide` | Aggregate the decisions waiting on you (concern options, PR-review forks, "needs decision" issues, autopilot escalations) into one surface where each expands in place to its real context — then emit **one prompt** to hand back to an agent to execute them all. |+| `branch-review` | Turn a branch or PR diff into a filterable HTML review: the full diff sliced by facet (code/tests/docs/spec) and regrouped by change-type — *why* each cluster exists, named by intent — with a summary that recomputes as you filter. **Read-only.** | -Both build on the **`html-doc`** skill, the shared format contract (self-containment / Artifact-CSP, theme-awareness, the expandable-context pattern) so the two outputs feel like one system.-`report` is for facts *about* things; `decide` is for the forks *between* them.+All three build on the **`html-doc`** skill, the shared format contract (self-containment / Artifact+CSP, theme-awareness, the expandable-context pattern) so the outputs feel like one system.+`report` is for facts *about* things; `decide` is for the forks *between* them; `branch-review` is+for what a change *does*.  ### `prototype` — clickable mocks in the product's own look @@ -193,7 +195,7 @@ auto-accepting them. Two ways to restore the hands-off behavior: │   │   └── agents/               # test-flow-headless │   ├── rich-html/               # interactive HTML deliverables (no spec coupling) │   │   ├── .claude-plugin/plugin.json-│   │   ├── commands/             # report, decide+│   │   ├── commands/             # report, decide, branch-review │   │   └── skills/               # html-doc (shared format contract) │   ├── prototype/              # clickable HTML mocks in the product's own look │   │   ├── .claude-plugin/plugin.json
docs/index.htmldocs+3 −3
@@ -295,7 +295,7 @@ <h2 class="reveal">Add the marketplace, install a plugin, reload</h2>  <span class="c"># 2 · install what you want</span> <span class="p">/</span><span class="cmd">plugin install</span> spec-workflow@moacyr-skills   <span class="c"># pulls live-verify with it</span>-<span class="p">/</span><span class="cmd">plugin install</span> rich-html@moacyr-skills       <span class="c"># report + decide</span>+<span class="p">/</span><span class="cmd">plugin install</span> rich-html@moacyr-skills       <span class="c"># report, decide, branch-review</span> <span class="p">/</span><span class="cmd">plugin install</span> prototype@moacyr-skills       <span class="c"># clickable mockups</span> <span class="p">/</span><span class="cmd">plugin install</span> utils@moacyr-skills           <span class="c"># standalone helpers</span> @@ -320,7 +320,7 @@ <h2 class="reveal">Five plugins, one marketplace</h2>       <a class="plug reveal" href="./rich-html-guide.html">         <div class="nm">rich-html</div>         <div class="dep">standalone</div>-        <p>Turn your work into self-contained interactive HTML. <code>report</code> synthesizes heterogeneous sources into a readable document; <code>decide</code> aggregates pending decisions into a surface that emits one prompt to execute them.</p>+        <p>Turn your work into self-contained interactive HTML. <code>report</code> synthesizes heterogeneous sources into a readable document; <code>decide</code> aggregates pending decisions into a surface that emits one prompt; <code>branch-review</code> turns a branch or PR diff into a filterable review, grouped by change-type.</p>         <span class="more">Read the guide</span>       </a>       <a class="plug reveal" href="./prototype-guide.html">@@ -359,7 +359,7 @@ <h2 class="reveal">New? Read a guide first</h2>       <a class="guide reveal" href="./rich-html-guide.html">         <div class="k">guide</div>         <div class="t">rich-html</div>-        <div class="d">Two tools, one system: <code>report</code> to read, <code>decide</code> to act on — the <code>html-doc</code> format rules.</div>+        <div class="d">Three tools, one system: <code>report</code> to read, <code>decide</code> to act on, <code>branch-review</code> to review — the <code>html-doc</code> format rules.</div>         <div class="md">also: rich-html-guide.md</div>       </a>       <a class="guide reveal" href="./prototype-guide.html">
spec-002-recordprocess/convention +32 −1 · 2 files

Closes the spec-workflow loop this repo runs on. Spec 002 renamed todo → done with a Status/Branch header and Implementation Notes recording the dogfood; the catalog row follows. Exists by convention, not by this change's distinctive intent.

specs/002-done-branch-review.mdspec+31 −0
@@ -1,3 +1,6 @@+Status: done+Branch: moacyrricardo/spec-002-branch-review+ # 002 — branch-review: a filterable diff review command for rich-html  ## Context@@ -139,3 +142,31 @@ facet. No coupling.   accepted as good-enough. - **Not yet dogfooded off boletim:** the redteam used boletim PRs. First non-boletim run may surface   path-heuristic gaps the target `CLAUDE.md` override is meant to absorb.++## Implementation Notes++Built as decided. `plugins/rich-html/commands/branch-review.md` is the new thin command; it+delegates all file HOW to `html-doc` (whose contract was widened from two commands to three) and+composes `dataviz` for the summary chart. Version bumped `0.2.0 → 0.3.0` in both `plugin.json` and+the top-level `.claude-plugin/marketplace.json`; the third command was propagated across+`docs/rich-html-guide.{md,html}`, `docs/index.html`, and `README.md`.++**Verified by a dogfood run** — a fresh agent given *only* the command file, the `html-doc`+contract, and PR #640 (no other context) produced a real 64 KB self-contained, CSP-safe, filterable+review. The intent-named taxonomy held (five clusters, each named by intent, none a bare layer+word; it independently reproduced the "headline change is the untagged cluster" asymmetry). Verdict:+~90% of a hand-written review out of the box.++**Differed from the spec:** the dogfood showed the *content model* was right but the *rendering+rules* were under-specified — the agent had to invent every filter/count/chart decision. Those were+then pinned down in the command (not anticipated at spec time): mixed-facet hunks may split into+presentational sub-hunks; summary/counts reflect the currently-visible filtered hunks; the chart+axis is pinned to the full-diff maximum (no rescale on filter); filters sit at the top of the+layout; the headline-often-untagged and test-cluster tie-breaker rules were added to §3; the+net-diff flag was scaffolded to distinguish a *changed* path from a mere context *reference*; and a+"the two axes are lenses, not a partition" caveat was added (facet `spec` and change-type+`process/convention` legitimately overlap on small PRs).++**Gap resolved:** `dataviz` is a harness-provided skill (not a repo file); it loads via the Skill+tool, so the command's "load `dataviz` first" is satisfiable. Known Gaps carried forward unchanged:+net-diff flag remains heuristic; off-boletim dogfooding still pending.
specs/CATALOG.mdspec+1 −1
@@ -3,4 +3,4 @@ | #   | Status  | Title / slug   | Branch | Issue | Notes                                          | |-----|---------|----------------|--------|-------|------------------------------------------------| | 001 | concern | branch-review  | —      | —     | → resolved by 002 (new thin command; taxonomy redteamed) |-| 002 | todo    | branch-review  | —      | —     | `/rich-html:branch-review`; ready for /spec-workflow:start |+| 002 | done    | branch-review  | moacyrricardo/spec-002-branch-review | — | `/rich-html:branch-review` shipped (0.3.0) |

No changes match the current filter.