Commit Messages
Commit messages drive release behavior, changelogs, and audit search. Because merges are squash-only, the PR title becomes the commit on main; write PR titles and commit subjects with the same grammar.
Required format
type(optional-scope): short imperative subject
optional body that explains why
optional footer with refs, closes, incident ids, or breaking-change notesGood one-line examples:
feat(profile): add language selectorfix(api): reject duplicate permit submissionsinfra(argocd): add preview namespace controlsdocs(gitops): clarify release tag promotionThe subject is mandatory. Use imperative present tense, lowercase unless a proper noun requires it, and no ending period.
Release impact
| Type | Use for | Release impact |
|---|---|---|
feat | New user-visible behavior | Minor |
fix | Bug fix | Patch |
security | Security hardening or vulnerability fix | Patch |
perf | Performance improvement | Patch |
feat!, fix!, security! | Backward-incompatible change | Major |
docs, test, ci, style, chore, build, infra, refactor | Non-product or internal work | None by itself |
revert | Reverse a previous change | Matches reverted impact |
Use ! or a BREAKING CHANGE: footer when callers, data, APIs, or operational behavior must change.
Body and footer
Write a body when context matters: motivation, previous behavior, user impact, rollout notes, migration notes, or rollback notes. The body should answer, “Why did this change need to happen?”
Use the footer for machine-readable references:
Refs: ADR-070Closes: PROJ-2211BREAKING CHANGE: API session token exchange now requires `aud`.Do not put issue IDs in the scope. Use scopes for stable system areas such as auth, profile, api, ci, release-prod, or docs.
Full examples
feat(profile): add language selector
Allow residents to choose a portal language from the header.Default remains English for compatibility with existing bookmarks.
Refs: ADR-070Closes: PROJ-2211feat(auth)!: migrate login flow to OIDC bearer assertions
The previous cookie-based session format is removed.Clients must use the new token exchange endpoint before this release.
BREAKING CHANGE: API session token exchange now requires `aud` to match the target client id.Refs: ADR-112Closes: SEC-4412infra(ci): tighten release pipeline timeout defaults
Lower the default timeout from 45m to 30m for LaunchPad dispatch jobs.Retries remain in place for the same failure classes.
Refs: OPS-771Exceptions
These generated Git forms are allowed:
chore: initMerge branch 'branch-name'Revert "reverted commit subject line"Do not rewrite Git-generated merge or revert subjects into artificial Conventional Commits unless you are creating a normal human-authored commit.
Enforcement
Commit messages are enforced by the conventional-commits GitHub ruleset on all branches with no bypass actors. PR titles are checked by the central governance workflow because the squash commit uses the title.
Run or inspect the enforcement script at templates/governance/enforce-commit-messages.sh.
ORG=mdds bash templates/governance/enforce-commit-messages.shReview rule
If validation fails, fix the title or commit before merge. Do not bypass the grammar during incidents; emergency changes need good release metadata more than routine changes do.