| name | releases |
| description | Read, synthesize, diagnose, clean, author, and publish the optional RELEASES.md planning ledger through one routed workflow. Use for /releases; release status or health checks; stale-plan review against merged PRs, commits, and CHANGELOG entries; disciplined release creation or updates; ledger cleanup; historical anchors or backfill; publishing a planned GitHub Release; or deciding whether Radar or Finish Line is the better follow-up. Default invocation is read-only and every write or publication requires a preview and confirmation. |
/releases — one release-planning router
Treat RELEASES.md as an optional forward-looking planning ledger, never as a second
CHANGELOG.md. Start every invocation by reading and synthesizing the ledger. Route into a mutating
subroutine only when the operator explicitly chooses or requests one.
Routes
/releases read-only synthesis, findings, and relevant route choices
/releases check [window] refresh the evidence-backed health assessment
/releases clean [version|active] preview a spec-aligned cleanup
/releases plan [version] create or explicitly update an upcoming release
/releases anchor <version...> add only the named shipped historical anchors
/releases backfill show eligible historical anchors as an optional menu
/releases publish <version> publish one planned entry to GitHub
Natural-language requests route the same way. Do not make the operator remember the route names.
The DB's second subsystem — the ROADMAP shadow (GH-69)
releases.db also mirrors ROADMAP.md's ledger (roadmap_items, one-way, lossless). This skill
does not own roadmap edits — ROADMAP.md stays the human file — but if a task you are part of
edited that ledger, finish with releases roadmap sync (a no-change sync is a free no-op;
--dry-run previews, roadmap list reads back). Contract: RELEASES-DB-FAQS.md.
Preflight
-
Resolve the repository root. Require utils/pdda/pdda.sh; stop if PDDA is absent because there
is no fallback release-ledger format.
-
Detect the ledger backend (GH-32). If releases.db exists at the repository root, this repo
is app-managed: the SQLite database is the source of truth, RELEASES.md is on its way to
becoming generated output, and every mutation this skill performs MUST go through the
releases CLI (utils/py/releases_app.py) — never a direct edit of RELEASES.md. A direct
edit in an app-managed repo is overwritten by the next generation and desynchronizes the dump;
refuse to make one even if asked, and point at the CLI instead. If releases.db is absent, this
is a legacy-managed repo and the direct-edit procedures below apply unchanged.
-
Read PROJECT/PDDA.md's RELEASES.md — release ledger contract, RELEASES.md, and
CHANGELOG.md. A missing, empty, sparse, or apparently old ledger is valid. In an app-managed
repo, also run releases check and surface any findings before proceeding.
In an app-managed repo, read the ledger through the CLI's readers, not raw SQL. All three
are read-only, take no lock, and mutate nothing:
releases next [--verbose] the next unshipped release, by target date
releases show --version 0.6.0 one full record (or --gid; --full disables elision)
releases list [--status ...] one line per release (--all-repos aggregates siblings)
There is no generated Markdown mirror of the database to read: RELEASES-PREVIEW.md was removed
2026-08-19. For a whole-ledger view, use releases list, open releases.db in a SQLite viewer,
or read the release cards releases project sync (GH-39) pushes to GitHub Projects.
After any merge that touched the ledger, run releases check before anything else. The
merge procedure resolves releases.sql as text and then requires releases check --rebuild to
regenerate the DB from it; skipping that leaves a DB that disagrees with the dump, and the DB is
what every reader above trusts. test/gh32-releases-artifacts.sh gates this on every full-suite
run, but it catches the mistake after the fact — checking first is cheaper. Never run
to make a red check go away without reading what diverged: it is for merge
resolution only, never crash recovery. See .
Default route — read and synthesize
Run this route before every other route unless the same invocation already established fresh state.
- Run
utils/pdda/pdda.sh releases and utils/pdda/pdda.sh releases-current. Preserve their
warn-only semantics.
- Select the evidence window: use an operator-supplied window, otherwise 21 days. Resolve the
active integration branch from repo policy (
development in this repo; otherwise the declared
WIP branch, then main/master). State the exact dates and branch.
- Read reachable non-merge commits plus merged and closed-unmerged PRs targeting that branch during
the window. Use merged PRs as completion evidence. Surface a closed-unmerged PR only when it
contradicts a block's claim that work is in flight or materially changes the cleanup decision.
A push is transport, not evidence; count the commits that reached the branch. Read exact
bracketed versions and dated entries from
CHANGELOG.md.
- When GitHub is available, inspect matching releases, milestones, and manifest issues. Verify PR
base branches and merge state before using them as evidence.
- Summarize, without dumping the file:
- shipped entries;
- active and upcoming entries, target dates, iteration bands, and milestones;
- strong inconsistencies and advisory drift signals;
- description or manifest discipline warnings;
- evidence that could not be obtained.
- Offer only routes relevant to the findings or the user's stated goal. Make no writes.
Staleness and drift rules
Call something stale only when evidence contradicts a block, not because the ledger is sparse or
has not changed recently.
Treat these as strong inconsistencies:
CHANGELOG.md records the exact version as shipped while the block remains unshipped.
- A GitHub Release exists but
GH_URL: is empty, points elsewhere, or Status: contradicts the
actual publish state.
Target Date: is past while Status: is not Shipped.
- A block says work is open, absent, or unbuilt while a merged PR, reachable commit, or canonical
project document proves the opposite.
- Iteration bands overlap or a non-owner release sits inside another block's band.
Treat these as advisory drift signals:
- Recent merged work materially follows a different theme than an active description.
- A manifest contains replaced, duplicated, unrelated, or silently added scope.
- A target date no longer fits explicit dependencies or the observed delivery rate.
Do not infer shipment from a closed-but-unmerged PR, an issue closure alone, a branch push, a commit
on an unmerged branch, or a populated GH_URL: that points to a draft.
Discipline and abuse warnings
Warn, without blocking, when:
Description: exceeds four sentences, becomes multi-paragraph execution history, or duplicates
CHANGELOG.md. Recommend a one-to-four-sentence theme and move history to CHANGELOG.md and
implementation detail to the canonical PROJECT/** document.
Manifest: names more than seven issues. The count triggers review, not condemnation.
- A manifest mixes unrelated themes, lacks a fixed denominator, grows without a dated re-scope,
crosses several release dependencies, or has no runnable/observable exit criterion.
- A block copies an issue inventory that should be represented by the
Milestone: join key.
Explain which signal fired. Never call a large manifest abusive solely because of its issue count.
Clean subroutine
- Default to active/unshipped blocks. Touch a shipped block only when the operator explicitly names
it.
- Propose the smallest cleanup that restores the documented shape: compact descriptions, preserve
theme and dependencies, reduce manifests to a fixed list or milestone pointer, preserve dated
re-scope decisions, and move historical narrative to
CHANGELOG.md or execution detail to its
existing project doc. Never create a new doc merely to shorten the ledger.
- App-managed repo: render the cleanup as the exact
releases update --gid <id> ... (and
releases manifest ... / legacy-line disposition) command set, preview those commands, and get
one confirmation. On confirmation run them, then releases gen --side-by-side and report the
drift. The CLI's own preimage/lock handling replaces the hash dance below.
- Legacy-managed repo: record the file hash before preview. Render the exact patch and get one
confirmation. Immediately before writing, re-read
RELEASES.md and compare its hash. If it
changed, discard the patch, synthesize again, and preview a new patch. Edit only the confirmed
blocks. Never reorder unrelated blocks.
- Run
utils/pdda/pdda.sh releases and report every finding.
Plan or update subroutine
- Apply the admission rule. A block earns a place only when it represents a named arc worth
planning toward. A restatement of shipped changes belongs only in
CHANGELOG.md. A version inside
another block's Iterations: band is already accounted for.
- If no version was supplied, compare the highest bracketed
CHANGELOG.md version with the highest
ledger version. Propose the next semantic version and explain the patch/minor/major judgment; let
the operator override it.
- Ask only for unanswered fields:
- status;
- optional iteration band;
- target date or blank/TBD;
- optional codename;
- optional GitHub milestone title;
- a one-to-four-sentence description of the theme;
- optional concise manifest;
- optional executable or observable exit criterion;
- optional QA fields (
Front-door reviewed, Shakedown reviewed, License file).
- Draft the flat block below, omitting blank optional fields except
GH_URL: when publication is
expected:
Release: 1.2.0
Iterations: 1.2.0-1.2.4
Status: Draft
Target Date: 2026-12-01
Codename: Example
Description: One coherent release theme in no more than four sentences.
Exit criterion: `command --that-proves-the-release` exits 0.
Manifest: FROZEN YYYY-MM-DD — #101, #102, #103.
GH_URL:
Milestone: Example
Front-door reviewed: No
Shakedown reviewed: No
License file: Yes
- App-managed repo: preview the equivalent
releases add ... (or releases update --gid ...)
command set — including the required tracking issue (a real URL, or a TMP- ref if GitHub is down)
— and get one confirmation, then run it. Legacy-managed repo: preview the complete new or
replacement block and get one confirmation. Re-check the file hash before writing. Append new blocks
after the last block; replace only an explicitly selected existing block. Never silently edit
neighboring blocks.
- Run
utils/pdda/pdda.sh releases and report findings.
Anchor and backfill subroutine
Run only when explicitly requested.
- For
anchor, draft exactly the shipped versions the operator named. Trace each one-line summary
to its bracketed CHANGELOG.md section and set Status: Shipped. In an app-managed repo the
draft is a previewed releases add ... + releases ship ... command pair, not a file patch.
- For
backfill, show bracketed CHANGELOG.md versions that are not already represented and do not
sit inside an existing iteration band. Present them as an optional menu, never as missing work.
Draft only the versions the operator selects; drafting none is valid.
- Never initiate either route because the ledger looks incomplete.
Publish subroutine
- Require
gh authentication and a specific existing release block. Stop if it is already
Shipped. If GH_URL: exists but status is unshipped, inspect the existing Release and ask how
to handle the draft or conflicting object.
- Run
utils/pdda/pdda.sh releases and surface its findings.
- Build release notes from the block's
Description: plus concise codename, exit-criterion, and
manifest context when useful. Never invent notes. Ask for missing release-facing prose.
- Preview together:
- the exact
gh release create <version> --title ... --notes ... action;
- the full release body;
- the
GH_URL: and Status: Shipped write-back.
- Get one explicit confirmation, publish live, and capture the returned URL. If creation fails,
report the error verbatim and make no ledger edit.
- On success only: app-managed repo — write back via
releases update --gid <id> --gh-release-url <url> and releases ship --gid <id> --evidence ...
(never a direct file edit); legacy-managed repo — re-check the file hash, write the returned
URL, set Status: Shipped. Then run utils/pdda/pdda.sh releases either way.
- Remind the operator that shipped history and lessons belong in
CHANGELOG.md; do not write that
entry unless separately asked.
Complementary routing
Offer at most one goal-matched follow-up; do not append generic reminders.
- Offer
/radar when the question is whether recent work, recurring defects, and release themes are
strategically aligned. State that Radar is broader than this ledger check and owns its own report
workflow. Never copy Radar's analysis into this skill or invoke it automatically.
- Offer
/finish-line when the operator has selected a release checkpoint and wants a frozen,
shortest safe path to ship it. State that Finish Line owns the done-list and parking workflow.
Never invoke it automatically.
- Stay within
/releases when the task is ledger synthesis, cleanup, authoring, or publication.
Guardrails
- Default to read-only synthesis.
- In an app-managed repo (
releases.db present) every mutation goes through the releases CLI;
never edit RELEASES.md directly there. Preview the exact command set instead of a patch — the
confirmation UX is unchanged, only the write path moves.
- Preview every file mutation and public action; obtain one confirmation per atomic write/publication
group.
- Re-read before writing and refuse stale patches.
- Never top up the optional ledger, fabricate release notes, or treat absence as failure.
- Keep
CHANGELOG.md authoritative for shipped history and PROJECT/** authoritative for execution
detail.
- Use repo-relative paths in edited documents.
- Never create, edit, install, or synchronize a Codex skill from this workflow.