···11+---
22+name: writing-changesets
33+description: >
44+ Writing user-facing CHANGELOG entries with the Changesets tool — `.changeset/*.md`
55+ files declaring affected packages, bump kind (patch/minor/major), and a message.
66+ Covers verb choice, audience, level of detail, and breaking-change migration
77+ patterns with diff samples. Use when adding a changeset to a PR.
88+---
99+1010+# Writing Changesets
1111+1212+A changeset is a Markdown file that declares **which packages changed**, **how to bump them**, and **what changed from the user's perspective**. It produces one entry in each affected package's CHANGELOG.
1313+1414+A user reads a changeset once, when they upgrade. It must answer: _did anything change that matters to me, and what do I do about it?_
1515+1616+## File format
1717+1818+Generate a changeset with:
1919+2020+```sh
2121+pnpm changeset
2222+```
2323+2424+This prompts for the affected packages and bump kinds, then writes a randomly-named file to `.changeset/`:
2525+2626+```md title=".changeset/witty-cats-bake.md"
2727+---
2828+"@your-org/your-package": patch
2929+---
3030+3131+Fixes a regression where `parseConfig()` returned `undefined` instead of the default object.
3232+```
3333+3434+You can also write the file by hand. The frontmatter lists every affected package on its own line:
3535+3636+```md title=".changeset/multi-package-change.md"
3737+---
3838+"@your-org/core": minor
3939+"@your-org/cli": patch
4040+---
4141+4242+Adds a new `--watch` flag.
4343+4444+#### `@your-org/core`
4545+4646+Exports a new `watch()` helper.
4747+4848+#### `@your-org/cli`
4949+5050+Wires `--watch` to call `watch()`.
5151+```
5252+5353+Bump kinds:
5454+5555+- `patch` — bug fixes, internal refactors, perf improvements (no user code change required)
5656+- `minor` — new features that are safe to opt into
5757+- `major` — breaking changes, including any change to default behavior
5858+5959+## The message
6060+6161+### Lead with a present-tense verb
6262+6363+Every changeset starts with a verb completing the sentence "This PR…":
6464+6565+- **Adds** — new feature, option, function
6666+- **Removes** — deletes a public API
6767+- **Fixes** — bug fix
6868+- **Updates** — changes existing behavior in a non-breaking way
6969+- **Refactors** — internal cleanup
7070+- **Improves** — perf, ergonomics, output quality
7171+- **Deprecates** — marks something for future removal
7272+7373+### Describe the user's experience, not the code's
7474+7575+❌ What the code now does:
7676+7777+> Logs helpful errors if content is invalid
7878+7979+✅ What the user will experience:
8080+8181+> Adds logging for content collection configuration errors
8282+8383+The reader doesn't care what the diff did internally. They care what they'll notice.
8484+8585+### Include the API name when readers might be using it
8686+8787+When the changed surface has a recognizable name, put it in the message:
8888+8989+❌ Vague:
9090+9191+> Improves automatic fallback generation
9292+9393+✅ Specific:
9494+9595+> Improves automatic `fallbacks` generation for the new Fonts API
9696+9797+If the API isn't user-facing or the name wouldn't ring a bell, describe the use case instead:
9898+9999+❌ Reader won't recognize the type:
100100+101101+> Adds `| (string & {})` for better autocomplete of `App.SessionData`
102102+103103+✅ Reader recognizes the outcome:
104104+105105+> Improves autocompletion for session keys
106106+107107+## Patch changes
108108+109109+Patch changes are usually internal: bug fixes, refactors, perf wins. The reader skims to decide if it's relevant.
110110+111111+Keep them short — often one line:
112112+113113+```md title=".changeset/one-liner.md"
114114+---
115115+"@your-org/core": patch
116116+---
117117+118118+Fixes a bug where the inspector incorrectly flagged inline images as above the fold
119119+```
120120+121121+```md title=".changeset/refactor.md"
122122+---
123123+"@your-org/core": patch
124124+---
125125+126126+Refactors internal handling of styles and scripts to improve build performance
127127+```
128128+129129+```md title=".changeset/type-update.md"
130130+---
131131+"@your-org/core": patch
132132+---
133133+134134+Updates the `HTMLAttributes` type exported from `@your-org/core` to allow data attributes
135135+```
136136+137137+Patch entries don't need full sentences or end punctuation when they fit on one line. State **what changed** _and_ **who needs to know** — the reader should be able to decide in five seconds whether to keep reading.
138138+139139+## Minor changes (new features)
140140+141141+Start with **Adds**. Name the new option, function, or component in the first sentence. Then say what users can now do that they couldn't before.
142142+143143+````md title=".changeset/new-feature.md"
144144+---
145145+"@your-org/core": minor
146146+---
147147+148148+Adds a new, optional `timeout` option to `defer()`.
149149+150150+This value sets a maximum wait, in milliseconds, before the deferred work is flushed, even if the trigger condition hasn't been met. You can use it to bound the latency of low-priority work while still preferring the natural flush point.
151151+152152+```ts
153153+defer(work, { trigger: "idle", timeout: 500 });
154154+```
155155+````
156156+157157+A minimal usage example is almost always worth including for new features. Don't try to cover every option — pick one realistic call.
158158+159159+> **Don't hide the good stuff in the changeset.** A changeset is read once, on upgrade. Documentation is referenced forever. Everything you put in a changeset should also exist in the proper feature docs.
160160+161161+## Major changes (breaking)
162162+163163+Verbs like **Removes**, **Changes**, **Deprecates** signal _required attention_. Unlike a new feature the reader can ignore, a breaking change cannot be skipped.
164164+165165+A breaking-change changeset must include **migration guidance**, almost always with a `diff` code sample:
166166+167167+```md title=".changeset/breaking-removal.md"
168168+---
169169+"@your-org/core": major
170170+---
171171+172172+Removes support for returning plain objects from endpoints. Endpoints must now return a `Response` instead.
173173+```
174174+175175+For an API rename or signature change, show the before and after:
176176+177177+````md title=".changeset/breaking-shape-change.md"
178178+---
179179+"@your-org/core": major
180180+---
181181+182182+Removes support for passing a `path` string to the `plugins` option. Import the plugin module directly and pass it instead.
183183+184184+```diff
185185++ import customPlugin from './plugins/custom.js'
186186+187187+ export default defineConfig({
188188+ plugins: [
189189+- { path: './plugins/custom.js' },
190190++ customPlugin,
191191+ ],
192192+ })
193193+```
194194+````
195195+196196+### Default-value changes
197197+198198+Changing a default value is a breaking change even if no API surface moved — most users don't set a value explicitly, so they're affected silently.
199199+200200+Document **both directions**: how to opt back into the old behavior, _and_ the fact that anyone who already set the new value can drop it.
201201+202202+````md title=".changeset/default-flip.md"
203203+---
204204+"@your-org/core": major
205205+---
206206+207207+Changes the default value of `security.checkOrigin` to `true`, enabling CSRF protection by default for on-demand pages.
208208+209209+If you previously set `security.checkOrigin: true`, you no longer need it — this is now the default and the line can be removed.
210210+211211+To restore the previous behavior, set `security.checkOrigin: false` explicitly:
212212+213213+```diff
214214+ export default defineConfig({
215215++ security: {
216216++ checkOrigin: false
217217++ }
218218+ })
219219+```
220220+````
221221+222222+## Section headings inside long changesets
223223+224224+When a changeset spans multiple paragraphs and needs internal structure, **start headings at `<h4>` (`####`)** — never `<h2>`. Changesets are concatenated into a CHANGELOG file where the package name and version are already at the `<h2>`–`<h3>` level. Using `##` inside a changeset breaks the hierarchy of the rendered CHANGELOG.
225225+226226+```md title=".changeset/long-feature.md"
227227+---
228228+"@your-org/core": minor
229229+---
230230+231231+Adds a new Sessions API to store user state between requests for on-demand pages.
232232+233233+#### Configuring session storage
234234+235235+…
236236+237237+#### Using sessions
238238+239239+…
240240+241241+##### In API endpoints
242242+243243+…
244244+245245+#### Upgrading from the experimental API
246246+247247+…
248248+```
249249+250250+## Quick checklist before merging
251251+252252+- [ ] Frontmatter lists every affected package with the right bump kind
253253+- [ ] Message starts with a present-tense verb (Adds, Removes, Fixes…)
254254+- [ ] Describes the user-facing change, not internal mechanics
255255+- [ ] Names the changed API when the name is recognizable
256256+- [ ] Breaking change? Includes a `diff` migration sample
257257+- [ ] Default-value change? Documents both the new behavior and the opt-out
258258+- [ ] Section headings (if any) start at `####`
259259+- [ ] The same explanation also exists in proper feature docs
260260+261261+## See Also
262262+263263+- `writing-docs/SKILL.md` — voice, code-sample, and instruction conventions used here
264264+- `writing-upgrade-guides/SKILL.md` — for major releases, breaking-change changesets feed into the upgrade guide
+259
skills/writing-docs/SKILL.md
···11+---
22+name: writing-docs
33+description: >
44+ Voice, style, structure, and code-sample conventions for user-facing software
55+ documentation — guides, reference pages, READMEs, recipes, API docs. Establishes
66+ the imperative instruction pattern, the "what to document vs. omit" rules, and
77+ the reference-entry format. Use when writing or reviewing prose docs.
88+---
99+1010+# Writing Docs
1111+1212+Docs exist to **help readers do something and get back to their project**. Document **how to use** the thing — not how the thing is built.
1313+1414+## Purpose
1515+1616+Every page should answer questions a real reader has:
1717+1818+- What is this?
1919+- What is it used for?
2020+- Why would I use it?
2121+- When can it (not) be used?
2222+- How do I use it?
2323+2424+Implementation details only belong if they help the reader **make decisions**: choose a non-default value, avoid a conflicting setting, understand a tradeoff. Otherwise, leave them out.
2525+2626+## Voice and tone
2727+2828+- **Neutral, factual, direct.** State facts; don't try to be funny, whimsical, or chatty.
2929+- **No first person.** Never `I`, `we`, `us`, `our`, `let's`. You aren't sitting next to the reader.
3030+- **Address the reader as "you"** — sparingly, for emphasis or warnings. Most instructions don't need it (use the imperative instead).
3131+- **Document only your thing.** Link out to authoritative sources for general concepts (Markdown, HTTP, regex). It is not your job to teach them.
3232+- **Use exclamation points sparingly.** A frustrated reader at 2am does not want vibes.
3333+3434+## Readability heuristics
3535+3636+Prefer:
3737+3838+- shorter sentences and paragraphs
3939+- plainer vocabulary
4040+- active voice
4141+- writing acronyms in full the first time
4242+- headings and lists to break up long stretches of prose
4343+4444+Many readers are tired, in a hurry, reading in a non-native language, or translating the page into another language. Clear writing helps every one of them.
4545+4646+## Headings
4747+4848+- Page title is `<h1>`. New sections start at `<h2>`.
4949+- Keep headings short — they appear in the page sidebar / table of contents.
5050+- No end punctuation (`:`, `.`, `?`).
5151+- Format code-shaped names as inline code, even in headings: `### \`navigate()\``.
5252+5353+## Lists
5454+5555+- **Unordered** for a group of related items where order doesn't matter (a set of options, properties, examples).
5656+- **Ordered** when the steps must be followed in sequence.
5757+- When list items grow into multiple paragraphs or are loaded with inline code, switch to subheadings.
5858+5959+## "Examples" vs. complete sets
6060+6161+`e.g.` means **some, not all**:
6262+6363+> If you store your project on a Git provider (e.g. GitHub, GitLab), you can…
6464+6565+When the list is **every possibility**, drop `e.g.`:
6666+6767+> Include the required image properties (`src`, `alt`) and any optional properties…
6868+6969+## Giving instructions
7070+7171+Use the **imperative**:
7272+7373+> Run the following command.
7474+7575+Not:
7676+7777+> ❌ Let's run the following command.
7878+> ❌ Next, we will run the following command.
7979+8080+### Avoid weasel words
8181+8282+| Phrase | Problem | When it's OK |
8383+| ------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
8484+| "You should…" | Reader can't tell if it's required | Describing expected outcome: "If installation succeeds, you should see a prompt" — and even then, prefer "After a successful install, there will be a prompt" |
8585+| "You can…" | Sounds permissive, not directive | Genuinely granting permission or stating an option exists |
8686+8787+If you find yourself writing "you should" in a step the reader is meant to follow, rewrite it as a direct instruction.
8888+8989+### No narrative scaffolding
9090+9191+Lead with the goal, then the steps. Don't tell a story.
9292+9393+❌ Narrative:
9494+9595+> As well as needing your content in different languages, you will often need to translate labels for UI elements around your site. We can do this by creating dictionaries of terms instead of hard-coding text in one language in our templates.
9696+>
9797+> 1. …
9898+9999+✅ Imperative + reason:
100100+101101+> Create dictionaries of terms to translate UI labels. This lets visitors experience your site fully in their language.
102102+>
103103+> 1. …
104104+105105+### Opinionated examples
106106+107107+When an instruction has many valid choices, separate the **action + criteria** from the **chosen option**:
108108+109109+❌ Vague:
110110+111111+> Add the `LanguagePicker` component to your site. A good place might be in a navigation component or a footer shown on every page.
112112+113113+✅ Action with criteria, then opinionated choice:
114114+115115+> Add the `LanguagePicker` component to a layout shown on every page. The example below adds it to the page footer:
116116+117117+The reader can substitute their own choice once they understand the criterion.
118118+119119+## Code samples
120120+121121+Code samples carry as much weight as the prose around them.
122122+123123+### Always include a sample file name
124124+125125+The reader needs to know **where this code goes**. Use a code-block title or a top-line comment:
126126+127127+````markdown
128128+```ts title="src/lib/auth.ts"
129129+export function signIn() {
130130+ /* … */
131131+}
132132+```
133133+````
134134+135135+````markdown
136136+```ts
137137+// src/lib/auth.ts
138138+export function signIn() {
139139+ /* … */
140140+}
141141+```
142142+````
143143+144144+### Show one real, working example — not all options
145145+146146+No `foo` / `bar`. No "here are all six possible values for this config." The reader will only configure one. Pick a realistic one and show it complete.
147147+148148+### Introduce every code sample with a sentence
149149+150150+On its own line, before the block:
151151+152152+> The following example shows the `base` config set so the project deploys at `www.example.com/docs`:
153153+154154+This forces you to name what the snippet demonstrates and primes the reader to recognize it. Avoid `like so:` — it's a substitute for explaining what to do, and the reader's natural follow-up is "like _how_?"
155155+156156+❌
157157+158158+> Add slide animation, like so:
159159+160160+✅
161161+162162+> The following example shows a `slide` animation attribute added to a `<header>` component:
163163+164164+### Multiple code samples
165165+166166+Don't dump three blocks and explain them all in a paragraph below — readers will already have skimmed past. Introduce each block individually and connect them only after each has been described:
167167+168168+> The following example shows `draft: true` configured in the project config, which prevents draft posts from being built:
169169+>
170170+> ```js
171171+> // …config sample
172172+> ```
173173+>
174174+> The following Markdown file uses the `draft` property in its frontmatter to mark a post as not ready to publish:
175175+>
176176+> ```md
177177+> // …frontmatter sample
178178+> ```
179179+180180+## Reference entries
181181+182182+Reference pages exist to be **scanned**, not read. Each entry has a fixed shape.
183183+184184+### Format
185185+186186+```markdown
187187+### `propertyOrFunctionName`
188188+189189+**Type:** `string | undefined`
190190+**Default:** `'auto'`
191191+**Added in:** `v1.4.0`
192192+193193+[One-sentence definition: what is this / what does this do.]
194194+195195+[Possible values, when applicable, as a bulleted list.]
196196+197197+[A minimal real-world code example.]
198198+```
199199+200200+### Definition
201201+202202+The first line answers "What is this?" or "What does this do?" with an unwritten "This is…" or "This…" prefix:
203203+204204+- An array of allowed hosts.
205205+- The base path to deploy to.
206206+- Specifies the output target for builds.
207207+- Enables CSRF protection for on-demand pages.
208208+209209+### Values
210210+211211+When the field accepts a small set of options, enumerate them:
212212+213213+- `'always'` — only match URLs with a trailing slash
214214+- `'never'` — only match URLs without a trailing slash
215215+- `'ignore'` — match URLs regardless
216216+217217+### Example
218218+219219+Show a single configured value, not every possibility:
220220+221221+```js
222222+{
223223+ trailingSlash: "always";
224224+}
225225+```
226226+227227+### Don't write a "why" essay
228228+229229+Reference entries are concise. Save the "when would I use this?" prose for guides — link from the entry when the topic genuinely needs explanation.
230230+231231+## Asides / callouts
232232+233233+Use sparingly. A callout for note, tip, or caution is for **complementary information that does not belong in the surrounding paragraph** — not for emphasis on essential information.
234234+235235+| Variant | Use for |
236236+| ----------- | ------------------------------------------------- |
237237+| **note** | tangential context |
238238+| **tip** | optional action that may help |
239239+| **caution** | risk of data loss, security, or other real danger |
240240+241241+Don't use:
242242+243243+- A **note** to add essential information — that belongs in the paragraph.
244244+- A **tip** for a required step — that's not a tip, it's a requirement.
245245+- A **caution** for mild surprises.
246246+- Multiple callouts in a row — visual clutter erases meaning.
247247+248248+If everything is highlighted, nothing is.
249249+250250+## What NOT to document
251251+252252+- **Implementation details that don't change how the user uses the feature.** "We filter the array internally" tells the reader nothing they can act on.
253253+- **Unsupported or off-happy-path uses.** "You can do this, but I wouldn't recommend it" — don't lead the reader down a dangerous path. They are free to explore on their own.
254254+- **Every possible combination of options.** Document the common path and the realistic decision points. Edge cases live in issues, discussions, or recipes.
255255+256256+## See Also
257257+258258+- `writing-changesets/SKILL.md` — per-change CHANGELOG entries (uses the voice and code-sample patterns from this skill)
259259+- `writing-upgrade-guides/SKILL.md` — major-version migration guides (uses the imperative-instruction and diff-sample patterns from this skill)
+217
skills/writing-upgrade-guides/SKILL.md
···11+---
22+name: writing-upgrade-guides
33+description: >
44+ Authoring a major-version upgrade guide or breaking-change migration document.
55+ Covers the standard guide structure, the per-entry format (past-tense before /
66+ present-tense after / "What should I do?"), verb choice by user impact, and
77+ diff-sample patterns. Use when shipping a major release or any document whose
88+ job is to walk users through breaking changes.
99+---
1010+1111+# Writing Upgrade Guides
1212+1313+An upgrade guide is a comprehensive, action-oriented list of **breaking changes a user must address to upgrade successfully**. It is not a feature showcase, not a release announcement, and not a CHANGELOG.
1414+1515+If a change doesn't block an existing project from upgrading, it doesn't belong here.
1616+1717+## Standard structure
1818+1919+Major-version upgrade guides follow a fixed structure. Use it as a template:
2020+2121+1. **Upgrade instructions** — the automated tool (e.g. an upgrade CLI), then manual steps for users who prefer it
2222+2. **"Things may just work — if not, read on"** — set expectations: most projects upgrade cleanly
2323+3. **Link to the full CHANGELOG** — for readers who want every detail
2424+4. **Experimental flags removed** — list flags from `experimental:` config that are now stable or gone
2525+5. **Dependency upgrades** — minimum runtime / engine / peer-dep versions that may affect projects
2626+6. **Breaking changes** — the bulk of the guide
2727+7. **Deprecations** — features that still work but will be removed in a future version
2828+8. **Previously deprecated features now removed** — features deprecated in earlier versions that are gone now
2929+9. **Community resources** — videos, blog posts, codemods (if any)
3030+10. **Known issues** — anything users will hit that isn't fixed yet
3131+3232+Each section can be empty. Don't pad — if there are no deprecations this release, omit the heading.
3333+3434+## Per-entry format
3535+3636+Every entry under **Breaking changes** follows the same shape.
3737+3838+```markdown
3939+### [verb]: feature/area name
4040+4141+In vX.x, [past-tense statement of what the library used to do].
4242+4343+vY.0 [present-tense statement of how the library works now].
4444+4545+#### What should I do?
4646+4747+[Imperative actions, often with a diff code sample.]
4848+```
4949+5050+### Title verbs
5151+5252+Pick the verb by **how the user feels the impact**, not by what the code change technically is.
5353+5454+| Verb | Use when |
5555+| ------------ | ------------------------------------------------------------------ |
5656+| `Changed` | Behavior, signature, or shape moved in a way the user can feel |
5757+| `Renamed` | An identifier — option, function, file — has a new name |
5858+| `Removed` | A public API is gone |
5959+| `Added` | A new behavior is now the default — the reader is "newly affected" |
6060+| `Deprecated` | Still works for now, but slated for removal |
6161+6262+A new default value _is_ `Changed: default value for X`, even though the underlying code "added" something. Title from the reader's seat: "my default value got switched on me."
6363+6464+### The body
6565+6666+Two short statements: **what it was**, **what it is now**:
6767+6868+```markdown
6969+### Changed: `app.render()` signature
7070+7171+In v3.x, the `app.render()` method accepted `routeData` and `locals` as separate, optional arguments.
7272+7373+v4.0 changes the `app.render()` signature. Both properties are now passed as a single object. Both the object and the properties remain optional.
7474+```
7575+7676+That's it. No motivation essay. No anecdote. The reader is in a hurry — they want to know whether they're affected and what to do.
7777+7878+### "What should I do?"
7979+8080+This section is the heart of the guide. It is **always present**, even when the answer is short.
8181+8282+The instruction must be an **action**, not a fact:
8383+8484+❌ Statement of fact:
8585+8686+> The minimum supported runtime version is now 22.x.
8787+8888+✅ Imperative action:
8989+9090+> Check your runtime version with `node --version`. If it's below 22.x, upgrade to a supported version before installing.
9191+9292+Whenever the user must edit code, include a **diff** sample:
9393+9494+````markdown
9595+#### What should I do?
9696+9797+If you maintain an adapter, the previous signature continues to work until the next major version.
9898+9999+To migrate now, pass `routeData` and `locals` as properties of an object instead of as separate arguments:
100100+101101+```diff
102102+- app.render(request, routeData, locals)
103103++ app.render(request, { routeData, locals })
104104+```
105105+````
106106+107107+For deprecations, state the **migration window** so users know they have time:
108108+109109+> The `oldOption` is still honored in vY.0 and will be removed in vZ.0. Replace it with `newOption` at your convenience.
110110+111111+## Worked examples
112112+113113+### Example 1: signature change
114114+115115+````markdown
116116+### Changed: `parseConfig()` signature
117117+118118+In v2.x, `parseConfig()` accepted a string path and returned a parsed config synchronously.
119119+120120+v3.0 makes `parseConfig()` async and accepts either a path or a `URL`. It now returns a `Promise<Config>`.
121121+122122+#### What should I do?
123123+124124+Await the result and update any callers:
125125+126126+```diff
127127+128128+- const config = parseConfig('./project.toml')
129129+130130+* const config = await parseConfig('./project.toml')
131131+ ```
132132+````
133133+134134+### Example 2: default-value change with opt-out
135135+136136+````markdown
137137+### Changed: default value for `security.checkOrigin`
138138+139139+In v4.x, `security.checkOrigin` defaulted to `false`.
140140+141141+v5.0 changes the default to `true`, enabling CSRF protection for on-demand pages by default.
142142+143143+#### What should I do?
144144+145145+If you previously set `security.checkOrigin: true` explicitly, you can remove it — that's now the default.
146146+147147+To preserve the previous behavior, set `security.checkOrigin: false` explicitly:
148148+149149+```diff
150150+export default defineConfig({
151151+152152+- security: {
153153+- checkOrigin: false
154154+- }
155155+ })
156156+ ```
157157+````
158158+159159+### Example 3: rewriting a fact-as-statement
160160+161161+❌ Useless:
162162+163163+```markdown
164164+### Changed: minimum runtime version
165165+166166+The minimum supported runtime is now 22.x.
167167+168168+#### What should I do?
169169+170170+The minimum supported runtime is now 22.x.
171171+```
172172+173173+✅ Action:
174174+175175+````markdown
176176+### Changed: minimum runtime version
177177+178178+In v4.x, runtimes 18.x and newer were supported.
179179+180180+v5.0 requires 22.x or newer.
181181+182182+#### What should I do?
183183+184184+Check your installed version:
185185+186186+`sh
187187+node --version
188188+`
189189+190190+If it reports below 22.x, install a supported version before upgrading. Most version managers (e.g. fnm, nvm, volta) can install 22.x in one command.
191191+````
192192+193193+## What does NOT belong in the upgrade guide
194194+195195+- **New optional features.** A feature the reader can ignore does not block upgrading. It belongs in the CHANGELOG, the release blog post, or proper feature docs — not here.
196196+- **Internal refactors.** If nothing about the user-facing API changed, leave it out.
197197+- **Bug fixes.** Same — the CHANGELOG covers these.
198198+- **Lengthy "why" essays.** Save the rationale for a blog post. The guide exists to get the reader unblocked.
199199+200200+If you find yourself writing entries that don't have a "What should I do?" answer, they probably don't belong in the guide.
201201+202202+## Quick checklist
203203+204204+- [ ] Standard sections in order (or omitted when empty)
205205+- [ ] Every breaking change has its own `###` entry
206206+- [ ] Each entry's title verb reflects user impact, not code mechanics
207207+- [ ] Body has two short statements: past behavior, present behavior
208208+- [ ] "What should I do?" exists for every entry
209209+- [ ] Imperative actions, not statements of fact
210210+- [ ] `diff` sample included whenever the user must edit code
211211+- [ ] Default-value changes show both directions (new default + opt-out)
212212+- [ ] No new-feature announcements, no bug-fix entries
213213+214214+## See Also
215215+216216+- `writing-docs/SKILL.md` — imperative-instruction and code-sample conventions used here
217217+- `writing-changesets/SKILL.md` — breaking-change changesets feed into this guide; the per-change content is often the source material for an upgrade-guide entry