STOP — DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by Claude Code's plugin system. Using the Read tool on this SKILL.md file wastes ~7,600 tokens. Begin executing Step 1 immediately.
Step 0 — Immediate Output
Before ANY tool calls, display this banner:
╔══════════════════════════════════════════════════════════════╗
║ PLAN-BUILD-RUN ► MILESTONE ║
╚══════════════════════════════════════════════════════════════╝
Then proceed to Step 1.
/pbr:milestone — Milestone Management
You are running the milestone skill. Milestones represent significant project checkpoints — a set of phases that together deliver a cohesive chunk of functionality. This skill handles the full milestone lifecycle: creation, completion, auditing, and gap analysis.
This skill runs inline for most subcommands, but spawns agents for audit.
References
references/questioning.md— Questioning patterns for milestone review decisionsreferences/ui-brand.md— Status symbols, banners, milestone celebration format
Context Budget
Reference: skills/shared/context-budget.md for the universal orchestrator rules.
Reference: skills/shared/agent-type-resolution.md for agent type fallback when spawning Task() subagents.
Additionally for this skill:
- Never perform integration checks yourself — delegate to the integration-checker subagent
- Minimize reading audit and verification outputs — read only frontmatter and status fields
- Delegate all cross-phase integration analysis to the integration-checker subagent
Multi-Session Sync
Before any phase-modifying operations (archiving phases, updating ROADMAP.md/STATE.md/PROJECT.md), acquire a claim:
acquireClaim(planningDir, sessionId)
If the claim fails (another session owns this project), display: "Another session owns this project. Use /pbr:progress to see active claims."
On completion or error (including all exit paths), release the claim:
releaseClaim(planningDir, sessionId)
Core Principle
Milestones are the rhythm of the project. They force you to step back, verify everything works together, and create a clean snapshot before moving on. Never skip the audit — integration issues hide at milestone boundaries.
Argument Parsing
Parse $ARGUMENTS for the subcommand and optional version:
$ARGUMENTS format: {subcommand} [{version/name}]
Examples:
"new" → subcommand=new, arg=none
"new User Auth" → subcommand=new, arg="User Auth"
"complete v1.0" → subcommand=complete, arg="v1.0"
"complete 1.0" → subcommand=complete, arg="v1.0" (auto-prefix v)
"preview v1.0" → subcommand=preview, arg="v1.0"
"audit v1.0" → subcommand=audit, arg="v1.0"
"audit" → subcommand=audit, arg=current milestone
"gaps" → subcommand=gaps, arg=most recent audit
If no subcommand recognized: Show usage:
Usage: /pbr:milestone <subcommand> [version]
Subcommands:
new [name] — Start a new milestone cycle
complete [ver] — Archive completed milestone
preview [ver] — Dry-run of complete (show what would happen)
audit [ver] — Verify milestone completion
gaps — Create phases to close audit gaps
CRITICAL — After parsing the subcommand, run init command before any manual state reads:
node plugins/pbr/scripts/pbr-tools.js init milestone
Store the JSON result as blob. This single call replaces multiple file reads across all subcommands:
blob.state.current_phase,blob.state.status— current phase and status from STATE.mdblob.state.last_milestone_version,blob.state.last_milestone_completed— milestone historyblob.has_roadmap— whether ROADMAP.md existsblob.has_project— whether PROJECT.md existsblob.milestones— array of milestone sections parsed from ROADMAP.md (each withnameandphases_range)blob.existing_archives— array of existing archive directory namesblob.phase_count— total phase countblob.config.mode,blob.config.planning,blob.config.git— config settings
If blob.error is set, display the error banner and stop (no project found).
Subcommand: new
Start a new milestone cycle with new phases.
Flow
Read current state from init blob:
blob.milestonesfor existing milestone sections from ROADMAP.mdblob.state.current_phaseandblob.state.statusfor current positionblob.has_projectto check if PROJECT.md exists (read it for milestone history if needed)blob.phase_countfor total phase count
Get milestone details via AskUserQuestion:
- "What's the name/goal for this new milestone?"
- "What are the major features or capabilities it should deliver?"
- If the user provided a name in
$ARGUMENTS, use it and skip the name question
Determine phase numbering:
- Find the highest phase number in the current ROADMAP.md
- New phases start at highest + 1
- Example: if phases 1-5 exist, new milestone starts at phase 6
Mini roadmap session: Run a condensed version of the
/pbr:new-projectquestioning flow:a. Ask about major components needed (via AskUserQuestion):
- "What are the 2-5 major areas of work for this milestone?"
b. For each area, ask:
- "Any specific requirements or constraints for {area}?"
c. Generate phases from the areas:
- Each major area becomes a phase
- Order by dependency (foundations first)
- Include brief description and success criteria
Update ROADMAP.md: Append new milestone section:
--- ## Milestone: {name} **Goal:** {goal statement} **Phases:** {start_num} - {end_num} ### Phase {N}: {name} **Goal:** {goal} **Requirements:** {REQ-IDs mapped to this phase} **Success Criteria:** {verifiable conditions for phase completion} **Depends on:** {prior phases} ### Phase {N+1}: {name} ...Create phase directories: For each new phase:
.planning/phases/{NN}-{slug}/Update PROJECT.md (create if needed): Add milestone to the active milestones list:
## Active Milestones ### {name} - **Phases:** {start} - {end} - **Created:** {date} - **Status:** In progress
CRITICAL (no hook) -- DO NOT SKIP: Update STATE.md frontmatter AND body with new milestone info.
- Update STATE.md:
- Set current phase to the first new phase
- Update milestone info
CRITICAL (no hook) -- DO NOT SKIP: Generate root MILESTONE.md file.
8b. Generate root MILESTONE.md:
Read the current milestone section from ROADMAP.md (the ## Milestone: section just created in Step 5) and STATE.md for current phase and status. Write MILESTONE.md at the project root with:
# Current Milestone: {name}
**Version:** {version} | **Status:** In Progress | **Created:** {date}
**Goal:** {goal}
## Phases
| Phase | Goal | Status |
|-------|------|--------|
| {N}. {name} | {goal} | Pending |
...
---
*Auto-generated by `/pbr:milestone new`. Updated by `/pbr:autonomous`.*
- Read the phase list from the ROADMAP.md section just written in Step 5
- Status column: "Pending" for all new phases
Milestone branch creation (when git.branching is 'milestone'):
When starting a new milestone and git.branching is milestone:
- Create branch:
git switch -c pbr/milestone-v{version} - All phase work happens on this branch
- Branch is merged when
/pbr:milestone completeis run
Commit if
planning.commit_docs: true:docs(planning): start milestone "{name}" (phases {start}-{end})Confirm with branded output — read
${CLAUDE_SKILL_DIR}/templates/new-output.md.tmpland fill in{name}(milestone name),{count}(phase count),{N}(first phase number).
Subcommand: preview
Dry-run of milestone completion — shows what would happen without making any changes.
Flow
Determine version:
- Same logic as
complete: use$ARGUMENTSor ask via AskUserQuestion
- Same logic as
Identify milestone phases:
- Read ROADMAP.md to find phases belonging to this milestone
- List each phase with its current status (from STATE.md or VERIFICATION.md)
Verification status check:
- For each milestone phase, check if VERIFICATION.md exists and its
resultfrontmatter - Flag phases that are unverified or have stale verification (SUMMARY.md newer than VERIFICATION.md)
- For each milestone phase, check if VERIFICATION.md exists and its
Preview archive structure:
- Show what the archive directory would look like:
.planning/milestones/v{version}/ ├── ROADMAP.md (snapshot) ├── STATS.md (would be generated) ├── REQUIREMENTS.md (snapshot) └── phases/ ├── {NN}-{slug}/ (moved from .planning/phases/) │ ├── PLAN-01.md │ ├── SUMMARY.md │ └── VERIFICATION.md └── ...
- Show what the archive directory would look like:
Show what would change:
- Which phase directories would be moved
- What ROADMAP.md section would be collapsed
- What STATE.md updates would occur
- What git tag would be created
Display summary:
╔══════════════════════════════════════════════════════════════╗ ║ PLAN-BUILD-RUN ► MILESTONE PREVIEW — v{version} ║ ╚══════════════════════════════════════════════════════════════╝ Phases to archive: {count} ✓ Verified: {verified_count} ⚠ Unverified: {unverified_count} ⚠ Stale verification: {stale_count} Archive location: .planning/milestones/v{version}/ Git tag: v{version} Ready to complete? Run: /pbr:complete-milestone v{version}
CRITICAL (no hook): This subcommand is READ-ONLY. Do not create directories, move files, modify STATE.md, modify ROADMAP.md, or create git tags. Only read and display.
Subcommand: complete
Archive a completed milestone and prepare for the next one.
Flow
Determine version:
- If provided in
$ARGUMENTS: use it (auto-prefixvif missing) - If not provided: ask via AskUserQuestion: "What version number for this milestone? (e.g., v1.0)"
- If provided in
Check verification debt across ALL phases:
- Use
blob.milestonesto find the target milestone's phase range - For each phase in the range, check VERIFICATION.md status:
gaps_foundorhuman_neededorpartial→ verification debt exists
- If verification debt found, display warning:
Verification Debt: - Phase {N}: {status} ({count} outstanding items) - This is non-blocking but prominently displayed before the completion decision
- Use
Verify all phases are complete:
For each phase in the range, check for VERIFICATION.md
If any phase lacks VERIFICATION.md:
Present the warning context: Unverified phases:
- Phase {N}: {name}
- Phase {M}: {name}
CRITICAL -- DO NOT SKIP: Present the following choice to the user via AskUserQuestion before proceeding: Use AskUserQuestion (pattern: yes-no from
skills/shared/gate-prompts.md): question: "{count} phases haven't been verified. Continue with milestone completion?" header: "Unverified" options: - label: "Continue anyway" description: "Proceed despite unverified phases (not recommended)" - label: "Stop and review" description: "Run /pbr:verify-work for unverified phases first"- If "Stop and review" or "Other": stop and suggest the review commands for each unverified phase
- If "Continue anyway": proceed with warning noted
Timestamp freshness check: For each phase that has a VERIFICATION.md, compare its
checked_atfrontmatter timestamp against the most recent SUMMARY.md file modification date in that phase directory (usels -tor file stats). If any SUMMARY.md is newer than its VERIFICATION.mdchecked_at:- Warn: "Phase {N} ({name}) was modified after verification. The VERIFICATION.md may not reflect the current code state."
- List affected phases with their freshness details
CRITICAL -- DO NOT SKIP: Present the following choice to the user via AskUserQuestion before proceeding: Use AskUserQuestion (pattern: stale-continue from
skills/shared/gate-prompts.md): question: "{count} phases were modified after verification. Re-verify or continue?" header: "Stale" options: - label: "Re-verify" description: "Run /pbr:verify-work for affected phases (recommended)" - label: "Continue anyway" description: "Proceed with potentially outdated verification"- If "Re-verify" or "Other": suggest the review commands for affected phases and stop
- If "Continue anyway": proceed with warning noted
Gather milestone stats:
# Get commit range for this milestone's phases git log --oneline --since="{milestone start date}" --until="now" # Count files changed git diff --stat {first_milestone_commit}..HEADCollect:
- Total commits in milestone
- Total files changed
- Lines added / removed
- Duration (start date to now)
- Number of phases completed
- Number of plans executed
- Number of quick tasks
Extract accomplishments: Read all SUMMARY.md files for milestone phases:
- Collect
providesfields (what was built) - Collect
key_decisionsfields - Collect
patternsfields - Collect
tech_stackunion
- Collect
Milestone branching (config-gated):
Read blob.config.git.branching (or fall back to reading config if blob unavailable).
- If
milestone: a. Check if milestone branch exists:git branch --list pbr/milestone-v{version}b. If branch exists:- Use AskUserQuestion:
question: "Milestone v{version} complete. Merge branch
pbr/milestone-v{version}to main?" header: "Merge milestone branch?" options:- label: "Yes, merge" description: "Merge milestone branch to main and delete it"
- label: "No, keep" description: "Keep the branch for manual review"
- If "Yes, merge":
git switch maingit merge --no-ff pbr/milestone-v{version}(no-ff to preserve milestone history)git branch -d pbr/milestone-v{version}- Log: "Milestone branch merged and deleted"
- If "No, keep": leave branch as-is c. If branch does not exist: no action (phases were on main or individual phase branches)
- Use AskUserQuestion:
question: "Milestone v{version} complete. Merge branch
- If
none,phase, ordisabled: no milestone branch operations
Archive milestone documents:
CRITICAL (no hook): Pre-flight safety checks BEFORE archiving. Do NOT skip this step.
Before creating or moving anything, verify the destination is safe:
- Check
blob.existing_archivesto see if the version directory already exists - If it exists AND contains files (phases/, STATS.md, etc.), STOP and display:
Ask the user via AskUserQuestion whether to use a different version or abort.╔══════════════════════════════════════════════════════════════╗ ║ ERROR ║ ╚══════════════════════════════════════════════════════════════╝ Archive destination `.planning/milestones/{version}/` already contains files. Completing this milestone would overwrite the existing archive. **To fix:** Run `/pbr:health` or manually inspect `.planning/milestones/{version}/`. Use a different version number (e.g., {version}.1) or remove the existing archive first. - Verify each source phase directory exists before attempting to move it
- If any source phase directory is missing, warn but continue with the phases that do exist
CRITICAL (no hook): Back up ROADMAP.md BEFORE any destructive operations. Do NOT skip this step.
Use the compound init-milestone command to atomically create the archive directory, copy ROADMAP.md, copy REQUIREMENTS.md (if present), and update STATE.md:
pbr-tools compound init-milestone {version} --name "{milestone_name}" --phases "{start}-{end}"This MUST happen before any of the following: moving phase directories, collapsing ROADMAP.md sections, or further STATE.md updates.
The compound command creates the archive directory and copies ROADMAP.md + REQUIREMENTS.md. Now move phase directories and create STATS.md:
.planning/milestones/{version}/STATS.md— milestone statistics.planning/milestones/{version}/phases/{NN}-{slug}/— move each milestone phase directory from.planning/phases/into the archive
CRITICAL (no hook): Move phase directories from .planning/phases/ to archive NOW. Do NOT skip this step.
Move phases: For each phase belonging to this milestone, move (not copy) its directory from
.planning/phases/{NN}-{slug}/to.planning/milestones/{version}/phases/{NN}-{slug}/. This keeps the active phases directory clean for the next milestone.CRITICAL (no hook): Write STATS.md to .planning/milestones/{version}/STATS.md NOW. Do NOT skip this step.
Stats file content:
Read
${CLAUDE_SKILL_DIR}/templates/stats-file.md.tmplfor the stats file format. Fill in all{variable}placeholders with actual data gathered in Steps 3-4.- Check
5b. Archive stale research data:
After archiving phase directories, prune stale research/intel/codebase data that predates the milestone:
pbr-tools data prune --before {milestone_start_date}
Where {milestone_start_date} is the earliest phase start date from the milestone (derived from the first SUMMARY.md start_time or the milestone creation date).
- Log the count of archived files (e.g., "Archived 12 stale research files")
- If no files to archive, log "No stale research files to archive"
- Note: SUMMARY.md, STACK.md, and FEATURES.md are preserved (never pruned) since they are canonical references for active work
Update PROJECT.md:
- Move milestone from "Active" to "Completed"
- Add completion date and version tag
## Completed Milestones ### {name} ({version}) - **Completed:** {date} - **Phases:** {start} - {end} - **Key deliverables:** {summary}- Move validated requirements from active to completed section
CRITICAL (no hook): Run PROJECT.md evolution review NOW. Do NOT skip this step.
6b. PROJECT.md Evolution Review: After moving the milestone to completed status, review and evolve the project definition:
- Move completed Active Requirements to Validated — Any requirement from the completed milestone that was satisfied (per VERIFICATION.md) should move from Active to Validated section
- Review Out of Scope — Check if any previously out-of-scope items are now unblocked by the completed milestone's deliverables. If so, note them for the user's consideration (do not move them automatically)
- Annotate Key Decisions with outcomes — For each Key Decision in PROJECT.md that relates to the completed milestone, add an Outcome column value:
Good(decision worked well),Revisit(decision caused issues), orPending(outcome not yet clear) - Update Constraints — Remove or update any constraints that changed during the milestone (e.g., a technology constraint that was relaxed)
- Refresh Core Value — If the project direction shifted meaningfully during the milestone, suggest an updated Core Value statement to the user via AskUserQuestion
CRITICAL (no hook): Update ROADMAP.md with collapsed milestone section NOW. Do NOT skip this step.
Collapse completed phases in ROADMAP.md: Replace detailed phase entries with a
<details>collapsed summary (backward compat: also recognized by-- COMPLETEDtext):<details> <summary>## Milestone: {name} ({version}) — SHIPPED {date}</summary> | Phase | Status | |-------|--------| | {N}. {name} | Completed | | {N+1}. {name} | Completed | Completed: {date} | Archive: `.planning/milestones/{version}/` </details>
7a. Update milestone index:
After collapsing the milestone, update or create a ## Milestones index section near the top of ROADMAP.md (after the title, before the first active milestone). Each entry is one line:
## Milestones
| Version | Name | Status | Date |
|---------|------|--------|------|
| {version} | {name} | SHIPPED | {date} |
If the section already exists, append a row. If it does not exist, create it.
CRITICAL (no hook): Update STATE.md to mark milestone as complete NOW. Do NOT skip this step.
7b. Update STATE.md:
- Update
.planning/STATE.mdfrontmatter to reset to idle state:current_phase: nullphase_slug: nullphase_name: nullphases_total: 0status: "idle"progress_percent: 0plans_total: 0plans_complete: 0last_activity: "{date} Milestone {version} complete"
- Update the body section to reflect idle state (no active phase)
7c. Record milestone completion in STATE.md frontmatter:
- Update STATE.md frontmatter with milestone completion data:
- Set
last_milestone_version: "{version}" - Set
last_milestone_completed: "{ISO datetime}"
- Set
- Do NOT write to a ## History section in STATE.md — History has been removed from STATE.md to keep it lean. Milestone completion records are preserved in the archive's STATS.md and ROADMAP.md snapshot.
- If a ## History section exists in STATE.md (from a prior version), remove it during milestone completion to enforce the new format.
Run state reconcile after archival to reset phases_total and current_phase to reflect the next milestone's phases:
pbr-tools state reconcile
This command re-derives phase counts from ROADMAP.md and reports any phantom phase rows (progress table rows with no corresponding directory on disk). Review and remove phantom rows manually if no longer needed.
CRITICAL (no hook): Reconcile ROADMAP phase statuses NOW. Do NOT skip this step.
7c2. ROADMAP Reconciliation: After state reconcile, run a full reconciliation pass to fix any stale phase statuses across the entire ROADMAP:
pbr-tools roadmap reconcile
- Log the output (number of entries fixed)
- This catches phase status mismatches that accumulated during the milestone lifecycle
- Covers both the just-completed milestone and any prior stale entries
7d. Aggregate learnings into KNOWLEDGE.md from milestone phases:
CRITICAL (no hook): Run learnings aggregation NOW. Do NOT skip this step.
node ${CLAUDE_PLUGIN_ROOT}/scripts/milestone-learnings.js .planning/milestones/{version} --project {project-name-from-STATE.md}
This script aggregates SUMMARY.md patterns, decisions, and deferred items into the project-scoped .planning/KNOWLEDGE.md (table format with K/P/L-prefixed IDs). It also writes to the global ~/.claude/learnings.jsonl for cross-project use.
- If the script outputs an error, log it but do NOT abort milestone completion — learnings aggregation is advisory.
- Display the aggregation summary line to the user (e.g., "KNOWLEDGE.md: 5 new entries, 2 duplicates skipped").
- After aggregation, check for triggered deferral thresholds:
pbr-tools learnings check-thresholds
If any thresholds are triggered, display each as a notification:
Note: Learnings threshold met — {key}: {trigger}. Consider implementing the deferred feature.
7e. Run calibration for all evaluative agents on expanded corpus:
pbr-tools calibrate all
This re-analyzes corpus data for all evaluative agents (verifier, audit, integration-checker, plan-checker) and updates .planning/intel/{agent}-calibration.md with gap patterns and recommendations. The calibration data informs each agent's few-shot examples.
- If the command fails, log it but do NOT abort — calibration is advisory.
- Display per-agent corpus size and pass rate summary to the user.
- If any agent has recommendations, note: "Calibration updated for {agents}. Review few-shot examples to apply findings."
Git tag:
git tag -a {version} -m "Milestone: {name}"Generate RETROSPECTIVE.md:
The CLI (
pbr-tools.js milestone complete) auto-generates a RETROSPECTIVE.md entry. Verify it exists at.planning/RETROSPECTIVE.md. If the CLI was not used (manual completion), create the entry using${CLAUDE_PLUGIN_ROOT}/templates/RETROSPECTIVE.md.tmplas the format reference. Fill in{version},{name},{date}, and the "What Was Built" section from MILESTONES.md accomplishments. Leave other sections as placeholders for the user to fill.
9aa. Insights integration:
Check for a recent /insights HTML report:
find ~/.claude/insights/ -name "*.html" -mtime -7 2>/dev/null | head -1
If a recent report exists (modified within 7 days):
- Read the HTML file and extract key workflow findings (friction patterns, efficiency suggestions, recurring issues)
- Append a "## Workflow Insights" section to
.planning/RETROSPECTIVE.mdwith 3-5 bullet points summarizing the most relevant insights for this milestone's work - Add the RETROSPECTIVE.md to the git staging area
If no recent report exists: Display this suggestion after the RETROSPECTIVE.md is generated:
Tip: Run /insights to capture workflow patterns from this milestone's sessions.
Insights feed into future audits and help the planner avoid repeated friction.
9a. Commit:
git add .planning/milestones/ .planning/phases/ .planning/ROADMAP.md .planning/PROJECT.md .planning/STATE.md .planning/RETROSPECTIVE.md
git commit -m "docs(planning): complete milestone {version}"
CRITICAL (no hook): Generate changelog entry NOW. Do NOT skip this step.
9b. Generate changelog entry:
Generate a user-facing changelog entry for this milestone. Read all SUMMARY.md files from the milestone phases (now in .planning/milestones/{version}/phases/) and categorize deliverables into Keep a Changelog sections:
- Added — New features, commands, capabilities (from SUMMARY.md
providesfields) - Changed — Modifications to existing behavior, UI updates, performance improvements
- Fixed — Bug fixes, error corrections (from commits with
fix:type)
Format each entry with a bolded feature name followed by an em-dash and description:
### Added
- **Feature name** — What it does and why it matters
- **Another feature** — Description focusing on user impact
Rules for good entries:
- Lead with the user-visible impact, not the implementation detail
- Group related commits into a single entry (e.g., 5 commits for "auth" become one "Authentication system" entry)
- Use bold feature names, not commit scopes
- No commit hashes — this is prose, not a git log
- No internal scopes (phase-plan numbers, TDD markers)
- End with install line:
Install/upgrade: \npx @sienklogic/plan-build-run@latest``
Draft the full entry and present it to the user for review:
Use AskUserQuestion:
question: "Here's the draft changelog for {version}. Want to edit it before writing?"
header: "Changelog"
options:
- label: "Looks good" description: "Write this to CHANGELOG.md as-is"
- label: "Edit" description: "I'll provide corrections"
- label: "Skip changelog" description: "Don't update the changelog for this release"
- If "Looks good": write the entry to CHANGELOG.md (insert after the header, before any existing version entries)
- If "Edit" or "Other": apply the user's corrections, then present again for final confirmation
- If "Skip changelog": proceed without changelog update
If writing to CHANGELOG.md:
git add CHANGELOG.md
git commit -m "docs: update changelog for {version}"
9c. Push milestone to remote:
Use AskUserQuestion to ask the user how they want to publish the milestone:
question: "How should this milestone be published to GitHub?"
header: "Publish"
options:
- label: "Push tag + commits" description: "Push the v{version} tag and any unpushed commits to origin"
- label: "Skip for now" description: "Keep everything local — push later manually"
- If "Push tag + commits": run
git push origin main --follow-tagsto push both commits and the annotated tag in one command. Display success or error. - If "Skip for now": display reminder: "Tag v{version} is local only. Push when ready:
git push origin main --follow-tags" - If "Other": follow user instructions (e.g., create a PR, push to a different branch, etc.)
9d. Automatic npm release:
After pushing, automatically run the npm release to publish this milestone:
npm run release -- --minor
Display the output to the user. The --minor flag is used because milestone completions always represent new features.
- If the release succeeds: display the new version number and GitHub Release URL
- If the release fails: show the error as an advisory warning — the milestone is already archived. Suggest the user run
npm run releasemanually after fixing the issue.
Post-Completion Smoke Test
If config.deployment.smoke_test_command is set and non-empty:
Run the command via Bash
If exit code 0: display "Smoke test passed" with command output
If exit code non-zero: display advisory warning:
⚠ Smoke test failed (exit code {N}) Command: {smoke_test_command} Output: {first 20 lines of output}This is advisory only — the milestone is already archived. Surface it as a potential issue for the user to investigate.
Confirm with branded output — read
${CLAUDE_SKILL_DIR}/templates/complete-output.md.tmpland fill in{version},{count}(phases, plans, commits),{lines},{duration}.
NEXT UP block after milestone complete:
After displaying the branded complete-output banner, always display a NEXT UP routing block:
╔══════════════════════════════════════════════════════════════╗
║ ▶ NEXT UP ║
╚══════════════════════════════════════════════════════════════╝
**Start the next milestone** — continue development with new phases
`/pbr:milestone new`
**Also available:**
- `/pbr:release` — tag and publish this milestone as a GitHub Release
- `/pbr:status` — review project state before continuing
<sub>`/clear` first → fresh context window</sub>
This ensures the milestone complete subcommand never ends in a routing dead end.
Subcommand: audit
Verify milestone completion with cross-phase integration checks.
Flow
Determine target:
- If version provided: audit that specific milestone
- If no version: audit the current milestone (use
blob.milestonesto identify the most recent active milestone)
Read all VERIFICATION.md files for milestone phases (use
blob.milestonesto identify the phase range):- Collect verification results
- Note any
gaps_foundstatuses - Note any phases without verification
Spawn integration checker:
Display to the user:
◆ Spawning integration checker...Spawn
Task(subagent_type: "pbr:integration-checker"). Read${CLAUDE_SKILL_DIR}/templates/integration-checker-prompt.md.tmpl, fill in{version or "current"},{list of phase directories}, and{phase SUMMARY.md paths}, then use the filled template as the Task() prompt.Check integration-checker completion:
After the integration-checker completes, check for
## INTEGRATION CHECK COMPLETEin the Task() output. If the marker is absent, warn:⚠ Integration checker did not return completion marker — results may be incomplete.Proceed with whatever findings were returned but note the incomplete status in the audit report.Check requirements coverage:
- Read REQUIREMENTS.md
- For each requirement tagged for this milestone:
- Search VERIFICATION.md files for coverage
- Search SUMMARY.md
providesfields - Flag uncovered requirements
Write audit report:
Create
.planning/{version}-MILESTONE-AUDIT.mdusing the structured template:Read
${CLAUDE_PLUGIN_ROOT}/templates/MILESTONE-AUDIT.md.tmplfor the audit report format with YAML frontmatter scores. Fill in all{variable}placeholders with actual data from the audit. The YAML frontmatter MUST includescores(requirements, phases, integration, flows),gapsarray, andtech_debtarray.Spot-check: After writing, verify
.planning/{version}-MILESTONE-AUDIT.mdexists on disk using Glob. If missing, re-attempt the write. If still missing, display an error and include findings inline.Report to user using branded banners — read
${CLAUDE_SKILL_DIR}/templates/audit-output.md.tmpl. The template contains all 3 variants (PASSED, GAPS FOUND, TECH DEBT). Select the appropriate section based on audit result. Fill in{version},{count},{gap 1},{gap 2}as applicable.
Subcommand: gaps
Create phases to close gaps found during an audit.
Flow
Find most recent audit:
- Search for
*-MILESTONE-AUDIT.mdin.planning/ - If multiple, use the most recent
- If none: "No audit found. Run
/pbr:audit-milestonefirst."
- Search for
Read audit report:
- Extract all gaps and tech debt items
- Parse severity levels
Prioritize gaps:
Group by priority:
- Must fix (critical/high): Blocking issues, broken integration, uncovered requirements
- Should fix (medium): Non-critical integration issues, important tech debt
- Nice to fix (low): Minor tech debt, optimization opportunities
Present to user:
Gaps from milestone audit: Must fix ({count}): - {gap}: {description} Should fix ({count}): - {gap}: {description} Nice to fix ({count}): - {gap}: {description} **CRITICAL -- DO NOT SKIP**: Present the following choice to the user via AskUserQuestion before proceeding: Use AskUserQuestion (pattern: multi-option-priority from `skills/shared/gate-prompts.md`): question: "Which gaps should we address? ({must_count} must-fix, {should_count} should-fix, {nice_count} nice-to-fix)" header: "Priority" options: - label: "Must-fix only" description: "Address {must_count} critical/high gaps" - label: "Must + should" description: "Address {must_count + should_count} critical through medium gaps" - label: "Everything" description: "Address all {total_count} gaps including low priority" - label: "Let me pick" description: "Choose specific gaps to address" - If "Must-fix only": filter to must-fix gaps for phase creation - If "Must + should": filter to must-fix + should-fix gaps - If "Everything": include all gaps - If "Let me pick" or "Other": present individual gaps for selectionGroup into logical phases:
- Group related gaps together (same subsystem, same files)
- Each group becomes a phase
- Name phases descriptively: "{N+1}. Fix {area} integration" or "{N+1}. Address {component} gaps"
Update ROADMAP.md: Add gap-closure phases after the current milestone phases:
### Phase {N}: Fix {area} (gap closure) **Goal:** Address gaps found in milestone audit **Gaps addressed:** - {gap 1} - {gap 2} **Success criteria:** All addressed gaps pass verificationCreate phase directories:
.planning/phases/{NN}-fix-{slug}/Commit:
docs(planning): add gap-closure phases from milestone auditConfirm with branded output — read
${CLAUDE_SKILL_DIR}/templates/gaps-output.md.tmpland fill in{count}(gap-closure phases created),{N}(first gap phase number),{name}(phase name).
State Integration
All subcommands use blob.state and blob.config from the init call for reading state. All subcommands update STATE.md on write:
new: Sets current milestone, resets phasecomplete: Clears current milestone, updates historyaudit: Notes audit status and dategaps: Updates phase count and roadmap info
Git Integration
Reference: skills/shared/commit-planning-docs.md for the standard commit pattern.
All subcommands commit if blob.config.planning.commit_docs is true:
new:docs(planning): start milestone "{name}" (phases {start}-{end})complete:docs(planning): complete milestone {version}audit:docs(planning): audit milestone {version} - {status}gaps:docs(planning): add gap-closure phases from milestone audit
Tags (complete only):
git tag -a {version} -m "Milestone: {name}"
Reference: skills/shared/error-reporting.md for branded error output patterns.
Edge Cases
For all edge case handling, see ${CLAUDE_SKILL_DIR}/templates/edge-cases.md.
Key scenarios: no ROADMAP.md, no phases, no gaps found, version collision, partially verified, large milestone (8+ phases).
Anti-Patterns
- DO NOT skip the audit before completing — integration issues hide at boundaries
- DO NOT auto-complete milestones without user confirmation
- DO NOT create gap phases without user approval of priorities
- DO NOT delete audit reports — they're historical records
- DO NOT reuse version numbers — each milestone gets a unique version
- DO NOT modify code during milestone operations — this is project management only
- DO NOT collapse phases in ROADMAP.md before archiving — archive first, collapse second
- DO NOT skip the git tag — tags make milestone boundaries findable