Proof-carrying review
Ordinary review asks you to reconstruct intent from a diff: you read the change and guess what it was meant to do, then guess whether it does it. For agent-authored PRs that is backwards. The agent that wrote the change has the session, the repo, and the implementation context you don’t. It is the best source for why this is correct — and the worst use of it is making you re-derive that from the lines it produced.
garden pr explain flips the direction. The author writes a walkthrough:
the change ordered into blocks, each stating what it does and pointing at
proof that it does it. Review becomes adjudicating evidence.
This is deliberately not a session dump. Raw sessions are enormous, ephemeral, and often personal. A walkthrough is the small, curated artifact the author chooses to stand behind.


Blocks are a tree, not a file list
Section titled “Blocks are a tree, not a file list”A block’s claim is established by its own proof plus the claims of its children. The top-level blocks are the roots; together they prove the PR as a whole. So a high-level claim sits at the top and the pieces that establish it nest underneath, each with proof of its own:
- An ack now means the event is on disk
- Append fsyncs before it returns
- A journal failure declines the ack instead of hiding it
The scaffold that garden pr explain <pr> prints starts at one block per
changed file, but that is only a starting point. Blocks get split when a file’s
hunks do different things, merged when they’re trivial, and nested to build the
tree. Sibling order is the reading order — it is never re-sorted.
Attention and risk are different questions
Section titled “Attention and risk are different questions”Every block carries both, because “important to understand” and “dangerous if wrong” are not the same property:
attention—skim,review, orscrutinize. How hard to look.risk—low,medium, orhigh. Blast radius if it’s wrong.
A subtle-but-reversible block and an obvious-but-irreversible one need different handling from a reviewer, and collapsing them into one “importance” score loses exactly the distinction that routes attention well.
The PR-level confidence and critical_path do the same job at the top: the
author’s own certainty, and the two or three blocks to read if you only have
five minutes.
unproven is the most valuable field
Section titled “unproven is the most valuable field”Each block lists what the author did not verify. An honest gap list beats any amount of prose — it is the difference between a claim and a claim you can calibrate:
The 503 path never runs in any test. A full disk is the realistic trigger and nothing simulates one.
That is a reviewer’s next question, answered before they asked it.
Proof is pointed at, not asserted
Section titled “Proof is pointed at, not asserted”Each proof entry is exactly one kind: a test CI already runs, a command you
can run yourself, an attachment (a screenshot or recording), a pointer at
any code in the repo — in the diff or not — an external link to a CI run or
preview, or a bare note, which is the weakest and pairs with unproven.
garden does not verify proof. CI runs the tests, the CLI handles the attachments, and you follow the pointer. The discipline is in having to name something concrete.
To say a block is proven by another block, make it a child — that’s the tree.


Reading order is the author’s choice
Section titled “Reading order is the author’s choice”The tree is fixed by the nesting; layout chooses how it flattens into the
reading pane. The sidebar outline stays top-down regardless.
layout |
reading order |
|---|---|
top-down (default) |
each claim before its sub-proofs — conclusion first |
bottom-up |
the building blocks before the claim they support |
sandwich |
summary, then bottom-up construction, then a closing synthesis |
Coverage is selective on purpose
Section titled “Coverage is selective on purpose”You do not have to cover every hunk. Cover what a reviewer needs to understand and trust, and leave out imports, renames, formatting, and generated code.
Nothing is hidden by that: garden computes the hunks no block covers and shows them as an “unaccounted for” list. An uncovered hunk is a signal that the author judged it didn’t need explaining — and a reviewer who disagrees can comment and ask why.
Reviewed state follows the code, not the block
Section titled “Reviewed state follows the code, not the block”Blocks have no stable identity across revisions — they split, merge, move, and
vanish. So marking a block reviewed does not record “I read block b3”. It
records “I have seen these hunks”, keyed by a content hash of the covered
lines, using the same checkpoint machinery as per-file
mark-reviewed.
At the next revision each block resolves against what you’ve already seen:
- every hunk seen → reviewed, and the block collapses;
- some changed or new → partial, surfacing only what changed;
- none seen → unreviewed.
Because the state belongs to the content, a re-blocked walkthrough doesn’t cost you a re-review. The author can restructure the whole document and the code you already read stays read.
Comments anchor to blocks
Section titled “Comments anchor to blocks”Threads attach to a block — and to the unaccounted-for section, so “why didn’t you explain this?” has somewhere to go. They behave like every other garden comment: drafts until submitted, and they gate the merge while unresolved.


unproven gap — and the thread it prompted.Per revision, frozen at merge
Section titled “Per revision, frozen at merge”A walkthrough belongs to one revision. A new push means a new revision and a
fresh walkthrough — garden doesn’t track blocks across revisions, because the
churn when blocks split and merge is not worth automating. garden pr explain
on a later revision starts from the previous one, to edit and re-apply.
It lives in garden’s backend, with no source-control footprint, and is frozen when the PR merges: a permanent record of why this was done and what was verified, readable long after everyone involved has forgotten.
Writing one
Section titled “Writing one”garden pr explain 42 # prints a scaffold from the diff# …edit it…garden pr explain apply 42 -f walkthrough.yamlgarden pr explain show 42 # read it backThere is no editor. Fill the printed template and pipe it back — agents can’t
drive editors, so the flow is print-template → fill → apply. garden push
prints the same reminder when an agent is the author.
Full schema: garden pr explain, or
garden docs walkthrough.