diff --git a/.claude/skills/pr/SKILL.md b/.claude/skills/pr/SKILL.md index 78491fc0..b5870650 100644 --- a/.claude/skills/pr/SKILL.md +++ b/.claude/skills/pr/SKILL.md @@ -1,15 +1,13 @@ --- name: pr -description: Write the pull request for the current famstack branch, a title that is the changelog line and a description by the repo's Pull requests rules, both checked with tools/commit-lint. Use when asked to write, draft or open a PR, or for its title or squash message. +description: Write the pull request for the current branch: a title that is the changelog line and a description per the Pull requests rules, both checked with tools/commit-lint. Use when asked to write, draft or open a PR, or to produce its title or squash message. --- -# Write the pull request +# Pull request -A PR is squash merged, so its title becomes the commit subject on main, and -that subject is the line in the release notes. The rules live in -`docs/agent/dev.md`, sections "Commits: the subject is the changelog" and -"Pull requests". Read both before writing: this file is the procedure, dev.md -is the rule, and where they differ dev.md wins. +A PR is squash merged: the title becomes the commit subject on main and the +release-notes line. `docs/agent/dev.md` ("Commits: the subject is the changelog", +"Pull requests") holds the rules; this file is the procedure. dev.md wins. ## 1. Read the branch @@ -19,50 +17,46 @@ git log --reverse --format='%h %s%n%b' origin/main..HEAD git diff --stat origin/main...HEAD ``` -Read the diff wherever the subjects don't say what an admin would notice. If -`HEAD..origin/main` is not empty, say the branch is behind; don't rebase unasked. +Read the diff wherever a subject does not state the user-visible change. Report a +non-empty `HEAD..origin/main` as "branch is behind". Do not rebase unasked. -## 2. One changelog entry, or two +## 2. One entry or two -List what a reader of the release notes would see: commits of a shown type -(`feat`, `fix`, `security`, `perf`, `docs`) and any commit with `!`, `Upgrade:` -or `BREAKING CHANGE:`. Tests, refactors and chores that serve one of those -belong to it and add no entry of their own. +Count the entries a release-notes reader sees: commits of a shown type (`feat`, +`fix`, `security`, `perf`, `docs`) plus any commit carrying `!`, `Upgrade:` or +`BREAKING CHANGE:`. Tests, refactors and chores serving one of those add no entry. -If that leaves two changes a reader would see separately, stop there. Don't -write a title with "and": say the PR should be split and which commits go in -which PR. One PR is one changelog entry. +Two visible entries mean two PRs. Never write a title containing "and": report +the split and which commits belong to which PR. -## 3. The title +## 3. Title -- `type(scope)!: subject`, with the type and scope from the tables in dev.md. - The scope is what a reader recognises (a stacklet or a bot), never a file. -- The change as an admin sees it: imperative, lowercase after the colon, no - full stop, no class or function names. At most 72 characters as commit-lint - counts them; dev.md asks under 70 for a PR. The ` (#N)` GitHub appends is - not counted. -- `!` only when the admin has to act, and then the description carries the - `Upgrade:` or `BREAKING CHANGE:` footer. -- For a one-commit branch whose subject already passes, use that subject: - GitHub takes the commit's subject as the squash title of a one-commit PR. +- Format: `type(scope)!: subject`. Types and scopes come from the dev.md tables. +- The scope names what a reader recognises, a stacklet or a bot, never a file. +- Imperative, lowercase after the colon, no full stop, no identifiers. +- Limit 72 characters as commit-lint counts them; dev.md asks for under 70. The + ` (#N)` appended at merge does not count. +- Use `!` only when the user must act. The description then carries `Upgrade:` + or `BREAKING CHANGE:`. +- Single-commit branch whose subject passes: reuse that subject. -## 4. The description +## 4. Description ``` ## Summary -- +- -Upgrade: +Upgrade: Refs: FAM-12 ``` -- One to three bullets. The footers only when they apply. +- One to three bullets. Footers only when they apply. - No "Test plan" section. Test output and measurements go in a PR comment. -- No em dashes: a comma, colon, period or parentheses. -- No Co-Authored-By trailer, no "Generated with" line, no tool link. The repo - is public and commit-lint rejects all three. +- No em dashes. Use a comma, colon, period or parentheses. +- No `Co-Authored-By`, no "Generated with" line, no tool link: this repository is + public and commit-lint rejects all three. -## 5. Check before showing it +## 5. Check ```bash python3 tools/commit-lint --title "" @@ -70,32 +64,29 @@ python3 tools/commit-lint --body "<description>" python3 tools/commit-lint --range origin/main..HEAD ``` -The last one is what CI runs over every commit in the PR. Fix and re-run until -all three pass. Rewording a commit that is already pushed needs a force push, -which needs Arthur's go. +CI runs the third over every commit in the PR. Fix and re-run until all three +pass. Rewording a pushed commit needs a force push: request approval first. -Then show the title, the description in a code block, and the three results. +Output: the title, the description in a code block, the three results. -## Opening it +## 6. Open -Pushing and opening the PR are Arthur's call. Ask for his go every time, even -if he gave it for the last one. With it: +Pushing and opening a PR need explicit approval, for every push. With approval: ```bash git push -u origin HEAD gh pr create --base main --title "<title>" --body-file <file> ``` -`--draft` if he asks for a draft. Never merge. +Add `--draft` when asked. Never merge. -## At merge time +## Merge -The repo's squash setting fills the commit body from the branch's commit -messages, not from the PR description. A footer in the description reaches -main only if the merge uses the description as the body, in the merge dialog -or with `gh pr merge --squash --body-file`. Merging is Arthur's: say this when -handing the PR over, and don't run it. +The repository builds the squash body from the branch's commit messages, not +from the PR description. A footer written in the description reaches main only +when the merge uses the description as the body: the merge dialog, or +`gh pr merge --squash --body-file`. State this when handing the PR over. -A PR Arthur marks for a rebase merge is the exception: every commit lands as -its own changelog line, so each one has to pass commit-lint on its own, and -the title is not a changelog line. +Rebase merge, when requested, is the exception: every commit becomes its own +changelog line, each must pass commit-lint alone, and the title is not a +changelog line.