# `notes-authoring.md`, release notes: GH body · Slack post · multi-version rollup

> Load for the end-of-cycle notes step or a notes-only request. The GH release
> body attached to each per-package tag is the **durable record**; drafts live in
> the session scratch dir and the operator copy-pastes, the skill never posts to
> Slack directly.

## §Author from the diff, not the intent

Draft every note from `git diff <prev-tag>..HEAD`, what actually shipped, never from an ADR's intent or a PR's plan. The first two commands of any draft:

```bash
git log --oneline <prev-tag>..HEAD
git diff --stat <prev-tag>..HEAD
```

If the diff contradicts the plan (a feature deferred, a refactor split across cuts), the notes follow the diff. This is a discipline because the inverse shipped a real defect: notes copied from an ADR once claimed features that were never staged into the cut. F-N1 catches *undocumented diff*, not *over-claimed notes*: that guard is the author's.

## §The GH release body (single version, ~80–200 lines)

Every roster package (package-paths.mjs) gets the same body (`gh release create <pkg>-vX.Y.Z --notes-file …`).

```markdown
## vX.Y.Z, <one-line tagline>

Lockstep **PATCH** cut (all roster packages). <One sentence on scope.>

### `@adia-ai/<substantive-pkg>`
- **<Bold-prefix headline>.** <Why → what → inline file paths.> Closes <FEEDBACK-NN>.

### Ride-along stubs
`@adia-ai/<pkg1>`, `@adia-ai/<pkg2>`, …, version bump only.

### Verification
- `check:lockstep` OK at `X.Y.Z / ^X.Y.0`
- **N/N vitest** · typecheck clean · `components --verify` clean · `verify:traits` 100%
- `check:demo-shells` · `check:lightningcss-build` · `verify:corpus` 0/0 · `check:embeddings-fresh` OK
- `smoke:engines` · `smoke:register-engine` 11/11 · `eval:diff zettel` cov=N% avg=N · `check:links` clean

### Install
npm i @adia-ai/web-components@X.Y.Z @adia-ai/web-modules@X.Y.Z
```

Shape rules: open with the tagline, no preamble; group by `### @adia-ai/<pkg>`; bold-prefix every bullet then why → what → files; cite tickets by ID; before/after fenced blocks for consumer-facing markup changes; paste the verification block from the actual pre-flight output (the cycle-to-cycle repetition is a feature); a breaking cut adds a `⚠️` paragraph linking its MIGRATION GUIDE section. Anti-patterns: marketing language, vague verbs, missing file paths.

## §The Slack post (~40–80 lines)

```markdown
🚀 **AdiaUI vX.Y.Z** is out, <tagline>

npm i @adia-ai/web-components@X.Y.Z @adia-ai/web-modules@X.Y.Z

Lockstep PATCH cut (all roster packages). <One sentence.>

## 🔷 `@adia-ai/<pkg>`, <headline>
<2–4 sentences.> Closes <FEEDBACK-NN>.

## ✅ Verification
<one line>

## 📚 Links
- GH Releases: https://github.com/adiahealth/gen-ui-kit/releases (filter `vX.Y.Z`)
- Live demos: https://ui-kit.exe.xyz/site/playground/gen-ui
```

- **Install matrix is mandatory, npm + CDN, both packages**: npm always names `web-components` AND `web-modules`; the CDN block pins the `@0.X` minor range, `web-components@0.X/dist/web-components.min.{css,js}` plus `web-modules@0.X/dist/everything.min.js` as the all-in-one `<script>`.
- Section emojis: 🔷 feature · 🛠️ DX fix · 🎨 visual · 🧹 cleanup · ⚠️ breaking/behavior · ✅ verification · 📚 links.
- Slack renders standard markdown (fenced blocks, `-` bullets, `[text](URL)`); no legacy mrkdwn needed.
- **Every `https://ui-kit.exe.xyz/site/<route>` URL must be verified against `site/sitemap.json` first**: the docs site is an SPA; an unmatched route returns 200 and renders blank, so curl proves nothing. The Gen UI Canvas is `/site/playground/gen-ui`; there is no `/site/gen-ui/`.

Save drafts to the session scratch dir (e.g. `<scratch>/release-vX.Y.Z/notes.md`); strip nothing for Slack, and the GH body is the same content without the rocket header.

## §Rollup, multi-version retrospective (≥2 versions since the last broadcast)

Audience: consumers or teammates catching up on a window (vA.B.C → vX.Y.Z). Five-section skeleton:

1. **Header**, `🚀 AdiaUI vA.B.C → vX.Y.Z, <tagline>` + install snippet + 2–4 sentences on the window (releases count, what held across all of them, e.g. "internal deps held at ^0.X.0 throughout").
2. **🧵 Framing section, pick ONE:**
   - **A. The arcs**, 2–4 thematic strands, each naming its contributing versions. Best mid-cycle with no dominant theme.
   - **B. The headline event**, one milestone (graduation, ADR ratification) with the package cuts as substrate. Best for milestone windows.
   - **C. Net deltas**, what consumers see differently end-to-end: new primitives / new APIs / breaking-ish / retired, as a bullet list. Best when the window includes a MINOR or a consumer is jumping a big gap.
3. **📦 Per-version breakdown**, one block per version: `### vN.M.X, <tagline>` + 3–5 bold-prefix bullets if substantive, 1–2 if small, a single sentence for stub-only versions. **Skip ride-along stubs entirely**, naming 6 no-change packages per version is noise.
4. **⚠️ Behavior-changes table** (only if the window has ≥2): `| Version | Change | Opt-out / migration |`.
5. **✅ Verification baseline**, one paragraph, not the full table: test-count growth across the window, gate roster held, eval floors held, F-N1 clean at every cut. Show the *growth*, it's the window's velocity signal. Close with one paragraph naming what the window accomplished, echoing the framing.

Save to `<scratch>/release-vA.B.C-vX.Y.Z/rollup.md`; announcement-grade rollups (milestone, MINOR) can also land as a GH "milestone" release body, operator's call.

## §What NOT to put in notes

Internal ticket fields; implementation details with no consumer effect; "coming soon" futures; jokes, notes are a permanent artifact attached to a tag.
