Bug Description
Re-running specify init --here --force regenerates integration skill files from the bundled core but does not reapply installed presets. The preset registry (.specify/presets/.registry) and specify preset list still report the preset as installed/enabled, while the materialized skill file on disk has silently reverted to the pristine core version. The registry and the on-disk state diverge with no warning.
specify integration upgrade <key> --force behaves differently (it preserves the preset-composed output), so init --here --force is asymmetric with the upgrade path.
Steps to Reproduce
-
Create an empty project and initialize spec-kit:
mkdir demo && cd demo && git init -q && git commit -q --allow-empty -m init
specify init --here --integration claude --script sh --ignore-agent-tools --force
sha256sum .claude/skills/speckit-specify/SKILL.md # record core hash (A)
-
Create a minimal dev preset that wraps speckit.specify:
presets-src/demo-wrap/preset.yml
schema_version: "1.0"
preset:
id: "demo-wrap"
name: "Demo Wrap"
version: "1.0.0"
description: "Wraps speckit.specify with a preamble"
author: "demo"
license: "MIT"
requires:
speckit_version: ">=0.1.0"
provides:
templates:
- type: "command"
name: "speckit.specify"
file: "commands/speckit.specify.md"
description: "Wrap speckit.specify with a preamble"
strategy: "wrap"
presets-src/demo-wrap/commands/speckit.specify.md
---
description: "Wrapped speckit.specify"
strategy: wrap
---
<!-- demo preamble -->
{CORE_TEMPLATE}
-
Apply it and confirm composition works:
specify preset add --dev ./presets-src/demo-wrap
sha256sum .claude/skills/speckit-specify/SKILL.md # composed hash (B), contains preamble + full core body
-
Re-run init:
specify init --here --integration claude --script sh --ignore-agent-tools --force
sha256sum .claude/skills/speckit-specify/SKILL.md # back to core hash (A) — wrap is gone
specify preset list # still shows demo-wrap as installed (Templates: 1)
cat .specify/presets/.registry # still lists demo-wrap as enabled
Reproduced twice from scratch with identical results.
Expected Behavior
After init --here --force regenerates the integration files, installed presets should be re-composed on top of the fresh core (or, at minimum, the CLI should warn that installed presets are no longer applied / mark them accordingly), so that preset list never reports a preset as active while the files on disk are pure core.
Actual Behavior
The materialized skill file reverts to the core version while the preset registry still reports the preset as installed and enabled. There is no warning. Recovery attempts:
specify preset add --dev ... again → fails with Error: Preset 'demo-wrap' is already installed. Use 'specify preset remove ...' first.
specify preset disable → enable → no re-composition (output itself says "Previously registered commands/skills remain active until preset removal")
specify preset set-priority → no re-composition
The only working recovery is the two-step specify preset remove demo-wrap → specify preset add --dev ./presets-src/demo-wrap.
Interestingly, specify integration upgrade claude --force --script sh re-applies while keeping the preset composition intact (verified twice), so only the init path loses it.
Specify CLI Version
0.15.2
AI Agent
Claude Code
Operating System
macOS 15 (Apple Silicon, Darwin 25.5.0)
Python Version
3.14.6
Additional Context
Possibly related but distinct: #3849 fixed integration upgrade --force overwriting extension/preset-derived SKILL.md content (PR #3853); that fix touches the upgrade path only, and in 0.15.2 the upgrade path indeed preserves the composition — it is the init --here --force path that reverts it while leaving the registry stale.
Bug Description
Re-running
specify init --here --forceregenerates integration skill files from the bundled core but does not reapply installed presets. The preset registry (.specify/presets/.registry) andspecify preset liststill report the preset as installed/enabled, while the materialized skill file on disk has silently reverted to the pristine core version. The registry and the on-disk state diverge with no warning.specify integration upgrade <key> --forcebehaves differently (it preserves the preset-composed output), soinit --here --forceis asymmetric with the upgrade path.Steps to Reproduce
Create an empty project and initialize spec-kit:
Create a minimal dev preset that wraps
speckit.specify:presets-src/demo-wrap/preset.ymlpresets-src/demo-wrap/commands/speckit.specify.mdApply it and confirm composition works:
specify preset add --dev ./presets-src/demo-wrap sha256sum .claude/skills/speckit-specify/SKILL.md # composed hash (B), contains preamble + full core bodyRe-run init:
Reproduced twice from scratch with identical results.
Expected Behavior
After
init --here --forceregenerates the integration files, installed presets should be re-composed on top of the fresh core (or, at minimum, the CLI should warn that installed presets are no longer applied / mark them accordingly), so thatpreset listnever reports a preset as active while the files on disk are pure core.Actual Behavior
The materialized skill file reverts to the core version while the preset registry still reports the preset as installed and enabled. There is no warning. Recovery attempts:
specify preset add --dev ...again → fails withError: Preset 'demo-wrap' is already installed. Use 'specify preset remove ...' first.specify preset disable→enable→ no re-composition (output itself says "Previously registered commands/skills remain active until preset removal")specify preset set-priority→ no re-compositionThe only working recovery is the two-step
specify preset remove demo-wrap→specify preset add --dev ./presets-src/demo-wrap.Interestingly,
specify integration upgrade claude --force --script shre-applies while keeping the preset composition intact (verified twice), so only theinitpath loses it.Specify CLI Version
0.15.2
AI Agent
Claude Code
Operating System
macOS 15 (Apple Silicon, Darwin 25.5.0)
Python Version
3.14.6
Additional Context
Possibly related but distinct: #3849 fixed
integration upgrade --forceoverwriting extension/preset-derived SKILL.md content (PR #3853); that fix touches the upgrade path only, and in 0.15.2 the upgrade path indeed preserves the composition — it is theinit --here --forcepath that reverts it while leaving the registry stale.