Skip to content

Commit 5b7eb8b

Browse files
committed
docs(contributing): adopt Conventional Commits and make the rules binding
CONTRIBUTING.md banned Conventional Commits outright. Its load-bearing argument was that nothing here generates from commit types, because release notes were hand-written in CHANGELOG.md. Notes are moving to generated, so that premise goes. Subjects become <type>(<scope>): <description>, keeping the component as the scope. The bans that were right are kept verbatim: ticket IDs, status tags, filenames in subjects. A short note records that the policy changed so it is not re-litigated from older git log entries. Co-Authored-By is now banned explicitly, on any artifact, whoever wrote the change. AGENTS.md states that the rules bind humans and agents equally and that a violating pull request is declined rather than fixed in review. Its inline copy of the prefix rules is gone — a second copy is one that goes stale. CL-7880
1 parent edb517f commit 5b7eb8b

2 files changed

Lines changed: 62 additions & 40 deletions

File tree

‎AGENTS.md‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,15 @@ same reason.
6161

6262
## Commits, pull requests, and issue tracking
6363

64-
**MUST follow `CONTRIBUTING.md`.** That file is the source of truth for commit
65-
titles and bodies, PR titles and bodies, and Linear/GitHub linking. Do not use
66-
Conventional Commits prefixes (`feat:`, `fix:`, `docs:`, `ci:`, …), ticket IDs
67-
in commit subjects, or free-form PR body sections. Rewrite before push if a
68-
message violates those rules. Commit with the operator's local git identity.
64+
**MUST follow `CONTRIBUTING.md`.** That file is the single source of truth for
65+
commit titles and bodies, PR titles and bodies, and Linear/GitHub linking. It
66+
is not summarized here on purpose — a second copy of the rules is a copy that
67+
goes stale, and the rules have changed before. Read it.
68+
69+
**This binds humans and agents equally. A pull request that violates
70+
`CONTRIBUTING.md` will be declined** — not fixed in review. Check your commit
71+
subjects against that file before you push, and rewrite them if they do not
72+
match. Commit with the operator's local git identity.
6973

7074
## Pushing
7175

‎CONTRIBUTING.md‎

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -43,56 +43,67 @@ not substitute a bare `bun test` (it also scans
4343

4444
### Title (MUST)
4545

46-
- Imperative, present tense, max **72** characters
47-
- Starts with a verb: `Add`, `Fix`, `Remove`, `Harden`, `Document`, …
48-
- No trailing punctuation, no abbreviations for their own sake
49-
- No filenames or paths in the subject — the diff already lists them
50-
- Match the voice of recent history:
46+
Follow [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/).
5147

52-
```bash
53-
git log origin/main --format='%s' | head -20
48+
```text
49+
<type>(<scope>): <description>
5450
```
5551

56-
**Banned subject prefixes** (all of them, including habits from other projects):
52+
- **Type** — one of `feat`, `fix`, `perf`, `refactor`, `test`, `docs`, `build`,
53+
`ci`, `chore`, `style`
54+
- **Scope** — the component the change lives in: `feat(executor)`,
55+
`fix(nameref)`, `perf(glob)`, `docs(release)`. Omit it only when a change
56+
genuinely spans the repo
57+
- **Description** — imperative, present tense, lowercase after the colon, no
58+
trailing period. The whole subject line stays within **72** characters
59+
- **Breaking changes** — `!` after the type/scope (`feat(config)!: ...`), or a
60+
`BREAKING CHANGE:` footer in the body
61+
62+
This repo's history used a bare `component: description` prefix (`executor:`,
63+
`nameref:`). New commits keep the component as the **scope** and lead with the
64+
type: `executor: add retry` becomes `feat(executor): add retry`.
65+
66+
Releases use `chore(release): perfi X.Y.Z`. Release notes use
67+
`docs(release): add perfi X.Y.Z release notes`.
5768

58-
- Conventional Commits: `feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:`, `ci:`, `perf:`, `style:`, `build:`
59-
- Scoped forms: `docs(changelog):`, `net:`, `frontend:`
60-
- Ticket IDs: `CL-1234:`, `INTR-79:`, `#456:`
69+
**Still banned in the subject:**
70+
71+
- Ticket IDs: `CL-1234:`, `INTR-79:`, `#456:` — linking is a pull-request
72+
concern (see [Issue tracking](#issue-tracking-linear-and-github))
6173
- Status tags: `WIP:`, `[urgent]`, `(security):`
74+
- Filenames and paths — the diff already lists them
75+
- Abbreviations for their own sake
6276

6377
**Good:**
6478

6579
```text
66-
Add retry logic for failed network requests
67-
Fix race condition in transaction verification
68-
Document the permission queue behavior
80+
feat(executor): add retry logic for failed network requests
81+
fix(inference): close race condition in transaction verification
82+
docs(permissions): document the permission queue behavior
83+
perf(glob): stop rescanning ignored directories
6984
```
7085

7186
**Bad:**
7287

7388
```text
74-
feat: add retry logic
75-
fix(auth): race in server.ts
76-
CL-5494: flatten model picker
77-
Update code
89+
add retry logic (no type)
90+
feat: add retry to src/executor.ts (no scope, filename in subject)
91+
fix(auth): CL-5494 race in server.ts (ticket ID, filename)
92+
chore: update code (says nothing)
7893
```
7994

80-
### Why not `feat:` / `fix:` / `docs:` / `ci:`?
81-
82-
Conventional Commits are useful when tools **generate** changelogs, SemVer bumps,
83-
or release notes from commit types. This project does not:
95+
### A note on the previous rule
8496

85-
- Release notes are hand-written in `CHANGELOG.md` and deliberately strip ticket
86-
and PR IDs from public notes.
87-
- Reviewers and `git log` readers need a sentence that stands alone years later,
88-
not a taxonomy debate (`chore` vs `refactor` vs `fix`).
89-
- An imperative subject already encodes the action: `Fix race in the approval
90-
queue` is clearer than `fix: race in the approval queue`.
91-
- Prefixes train agents and humans to smuggle scope, ticket IDs, and file names
92-
into the subject — noise we already reject elsewhere.
97+
This project previously **banned** Conventional Commits and required a plain
98+
imperative subject. That rule rested on the repo generating nothing from commit
99+
types — release notes were hand-written in `CHANGELOG.md`. That is changing:
100+
release notes move to being generated from merged pull requests, so the premise
101+
no longer holds.
93102

94-
The Git and Go projects use the same plain-English model. Familiarity with
95-
Angular-style prefixes is not a reason to adopt them here.
103+
The parts of the old rule that were right are kept: the subject is still an
104+
imperative sentence that stands on its own years later, and the ticket-ID,
105+
status-tag, and filename bans are unchanged. Only the type and scope are new.
106+
Please do not re-open this from reading older `git log` entries.
96107

97108
### Body (usually omit)
98109

@@ -118,6 +129,9 @@ hand, not for the person reviewing this PR today.
118129
- Separate refactors from feature additions
119130
- Separate formatting/whitespace from behavioral changes
120131
- Commit with the operator's local git identity (never invent author metadata)
132+
- **Never** add a `Co-Authored-By` trailer — to a commit, a pull request, a
133+
GitHub issue, or any other artifact. This holds whoever or whatever wrote the
134+
change
121135

122136
## Pull requests
123137

@@ -136,9 +150,13 @@ git log origin/main..HEAD --format='%s'
136150

137151
### Title (MUST)
138152

139-
Same rules as [commit titles](#title-must): imperative present-tense sentence,
140-
no prefixes, no ticket IDs, no trailing punctuation. The title describes the
141-
**whole branch**, not a single commit.
153+
Same rules as [commit titles](#title-must): `<type>(<scope>): <description>`,
154+
imperative present tense, no ticket IDs, no trailing punctuation. The title
155+
describes the **whole branch**, not a single commit — pick the type that fits
156+
the branch's main effect.
157+
158+
The pull-request title is what generated release notes quote, so it is read by
159+
people who never see the diff. Write it for them.
142160

143161
### Body (MUST)
144162

0 commit comments

Comments
 (0)