| name | pm-conventions |
| description | Use this skill when integrating, reading, or updating a project's conventions.md file — the document that captures house style for issue titles, labels, branch naming, PR descriptions, handoff phrasing, and review etiquette. Trigger phrases "set conventions", "load conventions", "where are the conventions", "what are our conventions", "add a convention", "edit conventions.md", "/pm-conventions", "the conventions say", "our team uses <X> format", "project conventions", "project title format". Also use proactively when another pm-* skill (pm-issues, pm-review, pm-improve, pm-branches, pm-handoff, pm-agent, pm-projects, pm-project-review) is about to write or evaluate text and a conventions file exists at `<repo>/.claude/pm/conventions.md` — the conventions must be loaded and applied before the skill writes anything user-facing. |
| version | 0.44.4 |
PM Conventions
A single document — conventions.md — that captures the project's house style for everything that flows through the PM plugin: how issue titles are formatted, which labels are required, how branches are named, how PR descriptions look, how handoff briefs read. Other PM skills consult this file before generating user-facing text, so the plugin's outputs match the project's conventions instead of the plugin's defaults.
Why this exists
The PM plugin has reasonable defaults baked in: branches look like feat/ENG-42-description, bug issues use a specific three-section template, handoffs require a "What's not done" block. But every team has its own quirks — some prefix every issue with a Jira-style domain code, some require an area:* label on every issue, some use bugfix/ instead of fix/. Hard-coding the plugin's preferences would either force teams to fight the plugin or fork it.
conventions.md is the escape hatch. The plugin's defaults still apply unless the conventions file overrides them.
Where it lives
<repo-root>/.claude/pm/conventions.md. That's the only location.
The whole PM config sits under .claude/pm/ in the repo — project.json (shared facts), project.local.json (per-machine gh_user, gitignored), conventions.md (this file), and templates/ (the issue template registry). Everything is portable across machines and contributors; the only thing in user-home is runtime cache.
If the file is present, it's loaded automatically; no config field is needed. If it's absent, the plugin runs with its baked-in defaults. That's a valid configuration — not every project needs custom conventions.
Pre-v0.20.0 projects that set a conventions_path field in the (now-removed) user-home projects.json should run /pm-setup to migrate — the wizard offers to move the file into .claude/pm/conventions.md.
Document shape
conventions.md is loosely structured. The PM plugin reads it whole, but it expects a small set of headings if the project wants to override specific behaviors. Sections the plugin recognizes:
| Heading | Consulted by | Effect when present | Example rule a project might write |
|---|
## Issue titles | pm-issues, pm-review | Format rules — prefixes, casing, banned words | "Bug titles start with [bug] (lowercase, brackets, trailing space)." |
## Issue labels | pm-issues, pm-review | Required labels, label-per-tag overrides | "Every issue must carry an area:* label (area:auth, area:billing, area:ui)." |
## Branches | pm-branches | Naming pattern, prefixes per tag | "Branch prefix matches the tag: bug→fix/, feature→feat/, task→chore/. Include the lowercased issue ID: feat/eng-42-jwt-refresh." |
## PRs | pm-branches | PR title format, required body sections | "PR body has ## Summary, ## Test plan, ## Closes (with Closes ENG-XX). Bugfix PRs include a ## Regression test section with the test file path." |
## Handoffs | pm-handoff | Required blocks beyond the four invariants, channel-specific phrasing | "Release-stage handoffs include a ## Rollback block naming the prior release tag." |
## Issue review | pm-review | Additional structural checks beyond the manifest's required_sections | "Every bug must reference at least one failing test path. Every feature acceptance criterion must be phrased 'Given … When … Then …'." |
## Issue enrichment | pm-improve | What to surface or skip per tag | "For bugs, always include the file containing the failing test. Do not link external docs unless they're from a registered SME repo." |
## Project titles | pm-projects, pm-project-review | Project name format | "[scope] Feature description" |
## Project labels | pm-projects, pm-project-review | Required project labels per tracker | "Linear: status:active; GitHub: type:project." |
## Project review | pm-project-review | Project-tier review etiquette | "Apply when a project has been open >30 days without a status update." |
## Project health thresholds | pm-report --profile project-health | Override default health-check thresholds | "atRiskTimelinePct: 0.6 to tighten the at-risk threshold." |
## Workstreams | pm-organize | Workstream tagging scheme (label prefix or enumerated list) — consumed by pm-organize for the workstream placement dimension | "- prefix: ws: — a label like ws:billing marks the billing workstream." |
Each row shows what a real project might write under that heading. The skills don't enforce these specific examples — they enforce whatever the operator actually writes.
Any additional sections are passed through as ambient context — downstream skills are allowed to read them but they don't have a designated consumer in the plugin.
The conventions file is prose with rules, not a JSON document. Skills read the relevant section and apply the rules using judgment. That's deliberate — a project saying "never use the word 'improve' in an issue title — it's vague" is more useful as a sentence than as a regex.
How other skills consume it
Resolving the file
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
CONVENTIONS_FILE="$REPO_ROOT/.claude/pm/conventions.md"
[ -f "$CONVENTIONS_FILE" ] && cat "$CONVENTIONS_FILE"
That's the whole resolution. If the file doesn't exist, the plugin runs with built-in defaults — don't warn, that's the expected "no conventions" case.
Applying it
Skills should:
- Read the conventions file at the start of their workflow.
- Identify the section(s) relevant to their task (the table above).
- Apply the rules during generation. When in doubt, prefer the conventions over the plugin defaults — the user wrote the conventions for a reason.
- When a generated output deviates from the conventions, say so explicitly: "Note: the conventions require an
area:* label; you'll need to add one."
The skills do not silently rewrite their behavior. Surface convention-driven decisions so the operator can see them.
Skill workflows
Initialize (when /pm-conventions init is run or /pm-setup offers to create one)
-
Check whether <repo>/.claude/pm/conventions.md already exists. If so, ask before overwriting.
-
Create the directory: mkdir -p <repo>/.claude/pm
-
Copy the starter template:
cp "${CLAUDE_PLUGIN_ROOT}/skills/pm-conventions/templates/conventions.md" \
"$REPO_ROOT/.claude/pm/conventions.md"
What's in the starter: the bundled templates/conventions.md ships with each of the twelve recognized headings (## Issue titles, ## Issue labels, ## Branches, ## PRs, ## Handoffs, ## Issue review, ## Issue enrichment, ## Project titles, ## Project labels, ## Project review, ## Project health thresholds, ## Workstreams) present as commented placeholders with example rules. Each heading has a 1-3 line comment explaining what kind of rule fits there. The operator's job is to replace the comments with real rules, or delete the headings they don't need. Empty sections are ignored at consume-time, so it's safe to leave heads they're undecided about.
-
Open the file (or print its path) and ask the operator to fill in project-specific rules. The starter has commented placeholders showing each recognized section.
-
Confirm: "Conventions registered. PM skills will consult .claude/pm/conventions.md from now on."
If a pre-v0.20.0 conventions file exists at a non-canonical path (referenced by an old conventions_path field), offer to migrate:
mv "$REPO_ROOT/$OLD_PATH" "$REPO_ROOT/.claude/pm/conventions.md"
And then delegate to /pm-setup to clean up the legacy field from the (deprecated) user-home projects.json entry.
Show
When the operator says "what are our conventions" or /pm-conventions show:
- Resolve the file path (
<repo>/.claude/pm/conventions.md).
- If it doesn't exist → tell the operator how to create one (
/pm-conventions init).
- If present → display the file.
Edit
/pm-conventions edit opens the file in the operator's editor. The skill itself does not modify the file — that's the operator's call.
Validate
/pm-conventions validate reads the file and lists which recognized sections are present. It's a "what does the plugin actually see" view. Useful when the operator suspects a section heading is misspelled (## Issue titles vs ## Issue Titles).
Resolving conflicts
Two cases come up regularly:
Plugin default vs convention. Convention wins. The plugin's behavior is a fallback, not a floor.
One convention vs another in the same file. First match wins — read top to bottom. If the operator wrote contradictory rules, they want the top one to apply; the bottom one is probably a stale note they forgot to delete. The skill should not silently merge; if it spots a contradiction, surface it in the output ("Note: conventions §X says A but §Y says B; applying A.").
What this skill does NOT do
- It does not enforce conventions. It loads them and exposes them to other skills.
- It does not write or modify the conventions file beyond the initial
init. The operator owns the document.
- It is not a general-purpose linter. Convention-violation checks happen in
pm-review; this skill is the loader.