diff --git a/commands/gsd/milestone-summary.md b/commands/gsd/milestone-summary.md
new file mode 100644
index 000000000..bd379c158
--- /dev/null
+++ b/commands/gsd/milestone-summary.md
@@ -0,0 +1,40 @@
+---
+name: gsd:milestone-summary
+description: Generate a comprehensive project summary from milestone artifacts for team onboarding and review
+argument-hint: "[version]"
+allowed-tools:
+ - Read
+ - Write
+ - Bash
+ - Grep
+ - Glob
+---
+
+
+Generate a structured milestone summary for team onboarding and project review. Reads completed milestone artifacts (ROADMAP, REQUIREMENTS, CONTEXT, SUMMARY, VERIFICATION files) and produces a human-friendly overview of what was built, how, and why.
+
+Purpose: Enable new team members to understand a completed project by reading one document and asking follow-up questions.
+Output: MILESTONE_SUMMARY written to `.planning/reports/`, presented inline, optional interactive Q&A.
+
+
+
+@~/.claude/get-shit-done/workflows/milestone-summary.md
+
+
+
+**Project files:**
+- `.planning/ROADMAP.md`
+- `.planning/PROJECT.md`
+- `.planning/STATE.md`
+- `.planning/RETROSPECTIVE.md`
+- `.planning/milestones/v{version}-ROADMAP.md` (if archived)
+- `.planning/milestones/v{version}-REQUIREMENTS.md` (if archived)
+- `.planning/phases/*-*/` (SUMMARY.md, VERIFICATION.md, CONTEXT.md)
+
+**User input:**
+- Version: $ARGUMENTS (optional — defaults to current/latest milestone)
+
+
+
+Read and execute the milestone-summary workflow from @~/.claude/get-shit-done/workflows/milestone-summary.md end-to-end.
+
diff --git a/get-shit-done/workflows/milestone-summary.md b/get-shit-done/workflows/milestone-summary.md
new file mode 100644
index 000000000..75740f270
--- /dev/null
+++ b/get-shit-done/workflows/milestone-summary.md
@@ -0,0 +1,190 @@
+# Milestone Summary Workflow
+
+Generate a comprehensive, human-friendly project summary from completed milestone artifacts.
+Designed for team onboarding — a new contributor can read the output and understand the entire project.
+
+---
+
+## Step 1: Resolve Version
+
+```bash
+VERSION="$ARGUMENTS"
+```
+
+If `$ARGUMENTS` is empty:
+1. Check `.planning/STATE.md` for current milestone version
+2. Check `.planning/milestones/` for the latest archived version
+3. If neither found, check if `.planning/ROADMAP.md` exists (project may be mid-milestone)
+4. If nothing found: error "No milestone found. Run /gsd:new-project or /gsd:new-milestone first."
+
+Set `VERSION` to the resolved version (e.g., "1.0").
+
+## Step 2: Locate Artifacts
+
+Determine whether the milestone is **archived** or **current**:
+
+**Archived milestone** (`.planning/milestones/v{VERSION}-ROADMAP.md` exists):
+```
+ROADMAP_PATH=".planning/milestones/v${VERSION}-ROADMAP.md"
+REQUIREMENTS_PATH=".planning/milestones/v${VERSION}-REQUIREMENTS.md"
+AUDIT_PATH=".planning/v${VERSION}-MILESTONE-AUDIT.md"
+```
+
+**Current/in-progress milestone** (no archive yet):
+```
+ROADMAP_PATH=".planning/ROADMAP.md"
+REQUIREMENTS_PATH=".planning/REQUIREMENTS.md"
+AUDIT_PATH=".planning/v${VERSION}-MILESTONE-AUDIT.md"
+```
+
+**Always available:**
+```
+PROJECT_PATH=".planning/PROJECT.md"
+RETRO_PATH=".planning/RETROSPECTIVE.md"
+STATE_PATH=".planning/STATE.md"
+```
+
+Read all files that exist. Missing files are fine — the summary adapts to what's available.
+
+## Step 3: Discover Phase Artifacts
+
+Find all phase directories:
+
+```bash
+gsd-tools.cjs init progress
+```
+
+This returns phase metadata. For each phase in the milestone scope:
+
+- Read `{phase_dir}/{padded}-SUMMARY.md` if it exists — extract `one_liner`, `accomplishments`, `decisions`
+- Read `{phase_dir}/{padded}-VERIFICATION.md` if it exists — extract status, gaps, deferred items
+- Read `{phase_dir}/{padded}-CONTEXT.md` if it exists — extract key decisions from `` section
+- Read `{phase_dir}/{padded}-RESEARCH.md` if it exists — note what was researched
+
+Track which phases have which artifacts.
+
+## Step 4: Gather Git Statistics
+
+```bash
+# If milestone is tagged
+git log v${VERSION} --oneline | wc -l
+git diff --stat $(git log --format=%H --reverse v${VERSION} | head -1)..v${VERSION}
+
+# If not tagged, use date range from STATE.md or earliest phase commit
+git log --oneline --since="" | wc -l
+```
+
+Extract:
+- Total commits in milestone
+- Files changed, insertions, deletions
+- Timeline (start date → end date)
+- Contributors (from git log authors)
+
+## Step 5: Generate Summary Document
+
+Write to `.planning/reports/MILESTONE_SUMMARY-v${VERSION}.md`:
+
+```markdown
+# Milestone v{VERSION} — Project Summary
+
+**Generated:** {date}
+**Purpose:** Team onboarding and project review
+
+---
+
+## 1. Project Overview
+
+{From PROJECT.md: "What This Is", core value proposition, target users}
+{If mid-milestone: note which phases are complete vs in-progress}
+
+## 2. Architecture & Technical Decisions
+
+{From CONTEXT.md files across phases: key technical choices}
+{From SUMMARY.md decisions: patterns, libraries, frameworks chosen}
+{From PROJECT.md: tech stack if documented}
+
+Present as a bulleted list of decisions with brief rationale:
+- **Decision:** {what was chosen}
+ - **Why:** {rationale from CONTEXT.md}
+ - **Phase:** {which phase made this decision}
+
+## 3. Phases Delivered
+
+| Phase | Name | Status | One-Liner |
+|-------|------|--------|-----------|
+{For each phase: number, name, status (complete/in-progress/planned), one_liner from SUMMARY.md}
+
+## 4. Requirements Coverage
+
+{From REQUIREMENTS.md: list each requirement with status}
+- ✅ {Requirement met}
+- ⚠️ {Requirement partially met — note gap}
+- ❌ {Requirement not met — note reason}
+
+{If MILESTONE-AUDIT.md exists: include audit verdict}
+
+## 5. Key Decisions Log
+
+{Aggregate from all CONTEXT.md sections}
+{Each decision with: ID, description, phase, rationale}
+
+## 6. Tech Debt & Deferred Items
+
+{From VERIFICATION.md files: gaps found, anti-patterns noted}
+{From RETROSPECTIVE.md: lessons learned, what to improve}
+{From CONTEXT.md sections: ideas parked for later}
+
+## 7. Getting Started
+
+{Entry points for new contributors:}
+- **Run the project:** {from PROJECT.md or SUMMARY.md}
+- **Key directories:** {from codebase structure}
+- **Tests:** {test command from PROJECT.md or CLAUDE.md}
+- **Where to look first:** {main entry points, core modules}
+
+---
+
+## Stats
+
+- **Timeline:** {start} → {end} ({duration})
+- **Phases:** {count complete} / {count total}
+- **Commits:** {count}
+- **Files changed:** {count} (+{insertions} / -{deletions})
+- **Contributors:** {list}
+```
+
+## Step 6: Commit
+
+```bash
+gsd-tools.cjs commit "docs(v${VERSION}): generate milestone summary for onboarding" \
+ --files ".planning/reports/MILESTONE_SUMMARY-v${VERSION}.md"
+```
+
+## Step 7: Present Summary
+
+Display the full summary document inline.
+
+## Step 8: Offer Interactive Mode
+
+After presenting the summary:
+
+> "Summary written to `.planning/reports/MILESTONE_SUMMARY-v{VERSION}.md`.
+>
+> I have full context from the build artifacts. Want to ask anything about the project?
+> Architecture decisions, specific phases, requirements, tech debt — ask away."
+
+If the user asks questions:
+- Answer from the artifacts already loaded (CONTEXT.md, SUMMARY.md, VERIFICATION.md, etc.)
+- Reference specific files and decisions
+- Stay grounded in what was actually built (not speculation)
+
+If the user is done:
+- Suggest next steps: `/gsd:new-milestone`, `/gsd:progress`, or sharing the summary with the team
+
+## Step 9: Update STATE.md
+
+```bash
+gsd-tools.cjs state record-session \
+ --stopped-at "Milestone v${VERSION} summary generated" \
+ --resume-file ".planning/reports/MILESTONE_SUMMARY-v${VERSION}.md"
+```
diff --git a/tests/milestone-summary.test.cjs b/tests/milestone-summary.test.cjs
new file mode 100644
index 000000000..12d622fa6
--- /dev/null
+++ b/tests/milestone-summary.test.cjs
@@ -0,0 +1,114 @@
+/**
+ * GSD Milestone Summary Tests
+ *
+ * Validates the milestone-summary command and workflow files exist
+ * and follow expected patterns. Tests artifact discovery logic.
+ */
+
+const { test, describe } = require('node:test');
+const assert = require('node:assert');
+const fs = require('fs');
+const path = require('path');
+
+const repoRoot = path.resolve(__dirname, '..');
+const commandPath = path.join(repoRoot, 'commands', 'gsd', 'milestone-summary.md');
+const workflowPath = path.join(repoRoot, 'get-shit-done', 'workflows', 'milestone-summary.md');
+
+describe('milestone-summary command', () => {
+ test('command file exists', () => {
+ assert.ok(fs.existsSync(commandPath), 'commands/gsd/milestone-summary.md should exist');
+ });
+
+ test('command has correct frontmatter name', () => {
+ const content = fs.readFileSync(commandPath, 'utf-8');
+ assert.ok(content.includes('name: gsd:milestone-summary'), 'should have correct command name');
+ });
+
+ test('command references workflow in execution_context', () => {
+ const content = fs.readFileSync(commandPath, 'utf-8');
+ assert.ok(
+ content.includes('workflows/milestone-summary.md'),
+ 'should reference the milestone-summary workflow'
+ );
+ });
+
+ test('command accepts optional version argument', () => {
+ const content = fs.readFileSync(commandPath, 'utf-8');
+ assert.ok(content.includes('argument-hint'), 'should have argument-hint');
+ assert.ok(content.includes('[version]'), 'version should be optional (bracketed)');
+ });
+});
+
+describe('milestone-summary workflow', () => {
+ test('workflow file exists', () => {
+ assert.ok(fs.existsSync(workflowPath), 'workflows/milestone-summary.md should exist');
+ });
+
+ test('workflow reads milestone artifacts', () => {
+ const content = fs.readFileSync(workflowPath, 'utf-8');
+ const requiredArtifacts = [
+ 'ROADMAP.md',
+ 'REQUIREMENTS.md',
+ 'PROJECT.md',
+ 'SUMMARY.md',
+ 'VERIFICATION.md',
+ 'CONTEXT.md',
+ 'RETROSPECTIVE.md',
+ ];
+ for (const artifact of requiredArtifacts) {
+ assert.ok(
+ content.includes(artifact),
+ `workflow should reference ${artifact}`
+ );
+ }
+ });
+
+ test('workflow writes to reports directory', () => {
+ const content = fs.readFileSync(workflowPath, 'utf-8');
+ assert.ok(
+ content.includes('.planning/reports/MILESTONE_SUMMARY'),
+ 'should write summary to .planning/reports/'
+ );
+ });
+
+ test('workflow has interactive Q&A mode', () => {
+ const content = fs.readFileSync(workflowPath, 'utf-8');
+ assert.ok(
+ content.includes('Interactive Mode') || content.includes('ask anything'),
+ 'should offer interactive Q&A after summary'
+ );
+ });
+
+ test('workflow handles both archived and current milestones', () => {
+ const content = fs.readFileSync(workflowPath, 'utf-8');
+ assert.ok(content.includes('Archived milestone'), 'should handle archived milestones');
+ assert.ok(content.includes('Current') || content.includes('in-progress'), 'should handle current milestones');
+ });
+
+ test('workflow generates all 7 summary sections', () => {
+ const content = fs.readFileSync(workflowPath, 'utf-8');
+ const sections = [
+ 'Project Overview',
+ 'Architecture',
+ 'Phases Delivered',
+ 'Requirements Coverage',
+ 'Key Decisions',
+ 'Tech Debt',
+ 'Getting Started',
+ ];
+ for (const section of sections) {
+ assert.ok(
+ content.includes(section),
+ `summary should include "${section}" section`
+ );
+ }
+ });
+
+ test('workflow updates STATE.md', () => {
+ const content = fs.readFileSync(workflowPath, 'utf-8');
+ assert.ok(
+ content.includes('state record-session'),
+ 'should update STATE.md via gsd-tools'
+ );
+ });
+});