Skip to content

fix(templates): start spec.md from the composed spec-template - #5187

Merged
mnriem merged 1 commit into
github:mainfrom
MannXo:fix/5177-specify-composed-template
Oct 29, 2026
Merged

mnriem merged 1 commit into
github:mainfrom
MannXo:fix/5177-specify-composed-template

Conversation

@MannXo

@MannXo MannXo commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Description

/speckit.specify told the agent to resolve spec-template and then copy "the resolved spec-template file" to spec.md. When a preset provides spec-template with append, prepend or wrap, no single file holds the composed template, so those layers silently drop out of new specs. /speckit.plan, /speckit.tasks, /speckit.checklist and /speckit.constitution already consume composed content.

This gives specify.md the same scripts: frontmatter as constitution.md (resolve-template for spec-template, in the sh, ps and py variants) and changes the prose to:

  • run {SCRIPT} and parse TEMPLATE_CONTENT before creating the directory, and stop on a resolution error rather than fall back to one layer
  • write TEMPLATE_CONTENT to SPECIFY_FEATURE_DIRECTORY/spec.md
  • use TEMPLATE_CONTENT (not a template file) for the required sections in step 4

Tests:

  • tests/test_presets.py: new test_core_specify_command_writes_composed_spec_template, next to the constitution and checklist assertions. It fails on main and passes with the change.
  • tests/integrations/test_integration_copilot.py: test_specify_agent_resolves_active_spec_template asserted the old wording (specify preset resolve spec-template). It now checks that the generated agent runs the resolver and writes TEMPLATE_CONTENT, and keeps the negative checks against hardcoding the core template.

Only the core template carried the copy instruction. The bundled presets' speckit.specify.md overrides do not reference a resolved file. #4883 also edits specify.md, but only the hook sections, so the two diffs do not overlap.

Fixes #5177

Testing

  • Tested locally with uv run specify --help
  • Ran existing tests with uv sync && uv run pytest
  • Tested with a sample project (if applicable)

Run inside the project venv with PATH="$PWD/.venv/bin:$PATH" .venv/bin/python -m pytest -n 2 -q:

13421 passed, 438 skipped

uvx ruff@0.15.0 check src tests and git diff --check are clean.

Sample project (specify init --integration claude --script sh from this branch, then the issue's append preset installed with specify preset add --dev):

$ grep -n "resolve-template" .claude/skills/speckit-specify/SKILL.md
97:   - Run `.specify/scripts/bash/resolve-template.sh spec-template --json` from the repository root and parse `TEMPLATE_CONTENT` as the active `spec-template`. ...

$ specify preset resolve spec-template
  spec-template: .specify/presets/example/templates/spec-addendum.md
    (top layer from: example v0.1.0)
    Final output is composed from multiple preset layers; the path above is the
highest-priority contributing layer.

So "copy the resolved file" gets either the addendum alone or, as the reporter saw, the core template alone. Following the new step (run the resolver, write TEMPLATE_CONTENT to spec.md) gives the composed template:

$ grep -n "^## " specs/001-team-dashboard/spec.md
11:## User Scenarios & Testing *(mandatory)*
81:## Requirements *(mandatory)*
106:## Success Criteria *(mandatory)*
120:## Assumptions
134:## Team Section

I followed the changed step by hand in the sample project. I did not run a full /speckit.specify session in a separate agent.

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (fill in the disclosure below)

AI disclosure: Implemented with Claude Code (Claude Opus 5.5, autonomous mode, default reasoning effort); code and test generation and this description.

The specify command told the agent to copy "the resolved spec-template
file" to spec.md. When a preset contributes spec-template with an
append, prepend or wrap strategy, no single file holds the composed
template, so the preset layers were dropped from new specs.

Run resolve-template for spec-template, as the constitution command
does, and write TEMPLATE_CONTENT to spec.md.

Fixes github#5177

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

There are no active review issues for the change to initialize spec.md from composed template content.

No open issues 🎉

What changed in this PR

Fixes #5177 by making /speckit.specify initialize spec.md from composed template content, preserving preset layers rather than copying a single contributing file.

Changes:

  • Adds Bash, PowerShell, and Python template-resolver commands.
  • Requires writing TEMPLATE_CONTENT to spec.md and stopping on resolution errors.
  • Adds regression assertions and updates Copilot integration checks for the rendered instructions.
File Description
tests/​test_presets.py Adds assertions requiring composed content and rejecting the old file-copy instruction.
tests/​integrations/​test_integration_copilot.py Checks resolver rendering and composed-content instructions in the generated agent.
templates/​commands/​specify.md Resolves and uses composed template content for spec creation and required sections.

Review effort: Balanced (auto)

@mnriem mnriem added the triage-must-have Verdict: high-value, important work for Spec Kit — do first label Oct 29, 2026
@mnriem
mnriem merged commit a283c9d into github:main Oct 29, 2026
16 checks passed
@mnriem

mnriem commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triage-must-have Verdict: high-value, important work for Spec Kit — do first

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: /speckit-specify copies "the resolved spec-template file", which drops append-strategy preset layers

3 participants