Skip to content

Updating and Versioning

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

Updating & Versioning

FeatherSpec is versioned, and projects created from it can update safely — including projects that have customized everything. Two ideas carry the whole mechanism:

  1. The version number is a migration signal. Template-semver: MAJOR means a derived project needs a real migration step (files move or are renamed, a command contract changes, a document schema is invalidated). MINOR means additive capability that merges in around your customizations. PATCH means wording and docs fixes. Releases are annotated git tags (v1.2.0, …) surfaced as GitHub Releases; CHANGELOG.md records them.
  2. Updates never destroy project knowledge. The updater compares three real states of every file — the template version you started from, the target version, and your copy — and whatever that comparison cannot prove is asked, never assumed. Your Memory Bank, specs, architecture maps, README and every customization are provably untouched or explicitly confirmed.

Which version am I on?

/sdd-featherspec-update check

Projects adopted from 1.2.0 onward carry one line in AGENTS.md's managed settings block:

FeatherSpecVersion: 1.2.0 # managed by /sdd-featherspec-update; do not edit by hand

Older projects have no stamp — check then estimates the version from feature probes (which commands and sections exist), and says so. Heavy customization can blur the estimate; the update run confirms it precisely by matching your files against the release tags before anything happens. check never writes and only reaches the network if you say yes to the latest-version lookup.

Updating

/sdd-featherspec-update

Optionally name a target version after the command; the default is the latest release. The workflow — identical in Claude Code and Copilot agent mode — walks through:

  1. Situate — find your constitution, read version + DocLanguage, detect which tool halves exist (deleting one per Committing to One Tool is fully supported), require a clean working tree.
  2. Fetch — one confirmed step clones your base version and the target into .sdd-update/ (gitignored, volatile). Both trees are validated against their tags.
  3. Classify — every file is hashed canonically (line endings and trailing whitespace never count as your edits) and sorted: unchanged · never-touched-by-you (auto) · already current · merge · conflict · new · removed. Files you deleted are never resurrected; files the updater does not know are invisible to it.
  4. Preview — one summary of everything before anything is written, exactly in the shape of issue #5: N new, N migrated, N conflicts, N pinned. One yes covers the safe batch; deletions, conflicts, slot edits and semantic flips stay individual questions.
  5. Apply — conflicts offer five answers: keep mine (optionally pin the file so future updates only report it) · take template (yours goes to the backup) · merge (draft shown first) · review manually · rename mine (for name collisions with your own commands — renames body, loader and table row together).
  6. Validate — mechanical checks, including the proof that the never-write set (.memory-bank/, .specs/ content, .architecture/, README.md, …) is byte-identical to before.
  7. Finalize — the version stamp moves last, so an interrupted run always resumes cleanly (/sdd-featherspec-update again — the files decide where it continues, not the conversation). A backup branch (featherspec-backup/pre-<version>) is your rollback.

Skipped many versions? One run covers the whole distance — file contents merge endpoint-to-endpoint, while per-version migration knowledge (renames, key migrations, data notes) replays in order from the version ledger.

After an update that added prompt files: VS Code needs a full restart to discover them (Claude Code does not). /sdd-overview verifies the result.

Installing the updater into an existing project

Projects adopted before 1.2.0 do not have the command yet. Copy two files from the template into your repo — that is the whole install:

  • .claude/commands/sdd-featherspec-update.md (the workflow)
  • .github/prompts/sdd-featherspec-update.prompt.md (skip if you deleted the Copilot half; restart VS Code afterwards if you kept it)

Any copy is good enough: on its first run the updater fetches the latest release and follows the newest version of itself. You do not need to commit the copied files first — the updater recognizes its own freshly installed files and includes them in its final commit.

Copilot-ejected repositories (you merged the command bodies into .prompt.md files): paste the body's content into a new .github/prompts/sdd-featherspec-update.prompt.md. The updater detects the ejected shape and runs in advisory mode — it stages the new version and guides you file by file instead of writing automatically. Never destroys, guided rather than automatic.

What the updater will never do

  • Touch .memory-bank/, .specs/ content, .architecture/, your README.md, LICENSE, docs/, or any *.local.* file — the never-write set is hashed before and proven identical after.
  • Resurrect files you deleted, or delete files it does not know.
  • Replace AGENTS.md wholesale — it merges section by section around your DocLanguage, your style preferences, your architecture: snapshot and your own command-table rows.
  • Write a conflict marker into live wiring, or move the version stamp before validation passed.

For the design reasoning — why fetched trees instead of a manifest, why the stamp lives in AGENTS.md, why tags never move — see Design Decisions. For cutting a release as the template author (or in a fork), see Releasing.

Clone this wiki locally