-
Notifications
You must be signed in to change notification settings - Fork 8.5k
feat: add /speckit.retro command — sprint retrospective & metrics #2042
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,245 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: Conduct a structured retrospective analysis of the completed development cycle with metrics, learnings, and improvement suggestions. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| scripts: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sh: scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ps: scripts/powershell/check-prerequisites.ps1 -Json -RequireTasks -IncludeTasks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## User Input | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| $ARGUMENTS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| You **MUST** consider the user input before proceeding (if not empty). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Pre-Execution Checks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| **Check for extension hooks (before retro)**: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Check if `.specify/extensions.yml` exists in the project root. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - If it exists, read it and look for entries under the `hooks.before_retro` key | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - If the hook has no `condition` field, or it is null/empty, treat the hook as executable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - For each executable hook, output the following based on its `optional` flag: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **Optional hook** (`optional: true`): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Extension Hooks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| **Optional Pre-Hook**: {extension} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Command: `/{command}` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description: {description} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Prompt: {prompt} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| To execute: `/{command}` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **Mandatory hook** (`optional: false`): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Extension Hooks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| **Automatic Pre-Hook**: {extension} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Executing: `/{command}` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EXECUTE_COMMAND: {command} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Wait for the result of the hook command before proceeding to the Outline. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Goal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Conduct a structured retrospective analysis of the completed development cycle — from specification through shipping. Analyze what went well, what didn't, and generate actionable improvement suggestions for future iterations. Track metrics over time to identify trends and continuously improve the spec-driven development process. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Operating Constraints | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| **CONSTRUCTIVE FOCUS**: The retrospective should be balanced — celebrating successes alongside identifying improvements. Avoid blame; focus on process improvements. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| **DATA-DRIVEN**: Base analysis on actual artifacts, git history, and measurable outcomes rather than subjective impressions. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| **OPTIONAL WRITES**: The retro report is always written. Updates to `constitution.md` with new learnings are offered but require explicit user approval. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Outline | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. Run `{SCRIPT}` from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute. For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot"). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 2. **Gather Retrospective Data**: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Load all available artifacts from the development cycle: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **REQUIRED**: Read `spec.md` — original specification and requirements | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **REQUIRED**: Read `tasks.md` — task breakdown and completion status | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **IF EXISTS**: Read `plan.md` — technical plan and architecture decisions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **IF EXISTS**: Read review reports in FEATURE_DIR/reviews/ — code review findings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **IF EXISTS**: Read QA reports in FEATURE_DIR/qa/ — testing results | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **IF EXISTS**: Read release artifacts in FEATURE_DIR/releases/ — shipping data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **IF EXISTS**: Read critique reports in FEATURE_DIR/critiques/ — pre-implementation review | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **IF EXISTS**: Read previous retros in FEATURE_DIR/retros/ — historical context | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - **IF EXISTS**: Read `/memory/constitution.md` — project principles | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 3. **Collect Git Metrics**: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Gather quantitative data from the git history: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Commit count for the feature | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git rev-list --count origin/{target_branch}..HEAD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Files changed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git diff --stat origin/{target_branch}..HEAD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Lines added/removed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git diff --shortstat origin/{target_branch}..HEAD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Number of authors | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git log origin/{target_branch}..HEAD --format='%an' | sort -u | wc -l | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Date range (first commit to last) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git log origin/{target_branch}..HEAD --format='%ai' | tail -1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git log origin/{target_branch}..HEAD --format='%ai' | head -1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Commit count for the feature | |
| git rev-list --count origin/{target_branch}..HEAD | |
| # Files changed | |
| git diff --stat origin/{target_branch}..HEAD | |
| # Lines added/removed | |
| git diff --shortstat origin/{target_branch}..HEAD | |
| # Number of authors | |
| git log origin/{target_branch}..HEAD --format='%an' | sort -u | wc -l | |
| # Date range (first commit to last) | |
| git log origin/{target_branch}..HEAD --format='%ai' | tail -1 | |
| git log origin/{target_branch}..HEAD --format='%ai' | head -1 | |
| # Determine the base ref for this feature once per repo. | |
| # Preferred: use the upstream branch (e.g., origin/main, origin/develop): | |
| # BASE_REF="$(git rev-parse --abbrev-ref --symbolic-full-name @{upstream})" | |
| # | |
| # Or set it explicitly if there is no upstream configured: | |
| # BASE_REF=main | |
| # BASE_REF=develop | |
| # | |
| : "${BASE_REF:?Set BASE_REF to the base branch/ref for this feature (e.g., main, develop, or an upstream ref)}" | |
| # Commit count for the feature | |
| git rev-list --count "$BASE_REF"..HEAD | |
| # Files changed | |
| git diff --stat "$BASE_REF"..HEAD | |
| # Lines added/removed | |
| git diff --shortstat "$BASE_REF"..HEAD | |
| # Number of authors | |
| git log "$BASE_REF"..HEAD --format='%an' | sort -u | wc -l | |
| # Date range (first commit to last) | |
| git log "$BASE_REF"..HEAD --format='%ai' | tail -1 | |
| git log "$BASE_REF"..HEAD --format='%ai' | head -1 |
Copilot
AI
Apr 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Step 12 says to generate the report “using the retrospective report template”, but the workflow never instructs the agent to read the template file (e.g., .specify/templates/retro-template.md) nor to create FEATURE_DIR/retros/ if it doesn’t exist. Add an explicit step to load the template and ensure the destination directory exists before writing retro-{timestamp}.md.
| Create the retro report at `FEATURE_DIR/retros/retro-{timestamp}.md` using the retrospective report template. | |
| - Load the retrospective report template from `.specify/templates/retro-template.md`. If the template file does not exist or cannot be read, continue using a reasonable fallback structure based on the sections above. | |
| - Ensure the `FEATURE_DIR/retros/` directory exists. If it does not exist, create it before writing any files. | |
| - Generate the retro report at `FEATURE_DIR/retros/retro-{timestamp}.md`, using the loaded retrospective report template and filling it with the metrics, findings, and improvement suggestions from the previous steps. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| # Retrospective: [FEATURE NAME] | ||
|
|
||
| **Date**: [DATE] | ||
| **Feature**: [Link to spec.md] | ||
| **Cycle**: [first_commit_date] → [last_commit_date] | ||
| **Overall Assessment**: [🌟 Excellent / ✅ Good / ⚠️ Adequate / 🔧 Needs Improvement] | ||
|
|
||
| --- | ||
|
|
||
| ## Metrics Dashboard | ||
|
|
||
| ``` | ||
| 📊 Development Cycle Metrics | ||
| ━━━━━━━━━━━━━━━━━━━━━━━━━━ | ||
|
|
||
| 📝 Specification | ||
| Requirements: [total] total, [fulfilled] fulfilled, [partial] partial | ||
| Spec Accuracy: [accuracy]% | ||
|
|
||
| 📋 Planning | ||
| Tasks: [total] total, [completed] completed | ||
| Added during impl: [unplanned_count] | ||
| Plan Score: [EXCELLENT / GOOD / ADEQUATE / NEEDS IMPROVEMENT] | ||
|
|
||
| 💻 Implementation | ||
| Commits: [count] | ||
| Files changed: [count] | ||
| Lines: +[additions] / -[deletions] | ||
| Test/Code ratio: [ratio] | ||
|
|
||
| 🔍 Quality | ||
| Review findings: 🔴[blockers] 🟡[warnings] 🟢[suggestions] | ||
| QA pass rate: [qa_pass_rate]% | ||
| Quality Score: [score] | ||
|
||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Specification Accuracy | ||
|
|
||
| | Requirement | Status | Notes | | ||
| |-------------|--------|-------| | ||
| | [FR-001] | ✅ Fulfilled | | | ||
| | [FR-002] | ⚠️ Partial | [deviation notes] | | ||
| | [FR-003] | ❌ Not Implemented | [reason] | | ||
| | [Unplanned] | ➕ Added | [why it was needed] | | ||
|
|
||
| **Accuracy Score**: [X]% ([fulfilled + partial×0.5] / [total] requirements) | ||
|
|
||
| --- | ||
|
|
||
| ## Plan Effectiveness | ||
|
|
||
| | Aspect | Assessment | Details | | ||
| |--------|-----------|---------| | ||
| | Architecture decisions | ✅/⚠️/❌ | [which decisions worked/didn't] | | ||
| | Task scoping | ✅/⚠️/❌ | [well-sized / too large / too small] | | ||
| | Dependency ordering | ✅/⚠️/❌ | [any ordering issues] | | ||
| | Missing tasks | [count] added | [what was missed] | | ||
|
|
||
| **Plan Score**: [EXCELLENT / GOOD / ADEQUATE / NEEDS IMPROVEMENT] | ||
|
|
||
| --- | ||
|
|
||
| ## What Went Well 🎉 | ||
|
|
||
| 1. **[Success area]**: [Description of what worked and why] | ||
| 2. **[Success area]**: [Description] | ||
| 3. **[Success area]**: [Description] | ||
|
|
||
| --- | ||
|
|
||
| ## What Could Improve 🔧 | ||
|
|
||
| 1. **[Improvement area]**: [Description of the issue and its impact] | ||
| 2. **[Improvement area]**: [Description] | ||
| 3. **[Improvement area]**: [Description] | ||
|
|
||
| --- | ||
|
|
||
| ## Improvement Suggestions | ||
|
|
||
| | ID | Impact | Category | Suggestion | Rationale | | ||
| |----|--------|----------|------------|-----------| | ||
| | IMP-001 | HIGH | [cat] | [specific action] | [why this matters] | | ||
| | IMP-002 | MEDIUM | [cat] | [specific action] | [why this matters] | | ||
| | IMP-003 | LOW | [cat] | [specific action] | [why this matters] | | ||
|
|
||
| **Categories**: Specification, Planning, Implementation, Quality, Process | ||
|
|
||
| --- | ||
|
|
||
| ## Historical Trends | ||
|
|
||
| <!-- Only populated if previous retros exist --> | ||
|
|
||
| | Metric | Previous | Current | Trend | | ||
| |--------|----------|---------|-------| | ||
| | Spec accuracy | [%] | [%] | 📈/📉/➡️ | | ||
| | QA pass rate | [%] | [%] | 📈/📉/➡️ | | ||
| | Review blockers | [n] | [n] | 📈/📉/➡️ | | ||
| | Unplanned tasks | [n] | [n] | 📈/📉/➡️ | | ||
|
|
||
| --- | ||
|
|
||
| ## Suggested Constitution Updates | ||
|
|
||
| Based on this retrospective, consider adding these principles: | ||
|
|
||
| 1. **[Principle name]**: [Principle description] | ||
| _Learned from: [specific experience in this cycle]_ | ||
|
|
||
| --- | ||
|
|
||
| *Generated by `/speckit.retro` — Sprint retrospective for spec-driven development.* | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the artifact list,
plan.mdis marked as “IF EXISTS”, but this command’s prerequisite script (check-prerequisiteswith--require-tasks) fails ifplan.mdis missing. To avoid the agent treating it as optional, markplan.mdas REQUIRED here (or relax the prerequisite script args if it truly should be optional).