@@ -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