gaia-react/gaia/.claude/skills/release-notes/SKILL.md
release-notes
Maintainer-only. Translate a version's GAIA CHANGELOG entries into plain-language public release notes for the marketing site (gaiareact.com). Writes a release-data `.ts` file under `../website/src/pages/changelog/releases/` plus an editorial-decisions report for human review. Use whenever the maintainer wants the adopter-facing notes for a version, e.g. "write release notes", "generate the changelog page entry", "translate the CHANGELOG for the website", "what's new on the site for v1.5.0", "pu
- Source repository stars
- 21
- Declared platforms
- 0
- Static risk flags
- 2
- Last source update
- 2026-08-04
- Source checked
- 2026-08-04
Decision brief
What it does—and where it fits
Translate one version's CHANGELOG entries into adopter-facing release notes. The CHANGELOG is written for GAIA's own contributors: terse, imperative, full of internal mechanics and PR numbers. Adopters read the website. They don't care that an ADR was reframed or a memory was pr…
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/gaia-react/gaia --skill ".claude/skills/release-notes"Inspect the Agent Skill "release-notes" from https://github.com/gaia-react/gaia/blob/395b416ee24619690a051c4dbcf9dcd20895e95b/.claude/skills/release-notes/SKILL.md at commit 395b416ee24619690a051c4dbcf9dcd20895e95b. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
Workflow
1. Resolve the version → block → date (Inputs above). For a live cut, run date +%F now. 2. Read ../website/src/pages/changelog/types.ts for the current Release fields and the newest releases/.ts for the current file form (export style + key order). Then read the version's block…
Resolve the version → block → date (Inputs above). For a live cut, run date +%F now.Read ../website/src/pages/changelog/types.ts for the current Release fields and the newest releases/.ts for the current file form (export style + key order). Then read the version's block from CHANGELOG.md. Classify eve…Translate the kept lines through the contract. Group by bucket (rule 10). Merge consolidations. - 02
Pre-flight: Worktree check
This skill writes into the sibling website checkout, resolved relative to the main checkout. If invoked from a linked worktree, reject hard: gaiarefuseifworktree (.gaia/scripts/main-only-lib.sh) asks the shared resolver which tree this is and refuses out loud, naming the main ch…
This skill writes into the sibling website checkout, resolved relative to the main checkout. If invoked from a linked worktree, reject hard: gaiarefuseifworktree (.gaia/scripts/main-only-lib.sh) asks the shared resolver…Detection (run this first, before anything else):If the detection does not fire, fall through to Inputs below. - 03
Inputs
Invocation carries a target version, e.g. release-notes 1.4.0 (no leading v). Resolve which CHANGELOG block to translate, and where the date comes from, by that version:
Graduated / historical: CHANGELOG.md contains [], . Translate that block. Take version and date verbatim from the header. The release already happened on that date; the shell clock is irrelevant.Live cut: the version isn't graduated yet; its entries live under [Unreleased]. Translate that block. version is the argument (the maintainer is cutting it now). date is today from the shell clock (date +%F).Invocation carries a target version, e.g. release-notes 1.4.0 (no leading v). Resolve which CHANGELOG block to translate, and where the date comes from, by that version: - 04
The date is never yours to invent
Whether historical or live, the date comes from the CHANGELOG header or the shell, never from your own notion of "today." Models routinely misdate by months; a wrong date silently ships a wrong timeline to every visitor. For a live cut, run date +%F and use exactly that. This is…
Whether historical or live, the date comes from the CHANGELOG header or the shell, never from your own notion of "today." Models routinely misdate by months; a wrong date silently ships a wrong timeline to every visitor… - 05
Output (a): the release data file
Write to ../website/src/pages/changelog/releases/.ts (version with no leading v; mkdir -p the directory if it's missing). The changelog page auto-discovers every file via import.meta.glob('../releases/.ts') and sorts by version, so dropping the file in is all that's needed, ther…
added → "New" (capabilities that didn't exist before). improved → "Improved" (changed/enhanced behavior). fixed → "Fixed".headline, required for any bucketed release (one or more added/improved/fixed items). A short title or one plain sentence, leading with the release's reason to exist. The buckets render with no title of their own, so a…summary vs buckets, mutually exclusive. The renderer shows summary as a single paragraph instead of the added/improved/fixed lists. The choice is driven by how many distinct adopter-facing items survive the cut, not by…
Permission review
Static risk signals and limitations
Writes files
The documentation asks the agent to create, modify, or delete local files.
After writing the file, print a report to the terminal (don't write a file, this is a human gate the maintainer reads before accepting the notes). It makes your editorial judgment auditable. Use this structure:Runs scripts
The documentation asks the agent to run terminal commands or scripts.
'GAIA apps now ship with a Content-Security-Policy that restricts which scripts can run, hardening them against script injection.',Writes files
The documentation asks the agent to create, modify, or delete local files.
`mkdir -p ../website/src/pages/changelog/releases` and write `<version>.ts`. No index to update, the page globs the directory.Evidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 87/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 21 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- gaia-react/gaia
- Skill path
- .claude/skills/release-notes/SKILL.md
- Commit
- 395b416ee24619690a051c4dbcf9dcd20895e95b
- License
- MIT
- Collected
- 2026-08-04
- Default branch
- main
View the original SKILL.md
release-notes
Translate one version's CHANGELOG entries into adopter-facing release notes. The CHANGELOG is written for GAIA's own contributors: terse, imperative, full of internal mechanics and PR numbers. Adopters read the website. They don't care that an ADR was reframed or a memory was promoted; they care what GAIA now does for their project. This skill is the translation layer between the two audiences.
Maintainer-only. Adopters never release GAIA, so this skill ships nowhere, it's excluded from the distribution tarball by .gaia/release-exclude (category 1), the same as /gaia-release. It pairs with /gaia-release but runs independently: you can point it at the [Unreleased] block while cutting a release, or at any historical ## [x.y.z] block to backfill the website.
It never edits CHANGELOG.md. The changelog stays technical and precise, that's its job. This skill only reads it.
Pre-flight: Worktree check
This skill writes into the sibling website checkout, resolved relative to the main checkout. If invoked from a linked worktree, reject hard: gaia_refuse_if_worktree (.gaia/scripts/main-only-lib.sh) asks the shared resolver which tree this is and refuses out loud, naming the main checkout, when the answer is a worktree.
Detection (run this first, before anything else):
. .gaia/scripts/main-only-lib.sh
gaia_refuse_if_worktree "/release-notes" || exit 1
If the detection does not fire, fall through to ## Inputs below.
Inputs
Invocation carries a target version, e.g. release-notes 1.4.0 (no leading v). Resolve which CHANGELOG block to translate, and where the date comes from, by that version:
- Graduated / historical:
CHANGELOG.mdcontains## [<version>], <YYYY-MM-DD>. Translate that block. Takeversionanddateverbatim from the header. The release already happened on that date; the shell clock is irrelevant. - Live cut: the version isn't graduated yet; its entries live under
## [Unreleased]. Translate that block.versionis the argument (the maintainer is cutting it now).dateis today from the shell clock (date +%F).
If no version was supplied and an [Unreleased] block exists, ask the maintainer which version is being cut, the version label has to come from a human, not a guess.
The date is never yours to invent
Whether historical or live, the date comes from the CHANGELOG header or the shell, never from your own notion of "today." Models routinely misdate by months; a wrong date silently ships a wrong timeline to every visitor. For a live cut, run date +%F and use exactly that. This is the same discipline GAIA enforces for wiki playbook dates.
Output (a): the release data file
Write to ../website/src/pages/changelog/releases/<version>.ts (version with no leading v; mkdir -p the directory if it's missing). The changelog page auto-discovers every file via import.meta.glob('../releases/*.ts') and sorts by version, so dropping the file in is all that's needed, there's no index or import list to update.
The schema lives in ../website/src/pages/changelog/types.ts (the Release type), read it as the source of truth before writing. As of this writing it is:
export type Release = {
added?: string[]; // "New"
date: string; // ISO yyyy-mm-dd
fixed?: string[]; // "Fixed"
headline?: string;
improved?: string[]; // "Improved"
summary?: string; // freeform fallback for legacy/coarse entries
version: string; // semver, no leading 'v'
};
Match the file form of the existing release files, don't trust this skill's literal shape. The website's convention drifts (export style and key order have both changed). Before writing, open the newest releases/*.ts and mirror it exactly: types.ts gives you the fields, a live sibling file gives you the serialization. Today that form is a bare default export with keys in alphabetical order (the formatter sorts them). Omit any optional key with no content:
export default {
added: ['...'],
date: '2026-06-02',
fixed: ['...'],
headline: 'A short title or one plain sentence.',
improved: ['...'],
version: '1.4.0',
};
added→ "New" (capabilities that didn't exist before).improved→ "Improved" (changed/enhanced behavior).fixed→ "Fixed".headline, required for any bucketed release (one or moreadded/improved/fixeditems). A short title or one plain sentence, leading with the release's reason to exist. The buckets render with no title of their own, so a bucketed card with noheadlineships titleless (this is exactly how1.1.0lost its title). A grab-bag with no single story still gets aheadline: use a descriptive umbrella line naming the two or three biggest items ("Built-in a11y testing, dead-code detection, and Serena code intelligence"), never nothing. The only way to omitheadlineis to let asummarycarry the lead instead (see below). For a newly-shipped capability, carry the rule 1nowinto the headline too, "GAIA apps now ship with a CSP", not "ship with". The website build enforces this:scripts/check-release-titles.mjs(wired intopnpm buildandpnpm check:releases) fails if any release file has neither aheadlinenor asummary, and theReleasetype intypes.tsencodes the same lead-required rule.summaryvs buckets, mutually exclusive. The renderer showssummaryas a single paragraph instead of theadded/improved/fixedlists. The choice is driven by how many distinct adopter-facing items survive the cut, not by the release's age or whether it's a backfill. Use buckets whenever one or more itemizable adopter-facing changes remain; each lands as its own bullet under New/Improved/Fixed. Reservesummaryfor: (1) an internal-only release where every change was dropped as maintainer plumbing, a one-line "no adopter-facing changes" note (e.g. "Internal release-tooling fixes. No change to how GAIA apps behave."); (2) a genuine one-sentence story; or (3) a broad inaugural / overview release where a narrative reads better than a long list (the1.0.0entry). Never set both.- Bullet strings are markdown-lite: inline code in backticks, links as
[text](url)(rendered as a new-tab link). PR links (https://github.com/gaia-react/gaia/pull/NNN) are optional, include one only when a reader would genuinely follow it for detail, never as decoration. The exemplars below omit them.
Output (b): the editorial-decisions report
After writing the file, print a report to the terminal (don't write a file, this is a human gate the maintainer reads before accepting the notes). It makes your editorial judgment auditable. Use this structure:
## Release notes, v<version> (<date>)
Wrote ../website/src/pages/changelog/releases/<version>.ts
**Dropped** (with reason)
- <changelog line>, <why: pure-internal / housekeeping / docs-only>
**Consolidated**
- <N changelog lines about X> → one <bucket> item
**Needs a human ruling** (ambiguous actor, see rule 6)
- <line>, feature or housekeeping? <why it's ambiguous>
Omit a section if it's empty. Never drop something silently: if it didn't make the notes, it appears under Dropped or Needs a human ruling.
The translation contract
This is the substance of the skill, the rules that turn a contributor's changelog into an adopter's release notes.
- Restate at capability/impact altitude, with a concrete subject. Name the component the adopter touches, CI, Code Review Audit,
/update-gaia, the quality gate. "what changed and what it means for me," not "which function moved." Avoid vague subjects, "the app", "the system", "the tooling", "things" read as placeholders. The scaffolded React app is GAIA apps (apps built from the template); effects on the developer's own code or files are your … (your utility classes, yourpackage.json). So "the app ships with a CSP" becomes "GAIA apps now ship with a CSP." - Be more specific, not less. Plain language is not vague language. One dense technical line often splits into two clear ones. Resist the urge to compress meaning out.
- Ban filler. No "improved performance," "various fixes," "enhanced reliability," "general improvements." If you write "optimized," say optimized what and the observable result. A bullet a reader can't act on or verify is noise. Don't restate the semver tier either: a "Patch release" / "Minor release" / "Major release" lead is redundant with the version number, which already conveys it. Descriptive framing ("Maintenance release", "Security release") is fine.
- Drop changes with no adopter relevance, judge by relevance, not residence. The test is whether an adopter building their own product would notice or benefit, not whether the changed file physically ships to their machine. A hook, guard, or workflow can ship to every adopter and still be maintainer-only in effect. Drop: ADR reframes, leak-check tweaks, internal status stamping, test-harness changes, docs-only edits, and fixes to GAIA's own development and release plumbing, sibling-repo push handling, release lockstep, contributor-only guard edge cases. The adopter's product behaves identically with or without them. Trap: "strip surrounding quotes from literal
git -Ccaptures so a quoted sibling-repo push is recognized as foreign" ships inside an adopter hook, yet only fires when you push across GAIA's own sibling repos during a release, drop it. (Contrast: GAIA CI / Code Review Audit that an adopter opts into via/setup-gaiais adopter-facing, residence aside, an adopter who runs it sees the benefit, so keep it.) - Drop maintainer housekeeping on GAIA's own repo/wiki. Promoting memories, reorganizing the wiki, dated audit artifacts, version-stamp bumps. These change GAIA's own state, not what GAIA does for an adopter.
- Flag ambiguous actors, don't guess. Imperative/passive changelog voice often hides the subject. "promote machine-local feedback memories into shared wiki" reads like a feature ("GAIA now promotes memories") but was the maintainer running
/gaia-auditon GAIA's own wiki, housekeeping, drop it. When a line could mean "GAIA now does X" (keep) or "I did X to the repo" (drop) and the voice won't tell you which, put it under Needs a human ruling rather than picking. Guessing wrong either invents a feature or buries a real one. - Consolidate scattered lines about one subject. Four CI / Code-Review-Audit lines describing one coherent change become one item. The adopter wants the story, not the commit-by-commit trail.
- Keep breaking changes and migrations, plainly framed, with a pointer. Plain does not mean painless. State the breakage in adopter terms, then point to the exact steps: "See the full changelog for exact steps" (or link the entry). Dropping the scary part to sound friendly is the one unforgivable edit.
- House style: no em-dashes, present tense. Use colons, commas, periods. The raw CHANGELOG violates both freely (em-dashes everywhere, "was changed from"), so never pipe a line through verbatim, always rewrite.
- Bucket mapping.
### Added→added("New").### Changed→improved("Improved").### Fixed→fixed("Fixed").### Removed→improved("Improved"): the website has no "Removed" bucket, and a removal that survives the cut reads to an adopter as a cleanup or simplification, but see rule 11, most convention-anchored removals are reframed or dropped, not bucketed verbatim. A**BREAKING:**or Migration sub-bullet stays in whatever bucket its parent lives in (usuallyimproved). - A
/update-gaia-automated cleanup is not a manual step. When a### Removed/### Changedentry carries the adopter-action convention anchor (an Action required: line and/or a literalpnpmcommand, seeCHANGELOG.md) and the action reduces to a single mechanical command/update-gaiasurfaces for the adopter (apnpm remove/pnpm install-style cleanup), do not present it as a chore the reader must perform. Either reframe at impact altitude, naming the cleanup as a benefit and noting the tooling handles it ("GAIA dropped the vestigialreact-router-domshim;/update-gaiacleans it up for you"), or drop it as no adopter-behavior-change. Log the decision in Output (b): a drop goes under Dropped with the reason "agent-automated by/update-gaia"; a reframe is visible in the notes themselves. Never a silent cut. Guardrail (does not erode rule 8): a genuine breaking change or hand-migration, anything the agent cannot do for the adopter (editing their code, resolving a conflict patch, a real API break), is still kept, plainly framed, with a pointer to the exact steps. The anchor is the discriminator: a one-command cleanup is automatable (reframe/drop); an Action required: that demands human code changes is a migration (keep). When you cannot tell which from the entry, route it to Needs a human ruling, never guess.
Worked exemplars
These are the calibration. Study how dense, internal-sounding changelog blocks collapse into a few adopter-meaningful bullets, and what gets cut. They show the editorial result and house style; take the literal export form and key order from a live releases/*.ts (see Output (a)), since the convention drifts.
1.3.5, seven Added, five Changed, four Fixed → two / three / one
export default {
added: [
'Dependency supply-chain hardening: new package versions are quarantined for 7 days before GAIA installs them, and downgrades are blocked, defending against a compromised fresh release.',
'GAIA apps now ship with a Content-Security-Policy that restricts which scripts can run, hardening them against script injection.',
],
date: '2026-06-02',
fixed: [
"`Form/Chain` merges class names with `twMerge`, so your utility classes override the component's defaults instead of conflicting with them.",
],
headline: 'Faster, cheaper CI and a hardened dependency supply chain.',
improved: [
'Code Review Audit on CI is now opt-in and installs on demand. When it runs, it only audits changes since the last green run instead of the whole codebase, so CI is faster and cheaper.',
'React Router v8 future flags are enabled so your app is ready for the v8 upgrade early. One flag (`v8_passThroughRequests`) changes how loaders and actions receive the request: if you have customized `app/root.tsx`, a small migration is needed. See the full changelog for exact steps.',
'Kickoff prompts print to the terminal instead of silently copying to your clipboard.',
],
version: '1.3.5',
};
Report for 1.3.5:
**Dropped** (with reason)
- stamp GAIA-Audit status on out-of-scope skips, internal status stamping, no adopter effect
- clarify the gate owns formatting; make PR merge marker-first, internal workflow mechanics
- document useDebounce return semantics, docs-only
- detect orphaned wiki drift in preflight via suggested_base, internal release tooling
- recover the un-evaluated window on sync re-anchor, internal wiki-sync mechanics
- gaia-release updates softwareVersion, maintainer-only release tooling
**Consolidated**
- four Code Review Audit / CI lines (install on demand, honor both tokens, gate on since-last-green delta, incremental scope, opt-in) → one "Improved" item
- two pnpm supply-chain lines (minimumReleaseAge quarantine, no-downgrade trustPolicy) → one "New" item
1.4.0, note the #270 housekeeping drop (rules 5/6)
export default {
date: '2026-06-02',
fixed: [
'`/update-gaia` no longer re-adds files you intentionally deleted.',
'`/update-gaia` only raises conflicts for files that actually changed in the release, instead of flooding you with spurious patches.',
'Wiki entries take their dates from your system clock instead of the model, so timestamps are always correct.',
],
headline: '`/update-gaia` stops fighting you over your own files.',
version: '1.4.0',
};
Report for 1.4.0:
**Dropped** (with reason)
- promote machine-local feedback memories into shared wiki (#270), reads like a feature but was the maintainer running /gaia-audit, a content action on GAIA's own wiki, not adopter-visible behavior (rule 5/6)
The #270 trap is the whole point of rule 6: under ### Changed, in imperative voice, it looks exactly like a shipped capability. It isn't. When the voice hides the subject and you can't resolve it from context, surface it under "Needs a human ruling" instead of dropping or keeping on instinct.
When summary fits, internal-only or one-line releases
A release with no distinct adopter-facing items left after the cut, an internal-only patch where everything was dropped as maintainer plumbing, or a genuinely one-sentence story, collapses to a single summary paragraph. This is about item count, not age: a backfilled old release with two real adopter changes still earns buckets. The shape, for an internal-only patch like 1.1.1:
export default {
date: '2026-05-11',
headline: 'GAIA release fixes',
summary:
'Fix to the gaia-release maintainer reference, plus follow-ups from live init runs.',
version: '1.1.1',
};
Use this only for an internal-only release or a genuinely one-line story. Anything with two or more distinct adopter-facing changes earns buckets, backfill or not.
Workflow
- Resolve the version → block → date (Inputs above). For a live cut, run
date +%Fnow. - Read
../website/src/pages/changelog/types.tsfor the currentReleasefields and the newestreleases/*.tsfor the current file form (export style + key order). Then read the version's block fromCHANGELOG.md. Classify every line: keep, drop (rule 4/5), consolidate-with-siblings (rule 7), reframe-or-drop a/update-gaia-automated cleanup (rule 11), or ambiguous (rule 6). - Translate the kept lines through the contract. Group by bucket (rule 10). Merge consolidations.
- Draft the
headline: required for any bucketed release. Lead with its reason to exist; for a grab-bag use a descriptive umbrella line, never omit it. Omitheadlineonly for asummary-only release. For a coarse backfill with no bucket-worthy detail, write asummaryparagraph instead of buckets. - Assemble the
.tsin the exact form of the file you read in step 2 (today: bare default export, keys alphabetical). Omit empty optional keys. Sweep for em-dashes and banned filler before writing (rule 3/9). mkdir -p ../website/src/pages/changelog/releasesand write<version>.ts. No index to update, the page globs the directory.- Print the editorial-decisions report. Every changelog line that didn't survive appears under Dropped or Needs a human ruling, no silent cuts.
See
.claude/commands/gaia-release.md, the release process this feeds: Step 14 invokes this skill for the changelog page entry and locksteps the other website version sites.CHANGELOG.md, the source. Read-only. Never edited here.eval/probe.py, trigger-boundary validation harness (maintainer-only, excluded from the tarball). After editing the frontmatterdescription, re-runpython3 .claude/skills/release-notes/eval/probe.py --runs 3to confirm the boundary still holds (target: 100% recall, 0% false-positive). Options in its docstring.
Alternatives
Compare before choosing
ffroliva/gflow-cli
pr-council-review
Multi-dimensional LLM council review of an open PR (default) or a local feature branch (§ 8 branch mode, invoked via `/gflow:branch-review`). Five baseline dimensions (correctness, quality, security, tests, memory-hygiene) plus adaptive dimensions per surface (transports / data / CLI / docs / auth / BDD / scripts / release-gate). Each agent invokes specialized skills (security-review, code-review, verify) for its dimension. Reads files via `git show <sha>:<path>` to avoid stale-working-tree fals
wshobson/agents
brand-landingpage
Brand-first landing page designer — runs a brand-identity interview (colors, typography, shape language), then generates and iterates on a polished landing page via Stitch with deployment-ready HTML. Use when the user asks to create, design, or build a landing page, homepage, or marketing page and has no established visual direction. Skip when they have a design mockup, need a dashboard or app UI, are working at component level, building a multi-page app, or restyling with known design tokens —
mgiovani/cc-arsenal
ci-local
Run the checks a GitHub Actions workflow would run, locally, when Actions is unavailable or out of quota. Parses .github/workflows/*.yml, extracts the jobs/steps that gate merges (lint, typecheck, test, build), translates them to local commands respecting the workflow's pinned node/python versions and env, executes them sequentially, and reports a parity table of what passed locally vs. what can't be replicated (service containers, secrets, matrix dimensions) and why. Activates on "CI quota", "A
aaron-he-zhu/aaron-marketing-skills
email-quality-auditor
Use it for deployment and marketing tasks; the detail page covers purpose, installation, and practical steps.