---
name: sentry-commit-message
source: https://app.decimal.ai/s/sentry-commit-message@1/SKILL.md
source_sha256: 78a23e17fa6f
---

# Sentry commit message conventions

## Contract

Format every git commit as `<type>(<scope>): <Subject>` with an optional body and
footer, using Sentry's specific spellings and casing. Apply whenever you write or
revise a commit message. These rules differ from plain Conventional Commits in three
ways the base gets wrong: the type token `ref` (not `refactor`), a **Capitalized**
subject (not lowercase), and the `Refs`/`Fixes` footer keywords.

## Rules

### 1. Header structure

```
<type>(<scope>): <Subject>
```

- The header line is **required**. `<scope>` and the parentheses are optional.
- Exactly one space after the colon. No space before the colon.
- The whole header (type + scope + subject) is at most **70 characters**.
- Every line in the message stays under **100 characters**.

### 2. Type token — use the Sentry spellings

Pick exactly one type from this closed set. The spellings in bold are the ones that
differ from the common Conventional-Commits vocabulary:

| Type | Use for |
|------|---------|
| `feat` | A new feature or user-visible capability |
| `fix` | A bug fix |
| **`ref`** | Refactoring with **no behavior change** (NOT `refactor`) |
| `perf` | A performance improvement, no new behavior |
| `docs` | Documentation only |
| `test` | Adding or correcting tests |
| `build` | Build system, dependencies, lockfiles, bundler config |
| `ci` | CI configuration (e.g. GitHub Actions workflows) |
| `chore` | Maintenance: dead-code removal, copyright bumps |
| `style` | Formatting only — whitespace, quotes, no logic change |
| **`meta`** | Repository metadata (CODEOWNERS, issue templates) |
| **`license`** | License changes |

The type token is **lowercase**. There is no other valid type — do not invent
`improvement`, `update`, `misc`, or `wip`.

### 3. Scope

- Optional. When present it goes in parentheses immediately after the type:
  `fix(api):`.
- The scope is **lowercase** and is a short noun for the affected area (`api`,
  `alerts`, `auth`). No spaces inside the parentheses.

### 4. Subject

- **Capitalize the first letter** of the subject: `fix(api): Handle null response`.
  This is the opposite of lowercase Conventional Commits and the single most common
  base mistake.
- **Imperative present tense**: `Add`, `Handle`, `Remove`, `Extract`. Never past tense
  (`Added`, `Fixed`) and never gerund (`Adding`, `Fixing`).
- **No trailing period.**
- Describe *what* the change does, concisely.

### 5. Body (optional)

- Separate from the header with one blank line.
- Explain **what** and **why**, not how. Include motivation; contrast with the previous
  behavior when it clarifies the change.
- Imperative present tense, same as the subject. Wrap at <100 chars.

### 6. Footer — issue references

Put issue references in the footer, separated from the body by a blank line. The
keyword choice is meaningful:

- **`Fixes`** — closes the issue when the commit merges. Use when the change resolves
  the issue: `Fixes SENTRY-1234`, `Fixes GH-1234`, `Fixes #1234`.
- **`Refs`** — links the issue **without closing** it. Use the exact keyword `Refs`,
  never `See`, `Related`, `Ref`, or `References`: `Refs GH-1234`, `Refs LINEAR-ABC-123`.

Issue identifier forms: `#1234`, `GH-1234`, `SENTRY-1234`, `LINEAR-ABC-123`.

### 7. Breaking changes

A breaking change needs **both** signals:

1. A `!` immediately after the type or scope and before the colon: `feat(api)!:` or
   `feat!:`.
2. A footer line beginning with `BREAKING CHANGE:` describing the break.

### 8. Revert

Format a revert as:

```
revert: <original header>

This reverts commit <full-sha>.

Reason: <why it was reverted>
```

The header is `revert:` followed verbatim by the reverted commit's original header.

## Worked examples

Each example shows the base model's wrong default (BEFORE) and the conforming form
(AFTER).

### Rule 2 — `ref`, not `refactor`

Task: you moved duplicate validation out of three handlers into one shared class; no
behavior change.

BEFORE (base default):
```
refactor: extract validation logic into a shared module
```
AFTER:
```
ref: Extract validation logic into a shared module

Move duplicate validation from three endpoints into one validator class.
No behavior change.
```

### Rule 4 — Capitalize the subject

Task: handle a null response in the user endpoint.

BEFORE (lowercase Conventional Commits default):
```
fix(api): handle null response in user endpoint.
```
AFTER (capitalized first letter, no trailing period):
```
fix(api): Handle null response in user endpoint
```

### Rule 4 — imperative present tense

Task: add CSV export to the reports page.

BEFORE (past/gerund tense):
```
feat: Added CSV export to reports page
```
AFTER:
```
feat: Add CSV export to the reports page
```

### Rule 6 — `Refs` links without closing

Task: alerts now post Slack thread replies; link GH-1234 but do not close it.

BEFORE (base reaches for `Closes`/`Fixes`):
```
feat: add slack thread replies for alerts

Closes GH-1234
```
AFTER:
```
feat(alerts): Add Slack thread replies for alert updates

Post a reply to the original Slack thread instead of a new message, keeping
related notifications grouped.

Refs GH-1234
```

### Rule 6 — `Fixes` closes the issue

Task: add a null check that resolves SENTRY-5678.

BEFORE:
```
fix: null check for deleted accounts (SENTRY-5678)
```
AFTER:
```
fix(api): Handle null response for deleted accounts

The user API returned null for deleted accounts and crashed the dashboard.
Add a null check before reading user properties.

Fixes SENTRY-5678
```

### Rule 7 — breaking change needs `!` AND footer

Task: remove the deprecated v1 endpoints; closes SENTRY-9999.

BEFORE (one signal only):
```
feat: Remove deprecated v1 endpoints

Fixes SENTRY-9999
```
AFTER:
```
feat(api)!: Remove deprecated v1 endpoints

Remove all v1 API endpoints deprecated in 23.1. Clients migrate to v2.

BREAKING CHANGE: v1 endpoints are no longer available
Fixes SENTRY-9999
```

### Rule 8 — revert format

BEFORE:
```
Revert "Add new endpoint" — broke prod
```
AFTER:
```
revert: feat(api): Add new endpoint

This reverts commit abc123def456.

Reason: Caused a performance regression in production.
```

## Edge cases & exceptions

- **`ref` vs `perf`**: if the change keeps behavior the same but improves speed, use
  `perf`. If it restructures code with no perf or behavior change, use `ref`.
- **`build` vs `ci`**: dependency/lockfile/bundler changes are `build`; the CI pipeline
  config (workflow YAML) is `ci`.
- **`chore` vs `style` vs `ref`**: pure formatting/whitespace is `style`; dead-code
  removal and housekeeping is `chore`; reorganizing live code is `ref`.
- **`meta` vs `docs`**: repository metadata files (CODEOWNERS, issue templates) are
  `meta`; human-readable documentation (README, guides) is `docs`.
- **Both link and close**: a commit may carry multiple footer lines — e.g. `Fixes`
  one issue and `Refs` another. Each reference goes on its own line.
- **Breaking change with no issue**: still requires the `!` and the `BREAKING CHANGE:`
  footer; the issue footer is just absent.
- **Scope when unsure**: scope is optional — omit it rather than guessing a wrong area.

## Do / Don't

- Never `refactor:` — always `ref:`.
- Never a lowercase subject — always capitalize the first letter.
- Never a trailing period on the subject — always end without punctuation.
- Never past/gerund tense (`Added`, `Adding`) — always imperative (`Add`).
- Never `See` / `Related` / `Closes` to link without closing — always `Refs`.
- Never rely on `!` alone for a breaking change — always add the `BREAKING CHANGE:`
  footer too.
- Never invent a type (`update`, `improvement`, `wip`) — always use a token from the
  table.

## Common mistakes

- Writing `refactor` (the universal Conventional-Commits token) instead of `ref`.
- Lowercasing the subject because most Conventional-Commits guides do.
- Adding a trailing period to the subject line.
- Using `Closes`/`Resolves` when the intent is to *link* (should be `Refs`), or `See`
  when the intent is to *close* (should be `Fixes`).
- Marking a breaking change with only `!` or only the `BREAKING CHANGE:` footer.
- Using `refactor`-flavored types like `cleanup` or `improvement` not in the set.

## Quick checklist

- [ ] Type from the closed set, Sentry spelling (`ref` not `refactor`).
- [ ] Optional lowercase scope in parentheses.
- [ ] Subject capitalized, imperative present, no trailing period, header ≤70 chars.
- [ ] Body explains what/why (optional), lines <100 chars.
- [ ] Footer: `Fixes` to close, `Refs` to link.
- [ ] Breaking change → `!` AND `BREAKING CHANGE:` footer.
- [ ] Revert → `revert:` + `This reverts commit <sha>.` + `Reason:`.
