spec-kitty upgrade lifecycle

Reference description of what spec-kitty upgrade modifies, in what order, and how its options interact. For task-oriented walkthroughs see Upgrade the CLI and Upgrade a project.

Two upgrade scopes

Spec Kitty has two distinct upgrade concepts:

Scope What it changes How
CLI The spec-kitty-cli Python package on PATH. pipx upgrade spec-kitty-cli, uv tool upgrade spec-kitty-cli, or pip install --upgrade spec-kitty-cli.
Project One project's .kittify/ + agent surfaces, to match the schema the installed CLI expects. spec-kitty upgrade inside the project root.

The CLI never silently upgrades a project. Projects never silently upgrade the CLI.

Synopsis

spec-kitty upgrade [OPTIONS]
Option Description
--cli Print CLI upgrade guidance only. Does not look for a project. Safe to run anywhere.
--project Run project migrations only; suppress the CLI nag banner. Errors outside a project.
--dry-run Show pending migrations without applying them.
--yes / --force Non-interactive confirmation. Does not bypass schema-incompatibility blocks.
--no-nag Suppress the upgrade-nag banner for this invocation only.
--target <version> Migrate to a specific intermediate schema version (rare; debugging only).
--json Emit a machine-readable plan / result.
--plan-json Emit the complete preview-only owner plan. Never applies changes.

--cli and --project together exit with code 2 (mutually exclusive).

What gets modified

Project upgrade walks pending migrations in version order. For each migration, it may:

  1. Read .kittify/config.yaml to learn which agents are configured. Migrations are config-aware and only touch directories for agents you have enabled.
  2. Refresh agent command directories for configured agents (.claude/commands/, .agents/skills/spec-kitty-*/, .amazonq/prompts/, etc.) from the CLI's bundled source templates.
  3. Update .kittify/ scaffold files — memory/, command-skills-manifest.json, and config schemas — to the new layout.
  4. Bump .kittify/metadata.yaml to record the new schema version after each migration step.
  5. Leave user data alone — kitty-specs/, architecture/, docs/, src/, and anything else you author is untouched.

Migrations are idempotent: re-running spec-kitty upgrade is a no-op when the schema is current.

Generated, git-ignored command skills (.agents/skills/)

The shared command-skill projection .agents/skills/spec-kitty-<command>/SKILL.md — consumed by Codex, Mistral Vibe, Pi, Letta, and Google Antigravity — is generated, local-only state. It is declared DERIVED / git-IGNORED by the state contract (shared_skills_projection), so it is never committed. Do not stage or commit the .agents/skills/ tree as normal project content; its ownership record is .kittify/command-skills-manifest.json, which a project may commit.

Because the projection is derived, init, upgrade, and spec-kitty agent config sync regenerate it idempotently to the canonical render:

  • A projection that already equals the current render is left byte-unchanged.
  • A stale or drifted projection — for example one written by an older build, or one that disagrees with a manifest another checkout rewrote — is regenerated to the canonical render, not treated as a local edit requiring consent (#702). This keeps .agents/skills/ coherent with the manifest after every reconcile and spec-kitty doctor skills green.
  • A hand edit to a spec-kitty.* command skill is replaced the same way. Put customizations in a skill of your own.
  • Your own, non-spec-kitty skills and files under .agents/skills/ are never touched.
  • Each regenerated projection is named once: Regenerated a generated command skill that differed from the current version: <path>. upgrade --json lists these paths under surface_repair.regenerated, and spec-kitty agent config sync --json under regenerated (without the human line). A regenerated skill counts as installed in the N command skills installed line. The exit code is unchanged (#6155).
  • The regenerate only runs while the state contract still declares shared_skills_projection DERIVED and git-IGNORED. If it does not, or the surface is missing, a drifted projection is kept and reported for consent, like any other managed surface.
  • A retired command's drifted projection is removed together with its manifest entry. A directory at that path is refused, a path the manifest does not own is never touched, and a projection another configured agent still owns is left in place.

Fresh clone: .agents/skills/ is absent until it is produced by init/upgrade, or restored with spec-kitty agent config sync --create-missing. Its absence is expected, not a defect; the manifest describes what will be regenerated.

After migration selection, one guarded finalizer orders activation provisioning, managed-surface repair, and the generated-churn commit. When hosted drain is on, upgrade only reports TeamSpace mission-state blockers (last, never committed); it never repairs. The repair runs only via spec-kitty doctor mission-state --fix. Owner preconditions are rechecked immediately before writes; a changed input requires reassessment rather than replaying stale prepared bytes.

What does not get modified

  • Git state: no commits, no stages, no branches.
  • kitty-specs/: every mission directory, spec, plan, task file, and status event log is preserved.
  • Agent directories that are not in config.yaml: if you removed .gemini/ and never added gemini back to config, the migration will not recreate it.
  • User-authored content under architecture/, docs/, src/, etc.
  • Environment variables, PATH, shell config.

Lazy compatibility gate

When the project schema does not match the installed CLI, commands like spec-kitty next and spec-kitty implement are blocked until you upgrade.

Schema state Exit code Remediation
Up to date 0 None.
Project older than CLI 4 spec-kitty upgrade
Project newer than CLI 5 Upgrade the CLI (pipx upgrade spec-kitty-cli). --yes does not bypass this.
Metadata corrupt 6 Check .kittify/metadata.yaml exists and is valid YAML.

Commands that are always allowed regardless of schema:

spec-kitty --help
spec-kitty --version
spec-kitty upgrade --dry-run   # always allowed
spec-kitty upgrade --cli       # always allowed

After the project schema is compatible, inspect the current Mission's work packages with:

spec-kitty agent tasks status --mission <mission>

When is a project upgrade required?

After a CLI upgrade, a project upgrade is required only when migrations have rolled since the project's recorded schema. Many patch releases roll no migrations and require no project upgrade.

Check ahead of time with:

spec-kitty upgrade --dry-run --json | jq '.pending_migrations'

An empty list means no project upgrade is needed.

Reviewing generated changes

Project upgrades modify version-controlled files. Inspect with git before committing:

git status
git diff .kittify/ .claude/ .gemini/

.agents/skills/ is git-ignored generated state (see above), so it does not appear in git diff; review it on disk and rely on spec-kitty doctor skills for its coherence.

Typical changes:

  • New or updated files under each configured agent directory (templates refreshed).
  • .kittify/metadata.yaml schema bump.
  • Occasionally .kittify/config.yaml schema migrations.

spec-kitty upgrade commits the files it changed itself when auto_commit is enabled (the default), and only those files; your own uncommitted work is left alone. If it reports that its changes were left uncommitted (auto-commit disabled, a hook rejected the commit, or files held for manual review), review them with git status and git diff, then stage the listed files by name:

git add -- .kittify/metadata.yaml <other files git status lists>
git commit -m "chore: upgrade Spec Kitty project to <version>"

Or use spec-kitty safe-commit <those files> -m "chore: upgrade Spec Kitty project to <version>".

Upgrade nag

When a newer CLI is available on PyPI, spec-kitty prints a single banner before normal output:

Spec Kitty 3.2.1 is available; you have 3.2.0.
Upgrade with: pipx upgrade spec-kitty-cli

Behaviour:

  • Throttled to once per 24 hours by default.
  • Configurable via SPEC_KITTY_NAG_THROTTLE_SECONDS=<seconds> or ~/.config/spec-kitty/upgrade.yaml → nag.throttle_seconds.
  • Disable per invocation with --no-nag; per session with SPEC_KITTY_NO_NAG=1.
  • Automatically suppressed in CI (CI=1) and when stdout is not a TTY.
  • Suppressing the nag never bypasses the compatibility gate — incompatible projects still exit 4 or 5.

JSON output

--json returns a structured plan / result.

spec-kitty upgrade --dry-run --json | jq .case
# "project_migration_needed"

spec-kitty upgrade --dry-run --json | jq -r '.upgrade_hint.command'
# pipx upgrade spec-kitty-cli

spec-kitty upgrade --dry-run --json | jq '.pending_migrations | length'
# 0

Schema is stable across patch releases.

--plan-json uses kitty-specs/upgrade-preview-mission-health-01M1V6E1/contracts/upgrade-plan.schema.json. It retains the full envelope for refusals and exposes complete, diagnostics, effects, dispositions, execution artifacts, and commit policy. The report is informational, not an apply token. Legacy --json shapes remain unchanged.

Examples

# Show CLI upgrade hint, anywhere
spec-kitty upgrade --cli

# Preview project migrations
spec-kitty upgrade --dry-run

# Apply project migrations non-interactively (CI)
spec-kitty upgrade --yes

# Project-only upgrade, no nag, JSON for tooling
spec-kitty upgrade --project --no-nag --json

See also