| name | generating-release-notes |
| description | Use when a batch of engineering work is complete. Generates team-readable release notes OR polished community-facing newsletter content from git history. Supports internal (default), newsletter, or both output modes.
|
| version | 2.1.0 |
| license | MIT |
| metadata | {"author":"VettedAI","category":"communication","tags":["release-notes","changelog","newsletter","community","team-communication","qa","product"],"created":"2026-02-18T00:00:00.000Z","updated":"2026-03-27T00:00:00.000Z"} |
| argument-hint | [date-range or commit-range] [newsletter|both] |
Generating Release Notes
Produces team-readable release notes and/or polished community-facing newsletter content from git history. Internal notes bridge commits to QA and stakeholders. Newsletter mode generates changelog content suitable for community distribution (think: Linear's changelog, Vercel's ship updates).
When to Use
- After completing a batch of features (end of sprint, weekly cadence)
- Before QA testing begins on a staging branch
- When stakeholders ask "what shipped this week?"
- When you want to announce shipped features to the community
- Before sending a weekly/biweekly product update email or changelog post
- When marketing or community team asks "what can we announce?"
- Explicitly via
/generating-release-notes
Why This Exists
Commits are developer-facing. Product, QA, and stakeholders need:
- What changed in plain English
- Where to find it (navigation path in the app)
- Why it matters (ties back to feedback or business goals)
- What to test (verification steps, edge cases)
The community needs something different — polished, benefit-led updates that celebrate what shipped and help users discover new features.
Inputs
The skill accepts a range. If none provided, ask which:
| Input | Example | Use When |
|---|
| Date range | last 7 days, since Feb 10 | Weekly cadence |
| Commit range | abc123..HEAD | After a specific batch |
| Tag/branch | since v1.2.0, main..staging | Release-based workflow |
| Plan file | path to .claude/plans/*.md | When detailed plans exist |
Output Mode
Append a mode keyword to your invocation:
| Keyword | Behavior |
|---|
| (none) | Internal release notes only (default, backward-compatible) |
newsletter | Community-facing newsletter only |
both | Generates both internal notes and newsletter |
Examples:
/generating-release-notes last 7 days — internal notes
/generating-release-notes since v1.2.0 newsletter — newsletter
/generating-release-notes last 7 days both — both outputs
Workflow
Step 1: Gather Raw Material
git log --oneline --no-merges <range>
git diff --stat <range>
git log --format="%h %s%n%b%n---" <range>
If plan files exist in .claude/plans/, read them — they contain the why behind changes and are richer than commit messages.
Step 2: Classify Changes
Group every change into exactly one category:
| Category | Icon | Criteria |
|---|
| New Features | NEW | Functionality that didn't exist before |
| Improvements | IMPROVED | Enhancements to existing functionality |
| Bug Fixes | FIXED | Corrections to broken behavior |
| Internal | INTERNAL | Refactors, tooling, infra — no user-visible change |
Rule: If a commit touches both a bug fix and an improvement, classify by the primary intent.
Step 3: Write Entries
3a: Internal Mode (default)
For each change, write:
**[Category]** Short description in user-facing language
- **Where:** Navigation path to find it (e.g., Workspace > New Project > Step 3)
- **What:** 1-2 sentences explaining the change from a user's perspective
- **Why:** The feedback, ticket, or problem that prompted this (if known)
- **Test:** How QA can verify this works (specific steps)
Writing rules:
- Use the user's language, not code language
- YES: "Weight sliders now snap to 10% increments"
- NO: "Updated adjustWeightsProportionally() to round to nearest 10"
- Include the navigation path so anyone can find the feature
- Testing notes should be specific enough for someone unfamiliar with the code
3b: Newsletter Mode
For each user-visible change (skip INTERNAL category entirely), write:
### [Emoji] [Feature Name in 3-6 Words]
[1-2 sentence "Now you can..." or "We shipped..." framing. Lead with the user
benefit, not the technical change.]
[Optional: Before/after comparison if the change modifies existing behavior]
<!-- SCREENSHOT: [Description of what to capture — e.g., "the new booking link
field on the profile page"] -->
---
Newsletter writing rules:
- Lead with benefit, not mechanism. "You can now add your Calendly link to your profile" not "Added booking_url column to participants table"
- Use "Now you can..." or "We shipped..." framing. These are action-oriented and put the user in the driver's seat.
- One emoji per feature. Pick from: ✨ (new), ⚡ (improvement), 🔧 (fix), 🎯 (precision/targeting), 📧 (email/comms), 🤝 (connection/matching), 📅 (scheduling). No emoji salad.
- Screenshot placeholders are mandatory for any visual change. Use HTML comments so they're invisible in rendered markdown but obvious in the source.
- Skip INTERNAL changes entirely. The community doesn't care about refactors, dependency bumps, or infra changes.
- Skip bug fixes that the community never saw. If a bug was introduced and fixed within the same release window, omit it. Only include fixes for bugs the community actually experienced.
Step 4: Compile the Document
4a: Internal Template (default)
Use this template:
# Release Notes — [Date or Version]
**Branch:** `[branch-name]`
**Commits:** [count] ([range])
**Key areas:** [1-3 word summary of main areas touched]
---
## User-Facing Changes
### New Features
[Entries from Step 3a]
### Improvements
[Entries from Step 3a]
### Bug Fixes
[Entries from Step 3a]
---
## Internal Changes
[Entries that don't affect users — optional, collapse if many]
---
## QA Checklist
A consolidated testing checklist extracted from individual entries:
- [ ] [Test item 1]
- [ ] [Test item 2]
- ...
---
## Deployment Notes
[Any edge functions to deploy, migrations to run, env vars to set, etc.]
Only include this section if there are actual deployment steps beyond "merge and deploy."
4b: Newsletter Template
Use this template:
# [Catchy Title — 5-8 words, no version numbers]
*[Date in human format, e.g., "March 15, 2026"]*
**TL;DR** — Here's what shipped this week:
- [Bullet 1 — most impactful feature, 1 line]
- [Bullet 2]
- [Bullet 3]
- [Up to 5 bullets max]
---
[Feature spotlight entries from Step 3b, ordered by impact — biggest first]
---
## Try It Out
[1-2 sentences pointing to the app or specific feature. Include a direct link
if possible.]
**[CTA button text] →** `[URL]`
---
*Shipped with ☕ by the [team name]*
*Questions? Reply to this email or drop us a note at [contact]*
Title guidelines:
- Confident, not clickbait. "Smarter Matching, Easier Scheduling" not "YOU WON'T BELIEVE what we shipped"
- No version numbers. Community doesn't care about v1.3.2.
- Action-oriented or benefit-oriented. "Book Coffee Chats in One Click" not "Release 47"
TL;DR guidelines:
- 3-5 bullets, each one line
- Start each bullet with a verb: "Added", "Improved", "Fixed", "Enabled"
- Most impactful item first
Step 5: Output
5a: Internal Mode
Write to docs/release-notes/[YYYY-MM-DD].md (create directory if needed).
If the user prefers a different location, ask once and remember.
5b: Newsletter Mode
Write to docs/changelog/[YYYY-MM-DD].md (create directory if needed).
5c: Both Mode
Write both files. Generate the newsletter after the internal notes, since the internal notes serve as the comprehensive source of truth that the newsletter distills from.
After writing, remind the team:
Next steps: Review the newsletter draft, fill in screenshot placeholders (marked with <!-- SCREENSHOT: ... -->), and send via your distribution channel.
Quality Checklist
Internal Notes
Before delivering:
Newsletter
Before delivering the newsletter draft:
Anti-Patterns
Internal Notes
Commit-message parroting:
# BAD - Just reformatting git log
- feat(wizard): Improve Role Summary and Role DNA pages
- fix(admin): Fix broken search
# GOOD - User-facing language with context
**IMPROVED** Role DNA page now lets you edit AI classifications
- **Where:** Workspace > New Project > Step 3 (Review Role DNA)
- **What:** Role Classification (formerly "Role Context") is now editable.
You can override the AI-assigned role family, seniority, and context flags.
- **Why:** Feedback from Lemuel — all AI-generated content should be user-overridable
- **Test:** Click Edit on Role Classification > change role family > Save > verify warning toast appears
Missing the "where":
# BAD - User can't find the feature
Weight sliders now increment by 10%.
# GOOD - User knows exactly where to look
**IMPROVED** Weight sliders snap to 10% increments (min 10%, max 50%)
- **Where:** Workspace > New Project > Step 3 > Performance Dimension Weights
Over-including internals:
# BAD - QA doesn't need to know about refactors
- Moved snapWeightsToGrid() helper function
- Updated useEffect dependency arrays
# GOOD - Only mention if it affects testing
(Omit entirely — internal refactors don't go in user-facing sections)
Newsletter
The corporate press release:
# BAD
We are excited to announce the release of VFA Coffee Chat v1.3.2, which
includes several new features and improvements designed to enhance the
user experience.
# GOOD
# Smarter Matches, Easier Scheduling
Here's what shipped this week — booking links, better follow-ups, and
a cleaner match experience.
The technical leak:
# BAD
We added a booking_url column to the participants table and updated the
edge function to include it in the mutual intro email template.
# GOOD
✨ Add your Calendly or booking link to your profile — your match will
see it right in their intro email, so scheduling is one click away.
The invisible fix:
# BAD
Fixed a race condition where duplicate automations could be created when
the cron job overlapped with a manual trigger.
# GOOD
(Omit entirely — the community never saw this bug. If they did:)
🔧 Fixed an issue where some participants received duplicate follow-up
emails. Sorry about the inbox clutter!
Screenshot-less visual changes:
# BAD
We redesigned the match card on the My Matches tab.
# GOOD
✨ Refreshed Match Cards
Your matches page got a visual upgrade — cleaner layout, your partner's
role and LinkedIn at a glance.
<!-- SCREENSHOT: My Matches tab showing the new match card with role
badge and LinkedIn link visible -->
The feature dump:
# BAD — listing 15 minor changes with equal weight
- Updated button color
- Changed font size on mobile
- Added aria labels
- ...
# GOOD — consolidate into a single entry or omit
⚡ Polish Pass
Small visual refinements across the app — cleaner buttons, better mobile
spacing, and improved accessibility.
Newsletter Voice Guide
The newsletter voice is confident builder — a team that ships fast, cares about its community, and communicates like humans.
| Do | Don't |
|---|
| "We shipped smarter matching this week" | "We are pleased to announce..." |
| "Now you can add your Calendly link" | "A new field has been added to the database" |
| "Fixed an issue where follow-up emails arrived late" | "Resolved a race condition in the automation scheduler cron job" |
| "Your coffee chats just got easier to schedule" | "We have implemented booking URL integration" |
| Name the benefit in the first sentence | Lead with technical details |
| Use "we" and "you" | Use passive voice or third person |
Tone calibration:
- More Linear changelog, less enterprise release notes
- More "shipped it" energy, less "please find attached"
- Warm but not cutesy. Professional but not corporate.
- Celebrate shipping without being breathless about it
Brand alignment:
- The product connects people. Language should reflect human connection.
- Use product-specific metaphors sparingly — once in sign-off is fine, not in every heading.
- Reference the community ("your match", "your profile") not the system ("the matching algorithm", "the pairing engine").
Tips
- Plan files are gold. If
.claude/plans/ has a plan for this work, read it. Plans contain the "why" and "what to verify" that commit messages lack.
- Ask about context. If commits reference a person's feedback (e.g., "Lemuel @ APP"), include that attribution — it helps the team trace decisions.
- Weekly > per-push. Small daily commits create noise. Batch into weekly summaries.
- Err on the side of too much QA detail. Testing notes that are too specific are better than vague "test it works."
- Newsletter is a distillation, not a translation. Don't convert every internal entry to newsletter format. Pick the 3-7 most impactful user-facing changes. A shorter, punchier newsletter beats a comprehensive one.
- Generate internal notes first, then newsletter. The internal notes are your source of truth. The newsletter cherry-picks from them.
- Screenshot placeholders save review cycles. Describing exactly what to capture ("the profile page with the new booking link field filled in") means the person adding screenshots doesn't need to guess.
- One newsletter per week max. Even if you ship daily, batch into weekly updates. Community attention is finite.
Step 6: Post to Fizzy
After writing release notes (any mode), create a summary card on the project's Fizzy board.
Fizzy Board Config (per-project)
Each project must define these values. Look in these locations (in order): .claude/rules/fizzy-api-patterns.md, memory files, qa-handoff skill, or the fizzy skill's SKILL.md for the board ID. The token is always in the project's .env.local as FIZZY_API_TOKEN.
| Field | Where to find |
|---|
| Account ID | 6102589 (shared across all VettedAI projects) |
| Board ID | Project-specific — check CLAUDE.md, memory, or fizzy skill |
| Token | .env.local as FIZZY_API_TOKEN (path varies per project) |
| Endpoint | POST https://app.fizzy.do/6102589/boards/{BOARD_ID}/cards.json |
Important: Always use .json suffix on the endpoint and include User-Agent: VettedAI/1.0 header — without these Fizzy returns 401/422.
Card Format
- Title:
Release Notes — [Date] ([N] commits)
- Body: HTML summary (use
description field — Fizzy ignores content) with these sections:
<h3>New Features ([count])</h3> — <ul> with <strong>name</strong> — one-line description per feature
<h3>Major Fixes ([count])</h3> — <ul> with one-line per fix
<h3>Improvements ([count])</h3> — same format
<h3>Security</h3> — if applicable
<h3>Internal</h3> — brief bullets
<h3>Deployment Notes</h3> — env vars, migrations, cron jobs, new endpoints
- Final
<p><em>Full QA checklist in docs/release-notes/[date].md</em></p>
Posting
Use Python for reliable JSON encoding (HTML in shell strings is fragile):
python3 << 'PYEOF'
import json, subprocess
body_html = """<h3>New Features</h3><ul><li>...</li></ul>..."""
payload = json.dumps({"card": {
"title": "Release Notes — YYYY-MM-DD (N commits)",
"description": body_html
}})
result = subprocess.run([
"curl", "-s", "-i", "-X", "POST",
"https://app.fizzy.do/6102589/boards/{BOARD_ID}/cards.json",
"-H", "Authorization: Bearer {TOKEN}",
"-H", "User-Agent: VettedAI/1.0",
"-H", "Content-Type: application/json",
"-d", payload
], capture_output=True, text=True)
print(result.stdout[:500])
PYEOF
Extract the card number from the Location header (e.g., /6102589/cards/500.json → card #500). Report the card number to the user when done.
If board details are unknown
If you can't find the Fizzy board ID for the current project, ask the user:
"Which Fizzy board should I post release notes to? I need the board ID (e.g., 03f58rc5c48jorujpxqp5da5b)."