.agents/skills/pr-commit-message/SKILL.md
Write commit messages that preserve the reason for the change, not just the diff.
A strong merge commit message should let a future maintainer answer:
Use this skill for merge commits, squash commits, and "please write a better commit message for this PR" requests.
For calibration and examples drawn from Jon Pryor's commit history in dotnet/android,
see references/pryor-style-guide.md.
Before writing anything, inspect the available evidence:
When working inside a repo with PR context available, prefer first-party context over guessing:
If a crucial piece of context is missing, either:
Do not force every commit into the same size.
The message should be as detailed as the change needs, not as short as possible. For bump commits in particular, a shorter body is fine if the compare link and a few upstream bullets already carry the important context.
Prefer the repo's existing conventions. Good defaults are:
[Area] Imperative summary (#PR)Area: imperative summary (#PR)Imperative summary (#PR) if there is no area prefix conventionSubject-line rules:
Add, Fix, Update, Bind, Remove, Use, Bumpaddress review comments, misc fixes, or merge PRUse the following pattern when it fits the change:
Context: <issue/doc/announcement/compare URL or commit SHA>
Fixes: <issue URL or #NNNN>
Changes: <compare URL or related PR/commit>
<1-2 paragraphs describing the problem or motivation>
<show the symptom, failure mode, or external trigger when that helps>
<1-3 paragraphs explaining the solution and the reasoning behind it>
- <optional bullets for notable sub-changes>
- <optional bullets for tradeoffs, risks, or follow-up work>
For large or multi-part changes, add section headers named after the actual topic or sub-problem, not generic template headings. For example:
~~ Fix assertion failure in <CheckApiCompatibility/> ~~
~~ Changes: Minor SDK Versions ~~
~~ Stable API-36.1 ~~
If there are many references, use numbered links at the end. Context: may also point
at a prior commit SHA when the lineage of the fix matters.
Include concrete, durable context when it exists:
Translate review feedback into the underlying change. For example:
Address PR commentsUse explicit bounds checks in SKBitmap.Resize to avoid overflowThe point is to preserve the engineering story, not the review choreography.
Avoid commit messages that:
Specifically avoid subjects or bodies like:
Fix review commentsMore changesPR feedbackUpdate after discussionThese help nobody once the PR is merged.
Also keep the formatting in-family for the target repo. If its history favors *
bullets, numbered link references, or indented code/log blocks over fenced ones, keep
that local style instead of forcing a new template.
Explain:
If there is a meaningful exception, assertion, or failing log line, include a short snippet. Evidence makes the message more trustworthy and more searchable later.
At minimum, include:
Do not leave these as anonymous bump commits unless the repo already has a strict mechanical bump format.
State:
When one PR contains multiple tightly related changes, organize the body so each part has a name and purpose. Use bullets or short section headers instead of a wall of text.
When the user asks for a commit message, return:
Missing context: bullets only if important context could not be found.Do not dump brainstorming notes unless the user explicitly asks for alternatives.
Before finalizing, make sure the message answers:
If the answer is still "you had to be there," the message needs more context.
Weak
Fix NativeAOT issue
Better
[NativeAOT] Wait for GC bridge processing via JNIEnv value manager (#12345)
Context: https://github.com/org/repo/issues/12340
Context: abcdef1234567890abcdef1234567890abcdef12
Apps using NativeAOT could abort during JNI wrapper creation while startup code
was still waiting on pending GC bridge work. The failures were intermittent, but
the stack traces consistently pointed at wrapper initialization before the active
value manager had finished processing queued state.
Route the wait through `JNIEnv.ValueManager?.WaitForGCBridgeProcessing()` instead
of the older runtime-specific path. This keeps the synchronization aligned with
the current value manager implementation and removes the startup crash without
changing the existing wrapper call pattern.
Weak
Bump submodule
Better
Bump to org/dependency@abc12345 (#4567)
Changes: https://github.com/org/dependency/compare/oldsha...abc12345
* pull in the upstream fix for manifest parsing on Windows
* include the follow-up change that avoids duplicate resolver entries during restore
These are the only behavior changes used by this PR; the remaining updates are
mechanical fallout from the bump.