From nanopm
Compares ROADMAP.md NOW items against actual commits since the last roadmap run. Surfaces what shipped, what drifted, and what to carry forward.
How this skill is triggered — by the user, by Claude, or both
Slash command
/nanopm:pm-retroThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- portability-v2 -->
Multi-host portability rules. When invoking
AskUserQuestion:
- The
headerfield MUST be a short noun phrase (≤ 12 characters). Mistral Vibe rejects longer headers withstring_too_long. Pick from:Start,Target,Scope,Audience,Methodology,Feature,Question.- The
optionslist MUST have at least 2 items. Vibe rejects empty/single-option calls. For free-text input, always provide ≥ 2 framing options (e.g.Yes, here's the input/Skip) — never callask_user_questionwithoptions: [].
source ~/.nanopm/lib/nanopm.sh 2>/dev/null || \
source .nanopm/lib/nanopm.sh 2>/dev/null || \
{ echo "ERROR: nanopm not installed. Run: curl -fsSL https://raw.githubusercontent.com/nmrtn/nanopm/main/setup | bash"; exit 1; }
nanopm_preamble
_RETRO_FILE=".nanopm/RETRO.md"
source ~/.nanopm/lib/nanopm.sh 2>/dev/null || source .nanopm/lib/nanopm.sh 2>/dev/null || true
nanopm_context_read pm-retro
nanopm_context_all
If prior retro found: "Prior retro from {ts}. This run covers commits since then."
[ -f ".nanopm/ROADMAP.md" ] && echo "ROADMAP_EXISTS" || echo "ROADMAP_MISSING"
_CHALLENGES=".nanopm/CHALLENGES.md"; [ -f "$_CHALLENGES" ] || _CHALLENGES=".nanopm/AUDIT.md" # legacy pre-rename name
[ -f "$_CHALLENGES" ] && echo "CHALLENGES_EXISTS" || echo "CHALLENGES_MISSING"
[ -d ".git" ] && echo "GIT_REPO" || echo "NOT_GIT_REPO"
If ROADMAP_MISSING and CHALLENGES_MISSING: "No ROADMAP.md or CHALLENGES.md found. Run /pm-challenge-me and /pm-roadmap first to get full retro value. Continuing with git history only."
If NOT_GIT_REPO: "This directory is not a git repo — can't read commit history. Run git init or navigate to your project root."
# When was the roadmap last written? Use as retro start point.
_ROADMAP_COMMIT=$(git log --oneline -1 -- .nanopm/ROADMAP.md 2>/dev/null | awk '{print $1}')
_CHALLENGES=".nanopm/CHALLENGES.md"; [ -f "$_CHALLENGES" ] || _CHALLENGES=".nanopm/AUDIT.md" # legacy pre-rename name
_CHALLENGES_COMMIT=$(git log --oneline -1 -- "$_CHALLENGES" 2>/dev/null | awk '{print $1}')
if [ -n "$_ROADMAP_COMMIT" ]; then
echo "WINDOW_START: $_ROADMAP_COMMIT"
_COMMITS=$(git log --oneline "${_ROADMAP_COMMIT}..HEAD" 2>/dev/null)
_COMMIT_COUNT=$(git rev-list --count "${_ROADMAP_COMMIT}..HEAD" 2>/dev/null || echo 0)
else
# Fall back to last 30 commits if no roadmap commit found
echo "WINDOW_START: last 30 commits (no roadmap anchor)"
_COMMITS=$(git log --oneline -30 2>/dev/null)
_COMMIT_COUNT=30
fi
echo "COMMITS_IN_WINDOW: $_COMMIT_COUNT"
echo "$_COMMITS"
Tell the user: "Reviewing {N} commits since roadmap was written {date or 'recently'}."
If ROADMAP_EXISTS, extract the NOW items (planned work):
grep -A 50 '## NOW' .nanopm/ROADMAP.md 2>/dev/null | \
grep -B 50 '## NEXT\|## LATER\|^---' | \
grep -v '^##\|^---' | grep -v '^$' | head -30
Also extract NEXT items (look for any that may have been pulled forward early):
grep -A 50 '## NEXT' .nanopm/ROADMAP.md 2>/dev/null | \
grep -B 50 '## LATER\|^---' | \
grep -v '^##\|^---' | grep -v '^$' | head -20
Analyze the commit messages from Phase 2 against the roadmap items from Phase 3.
For each roadmap NOW item, classify as:
Also identify:
Be specific: quote commit messages when attributing work. Don't guess — if a commit is ambiguous, mark it as unclear.
If the commit messages are ambiguous about intent (e.g., very terse messages), ask via AskUserQuestion:
"A few commits weren't clear from message alone — can you tell me what {commit X} was about? (e.g., 'that was the payment flow refactor' or 'skip — it was minor cleanup')"
Only ask if genuinely unclear. Skip if all commits are parseable. Max one question.
Write .nanopm/RETRO.md:
# PM Retrospective
Generated by /pm-retro on {date}
Project: {slug}
Window: {N} commits ({start date or commit} → HEAD)
---
## What Shipped
{For each shipped roadmap item: item name + supporting commit(s). Be specific.}
| Item | Status | Evidence |
|------|--------|----------|
| {item} | ✅ Shipped | {commit sha/msg} |
| {item} | 🔄 In progress | {commit sha/msg} |
| {item} | ❌ Not started | — |
---
## Unplanned Work
{Commits that weren't in the roadmap. Be neutral — unplanned ≠ bad.
Sometimes the right thing appears and you do it. But flag the pattern if it's >30% of commits.}
{list commits with one-line interpretation}
---
## Drift Signal
{If >30% of commits are off-roadmap: flag it. Name the pattern.
If the strategy or challenge session is stale: call it out.
If carry-forward items outnumber shipped items: flag capacity/planning issue.
If nothing to flag: "No significant drift — execution is tracking the plan."}
---
## Carry Forward
{NOW items not shipped that should move into the next cycle. Copy them here verbatim
from ROADMAP.md so the next /pm-roadmap run can pull them in.}
- {item from ROADMAP.md NOW section}
---
## Recommended Next Skill
**Run: /pm-roadmap**
Update your roadmap with carry-forward items and new priorities from this retro.
---
*Sources: ROADMAP.md, git log, CHALLENGES.md (if present)*
source ~/.nanopm/lib/nanopm.sh 2>/dev/null || source .nanopm/lib/nanopm.sh 2>/dev/null || true
nanopm_context_append "{\"skill\":\"pm-retro\",\"outputs\":{\"shipped\":\"$(grep -c '✅' .nanopm/RETRO.md 2>/dev/null || echo 0) items shipped\",\"window_commits\":\"${_COMMIT_COUNT:-?} commits\",\"next\":\"pm-roadmap\"}}"
Tell the user:
.nanopm/RETRO.md/pm-roadmapSTATUS: DONE
npx claudepluginhub nmrtn/nanopm --plugin nanopmSynthesizes project docs and codebase into roadmap status, gaps analysis, blockers, risks, and next actions. Use for health checks, progress tracking, and milestone planning.
Reconciles Plans.md against implementation status and detects drift. Use for sync-status, progress checks, or snapshot creation.
Reviews and updates a project roadmap by cross-referencing PRDs, stories, and code to identify done, blocked, or stale items; supports marking items complete, reprioritizing, and validating consistency.