agentleFS
lxsmnsyclxsmnsyc/agent-skills/skills/pr-author/SKILL.md

pr-author

Skill4 starsChanged 15 days agoMITView on GitHub

Write code changes as small, independent pull requests that can merge at any time. Uses git worktrees when the machine has room, splits any bug found on the base branch into its own fix PR so it ships without waiting, keeps PRs non-blocking (flags, expand and contract, owned paths), runs the project's checks locally, self-reviews with a fresh agent running the pr-review skill, opens the PR as a draft until the review is clean so review fixes do not start CI, and hands the PR to the maintainer. Use this skill whenever the user asks to implement a feature or fix and open a PR, work on several branches at once, split work into PRs, or when a roadmap worker from the parallel-roadmap skill builds a node, even if they do not say "pull request".

  • Reads credentials
  • Commits and pushes

2 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions2 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 2

    1. AcKeskin/contexture★ 2same name
    2. bang9/claude-code-settings★ 2same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository10 other files it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

15 rules. About 0 are common, 9 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every pull request should be able to merge on its own, at any time, without waiting for another one.

    line 8
  2. Very specific:

    Run capacity.py. It weighs free memory, CPU load, free disk and existing worktrees.

    line 27
  3. Very specific:

    2 or more: use one worktree per branch with wt.py new.

    line 29
  4. Distinctive:

    Never work directly in the user's main checkout when it has uncommitted changes.

    line 32
  5. Distinctive:

    When building a roadmap node, the node's brief is the spec.

    line 48
  6. Very specific:

    Read references/non-blocking.md.

    line 54
  7. Distinctive:

    When you find a bug that exists on the base branch (not one your branch introduced):

    line 63
  8. Very specific:

    Confirm it on the base: Write the smallest failing test.

    line 67
  9. Distinctive:

    The cause is unclear or the fix is large: do not guess. Write an issue (or a roadmap inbox entry) with the failing test and what you found, …

    line 70
  10. Distinctive:

    It does not need the fix: leave the fix out of the feature branch entirely.

    line 72
  11. Very specific:

    Run the project's checks in the worktree: python3 <skills>/pr-review/scripts/checks.py <worktree> --run --install.

    line 78
  12. Distinctive:

    Run at most two review rounds.

    line 103
  13. Very specific:

    Write the description from references/pr-body.md: what and why, changes, proof (the failing test on the base and passing on the branch, for …

    line 109
  14. Distinctive:

    Write all PR text by the plain-writing rules if that skill is installed.

    line 114
  15. Distinctive:

    If the repo deletes head branches on merge (GitHub setting "Automatically delete head branches"), nothing more is needed.

    line 128

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

PR author

Every pull request should be able to merge on its own, at any time, without waiting for another one. That is what lets several agents and people work at once without blocking each other. This skill is the habits and tools that make that true.

Scripts

python3 <skill>/scripts/capacity.py                 # how many worktrees this machine can take now
python3 <skill>/scripts/wt.py new <branch> --base main   # worktree in .worktrees/<branch>, hidden from git status
python3 <skill>/scripts/wt.py list
python3 <skill>/scripts/wt.py remove <branch> [--delete-branch]
python3 <skill>/scripts/wt.py prune-merged --base main [--base dev] [--remote] [--agent-worktrees] [--dry-run]
python3 <skill>/scripts/ci_guard.py                 # will a push start billed CI? exit 2 means ask first

The pr-review skill provides checks.py (lint, typecheck, build, tests), repro.py (fails on base, passes on head) and the review itself. This skill uses them from <skills>/pr-review/scripts/.

Steps

1. Decide where to work

Run capacity.py. It weighs free memory, CPU load, free disk and existing worktrees.

  • 2 or more: use one worktree per branch with wt.py new. Several branches (yours or other agents') can then be worked on and checked at the same time.
  • 1: the machine is busy. Work one branch at a time in a single worktree or the main checkout, and say why.

Never work directly in the user's main checkout when it has uncommitted changes. Those are theirs.

A new worktree has none of the main checkout's gitignored files, such as .env, so tests and dev servers that need them fail there. wt.py new copies the gitignored files that .worktreeinclude names (gitignore syntax, at the repo root) and lists them under copied. Claude Code does the same for the worktrees it creates. When checks need a gitignored file and the repo has no .worktreeinclude, tell the user and suggest adding one with that file's pattern.

Each worktree has an index (shown by wt.py new and wt.py list). When a dev server or test database needs a port, derive it from the index (for example 3000 + 10 * index) so parallel worktrees do not collide.

2. Branch from the right base

Find the base with python3 <skills>/pr-review/scripts/branch_policy.py --type <feature|fix|hotfix|...>. Trunk-based repos use the default branch for everything. Gitflow-style repos (a dev or develop branch exists, maybe next) send features and fixes to dev, hotfixes to the default branch, and promote dev -> next -> main in release PRs. A roadmap's GOAL.md or a .github/branches.yml file can set the policy explicitly. When a roadmap node has a target, that wins.

Start from the latest base: git fetch first, then wt.py new <branch> --base origin/<base> or the local base. Name branches by type: feat/..., fix/..., hotfix/..., refactor/..., docs/..., release/.... When the work starts in a worktree with a generated branch name (such as worktree-agent-<hash>), rename it with git branch -m <descriptive name> before the first commit, so the pull request does not carry the generated name. For a roadmap node, use the branch and pr_title from plan.py ready --json.

Hotfix: a fix that must reach the released branch now. Branch from the default branch, open the PR against it, and after it merges open back-merge PRs into the other integration branches (the back_merge list from branch_policy.py, for example next then dev), so the fix is not lost at the next release. A normal fix goes to dev and ships with the next release.

Release: a PR from one stage to the next (dev -> next, next -> main) with no new code in it. Its description lists the changes it promotes. In a roadmap it is a type: release node.

When building a roadmap node, the node's brief is the spec. Stay inside its owned paths.

Prove the problem first. Some changes fix a problem: a bug, a slow path, a memory or size cost, a flake. Such a change starts with proof that the problem exists on the base. That is the smallest test that fails there, or a cost beyond the noise that a profile places in the code you will change. Evidence in a brief, an issue or a planning document is a lead: it may come from an older commit. If the problem does not show, change nothing and report what you measured. Open the pull request only when the same proof passes on the branch.

3. Build it non-blocking

Read references/non-blocking.md. The short version:

  • One concern per PR. A feature, a fix and a refactor are three PRs.
  • Small. A reviewer reads it in one sitting.
  • Mergeable alone. Unfinished features hide behind a flag or stay unreachable. Breaking changes go through expand, migrate, contract. Nothing depends on a PR that has not merged, unless it is stacked on purpose (step 4).
  • Touch shared files lightly. Append to registries. Do not reformat or reorder files you do not own.

4. A bug in the base branch

When you find a bug that exists on the base branch (not one your branch introduced):

A vulnerability is the exception. Do not open a fix PR, an issue or an inbox entry for it, and do not push a test that shows it. Stop and report it to the user, or to the orchestrator when you are a subagent, and fix it with the security-fix skill.

  1. Confirm it on the base. Write the smallest failing test. Run it on the base with repro.py from pr-review, or in a worktree of the base. A bug you cannot show on the base is not ready for a fix PR.
  2. Decide.
    • The cause is clear and the fix is small: fix it in its own PR. wt.py new fix/<slug> --base <base>, add the failing test, fix, check, self-review, open the PR against the branch the policy gives for a fix (or for a hotfix, when the bug is in released code and cannot wait for the next release). It ships on its own, without waiting for your feature.
    • The cause is unclear or the fix is large: do not guess. Write an issue (or a roadmap inbox entry) with the failing test and what you found, and tell the user.
  3. Your feature branch.
    • It does not need the fix: leave the fix out of the feature branch entirely. The two PRs merge in either order.
    • It is blocked by the bug: stack it. Rebase the feature branch onto the fix branch, open the feature PR against the fix branch or the base, and write "Depends on #<fix PR>" at the top of its description. After the fix merges, rebase onto the base. GitHub retargets a PR when its base branch is deleted after merge.
    • Never hide the fix inside the feature PR. It would then wait for the feature's review, and a revert of the feature would bring the bug back.

5. Check

Run the project's checks in the worktree: python3 <skills>/pr-review/scripts/checks.py <worktree> --run --install. All of them must pass. When a check also fails on the base, say so in the PR and do not try to fix unrelated failures in this PR.

5b. Performance pass

When the change is a finished feature on code that runs often (render loops, request handlers, parsers, startup) or adds to what a browser downloads, run the perf-pass skill on it now, before the self-review: measure, try several options, keep the one with the best gain for its cost. Put its numbers in the PR's Cost section. Skip it for fixes, docs and changes with no measurable cost, and say so in the PR.

6. Self-review

Skip this step only for changes with no code or behavior in them, such as a typo in prose or a comment. Say in the PR that it was skipped and why. For everything else, review in one of two modes. Use the mode the caller gives you (a roadmap worker gets it as review from plan.py ready --json). Without one, use self mode for S changes and docs or chore changes, and fresh mode for the rest.

Fresh mode. Spawn a fresh agent to review the branch with the pr-review skill in local mode. Give it only the repo path, the base and the branch name. Do not give it your reasoning or a summary of what you did, because a reviewer that sees your reasoning tends to agree with it. The reviewer runs the full checks, so do not run them again on the same commit. A subagent cannot spawn agents. If you are one, as a roadmap worker is, skip the review, open the pull request, and report "fresh review needed": the caller spawns the reviewer and sends you its findings.

Review <branch> against <base> in <repo> with the pr-review skill, in local mode. Do not post anything.
Return the verdict, the checks result, and the findings, sorted into blocking, should fix, nits, and bugs found on the base.

Self mode. Review the branch yourself in this session. No new agent loads the repo again, so it costs less, but you will tend to agree with your own reasoning. Read git diff <base>...<branch> from start to end as if someone else wrote it. Go through pr-review's references/evaluation.md (correctness, simplicity, cost, risk), and run the full checks once with checks.py --run. Sort what you find into the same four groups. A self-review never counts toward auto-merge.

Then:

  • Blocking and should fix: fix them at the cause, with the simplest correct change, and run the checks again. A fix that hides the symptom (rounding a float to some number of places, a tolerance, a retry, a special case for the reported input) is not done. Change the representation or the logic instead, for example compute money in integer cents.
  • Nits: fix the trivial ones (a rename, a typo, a one-line change with no behavior change). Leave the rest, and list them under "Not done" in the PR description. A nit that needs restructuring or touches many files is not worth holding the PR for.
  • Bugs found on the base: handle them as in step 4. Every fix PR you open this way gets its own self-review round before it is handed over.

Run at most two review rounds. If blocking findings remain after the second, stop and tell the user what is left instead of looping. Report the mode, the rounds, the verdict and the checks result, so the caller does not review or check again.

7. Open the pull request

  1. Run ci_guard.py. On a private repo where a push would start workflows, ask the user before pushing: CI minutes there are billed. Until they say yes, keep the branch local and report the local checks. A draft saves CI runs only when the workflows skip drafts. When runs_on_drafts lists workflows, tell the user once, and suggest adding if: ${{ !github.event.pull_request.draft }} to their jobs and ready_for_review to their pull_request types (repo-setup's check.yml has both). Do not edit the workflows in this PR.
  2. Rebase onto the latest base, and rerun the checks if the base moved.
  3. Write the description from references/pr-body.md: what and why, changes, proof (the failing test on the base and passing on the branch, for fixes), roadmap node, cost, risk, and anything not done.
  4. git push -u origin <branch> and gh pr create --draft --base <base> --body-file <file>. Do not merge it.
  5. Keep it a draft until the review is clean: no blocking and no should-fix findings left. A fresh review that runs after the PR is open (a roadmap worker's "fresh review needed") usually takes two or three rounds of fixes. Each push to a ready PR starts CI again. When the review is clean and the local checks pass on the final commit, run gh pr ready <n>. When the review was already clean before the PR was opened, mark it ready right away. If the review stops with blocking findings left after two rounds, leave it a draft and say why.
  6. If the PR is a roadmap node and the roadmap's merge policy is auto, the orchestrator decides with plan.py can-merge and may merge it without the user (parallel-roadmap, "Auto-merge"). Otherwise, hand it to the maintainer as pr-review describes: if the user is the maintainer, give them the link, the evidence and gh pr review <n> --approve. Otherwise post a short comment that it is ready for maintainer approval and mention them.

Write all PR text by the plain-writing rules if that skill is installed.

8. Keep it mergeable

When the base moves and the PR conflicts, rebase onto the base, resolve the conflicts in the worktree, rerun the checks, and push with --force-with-lease. Resolve conflicts by keeping both sides' intent. When that is not clear, ask the author of the other change or the user.

9. Clean up

After a PR merges, run wt.py prune-merged with every integration branch as a --base (for example --base main --base next --base dev, the branches in the policy's promote list). For each merged branch it removes the worktree and the local branch. It asks GitHub for the merged pull request, so squash and rebase merges are found too, and it falls back to commit ancestry without gh. It keeps branches with no commits yet, branches with commits newer than their merged PR, and worktrees with uncommitted changes.

Agents started with worktree isolation leave their checkouts in .claude/worktrees/, and nothing removes them on its own. Add --agent-worktrees to sweep those too. It skips locked worktrees (an agent is still running), worktrees with a commit or checkout in the last 6 hours (--min-age-hours), and worktrees with uncommitted changes. It also removes clean detached review checkouts whose commit is in a base. Run it with --dry-run first when the machine is short on disk.

The remote branch:

  • If the repo deletes head branches on merge (GitHub setting "Automatically delete head branches"), nothing more is needed.
  • Otherwise add --remote to delete the remote branch of each merged PR. Deleting a remote branch is visible to others, so the first time in a repo, show the user what --dry-run --remote would delete and ask. Suggest turning the setting on with gh repo edit --delete-branch-on-merge (also a change others see, so ask).

GitHub moves stacked PRs onto the next base when their base branch is deleted after a merge, so deleting a merged fix branch does not break a feature stacked on it.

What the user sees

Opened #57 fix: subtotal skipped the first item -> main (draft until review was clean, now ready: gh pr review 57 --approve)
Opened #58 feat: sales tax on the subtotal -> main (independent of #57, marked ready after review)
Proof (#57): src/cart.test.js fails on main, passes on fix/subtotal-first-item
Checks: lint, build, tests pass locally on both branches
Self-review: 1 round, 0 blocking, 1 nit fixed, 1 nit left (listed in #58)
Worktrees: .worktrees/fix-subtotal-first-item, .worktrees/feat-tax (pruned after merge)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.