release-notes — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited release-notes (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Generate release notes for a release PR. Brief, truth-based, no fabrication.
_On startup, use the Read tool to load ~/.claude/skills/release-notes/preferences.md._
Tracker-agnostic — works with any issue tracker (Linear, Jira, GitHub Issues, Asana, ClickUp, Shortcut, Plane, Notion, custom). You configure two things: how to detect ticket IDs in PR bodies, and how to link them.
Expected keys:
- ticket-prefix: <PREFIX> # Optional. Tracker key — e.g., ENG, PROJ, ABC, JIRA. Used to detect IDs as <PREFIX>-NNNN. If unset, falls back to the generic regex [A-Z]{2,5}-\d+ (any uppercase prefix + dash + digits).
- ticket-url-template: <url-with-{TICKET}> # Optional. URL template with literal `{TICKET}` placeholder. Examples:
# Linear: https://linear.app/myorg/issue/{TICKET}
# Jira: https://myteam.atlassian.net/browse/{TICKET}
# GitHub Issues: https://github.com/myorg/myrepo/issues/{TICKET}
# Asana: https://app.asana.com/0/{TICKET}
# Shortcut: https://app.shortcut.com/myorg/story/{TICKET}
# Plane: https://app.plane.so/myorg/projects/.../issues/{TICKET}
# If unset, ticket IDs render as bare text without links.Behavior when keys are missing:
ticket-prefix → use the generic regex [A-Z]{2,5}-\d+. Works for most trackers.ticket-url-template → render bare ticket IDs (e.g., Closes ENG-1234.). Mention once at the end: "Set ticket-url-template in preferences.md to enable clickable ticket links."## Summary, not its full body.$ARGUMENTS is a number → that's the PR.gh pr list --base prod --state open --limit 5 --json number,title,headRefName and ask the user which one if multiple, or use the only open one.number, title, baseRefName, headRefName, url.gh pr view <release-pr> --json commits --jq '.commits[].messageHeadline'Each squash-merged commit headline ends in (#NNN) — extract the PR numbers. If commits is sparse (squash-merge collapsed history), fall back to:
git log origin/<base>..origin/<head> --onelineand grep (#\d+) from the headlines.
For each PR number, in parallel:
gh pr view <num> --json title,body,number,url,labelsExtract from each:
title (use as section heading after stripping conventional-commit prefix if helpful)## Summary paragraph (or first 1-3 sentences of the body if no Summary section)<TICKET-PREFIX>-NNNN (where TICKET-PREFIX comes from preferences, falling back to [A-Z]{2,5}-\d+). When ticket-url-template is set, substitute {TICKET} to build the link; otherwise render the bare ticket ID.#NNN link, GitHub auto-links)If a PR's Summary is more than ~3 sentences, halve it, then halve again. Keep only the user-visible/product-visible bits. Cut implementation prose ("service-side normalizers", "Zod widens", file paths) unless that is the product change.
Template:
## What's in this release
**1. <Short topic — strip cc-prefix> — #<PR>**
<1–3 sentence summary, sourced from the PR body. User-visible framing.>
Closes [<TICKET>](<ticket-url-template with {TICKET} substituted>)<` · [<TICKET-2>](...)` if multiple>. If no template configured, render as `Closes <TICKET>.` (no link).
**2. <Short topic> — #<PR>**
<1–3 sentences.>
Closes [<TICKET>](...).
## How to test
- <One bullet per PR — pulled from that PR's test plan, simplified to the manual-verify path.>
- <...>If — and only if — a source PR explicitly flags a follow-up that blocks prod (deploy ordering, flag flip, infra step), add:
## Follow-ups
- <The blocking item, verbatim from the source PR.>Otherwise, skip the Follow-ups section. Do not invent follow-ups.
Format: Release YYYY-MM-DD — <2–6 word theme>
The theme should name the 1–2 biggest user-visible changes (e.g., "PMI UI + migration cleanup"). Use today's date.
Print the full proposed title + body to the user. Then ask:
Push this to PR #<num>? (yes / edit / no)
gh pr edit on this org): gh api -X PATCH "repos/<org>/<repo>/pulls/<num>" \
-f title="<title>" \
-F body=@/tmp/pr-<num>-body.md \
--jq '"OK: " + .title + " — " + .html_url'Try gh pr edit first if you prefer; if it errors with Projects (classic) is being deprecated, fall back to the REST call above. The edit does not land on the GraphQL failure — always verify via gh pr view <num> --json title --jq .title.
After push, gh pr view <num> --json title,body --jq '.title' to confirm the edit landed. Report the URL.
#NNN links rather than splitting.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.