Skip to content

Releasing

Gregor Biswanger edited this page Aug 26, 2026 · 1 revision

Releasing

How a FeatherSpec release is cut. This page is written for the AI agent doing the work: give it to your assistant and say "cut release X.Y.Z" (or "prepare a release" and let it propose the number). It applies to the template repository and to forks that maintain their own template. It is never shipped into derived projects.

The mechanism it feeds is described in Updating & Versioning: derived projects identify their version by the FeatherSpecVersion: stamp and migrate by comparing real release trees plus the version ledger. Every rule below exists so that that comparison stays truthful. Time budget: 10–20 minutes for an additive release, 30–45 when structural operations require the rehearsal.

Invariants (never break these)

  1. A published tag never moves. Fix mistakes with a new patch release, never by re-tagging.
  2. Release = the tagged commit, window = zero. The stamp bump, the ledger entry and the changelog section land in the same change set as the feature (in the feature PR, or the final direct commit), and that commit is tagged. Between releases, main receives only never-write surface (README, wiki-mirrored prose) — wiring that sits unreleased on main gives every "Use this template" adopter a false baseline.
  3. The stamp on main always equals the latest tag, and every tag's own tree carries a matching stamp plus a ledger entry for its version — the updater verifies both on every fetch and aborts loudly on mismatch.
  4. The ledger is append-only. One entry per release in .claude/commands/sdd-featherspec-update.md's appendix, even if it is only - none.

Choosing the version number

The ledger operations decide the bump — not diff size, not marketing:

Bump When 10-second test
MAJOR Derived projects need a conscious migration: wiring files move/rename/delete, a command changes its invocation contract, a user-held document schema is invalidated, a slot-bearing AGENTS.md anchor moves the entry carries renames:, deletes:, or invalidating data-notes:
MINOR Additive capability that merges around preserved user slots: new commands, rules, agents, folders, constitution sections; guarded slot-edits: only adds:, additive section-renames:, key-migrations:, slot-edits:
PATCH Wording and docs fixes; in-place overwrite; no new surface, no gate-semantics shift - none beyond content refresh

Marketing lives in the release title ("FeatherSpec 1.2 — Versioned & Updatable"), never in the number.

The ritual

  1. Diff review. git diff v<previous>..HEAD (or the PR diff). From it, draft the ledger entry in the appendix's vocabulary (adds: · renames: · deletes: · key-migrations: · section-renames: with formerly: · slot-edits: · data-notes: with detect/offer · semantic-flips: · probes:) and propose the bump from the table above. The author ratifies both.
  2. Release contents into the change set. In the same commit/PR as the feature: bump FeatherSpecVersion: in AGENTS.md · append the ledger entry · add the CHANGELOG.md section (Keep-a-Changelog, plus the compare link at the bottom).
  3. Mechanical self-check. Stamp equals the intended tag · ledger entry present · every new command is complete (body + loader + AGENTS.md table row + frontmatter mirrored across all three) · scout twin bodies byte-identical · AGENTS.md under its line target · no content relies on trailing whitespace · wiki impact list drafted (step 6).
  4. Tag locally, then rehearse. git tag -a vX.Y.Z -m "FeatherSpec X.Y.Z — <title>" on the release commit. Rehearsal — mandatory when the entry carries structural ops (renames:, deletes:, section-renames:, slot-edits:, semantic-flips:), optional otherwise: export the previous tag into a scratch folder (git archive or degit), add one deliberate customization (edit a command body, add a style bullet), then run /sdd-featherspec-update in the scratch project with the local template path as the source — the updater accepts local paths exactly for this. Green means: customization preserved, changes applied, stamp moved, validation passed. A failed rehearsal: fix, re-commit, delete and re-set the local tag — it was never published, so invariant 1 is untouched.
  5. Publish on green. git push --follow-tags, then create the GitHub Release from the tag with the changelog section as notes: gh release create vX.Y.Z --title "FeatherSpec X.Y.Z — <title>" --notes "<changelog section>".
  6. Wiki impact pass. Walk the checklist: Commands (new/changed command sections and the command count) · Getting Started (counts, install notes) · Repository Layout (file list) · Updating & Versioning (anything the release changes about updating) · Extending FeatherSpec (reserved names) · Committing to One Tool (conversion tables) · Configuration · FAQ · Troubleshooting · Home + sidebar for new pages. Skip pages the release does not touch; say which.

Retroactive tags (historical record)

The pre-1.2.0 history was tagged retroactively on 2026-08-26 — annotated tags marked "(retroactive)", exempt from the stamp-equals-tag check because the stamp did not exist yet:

Tag Commit Anchor
v0.1.0 c43dcd0 bootstrap burst complete
v0.2.0 6566a88 adaptive product-owner interview
v0.3.0 578366f skills → commands, persisted plans (breaking, pre-1.0)
v0.4.0 8edeb9a /sdd-clarify + closed verification chain
v1.0.0 379d861 stabilization; confirmed by the three-week quiet period
v1.1.0 6013c45 brownfield deep scan

The deep scan is 1.1.0, not 2.0.0, on purpose: it is purely additive, and spending MAJOR on an additive release would teach users that major bumps are safe to take blindly — destroying the signal exactly when the first real breaking restructure needs it. 2.0.0 stays reserved.

Clone this wiki locally