-
Notifications
You must be signed in to change notification settings - Fork 64
Add create-pr skill encoding the project PR protocol #812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
92ed336
Add create-pr Claude skill encoding the project PR protocol
tigercosmos 2bee9e4
Prefer prose over bullets in PR descriptions
tigercosmos fcf8d13
Tighten create-pr skill from dogfooding feedback
tigercosmos 019fc0a
Stop the create-pr skill from posting the review-request comment
tigercosmos afcdfd9
Drop issue #811 reference; this file is now authoritative
tigercosmos 379fcde
Require unwrapped paragraphs in PR descriptions
tigercosmos File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| --- | ||
| name: create-pr | ||
| description: Open a modmesh pull request that follows the project PR protocol (concise subject, clear description, "related to #xxx" wording, draft by default, ready-for-review via global comment). Use when the user asks to create, open, or draft a pull request. | ||
| --- | ||
|
|
||
| # Create Pull Request (modmesh) | ||
|
|
||
| This file is the authoritative reference for the modmesh PR protocol. | ||
| The "Pull Request Guidelines" section of `CLAUDE.md` is the project-wide | ||
| cross-reference; flag any drift between the two. | ||
|
|
||
| ## Protocol the PR must satisfy | ||
|
|
||
| 1. **Subject** -- concise and informative. | ||
| 2. **Description** -- clear, short, human-readable global description. | ||
| Write it as prose paragraphs that a person would actually want to | ||
| read. Avoid bullet lists; only fall back to a short bulleted list or | ||
| a table when prose would genuinely be unreadable (e.g. a benchmark | ||
| matrix with many rows). State *what* changed and *why*. | ||
| **Do not hard-wrap paragraphs.** Each paragraph is a single | ||
| unbroken line; separate paragraphs with one blank line. GitHub | ||
| reflows the text to the viewer's width, and mid-sentence line | ||
| breaks at 79/80 columns render as ragged prose in the PR view. | ||
| The 79-char source-code limit does not apply to PR descriptions. | ||
| 3. **Issue reference** -- end with "Related to #xxx" or "For issue #xxx". | ||
| **Never** use "close #xxx", "closes #xxx", "fixes #xxx", or any closing | ||
| keyword. We do not let PR/commit text drive issue management. | ||
| 4. **Draft by default** -- open as draft unless the user explicitly says it | ||
| is ready for review. Pushing the "ready for review" button alone is | ||
| *not* a review request in this project. | ||
| 5. **Request review with a global comment** -- when the PR is ready, the | ||
| author posts a global PR comment that explicitly asks for review. The | ||
| button push is not quotable in follow-ups, so the comment is required. | ||
| 6. **Inline annotations** -- the author is expected to add inline review | ||
| annotations to guide the reviewer, unless the diff is one-liner-ish. | ||
| The skill should remind the user; it does not write the annotations. | ||
| 7. **Human authorship** -- all PR comments are written by humans. Tool | ||
| assistance is OK, but the user must know what the text says. When the | ||
| skill drafts text, present it for the user's review and edits before | ||
| posting. | ||
|
|
||
| ## Workflow | ||
|
|
||
| 1. **Confirm scope with the user.** Ask directly when unclear from | ||
| context: | ||
| - Which issue does this PR relate to? (issue number) | ||
| - Is this ready for review, or should it be opened as draft? | ||
| - One-line gist of the change. | ||
|
|
||
| 2. **Verify branch state.** modmesh's main branch is `master`. Run in | ||
| parallel: | ||
| - `git status --porcelain` -- check for staged or unstaged changes | ||
| and untracked files. | ||
| - `git log --oneline origin/master..HEAD` -- list the commits the PR | ||
| will carry. | ||
| - `git diff --stat origin/master...HEAD` -- summarize the diff | ||
| (three-dot uses the merge base). | ||
| - `git rev-parse --abbrev-ref --symbolic-full-name @{u}` -- check if | ||
| the branch tracks a remote. | ||
|
|
||
| If `git status --porcelain` shows any output, the working tree is | ||
| not clean. Show the user the list (staged, unstaged, and untracked | ||
| separately) and ask explicitly how to proceed: stage and commit | ||
| selected files, stash, or abort. Never run `git add -A` or | ||
| `git add .` without confirmation -- pick specific paths so that | ||
| stray files (local settings, generated artifacts) are not pulled | ||
| into the PR. | ||
|
|
||
| If the branch has no commits ahead of `origin/master`, abort -- the | ||
| PR would be empty. | ||
|
|
||
| If the branch is not pushed (or is behind its remote), push after | ||
| confirming with the user. | ||
|
|
||
| 3. **Draft the subject and body.** Inspect the diff and the user's | ||
| gist, then propose a subject and a body. The body should be **short | ||
| prose** -- a person reading it should understand what changed and | ||
| why without scanning a checklist. Prefer one to three paragraphs. | ||
| Reserve bullets for cases where prose would genuinely be unreadable | ||
| (long enumerations, benchmark matrices). End with the closing line | ||
| `Related to #xxx.` or `For issue #xxx.`. | ||
|
|
||
| **Write each paragraph as one continuous line.** Do not insert | ||
| hard line breaks inside a paragraph -- not at 79 columns, not at | ||
| any column. Paragraphs are separated by exactly one blank line. | ||
| GitHub wraps to the viewer's width; pre-wrapped prose looks | ||
| ragged in the rendered PR. This applies to the draft you show | ||
| the user and to the text written into `$body_file` in step 4. | ||
|
|
||
| Present the draft to the user (subject and body) and wait for edits | ||
| or approval before opening the PR. Do not post Claude-Code | ||
| attribution trailers in the PR body -- this project treats PR text | ||
| as human-authored. | ||
|
|
||
| 4. **Open the PR.** Load the approved title and body into shell | ||
| variables using **quoted heredocs** -- the single-quoted delimiter | ||
| suppresses every form of shell expansion, so the placeholder text | ||
| can contain backticks, `$`, `"`, or apostrophes without escaping. | ||
| Then pass the title as a double-quoted variable expansion (safe | ||
| because the value is already in memory) and the body via a temp | ||
| file: | ||
|
|
||
| ```bash | ||
| title=$(cat <<'TITLE' | ||
| <approved subject> | ||
| TITLE | ||
| ) | ||
|
|
||
| body_file=$(mktemp) | ||
| trap 'rm -f "$body_file"' EXIT | ||
| cat >"$body_file" <<'BODY' | ||
| <approved body, already ending with "Related to #xxx." or | ||
| "For issue #xxx." from step 3> | ||
| BODY | ||
|
|
||
| gh pr create --draft \ | ||
| --title "$title" \ | ||
| --body-file "$body_file" | ||
| ``` | ||
|
|
||
| Drop `--draft` only when the user has explicitly said the PR is | ||
| ready for review. Do not append a second issue-reference footer here; | ||
| the body from step 3 already has one. The `trap` ensures the temp | ||
| file is removed on any exit path. If the approved body would itself | ||
| contain the literal token `BODY` on its own line, swap the delimiter | ||
| to something unique (e.g. `BODY_EOF_811`). | ||
|
|
||
| 5. **After creation.** Report the PR URL back to the user. Then: | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My favor part. |
||
| - Remind the user that the global review-request comment is the | ||
| author's responsibility -- the skill does **not** post it. When | ||
| the PR is ready (now, or later after leaving draft), the author | ||
| must open a global PR comment that explicitly asks the | ||
| maintainer to review. Point the user at the PR URL and let them | ||
| write and post the comment themselves; do not draft text for it | ||
| and do not call `gh pr comment`. | ||
| - Remind the user to add inline annotations on the diff (the skill | ||
| does not write them). Recommend the user focus on the points | ||
| that help the reviewer most: | ||
| - non-obvious design choices and the alternatives considered; | ||
| - subtle logic, invariants, or ordering constraints a reader | ||
| might overlook; | ||
| - changes that look like dead code or accidental edits but are | ||
| intentional, so the reviewer does not "fix" them; | ||
| - known limitations, follow-up work, and test-coverage gaps; | ||
| - tricky diffs (large reformatting next to substantive edits, | ||
| cross-file renames) where the reviewer needs guidance on what | ||
| to inspect carefully versus what is mechanical. | ||
| Skip the reminder when the diff is genuinely one-liner-ish. | ||
|
|
||
| ## Guardrails | ||
|
|
||
| - **Closing keywords.** After loading `$title` and writing `$body_file` | ||
| in step 4, but **before** the `gh pr create` call, scan title and | ||
| body together with a single case-insensitive check: | ||
|
|
||
| ```bash | ||
| { printf '%s\n' "$title"; cat "$body_file"; } \ | ||
| | grep -iEn '\b(close[sd]?|fix(e[sd])?|resolve[sd]?)[[:space:]]+#[0-9]+' | ||
| ``` | ||
|
|
||
| Any hit means the text uses a banned closing keyword (close/closes/ | ||
| closed/fix/fixes/fixed/resolve/resolves/resolved followed by `#nnn`). | ||
| Rewrite the offending line to "Related to #xxx" or "For issue #xxx" | ||
| and re-confirm with the user before retrying. | ||
| - **Branch protection.** Never push directly to `master`/`main`, never | ||
| `--no-verify`. If `gh pr create` fails, surface the error and stop -- | ||
| do not work around it. | ||
| - **No fabricated context.** Do not invent benchmark numbers, test | ||
| results, or verification claims. Only include what the user has stated | ||
| or what is visible in the diff/commits. | ||
| - **Trailers.** Do not append `Co-Authored-By:` or "Generated with Claude | ||
| Code" trailers to the PR body. Commits in this project are | ||
| human-authored by convention. | ||
|
|
||
| ## Output | ||
|
|
||
| - Show the draft subject and body to the user before calling `gh pr | ||
| create`. Use a fenced block so it is easy to edit. | ||
| - After creation, output a single line: `opened: <PR URL> (draft|ready)`. | ||
| - If guardrails block the action (closing keyword, dirty tree, unpushed | ||
| branch), output `blocked: <reason>` and stop. Do not retry silently. | ||
|
|
||
| <!-- vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4 tw=79: --> | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Workflow confirmed while opening this PR.