name: cleanup-trn description: Clean up the Technical Release Notes (TRN) for a Livingdocs release. Use this skill whenever the user wants to clean up or work on release notes, mentions "TRN cleanup", "clean up release notes", "release notes cleanup", or asks about preparing or editing the TRN for any release (e.g. "let's clean up the TRN for release-2026-07"). This skill handles the full workflow: gathering features/breaking changes/deprecations from Notion, creating the git branch and PR, checking migrations, and systematically editing the TRN file.
Cleanup TRN
The TRN (Technical Release Notes) file gets auto-generated by a bot during the release cycle. Before a release is announced, it needs to be cleaned up: PRs removed from the "PRs to Categorize" list once their content is covered in the right sections, new features/breaking changes/deprecations added, migrations documented, and boilerplate removed.
Step 1: Get the release handle and demo deck
Ask one question at a time — wait for each answer before asking the next:
- Release handle — if the user hasn't specified one, ask: "Which release are we cleaning up? (e.g.
release-2026-07)" - Cycle Demo Presentation — ask: "Do you have the Cycle Demo Presentation for this release? Paste the Figma Slides link and I'll cross-check it against Notion — or say 'none' to skip." A node-specific slide link (URL contains
node-id=...) reads at higher fidelity, but a plain deck URL works too. Hold onto the link for Step 2.
The TRN file lives at: documentation/content/operations/releases/<release-handle>.md
Read this file now. Also read the previous release's TRN (e.g. if this is release-2026-07, read release-2026-05) to understand what the last migration number was.
Step 2: Fetch Features, Breaking Changes & Deprecations from Notion
Use the Notion MCP to query the packages database:
- View URL:
https://www.notion.so/330c559571d68026b470d743ae75ac6c?v=330c559571d68023928b000cc91cba83
Call notion-query-database-view with that URL. The database contains all releases, so the result will be large — Claude Code saves oversized tool results to a temp file and gives you the path. Filter the file with this script:
import json
with open('<path-from-response>') as f:
content = f.read()
data = json.loads(content)
results = json.loads(data[0]['text'])['results']
# The "Cycles" column stores values in YYYY-MM format
cycle = '<release-handle>'.replace('release-', '') # e.g. "release-2026-05" → "2026-05"
filtered = [r for r in results if r.get('Computed Cycle') == cycle]
for r in filtered:
print('Title:', r.get('Title', ''))
print('Type:', r.get('Type', ''))
print('URL:', r.get('url', ''))
print('---')
Categorize the results:
Type: Customerpackages → Features- If a package titled "Deprecations and Breaking Changes" (
Type: Operational) is present, callnotion-fetchon itsurlto retrieve the page body, which lists the individual breaking changes and deprecations.
If a Cycle Demo Presentation link was provided in Step 1, read it now — see Reading a Figma Slides deck in .claude/skills/write-trn-feature-section/SKILL.md (Step 2) — and reconcile it against the Notion buckets, flagging anything present in one source but not the other.
Present the three-bucket list to the user:
"Here's what I found in the Notion packages page for
<release-handle>:Features: ... Breaking Changes: ... Deprecations: ...
[If a deck was read: "Cross-checked against the Cycle Demo Presentation — <matches / discrepancies>."] [If no deck was provided: "I didn't have the Cycle Demo Presentation to cross-check — please verify nothing is missing."]
Let me know if anything is missing or needs to be corrected before we proceed."
Wait for the user to confirm or amend the list.
Step 3: Create the branch
Run from the documentation/ repo root:
git checkout main
git pull origin main
git checkout -b release-notes/<release-handle>
Step 4: Check for new migrations
Use the GitHub MCP to list migration files in livingdocsIO/livingdocs-server at path db/migrations.
Compare the file list against the previous release's TRN (which you read in Step 1) to identify any migration files added since that release. Migration files follow the naming pattern NNN-description.js where NNN is a sequential number — anything with a higher number than the last one documented in the previous TRN is new.
If new migrations exist and are not already listed in the TRN, note them — you'll fill them into the Deployment section in the next step.
Step 5: Clean up the TRN file
Work through the sub-steps below in order. Some require user input before you can proceed.
Leave the
## Webinarsection untouched. The recording and slide links are filled in after the release is announced — don't remove or change anything there.
5a. Add confirmed Features, Breaking Changes, Deprecations
First, scan the existing ## Breaking Changes, ## Deprecations, and ## Features sections and note what's already documented. Then compare against the confirmed Notion list and only work on the gaps — items missing entirely or listed as "TODO"/incomplete.
For each missing item, add it to the appropriate section. Use the related PRs from the ## PRs to Categorize list to gather details — read the PR descriptions for context on what changed and why.
When writing a new Feature entry, follow the writing guidelines in .claude/skills/write-trn-feature-section/SKILL.md (Steps 3 and 4) — this covers format, tone, activation status, config blocks, and the :gift: emoji convention. During cleanup you won't have all the inputs that skill normally gathers (demo slides, screenshots, Notion requirement, doc links) — write the best entry you can from the PR alone, and for any inputs that are missing but would meaningfully improve the entry, add a checkbox to the PR's ## Open Tasks list rather than leaving a placeholder in the entry itself.
If items exist in the file already but are incomplete (e.g. listed as "TODO" or lacking description), flag them to the user and ask how to proceed.
5b. Update the Deployment / Migrations section
The file has a ## Deployment section with a #### Migrate the Postgres Database subsection.
- No new migrations: Leave the "No migrations are required for this release." text as is.
- New migrations found: Replace the no-migration placeholder with a shell code block listing each new migration with a short comment. Follow the format from
release-2025-03:
# run `livingdocs-server migrate up` to update to the newest database schema
# migration NNN-description.js
# short description of what this migration does
livingdocs-server migrate up
Also update the ### Rollback section to include livingdocs-server migrate down if migrations were added.
5c. Update the release link
Find this line near the top of the file (just after the ## Caveat section):
To get an overview about new functionality, read the [Release Notes](TODO).
To learn about the necessary actions to update Livingdocs to `release-XXXX-XX`, read on.
The [Release Notes](TODO) link should point to the public marketing release notes URL. The URL pattern is based on the release month name:
https://livingdocs.io/en/release-<month-name>-<year>
For example, release-2026-03 → https://livingdocs.io/en/release-march-2026.
Update the TODO with the correct URL.
5d. Clean up the "PRs to Categorize" section
Many features ship as a server PR + editor PR with the same title — treat these pairs as one item, not two.
Go through each PR listed under ## PRs to Categorize. For each one:
- If it belongs to a feature already in
## Features— remove it from the list. - If it's a dependency bump, backported bugfix, chore, or release management noise (titles like
fix(deps):,chore(deps):,Patch vulnerabilities,Bump minor version for release management) — remove it from the list. For any PR where the title doesn't make this obvious, fetch the PR body and check for a line likeBackport: release-YYYY-MM— if present, the PR is a backport and can be safely removed from the list. - If it looks like a Breaking Change not yet in
## Breaking Changes— add it to that section and remove it from the list. The number of breaking changes should match the version jump between releases. - If it's internal infrastructure (e.g. "Add 2026-05 version support to Public API") — ask the user whether it should be added to the Open Tasks list or just removed.
- If it doesn't fit any category and isn't noise — it may represent an undocumented feature or change. Flag it to the user: either add an entry for it in the appropriate TRN section, or reach out to the PR author to clarify what it covers. If the user wants to defer it, add it as a checkbox in an
## Open Taskssection on the PR usinggh pr edit.
Once all PRs have been handled, remove the entire ## Caveat block and the ## PRs to Categorize section.
5e. Update Vulnerability Patches
The ## Vulnerability Patches section has two subsections (Server and Editor) with a - TBD placeholder.
Use the GitHub MCP to search for merged PRs that have both the security label and the released on @<release-handle> label in both repos (substituting the actual release handle):
repo:livingdocsIO/livingdocs-server is:pr is:merged label:security label:"released on @release-2026-05"
repo:livingdocsIO/livingdocs-editor is:pr is:merged label:security label:"released on @release-2026-05"
Extracting the CVE list: Read the body of each matching PR and extract the vulnerability entries. The format for the TRN is:
- [CVE-XXXX-XXXXX / GHSA-xxxx-xxxx-xxxx](https://github.com/advisories/GHSA-xxxx-xxxx-xxxx) patched in <package> v<version>
Some entries may only have a GHSA identifier (no CVE) — that's fine, just omit the CVE-... / prefix. See older releases (already read in Step 1) for style reference.
Replace each - TBD placeholder with the extracted list. If a subsection has no patches, leave its - TBD in place. If neither subsection has any patches, also add a checkbox to the PR's ## Open Tasks section (do not mention it in the changelog).
Step 6: Commit, push, and open PR
Check what is staged before committing — only the TRN file should be included:
git status
git add content/operations/releases/<release-handle>.md
git commit -m "fix(<release-handle>): clean up technical release notes"
# The `fix` prefix is required — without it, no deployment is triggered.
# The release-handle is included only for readability.
git push -u origin release-notes/<release-handle>
Then create the PR using gh pr create:
- Title:
<release-handle>: Update Technical Release Notes - Base branch:
main - Body: Build the changelog from what was actually done during cleanup. Use this structure:
## Motivation
Cleanup of the technical release notes of the <release-handle>
_Implemented using the [cleanup-trn](/.claude/skills/cleanup-trn/SKILL.md) Claude Code skill._
## Changelog
**Release Notes Updates**
- <list each action actually taken, e.g.:>
- Added N features to the Features section
- Added X breaking changes
- Added Y deprecations
- Added migrations NNN-... (or: No new migrations)
- Removed N PRs from PRs to Categorize
- Updated release link
- Updated Vulnerability Patches section (omit this line if no patches were found yet)
Only add an ## Open Tasks section if there are unresolved PRs from Step 5d:
## Open Tasks
- [ ] <unresolved item>
Return the PR URL to the user.
Next.js App Router Expert
Development
A skill that turns Claude into a Next.js App Router expert.
README Generator
Development
Creates professional and comprehensive README.md files for your projects.
API Documentation Writer
Development
Generates comprehensive API documentation in OpenAPI/Swagger format.