First PR
The "I just landed in this repo, how do I ship something safely" composite. Forces onboarding + scoping + TDD + release-branch flow in one chain so the first PR matches the repo's conventions instead of fighting them.
Auto-invocation triggers
- User says "first PR", "I just cloned X", "starter contribution", "good first issue"
- Repo has never appeared in
~/.claude/handoffs/AND user is asking for any change - User explicitly invokes
/first-pr
Workflow
Phase 1 — Onboard (always)
Invoke onboard-new-repo. Required outputs:
- Architecture summary (1 paragraph)
- Build / test / lint commands
- CI provider + required checks
- Conventional commit prefix (detected from history)
- Whether
releasebranch exists (drives later phase) - Whether a CHANGELOG.md exists and follows Keep a Changelog
- Code-review tools installed (CodeRabbit / Greptile / SonarCloud / Sentry)
Save outputs to ~/.claude/handoffs/<repo>/onboarding.md so this phase never
needs to repeat for the same repo.
Phase 2 — Pick a safe scope (always)
If the user has not specified a change, suggest one from:
- A typo / doc fix flagged by spell/lint
- A test that documents existing behavior (no behavior change)
- A
// TODO:with low surface area - An issue labeled
good first issueorhelp wanted
Refuse to scope a first PR as: refactor, dependency bump, architectural change, or anything spanning >3 files. Surface to user: "First PRs should be ≤3 files and have an obvious blast radius. Want to pick something smaller?"
Phase 3 — Context pack (always, before any edit)
Invoke context-pack scoped to the target files + their callers + any rules
in .claude/standards/, CLAUDE.md, or docs/adr/ that govern the area.
Token budget cap: 6k tokens. If retrieval exceeds the cap, narrow scope further before continuing.
Phase 4 — Scope and execute
Invoke scope-and-execute with the change framed as a one-line goal:
"Change : to so that no longer ."
If the goal cannot fit in one line: scope is too big — return to Phase 2.
Phase 5 — Test-driven (mandatory for first PRs)
Invoke test-driven-development:
- Write a failing test that asserts the desired behavior
- Run the test, confirm it fails for the right reason
- Implement the smallest change that makes the test pass
- Re-run the full test file (not just the new test) to catch unintended breakage
Refuse to skip this phase for a first PR. Even doc-only changes get a smoke check that the rendered output still parses.
Phase 6 — Pre-flight checks (always)
Run the repo's own commands as discovered in Phase 1:
- Lint (
npm run lint/pnpm lint/ruff/ detected equivalent) - Type check (
tsc --noEmit/mypy/ equivalent) - Test (just the affected suite, not the full matrix)
- Build, if cheap (<60s)
If ANY check fails: fix before opening the PR. Never open a red PR for a first contribution.
Phase 7 — Open the PR
Detect base-branch model:
- If
releasebranch exists → invoke/pr-to-release(handles full chain including CodeRabbit waits and CHANGELOG entry) - If direct-to-main repo → invoke
/merge-confidently
Title and body follow the conventions detected in Phase 1. Body must include:
- Why this change (link issue if it exists)
- What was tested (the new test added, plus any manual verification)
- A line acknowledging "first contribution to this repo" so reviewers know to apply a lighter touch for unfamiliarity but a heavier touch for convention mismatch
Phase 8 — Capture the onboarding (always)
Invoke knowledge-loop to save a durable memory:
- Repo name
- Architecture summary from Phase 1
- Build/test/lint commands
- Conventions encountered (commit prefix, merge method, base branch)
- Surprises ("the test runner is
bun test, notvitest")
This way subsequent sessions in this repo skip Phase 1.
Stop / escalation conditions
- Phase 1 can't determine build/test commands → surface to user; do not guess
- Phase 2 user insists on a wide-scope first PR → ask twice, then refuse
- Phase 5 can't write a failing test (repo has no test infrastructure) → surface; recommend that the test infra get scaffolded as the actual first PR
- Phase 6 lint/type/build fails on
mainitself (not just the change) → surface; first PR should not be in a repo where main is broken - No CHANGELOG.md and the project clearly versions itself → surface; ask whether to add one as a separate first PR before code changes
Reconciliation
FIRST PR — <repo>
Onboarding: saved to handoffs/<repo>/onboarding.md
Scope: <one-line goal>
Files touched: <N> (≤3 enforced)
Tests: 1 new test added; suite passes
Checks: lint ✓ | typecheck ✓ | test ✓ | build ✓
PR: #<n> opened against <release|main>
Captured: knowledge note: <repo> conventions
Outputs / Evidence
- Onboarding summary path
- Scope statement
- PR number + base branch + CI status
- Knowledge note slug
What this composite is NOT
- Not for routine work in repos you already know →
/pr-to-release - Not a refactor or architectural change →
/refactor-pipeline - Not an emergency fix →
/hotfix - Not for adding a new feature end-to-end →
/feature-from-zero
Pairs with
/onboard-new-repo— used internally; standalone if no PR is intended/pr-to-release— Phase 7 delegates to it when release branch exists/knowledge-loop— Phase 8 ensures the onboarding cost is paid once