From 6a14687ef7e859a189db7a435d813f548872ec69 Mon Sep 17 00:00:00 2001 From: Okiki Ojo Date: Sun, 12 Apr 2026 22:56:09 -0400 Subject: [PATCH] docs(instructions): clarify naming conventions for data fields in general instructions Signed-off-by: Okiki Ojo --- instructions/commit-writing.instructions.md | 333 ++++---------------- instructions/general.instructions.md | 2 +- 2 files changed, 61 insertions(+), 274 deletions(-) diff --git a/instructions/commit-writing.instructions.md b/instructions/commit-writing.instructions.md index d934e0c..ad57a2d 100644 --- a/instructions/commit-writing.instructions.md +++ b/instructions/commit-writing.instructions.md @@ -7,287 +7,91 @@ applyTo: "**" Apply these rules only when writing or revising commit messages. -Do not apply these rules to changelog entries, release notes, docs, PR prose, code comments, or TSDoc unless the task is specifically about commit messages. +Do not apply them to changelog entries, release notes, PR prose, docs, code comments, or TSDoc unless the task is specifically about commit messages. -A commit message is not just a Git label. It is a durable record for other developers reading history later to understand what changed, why it changed, and how the change should be interpreted. +A good commit message should let someone scan `git log` and understand the work without opening every diff. Each message should make clear: -Write commit messages so a reader can understand the important change without opening the diff first. +1. what changed +2. why it mattered +3. what behavior, workflow, edge case, or maintenance outcome is now true +4. whether there is migration or upgrade impact -Keep commit messages changelog-friendly, but do not write them like polished release notes. A commit should preserve implementation-relevant detail that may later help someone write a changelog. +Keep messages changelog-friendly, but preserve enough context that the commit history still tells the story of the work. +## Core shape -## Core goal - -Each commit message should make these questions easy to answer: - -1. What changed? -2. Why did it matter? -3. What behavior, workflow, edge case, or maintenance outcome changed? -4. Does this have migration or upgrade impact? -5. If a future changelog writer reads this commit, what details are worth carrying forward? - -The subject is the scan line. -The body is where nuance goes. - - -## Subject format - -Use Conventional Commits. - -Use this shape: +Use Conventional Commits: `type(scope?): short precise outcome summary` -Replace `type`, `scope`, and the summary with real values. -Do not output placeholder text literally. -Do not use vague explanation verbs such as `clarify`, `explain`, `document`, `improve`, or `update` unless the rest of the subject names the exact fact, contract, rule, behavior, or workflow being documented. +The subject is the scan line. The body carries the nuance. + +Write the subject around the most important outcome, not the activity that produced it. Good: -- `fix(parser): preserve trailing blank lines in stringify` -- `feat(events): add outline-only section events` -- `docs(instructions): clarify commit body expectations` -- `perf(tokenizer): avoid substring allocation in delimiter scan` +- `fix(parser): recover table parsing after unmatched row delimiter` +- `feat(cli): add --json extraction summary output` +- `docs(api): describe when callers must preserve UTF-16 offsets` Bad: -- `(): ` - `fix: improve parser` -- `chore: update stuff` -- `docs: update instructions` - +- `feat: add support` +- `docs: update docs` ## Subject rules -- Use lowercase for the type. -- Use a single space after the colon. +- Use a lowercase type. +- Use a scope only when it helps a reader locate the area quickly. - Do not end the subject with a period. -- Keep the subject specific and outcome-focused. -- Describe the result, not just the activity. -- Name the actual behavior, workflow, edge case, or repository outcome that changed. -- Avoid filler verbs such as `improve`, `update`, `enhance`, `clean up`, or `address` unless the object makes the change concrete. -- Prefer the most important outcome when the commit includes several changes. - -Good: -- `fix(ast): keep heading end offsets aligned after recovery` -- `feat(cli): add --json extraction summary output` -- `docs(parser): explain why recovery never throws` - -Bad: -- `fix: improve parsing` -- `feat: add new option` -- `refactor: clean up code` -- `docs: improve docs` - - -## Choosing the subject when a commit has several changes - -A commit often includes one main change and several supporting changes. - -The subject should name the highest-value outcome. -The body should capture the important secondary details. - -Do not turn the subject into a shopping list. +- Name the result, not the effort. +- Prefer the behavior or workflow that changed over implementation detail. +- If the commit includes several changes, lead with the highest-value outcome and leave supporting detail for the body. +- Avoid vague verbs such as `improve`, `update`, `enhance`, `clean up`, or `address` unless the object makes the outcome concrete. +- Avoid turning the subject into a shopping list. -Bad: -- `fix(parser): handle headings, tables, and links better` - -Better: -- `fix(parser): recover table parsing after unmatched row delimiter` +Useful scopes include areas like `parser`, `events`, `cli`, `deps`, `scripts`, or `instructions`. Skip vague scopes such as `misc`, `general`, or `stuff`. -Body: -- stop recovery from swallowing following link tokens -- preserve heading parsing after malformed tables -- add regression coverage for mixed table and heading input +## Body +Add a body when the subject alone would hide important context. Typical cases: -## When to add a body +- the change is not obvious from the subject +- the commit fixes or covers more than one important case +- the behavior is subtle or easy to misread +- the change affects migration, compatibility, rollout, or upgrade work +- the commit includes performance or measurement claims that need support -Add a body when any of these are true: -- the change is not obvious from the subject alone -- the commit changes more than one important case -- the change is subtle or easy to misunderstand -- the commit has migration or upgrade impact -- the commit is likely to matter in a future changelog -- the subject would be accurate but incomplete without context +A good body usually explains: -A good body explains: - what was wrong or limited before - what is true now -- the most important cases covered -- any migration, upgrade, compatibility, or rollout note if relevant - -Prefer short bullets or short paragraphs. -Keep the body concrete. -Do not waste the body on empty filler. - -Good: -- previously the final blank line could disappear when the source ended in `\r\n` -- stringify now preserves the original trailing blank line count -- keeps roundtrip output stable for range-based consumers - -Weak: -- improve behavior -- add tests -- cleanup -- various fixes - - -## Type-specific precision rules - -Different commit types need different kinds of specificity. - -### feat - -For `feat`, say what new capability now exists. - -Good: -- `feat(events): add outline-only section events` -- `feat(cli): add --json extraction summary output` - -Avoid: -- `feat: add support` -- `feat: improve API` - -### fix - -For `fix`, say what broken behavior now works correctly. - -Good: -- `fix(tokenizer): stop merging adjacent pipe runs across template boundaries` -- `fix(stringify): preserve trailing blank lines in CRLF input` - -Avoid: -- `fix: improve parser` -- `fix: handle edge cases` - -### docs +- the most important secondary cases or tradeoffs +- any migration or rollout note a future reader will need -For `docs`, name the specific fact, contract, rule, workflow, guarantee, limitation, or migration step that the docs now make clear. +Prefer short bullets or short paragraphs. Avoid filler such as `add tests`, `cleanup`, or `misc fixes` unless tied to the behavior they protect or enable. -Good: -- `docs(text_source): explain that plain strings satisfy the TextSource contract` -- `docs(parser): document why recovery never throws` -- `docs(events): define stack balancing rules for nested sections` -- `docs(api): describe when callers must preserve UTF-16 offsets` - -Avoid: -- `docs: update docs` -- `docs: improve readme` -- `docs: clarify usage` -- `docs(text_source): clarify purpose and usage of TextSource interface` - -Do not describe the writing effort in vague terms such as `clarify`, `improve`, or `update` unless the rest of the subject names the exact thing that is now easier to understand. - -### refactor - -For `refactor`, say what internal structure changed and why that matters. - -Good: -- `refactor(events): split section balancing from text emission` -- `refactor(parser): isolate table recovery from inline parsing` - -Avoid: -- `refactor: clean up code` -- `refactor: reorganize internals` - -Use `refactor` only when there is no intended behavior change. - -### perf - -For `perf`, say what got faster, smaller, or cheaper. - -Good: -- `perf(tokenizer): avoid substring allocation in delimiter scan` -- `perf(stringify): reduce intermediate joins for large table output` -- `perf(events): reuse section frame objects during recovery` - -Avoid: -- `perf: improve performance` -- `perf: optimize code` - -If the improvement is measurable and worth mentioning, say what improved in the body such as allocation count, hot-path work, latency, or steady-state throughput. - -### test - -For `test`, say what behavior is now protected. - -Good: -- `test(parser): add regression case for malformed heading recovery` -- `test(tokenizer): cover adjacent pipe runs across template boundaries` -- `test(stringify): verify trailing blank line preservation with CRLF input` - -Avoid: -- `test: add tests` -- `test: improve coverage` - -### bench - -For `bench`, say what benchmark coverage or measurement trust improved. +## Type guidance -Good: -- `bench(tokenizer): add malformed table hot-path scenarios` -- `bench(parser): separate recovery cases from steady-state runs` -- `bench(stringify): compare CRLF roundtrip cost against baseline` - -Avoid: -- `bench: add benchmarks` -- `bench: improve perf tests` - -### chore - -For `chore`, say what maintenance outcome changed. - -Good: -- `chore(deps): pin jsr imports for reproducible installs` -- `chore(repo): remove generated parser snapshots from source control` -- `chore(scripts): standardize release script argument parsing` - -Avoid: -- `chore: clean up repo` -- `chore: maintenance` -- `chore: update dependencies` - -Do not use `chore` as a bucket for meaningful fixes, behavior changes, or performance work. - -### build - -For `build`, say what build, packaging, or dependency behavior changed. - -Good: -- `build(npm): include generated type maps in published package` -- `build(jsr): stop bundling fixture files into release tarballs` +Choose the type that best matches the outcome: -### ci +- `feat`: a new capability now exists +- `fix`: broken behavior now works correctly +- `docs`: a specific fact, contract, rule, limitation, or migration step is now clear +- `refactor`: internal structure changed with no intended behavior change +- `perf`: something got faster, smaller, or cheaper in a way worth naming +- `test`: a behavior or regression case is now protected +- `bench`: benchmark coverage or measurement trust improved +- `chore`: maintenance outcome changed, but not a user-visible behavior +- `build`: build, packaging, or dependency behavior changed +- `ci`: pipeline or automation behavior changed -For `ci`, say what pipeline or automation behavior changed. - -Good: -- `ci(actions): fail release workflow when changelog generation is missing` -- `ci(test): run parser regression suite on pull requests` - - -## Scopes - -Use a scope when it helps a reader locate the area of change quickly. - -Good scopes: -- `parser` -- `tokenizer` -- `events` -- `ast` -- `stringify` -- `cli` -- `instructions` -- `deps` -- `repo` -- `scripts` - -Avoid vague scopes such as: -- `misc` -- `general` -- `stuff` - -Skip the scope if it does not add useful meaning. +Type-specific precision matters. For example: +- `feat` should name the new capability, not just "support" +- `fix` should name the broken behavior that now works +- `docs` should name the fact or workflow now documented, not the writing effort +- `refactor` and `chore` should not be used to hide meaningful behavior changes +- `perf` should say what got cheaper and where it matters; include the practical effect in the body when useful ## Breaking changes @@ -301,31 +105,14 @@ feat(api)!: remove implicit trim from align() BREAKING CHANGE: Callers that relied on implicit trimming must call trimEnd() explicitly before align(). ``` -A breaking commit must make these things clear: - -* what changed -* who is affected -* what they now need to do - -## Anti-patterns - -Avoid: - -* typeless commits -* WIP commits on main -* vague subjects -* issue or PR numbers in the subject -* subjects that describe effort instead of result -* internal implementation detail with no meaning to later readers -* bodies that only say `add tests`, `cleanup`, or `misc fixes` -* using `chore` or `refactor` to hide meaningful behavior changes +Make the impact easy to spot. State what changed, who is affected, and what they now need to do. ## Final check Before finalizing a commit message, check: -* Can another developer tell what changed from the subject alone? -* If they read the body too, can they understand the problem and outcome without opening the diff? -* Would a future changelog writer know what details are worth carrying forward? -* If the commit is breaking, is the migration impact explicit? -* If the commit has several important changes, does the body capture the secondary details clearly? +- can someone tell what changed from the subject alone +- if they read the body, can they understand the important context without opening the diff +- does the commit preserve the details a future changelog writer would want +- if several commits are viewed together in `git log`, do their subjects read like a coherent story instead of a list of activities +- if the change is breaking, is the migration step explicit diff --git a/instructions/general.instructions.md b/instructions/general.instructions.md index 0fd9eb7..1b3a971 100644 --- a/instructions/general.instructions.md +++ b/instructions/general.instructions.md @@ -8,7 +8,7 @@ Let the role of the code decide its shape. Do not blindly force one naming rule Make data look like data, and make behavior look like behavior. -Use `snake_case` for plain records, normalized payloads, persistence-oriented fields, schema-like data, and other shapes that are primarily stable data. +Use `snake_case` for fields in plain records, normalized payloads, persistence-oriented fields, schema-like data, and other shapes that are primarily stable data. Use `camelCase` for functions, methods, variables, parameters, getters, setters, class properties, and other runtime behavior. Classes are runtime objects, not plain records, so their properties and methods should read like normal JavaScript. -- 2.51.2