--- name: tanner-create-pr description: How Tanner wants pull requests written — title format, body structure, and the checks that must pass first. Use whenever you are creating, opening, generating, or drafting a PR (including from an agent harness like Conductor that invokes a create-PR step), or writing a PR title or description. --- # Tanner Create PR How to open a pull request the way Tanner wants it. Run this **whenever a PR is being created** — by hand, or when an agent harness (Conductor and others) invokes its create-PR step. The goal is a PR whose title and body tell a reviewer exactly what changed and why, that reads in Tanner's voice, and that never lands with lint or build broken. > Plain markdown — any agent can read this file directly; Claude Code additionally > auto-loads it as a skill. ## Before you open the PR Do these first — a PR that fails them isn't ready to exist: 1. **The repo's checks pass.** Run whatever the repo defines — typically `npm run lint`, `npm run build`, and its test command. Each one green before you push; if one fails, fix it or don't open the PR. Skip a check only when the repo genuinely doesn't have it (some repos have no build or lint step) — don't invent scripts that aren't there. 2. **The diff is the change and nothing else.** No stray debug logs, no unrelated formatting churn, no committed lockfile from the wrong package manager (npm only — never `pnpm-lock.yaml` or `yarn.lock`). 3. **Know the base.** Open against the intended target branch (usually `main`), and make sure the branch is up to date with it. ## Title Format: `[project_name][Surface Area] Concise Title Case Title Of What This PR Accomplishes` - **Both prefixes are required.** Lead with `[project_name]` — the repo/app's short name — then `[Surface Area]`, the part of the app the PR touches (e.g. `[Blog]`, `[Auth]`, `[Design System]`). Two adjacent brackets, no space between them: `[tanner-site][Blog] Add Masonry Grid To The Index`. - **Title Case** — capitalize the first letter of every word. - **Concise, and about what the PR accomplishes** — a plain statement of the outcome, not "Added…" or "This PR adds…". Short enough to read at a glance; the body carries the detail. - **No trailing period**, and **no periods inside** the title — same rule as headings in the `tanner-brand-voice` (`.claude/skills/tanner-brand-voice/SKILL.md`) skill. - **No AI filler** — none of the padding vocabulary the brand-voice skill bans. ## Body Write for the reviewer deciding whether to merge. Lead with substance — no preamble, no "This pull request…". In order: 1. **Summary — 2–3 sentences, framed around the business goal.** What was done and what it achieves, stated in terms of the explicit business outcome, not the mechanics. Lead with the goal the change serves. Keep it to two or three sentences. 2. **Detail paragraph.** A fuller paragraph describing what was actually done and changed — the approach, the files or systems touched, anything a reviewer needs to follow the diff. Length follows the change: a small PR gets a few sentences, a large one gets more. Don't pad it. 3. **`## Test Plan`.** A section under a heading literally named **Test Plan**, documenting the steps taken to validate the change: what was tested and how, the repo's checks that were run (lint / build / test, whichever the repo has), and any bug testing performed. This is where the reviewer sees the work was actually verified, not assumed. 4. **Testable paths.** Where applicable, list the route(s) a reviewer can open to exercise the change — e.g. a change to the home page lists `/home`. Give the concrete paths so the reviewer can go straight to the affected surface. ## Screenshots Still **capture a screenshot for every change that produces a visual update** — a visual change with no visual evidence is incomplete. Drive a headless Chrome instance to capture the touched surface area (Claude Code can do this with its browser tools — see the `tanner-code-review` (`.claude/skills/tanner-code-review/SKILL.md`) skill for spinning one up). **Do not embed the screenshot in the PR body, and never commit it.** A GitHub PR body can only render an image that already lives at a URL GitHub can fetch; `gh pr create` has no upload step, so a local file path never renders. Instead, save each screenshot **outside the repository** so git never tracks it, and leave it for Tanner to drag into the PR description if he wants it inline (GitHub uploads and hosts it at that point). - **Location:** a user-accessible folder that is not the repo — `~/Desktop` (fall back to `~/Downloads` if Desktop isn't present). - **Filename:** `branchname_author_screenshotname_date` — underscores between the four parts. - `branchname` — the current git branch (`git rev-parse --abbrev-ref HEAD`) - `author` — the git author name (`git config user.name`) - `screenshotname` — a short name for what the shot shows (e.g. `blog-index-grid`) - `date` — `YYYY-MM-DD` - Replace spaces and slashes with hyphens *within* each part; keep the underscores between parts. Example: `tannergodarzi-palembang_tanner_blog-index-grid_2026-07-04.png`. All prose follows the `tanner-brand-voice` (`.claude/skills/tanner-brand-voice/SKILL.md`) skill — Tanner's voice, no periods in headings, no AI filler. The PR should read like Tanner wrote it, not like a template.