Skip to content

feat: add Table of Contents to generated markdown documents (#1970)#2080

Open
Quratulain-bilal wants to merge 14 commits intogithub:mainfrom
Quratulain-bilal:feat/toc-generated-markdown
Open

feat: add Table of Contents to generated markdown documents (#1970)#2080
Quratulain-bilal wants to merge 14 commits intogithub:mainfrom
Quratulain-bilal:feat/toc-generated-markdown

Conversation

@Quratulain-bilal
Copy link
Copy Markdown
Contributor

Summary

  • Add exemplar TOC sections to structure templates (spec-template.md, plan-template.md,
    tasks-template.md)
  • Add TOC generation instructions to command templates (specify.md, plan.md, tasks.md)
  • Only ##-level headings included to keep TOC concise

Closes #1970

Changes

File Change
templates/spec-template.md Added TOC with links to User Scenarios, Requirements, Success
Criteria, Assumptions
templates/plan-template.md Added TOC with links to Summary, Technical Context, Constitution
Check, Project Structure, Complexity Tracking
templates/tasks-template.md Added TOC with links to Phase 1, Phase 2, Phase 3, Dependencies,
Implementation Strategy
templates/commands/specify.md Instruction in step 5 to generate TOC with anchor links
templates/commands/plan.md Instruction in step 3 to generate TOC with anchor links
templates/commands/tasks.md Instruction in step 4 to generate TOC with anchor links

Design decisions

  • Pure template change — no Python code or test changes needed
  • Standard GitHub anchor format (lowercase, spaces to hyphens, strip special chars)
  • Skipped small documents (checklist, constitution) — too short to need TOC

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Table of Contents (TOC) guidance to the Speckit command templates so generated spec.md, plan.md, and tasks.md include a concise TOC linking to ##-level sections.

Changes:

  • Instruct /speckit.specify to include a TOC after the document header and before the first content section.
  • Instruct /speckit.plan to include a TOC after the document header and before the Summary section.
  • Instruct /speckit.tasks to include a TOC after the document header and before the first phase.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
templates/commands/specify.md Adds instruction to generate a ##-heading TOC with GitHub-style anchors.
templates/commands/plan.md Adds instruction to generate a ##-heading TOC before Summary.
templates/commands/tasks.md Adds instruction to generate a ##-heading TOC before phases.
Comments suppressed due to low confidence (1)

templates/commands/specify.md:123

  • PR description mentions adding exemplar TOC sections to templates/spec-template.md, templates/plan-template.md, and templates/tasks-template.md, but those files currently contain no “Table of Contents” section (verified via search). Either update the structure templates as described, or adjust the PR description/scope so it matches what’s actually changed.
5. Write the specification to SPEC_FILE using the template structure, replacing placeholders with concrete details derived from the feature description (arguments) while preserving section order and headings. Include a **Table of Contents** section immediately after the header metadata block and before the first content section. The TOC must list all `##`-level headings as markdown anchor links (lowercase, spaces to hyphens, strip special characters). Example: `- [User Scenarios & Testing](#user-scenarios--testing)`. Only include sections that actually appear in the final document.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

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

Please address Copilot feedback. If not applicable, please explain why

@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Addressed all 3 Copilot comments replaced ambiguous 'header metadata block' wording with
template-accurate descriptions in all three command files.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 3, 2026

Please address Copilot feedback. If not applicable, please explain why

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 3, 2026

Please address Copilot feedback. If not applicable please explain why!

@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Addressed Copilot feedback — fixed TOC anchors in spec-template.md to include the -mandatory suffix matching the actual heading IDs.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 3, 2026

Please address Copilot feedback. Hopefully that will be the last round

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 3, 2026

Address the last nit from Copilot and I think we are ready :)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 3, 2026

Looks like there is more critical Copilot feedback

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 3, 2026

Please address Copilot feedback. Keep in mind that these are indeed templates so we probably have instructions in the corresponding command to actually add those slugs with an example there and have none here? This should apply to all templates I would guess.

@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Good point removed all hardcoded anchor links from the structure templates. Templates now contain
plain-text exemplar TOC entries with a comment noting the corresponding command must regenerate the
list with proper anchor links from the actual ## headings in the final document. This applies
consistently across all three templates.

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 3, 2026

The comment should not be in the template as the command that uses the template is responsible for filling it in and knows how to do that

@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Removed the HTML comments from all three templates — the command templates already have the
instructions for generating proper anchor links.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Table of Contents (TOC) guidance and exemplar sections to the markdown templates used by speckit so generated spec.md, plan.md, and tasks.md are easier to navigate.

Changes:

  • Added ## Table of Contents sections to spec/plan/tasks structure templates.
  • Updated command templates (specify, plan, tasks) to instruct agents to generate TOCs from ## headings using GitHub-style anchors.
  • Standardized TOC scope to ##-level headings to keep TOCs concise.
Show a summary per file
File Description
templates/tasks-template.md Adds an exemplar TOC section to the tasks template.
templates/spec-template.md Adds an exemplar TOC section to the spec template.
templates/plan-template.md Adds an exemplar TOC section to the plan template.
templates/commands/tasks.md Instructs tasks generation to include a TOC with anchor links.
templates/commands/specify.md Instructs spec generation to include a TOC with anchor links (with example).
templates/commands/plan.md Instructs plan generation to include a TOC with anchor links.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 6/6 changed files
  • Comments generated: 2

@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 3, 2026

OK since this seems to have higher impact than I initially realized I suggest we pivot and I am going to ask you to deliver this as a preset (see https://github.com/github/spec-kit/tree/main/presets) so you can try out these changes and make sure they work well and we can refer people to the preset.

Below I have included an impact assessment that explains why I am asking for this pivot.

PR #2080 Impact Assessment: TOC Generation for Spec-Driven Documents

1. Template TOC Entries Are NOT Anchor Links (Inconsistency with Commands)

The command files (specify.md, plan.md, tasks.md) all instruct the AI to generate markdown anchor links:

"List all ##-level headings as markdown anchor links (lowercase, spaces to hyphens, strip special characters)"

The specify.md command even shows an example: - [User Scenarios & Testing](#user-scenarios--testing)

But the template exemplars use plain text instead:

- Summary
- Technical Context

The templates serve as the structural reference that commands instruct AI to follow. An AI seeing the template's plain-text format may replicate it verbatim instead of generating proper anchor links as the command instructions demand — creating a direct conflict between the two sources of truth.


2. Missing Headings in tasks-template TOC

The tasks-template.md has 12 ##-level headings:

# Actual Heading In TOC?
1 ## Format: [ID] [P?] [Story] Description ✅ as "Format"
2 ## Path Conventions
3 ## Phase 1: Setup (Shared Infrastructure)
4 ## Phase 2: Foundational (Blocking Prerequisites)
5 ## Phase 3: User Story 1 - [Title] (Priority: P1) 🎯 MVP ❌ merged as "Phase 3+"
6 ## Phase 4: User Story 2 - [Title] (Priority: P2) ❌ merged as "Phase 3+"
7 ## Phase 5: User Story 3 - [Title] (Priority: P3) ❌ merged as "Phase 3+"
8 ## Phase N: Polish & Cross-Cutting Concerns
9 ## Dependencies & Execution Order
10 ## Parallel Example: User Story 1 ❌ missing
11 ## Implementation Strategy
12 ## Notes

The TOC entry Phase 3+: User Story phases (generated from spec.md priorities) is a generalized description that doesn't match any actual heading in the template. This violates the PR's own command instruction: "Only include sections that actually appear in the final document." Meanwhile ## Parallel Example: User Story 1 is absent entirely.


3. spec-template TOC Omits Heading Decorators

The actual headings in spec-template.md include *(mandatory)* annotations:

## User Scenarios & Testing *(mandatory)*
## Requirements *(mandatory)*
## Success Criteria *(mandatory)*

The TOC lists them without the annotation:

- User Scenarios & Testing
- Requirements
- Success Criteria

This is arguably fine since the command instruction says "strip special characters" — but the *(mandatory)* text isn't a special character, it's part of the heading text. This means the anchor link would need to be #user-scenarios--testing-mandatory (with * stripped), not #user-scenarios--testing. The exemplar doesn't demonstrate how to handle this, leaving the AI to guess.


4. plan-template TOC Placement Creates Awkward Structure

The TOC is inserted between the metadata block and the **Note** paragraph:

**Input**: Feature specification from `/specs/[###-feature-name]/spec.md`

## Table of Contents        ← TOC inserted here
- Summary
...

**Note**: This template is filled in by...    ← Meta-content now sits between TOC and first real section

## Summary

The **Note** paragraph is meta-guidance about the template, not content that belongs in a generated document. In the final output, this creates an orphaned paragraph between the TOC and the first section. The plan command should strip that **Note** line anyway, but the template now visually buries it.


5. Downstream Consumer: analyze.md Cross-Artifact Consistency

The analyze.md command performs consistency analysis across spec.md, plan.md, and tasks.md. It loads specific sections from each artifact. A new ## Table of Contents heading introduces a section that:

  • Is not in the analysis taxonomy (it looks for "Functional Requirements", "Success Criteria", etc.)
  • Could be flagged as a "section without meaningful content" if the analyzer is overly strict
  • May need to be excluded from section-counting or completeness heuristics

The PR doesn't update analyze.md to acknowledge or skip the TOC section.


6. Downstream Consumer: clarify.md Spec Rewriting

The clarify.md command rewrites spec.md with clarification answers embedded directly into the document. If the spec now contains a TOC, the clarify command may:

  • Add new sections (e.g., a clarified requirement area) without updating the TOC
  • Remove a [NEEDS CLARIFICATION] marker that was in a section listed in the TOC
  • Leave the TOC stale after modifications

The clarify command has no instruction to maintain or update the TOC after rewriting sections.


7. Downstream Consumer: implement.md Task Parsing

The implement.md reads tasks.md and iterates through phases. The ## Table of Contents heading now appears as the first ##-level section in the document. The implement command currently scans for phase structure (Phase 1, Phase 2, etc.), but an LLM could potentially misinterpret the TOC section as something requiring execution — e.g., trying to process it as a phase or task group. This is a low-risk but non-zero concern for less capable models.


8. Self-Referencing Paradox in Command Instructions

The commands say: "List all ##-level headings as markdown anchor links."

The TOC itself is a ## Table of Contents heading. The command also says: "Only include sections that actually appear in the final document."

This creates a subtle paradox: should the TOC link to itself? The templates don't include a self-reference (correct), but there's no explicit exclusion instruction in the commands. A literal-minded LLM could include - [Table of Contents](#table-of-contents) in the output.


8. Internal Format Inconsistency

The PR introduces unlinked, unnumbered plain-text TOC entries in the templates, while the command instructions within the same PR explicitly require markdown anchor links. This internal inconsistency means the templates and commands disagree on the expected output format.


Summary of Findings

# Angle Severity Type
1 Template exemplars use plain text, not anchor links High Conflict between templates and command instructions
2 tasks-template TOC has fabricated/missing headings High Factual incorrectness
3 spec-template TOC ignores *(mandatory)* in headings Medium Ambiguous anchor generation
4 plan-template TOC placement buries **Note** paragraph Low Structural awkwardness
5 analyze.md not updated for new TOC section Low Potential false positive in analysis
6 clarify.md may leave TOC stale after spec edits Medium TOC drift after clarification
7 implement.md could misparse TOC as a task phase Low Edge case for weaker models
8 Internal format inconsistency (plain text vs. anchor links) Medium Self-contradictory PR

Items 1, 2, and 3 are the most actionable and should be addressed before merge.

Quratulain-bilal and others added 2 commits April 4, 2026 01:03
Pivots from core template changes to a preset approach per reviewer
request. Adds presets/toc-navigation/ with 3 template overrides and
3 command overrides that add Table of Contents sections to generated
spec.md, plan.md, and tasks.md documents.

Addresses all 8 impact concerns from review:
- Templates use anchor links (not plain text) matching command instructions
- All 12 tasks-template headings accounted for (dynamic phases as plain text)
- spec-template anchors include -mandatory suffix
- TOC placed after Note paragraph in plan-template
- Self-reference exclusion explicit in all commands
- Clarify stale TOC instruction in specify command
- Implement misparse warning in tasks command

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

--- Pivoted to a preset approach as requested. The TOC is now delivered as presets/toc-navigation/ instead
of core template changes.

What changed:

  • Reverted all core template modifications — templates/ has zero diff vs main
  • Created presets/toc-navigation/ with preset.yml, 3 template overrides, and 3 command overrides

All 8 impact concerns addressed:

  1. Plain text vs anchor links conflict — Templates now use anchor links, matching command instructions
  2. Missing/fabricated headings in tasks TOC — All 12 ## headings covered. Stable ones as anchors,
    dynamic Phase 3-5 as plain text
  3. (mandatory) suffix ignored — Anchors include -mandatory suffix (e.g., #requirements-mandatory)
  4. TOC buries Note in plan — TOC placed after the Note paragraph, before ## Summary
  5. analyze.md not updated — Preset scope, analyze.md not overridden. Tasks command warns downstream
    consumers to skip TOC
  6. clarify.md leaves TOC stale — specify command instructs: "If /speckit.clarify later rewrites the
    spec, it must regenerate the TOC"
  7. implement.md could misparse TOC tasks command states: "navigational only downstream consumers
    like /speckit.implement must not treat it as a phase or task group"
  8. Self-referencing paradox —All 3 commands explicitly say: "Do not include a self-referencing entry
    for ## Table of Contents itself"

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Table of Contents (toc) in each generated markdown

3 participants