The “conventional commit” format encourages prefixing commit messages with a small number of keywords:
41e7be2 feat: notify user on new messages f3b33ab build: enable caching to decrease build times 7501fb2 fix(api): detect invalid query parameter f5baa4d docs: typo 06e851a perf(ui): optimize loading time
The keyword usually answers the question: “How does this commit modify existing code?” It
refactors it, enhances its
performance, or adds a new
feature on top. Sometimes it answers a different question: “What area does this affect?” The
build process, or the
docs. Yet other times, it answers both by adding a “scope”: it’s a
fix to the
(api); it’s a
performance enhancement to the
What if you’re fixing a doc, or improving the build’s performance?
To stop and think in these loaded, non-orthogonal terms, recently started to feel like a bump in the road to me. Enough things threaten a programmer’s flow already. The resulting descriptions aren’t as descriptive as they could, either, so it’s not a clear win.
Luckily, I found out that a few extra keystrokes are all you need to lower the burden on the writer and boost the value for the reader.
Meet the “-ilities”
A more useful question you can ask about a change is: “What quality of the system does this change directly improve?” (“Directly” because everything, eventually, aims at improving end-user functionality, business profitability, and similar bottom lines, so those aren’t good descriptors at a local level.) A change to the front end might improve usability; one to the back end might improve observability; another to the API docs might improve understandability.
The book Building Evolutionary Architectures has a long list of these qualities. It calls them a system’s “-ilities”:
- (…two more pages)
Another way to express the same question in, to speak, Conway terms, is: “Whose life does this directly improve?”
You can use these qualities to better describe, and think of, changes.
Value-based, bi-dimensional commit messages
What qualities matter to your team and project right now? Pick a manageable number, e.g.: functionality, usability, devability (a mixture of code understandability, debuggability, and tool ergonomy), stability, observability, and security.
When you change these qualities, whose life improves?
|Quality||Whose life does it improve?|
|functionality||a subsystem’s users (end-users for a UI, developers for a service)|
An element of this list should the your answer to the above question: “What quality of the system does this change directly improve?”
This “what” is the first dimension:
- 41e7be2 feat: notify user on new messages + 41e7be2 func: notify user on new messages - f3b33ab build: enable caching to decrease build times + f3b33ab dev: enable caching to decrease build times - 7501fb2 fix(api): detect invalid query parameter + 7501fb2 stab: detect invalid query parameter
Next, answer the question: “How does this change improve that quality?”
“How” is the second dimension:
|Keyword||In what way does this change improve the specified quality?|
||changes what’s there so it’s less bad|
||changes what’s there so it’s better|
||adds something new|
(Note the absence of
refactor, which is an
enhancement in devability.)
- 41e7be2 usab: notify user on new messages + 41e7be2 usab,func: notify user on new messages - f3b33ab dev: enable caching to decrease build times + f3b33ab dev,enh: enable caching to decrease build times - 7501fb2 fix(api): detect invalid query parameter + 7501fb2 stab,fix: detect invalid query parameter
On larger projects, it makes sense to keep the optional scope to answer the question, “Which component does this affect?”
- 7501fb2 fix(api): detect invalid query parameter + 7501fb2 stab,fix(api): detect invalid query parameter
41e7be2 usab,feat: notify user on new messages f3b33ab dev,enh: enable caching to decrease build times 7501fb2 stab,fix(api): detect invalid query parameter f5baa4d dev,fix: typo 06e851a usab,enh(ui): optimize loading time
In the end, this is just a strategy to systematically answer — in a way that allows both being informative and diverting little focus from coding — the critical question:
“What VALUE does this change deliver?”