From harness-claude
Creates and manages unified project roadmaps by scanning specs in docs/changes/* and plans, proposing milestone groupings for human confirmation before writing docs/roadmap.md. Use for status checks or --create/--add/--sync/--edit.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Create and manage a unified project roadmap from existing specs and plans. Interactive, human-confirmed, always valid.
Reviews and maintains project ROADMAP.md by cross-referencing codebase, PRDs, marking items done, reprioritizing, and committing updates.
Selects next highest-impact unblocked roadmap item from docs/roadmap.md by scoring candidates on position, dependents, affinity; analyzes top specs and pulse reports; recommends and assigns after confirmation. For prioritizing multiple items.
Updates, creates, or reprioritizes product roadmaps using project trackers or user input. Adds items, changes statuses, applies RICE/MoSCoW/ICE prioritization, shifts timelines.
Share bugs, ideas, or general feedback.
Create and manage a unified project roadmap from existing specs and plans. Interactive, human-confirmed, always valid.
--create)--add <feature-name>)--sync)--edit)--createmanage_roadmap MCP tool directly)Never write docs/roadmap.md without the human confirming the proposed structure first.
If the human has not seen and approved the milestone groupings and feature list, do not write the file. Present. Wait. Confirm. Then write.
--create -- Bootstrap Roadmapdocs/roadmap.md already exists.
docs/changes/*/proposal.mddocs/changes/*/plans/*.md (preferred — co-located with proposals)docs/plans/*.md (legacy fallback for plans not yet migrated)spec:) or body text. Link them when a match is found.in-progress or completeplannedbacklogplanned (unusual, flag for human review)harness.config.json project field, or package.json name field, or directory name as fallback.Present scan summary:
SCAN COMPLETE
Project: <name>
Found: N specs, N plans
Matched: N spec-plan pairs
Unmatched specs: N (backlog candidates)
Unmatched plans: N (flag for review)
Present discovered features in default milestone groupings:
in-progressProposed Roadmap Structure:
## Current Work
- Feature A (in-progress) -- spec: docs/changes/feature-a/proposal.md
- Feature B (in-progress) -- spec: docs/changes/feature-b/proposal.md
## Backlog
- Feature C (planned) -- spec: docs/changes/feature-c/proposal.md
- Feature D (backlog) -- spec: docs/changes/feature-d/proposal.md
Offer choices:
Ask: "Are there additional features not captured in specs that should be on the roadmap?"
Repeat until the human selects (A) Accept.
Build the roadmap structure:
project, version: 1, created, updated timestampsStatus, Spec, Summary, Blockers, PlanWrite via manage_roadmap MCP tool if available. If MCP is unavailable, write directly using the roadmap markdown format and warn: "External sync skipped (MCP unavailable). Run manage_roadmap sync when MCP is restored to push changes to GitHub."
---
project: <name>
version: 1
created: YYYY-MM-DD
updated: YYYY-MM-DD
---
# Roadmap
## Current Work
### Feature A
- **Status:** in-progress
- **Spec:** docs/changes/feature-a/proposal.md
- **Summary:** One-line description of the feature
- **Blockers:** none
- **Plan:** docs/changes/feature-a/plans/2026-03-20-feature-a-plan.md
Write to docs/roadmap.md.
Read back docs/roadmap.md.
Verify via manage_roadmap show if MCP is available -- confirms round-trip parsing.
Run harness validate.
Present summary to human:
Roadmap created: docs/roadmap.md
Milestones: N
Features: N
harness validate: passed
--add <feature-name> -- Add a Featuredocs/roadmap.md exists.
--create first to bootstrap one."manage_roadmap show or direct read).<feature-name> already exists: error with message. "Feature '' already exists in milestone ''. Use a different name or edit the existing feature."Ask the human for each field interactively:
[NEW] option. If [NEW]: ask for the new milestone name.backlog, planned, in-progress, blocked.none.none.none.Present the collected details for confirmation:
New feature to add:
Milestone: Current Work
Name: Feature E
Status: planned
Spec: docs/changes/feature-e/proposal.md
Summary: Add feature E to the system
Blockers: none
Plan: none
Confirm? (y/n)
Wait for confirmation before proceeding.
manage_roadmap add MCP tool if available. If MCP is unavailable, parse the roadmap, add the feature to the specified milestone, and serialize back. Warn: "External sync skipped (MCP unavailable). Run manage_roadmap sync when MCP is restored to push changes to GitHub."[NEW]: create the milestone section, then add the feature.docs/roadmap.md.Read back docs/roadmap.md.
Verify the new feature appears in the correct milestone.
Run harness validate.
Confirm to human:
Feature added: Feature E -> Current Work
Total features: N
harness validate: passed
docs/roadmap.md exists.
--create. "No roadmap found at docs/roadmap.md. Run --create to bootstrap one from existing specs and plans."manage_roadmap show or direct read).Display a compact summary of the roadmap:
ROADMAP: <project-name>
Last synced: YYYY-MM-DD HH:MM
## <Milestone 1> (N features)
- Feature A .................. in-progress
- Feature B .................. planned
- Feature C .................. blocked (by: Feature A)
## <Milestone 2> (N features)
- Feature D .................. done
- Feature E .................. backlog
Total: N features | N done | N in-progress | N planned | N blocked | N backlog
If any features have stale sync timestamps (last_synced older than 24 hours), append a note:
Hint: Roadmap may be stale. Run `--sync` to update statuses from plan execution state.
No file writes. This is a read-only operation. No harness validate needed.
--sync -- Sync Statuses from Execution Statedocs/roadmap.md exists.
--create first to bootstrap one."manage_roadmap show or direct read)..harness/state.json (root execution state).harness/sessions/*/autopilot-state.json (session-scoped execution state)Infer status for each feature:
donein-progressblockedCheck the human-always-wins rule: if last_manual_edit is more recent than last_synced for a feature, preserve the manually set status. Report it as "skipped (manual override)".
Present proposed changes:
SYNC RESULTS
Changes detected:
- Feature A: planned -> in-progress (3/8 tasks started)
- Feature B: in-progress -> done (all tasks complete)
- Feature C: planned -> blocked (blocked by: Feature A, not done)
Unchanged:
- Feature D: done (no change)
Skipped (manual override):
- Feature E: kept as "planned" (manually edited 2h ago)
Apply these changes? (y/n)
Wait for human confirmation before applying.
manage_roadmap sync MCP tool if available, or via manage_roadmap update for each changed feature. If MCP is unavailable, parse the roadmap, update statuses, and serialize back. Warn: "External sync skipped (MCP unavailable). Run manage_roadmap sync when MCP is restored to push changes to GitHub."last_synced timestamp in frontmatter.docs/roadmap.md.Read back docs/roadmap.md.
Verify changes applied correctly via manage_roadmap show if MCP is available.
Run harness validate.
Present summary:
Sync complete: docs/roadmap.md
Updated: N features
Skipped: N (manual override)
Unchanged: N
harness validate: passed
--edit -- Interactive Edit SessionCheck if docs/roadmap.md exists.
--create first to bootstrap one."Parse the roadmap (via manage_roadmap show or direct read).
Present current structure:
Current roadmap: <project-name>
## <Milestone 1>
1. Feature A (in-progress)
2. Feature B (planned)
## <Milestone 2>
3. Feature C (done)
4. Feature D (backlog)
Offer edit actions in a loop until the human is done:
Reorder features within a milestone:
Move a feature between milestones:
[NEW]) -> move.[NEW]: ask for the new milestone name, create it.Update blockers:
Update status:
backlog, planned, in-progress, blocked, done -> update.Rename a feature:
Remove a feature:
Rename a milestone:
Done:
Present the menu after each action:
Edit actions:
(1) Reorder features within a milestone
(2) Move feature to different milestone
(3) Update blockers
(4) Update status
(5) Rename feature
(6) Remove feature
(7) Rename milestone
(D) Done -- save and exit
Choice?
Present a diff summary of all changes made during the edit session:
Changes to apply:
- Moved "Feature B" from "Current Work" to "Q2 Release"
- Updated "Feature A" blockers: none -> Feature C
- Reordered "Q2 Release": Feature B now at position 1
Apply? (y/n)
Wait for confirmation before writing.
Apply all changes via manage_roadmap update / manage_roadmap remove MCP tool calls, or direct file manipulation if MCP is unavailable. If falling back to direct manipulation, warn: "External sync skipped (MCP unavailable). Run manage_roadmap sync when MCP is restored to push changes to GitHub."
Update last_manual_edit timestamp in frontmatter (since this is a human-driven edit).
Write to docs/roadmap.md.
Read back docs/roadmap.md.
Verify changes applied correctly.
Run harness validate.
Present summary:
Edit complete: docs/roadmap.md
Changes applied: N
harness validate: passed
--query <filter> -- Query Features by Filterdocs/roadmap.md exists.
--create first to bootstrap one."manage_roadmap query or direct read).Accept filter patterns:
backlog, planned, in-progress, done, blocked -- returns all features with that statusmilestone:<name> -- returns all features in the named milestone (partial match)Display matching features with their milestone context:
QUERY: <filter>
Results (N matches):
- Feature A (Current Work) .................. in-progress
- Feature B (Backlog) ....................... planned
Total: N matches
No file writes. This is a read-only operation.
manage_roadmap MCP tool -- Primary read/write interface for roadmap operations. Supports show, add, update, remove, and query actions. Use this when MCP is available for structured CRUD.harness validate -- Run after any roadmap modification to verify project health. Mandatory in the VALIDATE phase of both --create and --add.parseRoadmap/serializeRoadmap -- Fallback when MCP is unavailable. These functions in packages/core/src/roadmap/ handle parsing and serializing the roadmap markdown format directly.docs/roadmap.md. This is the single source of truth for the project roadmap.--create discovers all specs (docs/changes/*/proposal.md) and plans (docs/changes/*/plans/*.md and legacy docs/plans/*.md)--create proposes groupings and waits for human confirmation before writing--create produces a valid docs/roadmap.md that round-trips through parseRoadmap/serializeRoadmap--add collects all fields interactively (milestone, status, spec, summary, blockers, plan)--add rejects duplicate feature names with a clear error message--add errors gracefully when no roadmap exists, directing the user to --create--create when no roadmap exists--sync when roadmap may be stale--sync scans .harness/state.json and .harness/sessions/*/autopilot-state.json for execution state--sync respects the human-always-wins rule -- manually edited statuses are preserved--sync presents proposed changes and waits for human confirmation before applying--sync errors gracefully when no roadmap exists, directing the user to --create--edit offers reorder, move, blocker update, status update, rename, and remove actions--edit presents a diff summary and waits for confirmation before writing--edit updates last_manual_edit timestamp (since changes are human-driven)harness validate passes after all operations--query filters features by status or milestone and displays results with milestone context--query errors gracefully when no roadmap exists, directing the user to --create| Rationalization | Reality |
|---|---|
| "The feature list looks correct, so I can skip the PROPOSE phase and write the roadmap directly" | The Iron Law: never write docs/roadmap.md without the human confirming the proposed structure first. |
| "This sync detected a status change and the inference is clearly correct, so I can apply it without confirmation" | The sync PROPOSE phase requires presenting proposed changes and waiting for human confirmation. The human-always-wins rule applies. |
| "The existing roadmap is outdated, so I will recreate it with --create to get a fresh start" | No overwriting an existing roadmap without explicit user consent. Silent overwrites destroy prior manual edits and status tracking. |
| "There is no roadmap yet but the user asked me to add a feature, so I will create one as a side effect of --add" | When the roadmap does not exist, --add must error with a clear message directing the user to --create. |
--create -- Bootstrap a Roadmap from Existing ArtifactsContext: A project with 3 specs and 2 plans. Two specs have matching plans (in-progress), one spec has no plan (backlog).
Phase 1: SCAN
SCAN COMPLETE
Project: my-project
Found: 3 specs, 2 plans
Matched: 2 spec-plan pairs
Unmatched specs: 1 (backlog candidates)
Unmatched plans: 0
Phase 2: PROPOSE
Proposed Roadmap Structure:
## Current Work
- Unified Code Review (in-progress) -- spec: docs/changes/unified-code-review/proposal.md
- Update Checker (in-progress) -- spec: docs/changes/update-checker/proposal.md
## Backlog
- Design System (backlog) -- spec: docs/changes/design-system/proposal.md
Options:
(A) Accept this structure
(B) Rename milestones or features
(C) Reorganize -- move features between milestones
(D) Add milestones
Any additional features not captured in specs? (y/n)
Human selects (A) Accept.
Phase 3: WRITE
Writing docs/roadmap.md...
2 milestones, 3 features
Phase 4: VALIDATE
Roadmap created: docs/roadmap.md
Milestones: 2 (Current Work, Backlog)
Features: 3
harness validate: passed
--add -- Add a Feature to an Existing RoadmapContext: A roadmap exists with 2 milestones and 3 features. Adding a new feature.
Phase 1: SCAN
Roadmap loaded: docs/roadmap.md
Milestones: 2 (Current Work, Backlog)
Features: 3
No duplicate found for "Notification System"
Phase 2: PROPOSE
Which milestone? [1] Current Work [2] Backlog [NEW] Create new
> 1
Status? [backlog] [planned] [in-progress] [blocked]
> planned
Spec? (path or "none")
> docs/changes/notification-system/proposal.md
One-line summary:
> Real-time notification delivery with WebSocket and email channels
Blockers? (or "none")
> none
Plan? (path or "none")
> none
New feature to add:
Milestone: Current Work
Name: Notification System
Status: planned
Spec: docs/changes/notification-system/proposal.md
Summary: Real-time notification delivery with WebSocket and email channels
Blockers: none
Plan: none
Confirm? (y/n)
Human confirms y.
Phase 3: WRITE
Adding feature to Current Work...
Phase 4: VALIDATE
Feature added: Notification System -> Current Work
Total features: 4
harness validate: passed
These are hard stops. Violating any gate means the process has broken down.
docs/roadmap.md without human confirmation of structure. The PROPOSE phase must complete with an explicit accept before any file is written. Skipping confirmation produces a roadmap the human did not agree to.docs/roadmap.md exists when --create runs, the human must confirm the overwrite. Silent overwrites destroy prior work.docs/roadmap.md is missing for --add. If the roadmap does not exist, do not create one silently. Error and direct the user to --create.docs/roadmap.md does not exist. --sync must error immediately with a message directing the user to --create. Do not create a roadmap as a side effect of sync.--edit without showing a diff summary and getting confirmation. The WRITE phase must present all pending changes and wait for explicit accept before modifying docs/roadmap.md.--create: Suggest creating a minimal roadmap with just a Backlog milestone containing features described verbally by the human. Alternatively, suggest running harness:brainstorming first to generate specs that can then be discovered by --create.docs/roadmap.md or recreation with --create (after backing up the existing file).parseRoadmap/serializeRoadmap functions handle the format. Report the fallback to the human: "MCP tool unavailable, using direct file operations. External sync skipped — run manage_roadmap sync when MCP is restored to push changes to GitHub."