Repos squash-and-merge. The **PR title becomes the commit on the default branch**. A conventional commit on a branch tip is not enough if the PR title drifts into a free-form sentence.
Align with CODING_PHILOSOPHY.md §8 (Interaction Mandate).
Format
<type>(optional-scope): <description>
- **type** (required): one of
feat,fix,docs,style,refactor,perf,test,build,ci,chore,revert - **scope** (optional): short area (
cli,canvas,skills,mcp, …) - **description**: imperative, lowercase start, no trailing period, ≤ ~72 chars for the subject line
- Breaking change:
!after type/scope (feat(api)!: …) and/or aBREAKING CHANGE:footer in the body
Examples:
| Good | Bad | |------|-----| | feat: add agent-debug skill | Add agent-debug skill | | fix(cli): retry transient R2 errors | Fixed the R2 issue | | docs: prefer Mermaid over ASCII diagrams | Prefer Mermaid diagrams over ASCII art | | chore: update .gitignore for env files | Update gitignore |
Rules
1. **Every git commit message** uses the format above (subject line). 2. **Every pull request title** uses the same format. Treat the PR title as the squash-merge commit message. 3. When updating a PR, keep the title conventional if the primary change type is unchanged; retitle if the PR’s purpose shifted (e.g. feat → fix). 4. Prefer one clear type that matches the user-visible outcome. Kit/docs/skills-only changes → docs or chore. Product behavior → feat / fix. 5. Do not use merge-commit style subjects (Merge pull request #…) as PR titles.
Checklist before open / update PR
- [ ] PR title matches
<type>(scope): description - [ ] Title summarizes the whole PR (what lands on main after squash), not a single intermediate commit
- [ ] Body can stay free-form (summary, test plan); title stays conventional