Bug Description
When a preset overrides a core command with strategy: wrap and its command file's frontmatter declares only description (no argument-hint), the composed skill file loses the core command's argument-hint key — and the orphaned value string is concatenated into the description value. The result still parses as YAML, so the corruption is easy to miss, but the skill metadata is wrong (agents relying on description/argument-hint get a mangled description and no argument hint).
Steps to Reproduce
-
Initialize a fresh project:
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
head -12 .claude/skills/speckit-specify/SKILL.md
The core frontmatter contains both keys, e.g.:
description: Create or update the feature specification from a natural language feature description.
argument-hint: Describe the feature you want to specify
-
Create a minimal wrap preset whose command frontmatter has only description and strategy (same layout as in the scaffold example):
presets-src/demo-wrap/commands/speckit.specify.md
---
description: "Wrapped speckit.specify"
strategy: wrap
---
<!-- demo preamble -->
{CORE_TEMPLATE}
(plus a matching preset.yml with provides.templates: [{type: command, name: speckit.specify, file: commands/speckit.specify.md, strategy: wrap}])
-
Apply and inspect:
specify preset add --dev ./presets-src/demo-wrap
head -12 .claude/skills/speckit-specify/SKILL.md
python3 -c "import yaml,io; f=open('.claude/skills/speckit-specify/SKILL.md'); t=f.read().split('---')[1]; print(yaml.safe_load(t))"
Expected Behavior
Core frontmatter keys that the preset does not explicitly override (such as argument-hint) should be inherited into the composed skill frontmatter, and description should contain exactly the preset's declared description.
Actual Behavior
Parsing the composed frontmatter shows:
- the
argument-hint key is gone, and
- its value (
Describe the feature you want to specify) appears inside the description string appended to the preset's description.
Because the YAML remains syntactically valid, nothing fails loudly; we only noticed because the agent's skill list started showing a fallback title instead of the intended description.
Workaround: explicitly repeating the core value in the preset command frontmatter (argument-hint: "Describe the feature you want to specify") produces a correct composition (this goes through the apply_argument_hint path added in #2978).
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
Related earlier work (all about argument-hint survival, but covering different cases):
Reading src/specify_cli/presets/__init__.py on current main, the wrap-composition layer inheritance appears to carry over only scripts / agent_scripts from the base layer, which would explain why argument-hint is not inherited; the leakage of the value into description suggests the frontmatter re-serialization also mis-attaches the orphaned value.
Bug Description
When a preset overrides a core command with
strategy: wrapand its command file's frontmatter declares onlydescription(noargument-hint), the composed skill file loses the core command'sargument-hintkey — and the orphaned value string is concatenated into thedescriptionvalue. The result still parses as YAML, so the corruption is easy to miss, but the skill metadata is wrong (agents relying ondescription/argument-hintget a mangled description and no argument hint).Steps to Reproduce
Initialize a fresh project:
The core frontmatter contains both keys, e.g.:
Create a minimal wrap preset whose command frontmatter has only
descriptionandstrategy(same layout as in the scaffold example):presets-src/demo-wrap/commands/speckit.specify.md(plus a matching
preset.ymlwithprovides.templates: [{type: command, name: speckit.specify, file: commands/speckit.specify.md, strategy: wrap}])Apply and inspect:
specify preset add --dev ./presets-src/demo-wrap head -12 .claude/skills/speckit-specify/SKILL.md python3 -c "import yaml,io; f=open('.claude/skills/speckit-specify/SKILL.md'); t=f.read().split('---')[1]; print(yaml.safe_load(t))"Expected Behavior
Core frontmatter keys that the preset does not explicitly override (such as
argument-hint) should be inherited into the composed skill frontmatter, anddescriptionshould contain exactly the preset's declared description.Actual Behavior
Parsing the composed frontmatter shows:
argument-hintkey is gone, andDescribe the feature you want to specify) appears inside thedescriptionstring appended to the preset's description.Because the YAML remains syntactically valid, nothing fails loudly; we only noticed because the agent's skill list started showing a fallback title instead of the intended description.
Workaround: explicitly repeating the core value in the preset command frontmatter (
argument-hint: "Describe the feature you want to specify") produces a correct composition (this goes through theapply_argument_hintpath added in #2978).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
Related earlier work (all about
argument-hintsurvival, but covering different cases):argument-hintin preset SKILL.md generation when the preset's own frontmatter declares it; the case reported here (preset relies on wrap inheritance from core) is one step outside that fixReading
src/specify_cli/presets/__init__.pyon current main, the wrap-composition layer inheritance appears to carry over onlyscripts/agent_scriptsfrom the base layer, which would explain whyargument-hintis not inherited; the leakage of the value intodescriptionsuggests the frontmatter re-serialization also mis-attaches the orphaned value.