OpenHands pr-design-doc
git clone https://github.com/OpenHands/OpenHands
T=$(mktemp -d) && git clone --depth=1 https://github.com/OpenHands/OpenHands "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.agents/skills/pr-design-doc" ~/.claude/skills/all-hands-ai-openhands-pr-design-doc && rm -rf "$T"
.agents/skills/pr-design-doc/SKILL.mdpr-design-doc - a reviewable design doc for a non-trivial PR
A diff shows what changed line by line. It does not show the design: the shape of the change, the API before and after, and why this approach. Reviewers reconstruct that by hand, slowly. The scarce resource is the maintainer's attention and trust budget - not the agent's effort. Spend extra effort to hand them one self-contained HTML page that conveys the big picture and the before → after core difference, with every claim clickable back to the real code, then link it from the PR description.
This is the same craft as a "show me this change" explainer, aimed at one job: making a non-trivial PR easy to review.
When to use it
- Opening or updating a non-trivial PR: new/changed public API, a new module or subsystem, a behavior change in core logic, a migration, or anything a reviewer can't fully judge from the diff in a couple of minutes.
- Skip it for trivial PRs - a typo, a one-line guard, a dependency bump, a docs tweak, a simple bug fix. A design doc adds more to review. Use judgment; if the diff is the explanation, don't add a page.
The .pr/
workflow
.pr/Use the temporary
directory for PR-only artifacts. Before relying on automatic
cleanup, verify that the target repository has an enabled
.pr/
.github/workflows/pr-artifacts.yml workflow that removes .pr/ after approval.
- Same-repository PR with verified cleanup workflow: the workflow removes
after approval..pr/ - Fork PR, or repository without a verified cleanup workflow: remove
manually before merge..pr/
The design doc is a review aid that lives with the branch while the PR is open. It must not ship in the merged tree.
Workflow
-
Check out and verify the PR head. Do not write or commit the design doc from the base branch or an unrelated checkout. Start with a clean worktree, then inspect and check out the PR:
gh pr view <n> --json title,body,url,baseRefName,baseRefOid,headRefName,headRefOid,headRepository,headRepositoryOwner,isCrossRepository,files,additions,deletions gh pr checkout <n> git rev-parse HEAD gh pr view <n> --json headRefOid --jq .headRefOidThe final two SHAs must match before you continue. If they do not, stop and fix the checkout. Compute the merge-base SHA with
. Group changed files by area and keep both the merge-base SHA and head SHA for source links.git merge-base <baseRefOid> <headRefOid> -
Read both sides of each logical file. Compare
with the verified head. Capture the function-level behavioral difference - what the code did vs does now.git show <merge-base-sha>:<path>- new file → no "before"; one "after" diagram + a line on the role it adds.
- deleted file → "before" diagram + who/what takes over.
- edited file → a before/after pair, with the delta highlighted.
-
Classify each file. Logic change (behavior moved) → draw before/after. Mechanical change (rename, constant, config, import move) → a one-line
row, no diagram. Don't dilute the signal by drawing mechanical edits.before → after -
If the change is an API change, lead with the API. Show the signature/schema/type before and after side by side (function signature, endpoint + payload, config field, event shape). Name the compatibility impact plainly: additive, breaking, or behind a flag.
-
Find the cross-file story. If one call chain threads several files, draw a single overview before/after at the top; per-file cards drill in.
-
Build the page per
- one self-contained, offline, editorial HTML file with hand-drawn SVG figures. Save it to the repo'sreferences/html-craft.md
directory, e.g..pr/
(or.pr/design.html
). Before writing, reject a symlink at.pr/<topic>.html
or at the exact output path; never follow a branch-controlled symlink outside the worktree..prtest ! -L .pr && test ! -L .pr/design.html mkdir -p .pr -
Commit under
, push to the verified PR head, and link it. Confirm that the push remote resolves to.pr/
; never push the artifact to the base repository's default branch.headRepository.nameWithOwnergit add .pr/design.html git commit -m "docs(.pr): design doc for <PR topic>" git push <head-repo-remote> HEAD:<headRefName>Query the base repository's visibility before choosing the link:
gh repo view <base-owner>/<base-repo> --json visibility,url- Public repository: add an htmlpreview link near the top of the PR description,
pointing at the fork and branch the PR is opened from (it renders before merge):
📄 Design doc: https://htmlpreview.github.io/?https://github.com/<fork-owner>/<repo>/blob/<pr-branch>/.pr/design.html - Private or internal repository: link the access-controlled GitHub blob and include local download/open instructions, or use an existing access-controlled artifact service. Never send the document through htmlpreview or another public host.
- Public repository: add an htmlpreview link near the top of the PR description,
pointing at the fork and branch the PR is opened from (it renders before merge):
What the page contains
- What changed (decision first) - one paragraph: the intent, net effect, and why the
reviewer should care. Put the highest-impact conclusion, risk, or API-compat note in a
callout, with the most important changed★
nearby. Stats (path:line
) are context, not the lead. If there's a cross-file flow, the overview before/after SVG goes here.N files · +A / −D - API before → after (when the PR changes an interface) - signatures/schemas/types side by side, with the compatibility verdict stated.
- Left rail / index - changed files grouped by area, each tagged (🟢 added · 🔴 removed · ✏️ changed · ⚙️ mechanical) with +/− counts; click to jump.
- Per-file cards - for each logical file: a claim-carrying title, a one-line summary of
how its behavior changed, before/after diagrams with real symbol names +
(changed nodes in orange), and the diff in a collapsedfile:line
. Mechanical files get a small<details>
table, no diagram.before → after - (optional) Risk / follow-ups - only if grounded in what you read.
Non-negotiable principles
- Optimize for scarce reviewer attention. The first screen answers, in ~15 seconds: what this PR does, whether it's risky, where to look first, and what evidence backs the claim. Lead with the conclusion, not your process.
- Show the difference, not just the after. For any logic or API change, draw before and after and make the delta visually loud (color + line style). The contrast is the product.
- Ground everything to code, beside the claim. Every box, node, and sentence names a
real symbol +
, and links to the correct source revision where possible: the merge-base SHA for before-state evidence and the verified head SHA for after-state evidence. One click from "this changed" to the exact code.path:line - Hand-draw the carrying diagrams. Prefer bespoke inline SVG for the before/after that makes the argument; Mermaid is fine only for quick auxiliary graphs.
- Self-contained & offline. One HTML file, inline CSS/SVG, no external scripts or assets, opens by double-click, and survives being copied to another machine.
only, and temporary. The doc is a review aid, not project docs. Keep it in.pr/
and ensure it is removed before merge. Rely on automatic cleanup only when the repository's workflow has been verified; otherwise remove it manually. Do not move design HTML into.pr/
or ship it in the merged tree.docs/
Anti-patterns
- ❌ Dumping the raw diff / file tree and calling it a "design doc" - adds nothing over the PR page.
- ❌ Empty nodes ("process data", "handle request") - every node is a real symbol + location.
- ❌ Only the after-state when something changed - reviewers want the contrast.
- ❌ A design doc on a trivial PR - noise. Skip it.
- ❌ Committing the HTML outside
(e.g..pr/
), where it would merge intodocs/
.main - ❌ Publishing a private-repository design doc through htmlpreview, GitHub Pages, or another public host. Use the private/local preview path in the craft reference. Use GitHub Pages only with explicit user authorization after verifying private Pages access control.