> AI-assisted selection of the next highest-impact unblocked roadmap item. Scores candidates, recommends one, and transitions to the appropriate next skill. Selection does NOT assign — the `assignee` field names who is _executing_, and is written at execution start (harness-execution), not at selection.
Scanned 9/11/2026
Install to Claude Code
npx -y skills add Intense-Visions/harness-engineering --skill harness-roadmap-pilot --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Harness Roadmap Pilot?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/intense-visions-harness-roadmap-pilot)More formats (shields.io, HTML) on the badges page.
# Harness Roadmap Pilot
> AI-assisted selection of the next highest-impact unblocked roadmap item. Scores candidates, recommends one, and transitions to the appropriate next skill. Selection does NOT assign — the `assignee` field names who is _executing_, and is written at execution start (harness-execution), not at selection.
## When to Use
- When the team or individual needs to pick the next item to work on from the roadmap
- When there are multiple unblocked items and prioritization guidance is needed
- After completing a feature and looking for the next highest-impact work
- NOT when the roadmap does not exist (direct user to harness-roadmap --create)
- NOT when the user already knows what to work on (use harness-brainstorming or harness-autopilot directly)
## Process
### Iron Law
**Never transition without the human confirming the recommendation first. Selection never writes `assignee`.**
Present the ranked candidates, the AI reasoning, and the recommended pick. Wait for explicit confirmation before transitioning. The `assignee` field means _who is executing_ and is claimed at execution start by harness-execution — picking an item must NOT mark it assigned (an early assignee makes the item look human-claimed and the orchestrator silently skips it).
---
### Phase 1: SCAN -- Score Candidates
1. Resolve the roadmap mode with `loadProjectRoadmapMode(projectRoot)` from `@harness-engineering/core`.
- In `file-backed` mode (default): check that `docs/roadmap.md` exists. If missing, error. "No roadmap found at docs/roadmap.md. Run harness-roadmap --create first."
- In `file-less` mode: `docs/roadmap.md` is intentionally absent. Synthesize the roadmap from the tracker:
a. `loadTrackerClientConfigFromProject(projectRoot)` -> `createTrackerClient(config)` to obtain a `RoadmapTrackerClient`.
b. `client.fetchAll()` -> map each `TrackedFeature` into a `RoadmapFeature` and group by milestone (or use a single synthetic milestone if the tracker has no milestone field).
c. If the tracker call fails, surface the error verbatim; do not fall back to a file-backed branch.
2. Parse the roadmap (file-backed only) using `parseRoadmap` from `@harness-engineering/core`. (File-less mode produces the in-memory roadmap directly from step 1.)
3. Determine the current user:
- Use the `--user` argument if provided
- Otherwise, attempt to detect from git config: `git config user.name` or `git config user.email`
- If neither available, proceed without affinity scoring
4. Call `scoreRoadmapCandidatesForMode(roadmap, { currentUser }, config)` from `@harness-engineering/core` (FR-S3). This is the mode-aware wrapper: in `file-backed` mode it delegates to `scoreRoadmapCandidates` unchanged; in `file-less` mode it routes through `scoreRoadmapCandidatesFileLess` for the D4 priority+createdAt ordering. Always passing through this wrapper keeps the skill mode-agnostic.
5. If no candidates: inform the human. "No unblocked planned or backlog items found. All items are either in-progress, done, blocked, or the roadmap is empty."
Present the top 5 candidates:
```
ROADMAP PILOT -- Candidate Scoring
Top candidates (scored by position 50%, dependents 30%, affinity 20%):
# Feature Milestone Priority Score Breakdown
1. Feature A MVP Release P0 0.85 pos:0.9 dep:0.8 aff:1.0
2. Feature B MVP Release P1 0.72 pos:0.8 dep:0.6 aff:0.5
3. Feature C Q2 Release -- 0.65 pos:0.7 dep:0.5 aff:0.0
4. Feature D Backlog -- 0.40 pos:0.3 dep:0.4 aff:0.0
5. Feature E Backlog -- 0.35 pos:0.2 dep:0.3 aff:0.0
```
### Phase 2: RECOMMEND -- AI-Assisted Analysis
1. For the top 3 candidates, read their spec files (if they exist):
- Read the spec's Overview and Goals section
- Read the spec's Success Criteria section
- Assess effort and impact from the spec content
1a. **Read `STRATEGY.md` if present at repo root (strategy-alignment input).** Use a Node one-liner that calls `validateStrategy` from `@harness-engineering/core`, then (when valid) `parseStrategyDoc` + `asStrategyDoc`:
```bash
node -e "import('@harness-engineering/core').then(async m => {
const v = await m.validateStrategy(process.cwd());
if (!v.present || !v.valid) { console.log(JSON.stringify({ grounded: false })); return; }
const raw = require('fs').readFileSync('STRATEGY.md', 'utf-8');
console.log(JSON.stringify({ grounded: true, doc: m.asStrategyDoc(m.parseStrategyDoc(raw)) }));
})"
```
When `grounded: true`, capture the `Target problem`, `Our approach`, and `Tracks` section bodies. For each top-3 candidate, compute a strategy-alignment score:
- `+0.5` if the candidate's feature name or spec keywords plausibly advance one of the `Tracks` (case-insensitive substring or paraphrase match)
- `+0.25` if the candidate's spec Overview cites the `Target problem` or `Our approach` verbatim or near-verbatim
- `0` otherwise
The alignment score is a **tiebreaker bonus**, NEVER a hard filter:
- Apply only when the absolute difference between two candidates' base scores is `≤ 0.05` (items score similarly on `position × 0.5 + dependents × 0.3 + affinity × 0.2`).
- Never let the bonus override a meaningful base-score difference.
- When alignment is applied, cite it in the recommendation rationale ("Tiebreaker: aligned with track 'pulse-reports' from STRATEGY.md").
- When `STRATEGY.md` is absent or invalid, skip this step silently; the recommendation proceeds without a strategy tiebreaker.
1b. Read the most recent pulse report (if any):
- List entries in `docs/pulse-reports/` and **filter to those matching the
regex `/^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.md$/`** (the canonical
`YYYY-MM-DD_HH-MM.md` pulse-report filename shape). Filtering before
sorting prevents non-conforming files (e.g. `README.md`, `NOTES.md`,
partial-timestamp drafts) from corrupting the signal.
- Lexical-sort the matched filenames (ISO timestamps sort
chronologically) and take the LAST entry as the most recent.
- If zero entries match the regex (directory empty, absent, or only
contains non-conforming files), soft-fail: skip this step and proceed
without pulse signal. Do not block recommendation.
- For each top-3 candidate, scan the most recent pulse report's Headlines and
Followups sections for keywords matching the candidate's name, milestone, or
spec keywords. Note any signal that elevates priority (top followup item
related to a candidate; an error spike in a candidate's area) or suppresses
it (recent stable signal in candidate's area).
- When pulse signal is found, cite it verbatim in the recommendation rationale
(e.g., "Pulse 2026-05-05_08-00 headline: 'auth errors up 30%' — elevates
Auth Hardening").
- Use ONLY the most recent file. If older reports conflict with the most
recent, ignore the older signal.
2. Provide a recommendation with reasoning:
```
RECOMMENDATION
I recommend Feature A (MVP Release, P0, score: 0.85).
Reasoning:
- Highest priority (P0) with strong positional signal (first in MVP milestone)
- Unblocks 2 downstream features (Feature X, Feature Y)
- You completed its blocker "Foundation" -- high context affinity
- Spec exists with clear success criteria (12 acceptance tests)
- Estimated effort: medium (8 tasks in the plan)
Alternative: Feature B (P1, score: 0.72) -- consider if Feature A's scope is too large for the current time window.
Proceed with Feature A? (y/n/pick another)
```
### Phase 3: CONFIRM -- Human Decision
Ask the human in plain text (matching the `y/n/pick another` example above). Do not elevate this confirmation to an `AskUserQuestion` tool call — candidate labels and natural header choices ("Pick candidate", etc.) exceed its 12-char `header` cap and the prompt is rejected as ERR.
1. Wait for human confirmation.
- If **yes**: proceed to Phase 4.
- If **pick another**: ask which candidate number, then proceed with that pick.
- If **no**: stop. No changes made.
### Phase 4: TRANSITION -- Hand Off to the Next Skill
**Do NOT write the `assignee` field here.** Selection picks the item; it does not
claim it. harness-execution claims the item (`status=in-progress` + `assignee`) at
execution start. Writing an assignee at selection makes the orchestrator treat the
item as already-claimed and silently skip it (the bug this skill must not reintroduce).
The item stays `planned`/`backlog` with `Assignee: —` and remains orchestrator-eligible.
**Sharded mode + auto-done.** When the claim is later written (at execution start),
in sharded mode (`docs/roadmap.d/` present) it patches the **single row's shard**
and appends an assignment record to the shared `_meta.md`, then regenerates the
`docs/roadmap.md` aggregate — stage both. And there is **no manual done-marking
step**: a row reaches `done` automatically when the implementing PR merges
(merge-triggered auto-done via `External-ID`; the reconciler clears the assignee per
RMH005). See knowledge [`merge-triggered-auto-done.md`](../../../../docs/knowledge/roadmap/merge-triggered-auto-done.md).
1. Determine the transition target:
- If the feature has a `spec` field (non-null): transition to `harness:autopilot`
- If the feature has no `spec`: transition to `harness:brainstorming`
- **Optional (feature-shaped items):** before brainstorming, a no-spec item that carries
user-facing behavior may first run `product-requirements` to author a PRD (user stories +
acceptance criteria + prioritization) at `docs/product-requirements/<item>/prd.md`, which
brainstorming then consumes. Suggest this for feature work; skip it for bugs, chores, and
refactors (a PRD there is speculative ceremony).
2. Present the transition to the human via `emit_interaction`:
```json
emit_interaction({
path: "<project-root>",
type: "transition",
transition: {
completedPhase: "roadmap-pilot",
suggestedNext: "<brainstorming|autopilot>",
reason: "Feature '<name>' selected and ready for <brainstorming|execution>",
artifacts: ["docs/roadmap.md"],
requiresConfirmation: true,
summary: "Selected '<name>'. <Spec exists -- ready for autopilot|No spec -- needs brainstorming first>. (Not assigned — harness-execution claims it at execution start.)",
qualityGate: {
checks: [
{ "name": "roadmap-parsed", "passed": true },
{ "name": "candidate-scored", "passed": true },
{ "name": "human-confirmed", "passed": true },
{ "name": "no-assignment-at-selection", "passed": true }
],
allPassed: true
}
}
})
```
3. Run `harness validate`.
---
## Harness Integration
- **`parseRoadmap` / `serializeRoadmap`** -- Parse and write `docs/roadmap.md` (file-backed mode only). Import from `@harness-engineering/core`.
- **`loadProjectRoadmapMode` / `loadTrackerClientConfigFromProject` / `createTrackerClient`** -- Resolve `roadmap.mode` and obtain a `RoadmapTrackerClient` for file-less mode. Import from `@harness-engineering/core`.
- **`scoreRoadmapCandidatesForMode`** -- Mode-aware scoring entry point. Import from `@harness-engineering/core`. In file-backed mode delegates to `scoreRoadmapCandidates`; in file-less mode routes through `scoreRoadmapCandidatesFileLess` (priority + createdAt sort, FR-S3).
- **`scoreRoadmapCandidates`** -- Underlying file-backed scoring algorithm. Prefer `scoreRoadmapCandidatesForMode` from the skill; direct callers in file-backed-only code paths can still use this.
- **`emit_interaction`** -- Used for the skill transition at the end. Transitions to `harness:brainstorming` (no spec) or `harness:autopilot` (spec exists). This skill does NOT call `manage_roadmap update` to assign — the `assignee` field is owned by harness-execution (claim at execution start), enforced by RMH005 (`assignee ≠ null ⟺ in-progress`).
- **`STRATEGY.md` alignment (Phase 2 step 1a)** -- When present at repo root and valid, loaded via `validateStrategy` + `parseStrategyDoc` + `asStrategyDoc` from `@harness-engineering/core`. Applied as a bounded tiebreaker bonus (max `+0.75`) only when candidates score within `0.05` on the base formula. Boundary: roadmap-pilot READS; `harness-strategy` WRITES. Never modify `STRATEGY.md` from this skill.
- **`harness validate`** -- Run after the transition is presented.
## Success Criteria
1. Roadmap is parsed and unblocked planned/backlog items are scored
2. Scoring uses two-tier sort: explicit priority first, then weighted score
3. AI reads top candidates' specs and provides recommendation with reasoning
4. Human confirms before the transition is made
5. Selection does NOT write the `assignee` field (no assignment, no history record, no external assignee sync) — the pick stays `planned`/`backlog` and orchestrator-eligible
6. The `assignee` field is owned by harness-execution, which claims at execution start; RMH005 enforces `assignee ≠ null ⟺ in-progress`
7. Transition routes to brainstorming (no spec) or autopilot (spec exists)
8. When a pulse report exists, the recommendation rationale cites pulse signal for any top-3 candidate whose area is referenced in the pulse Headlines or Followups.
9. When `STRATEGY.md` is present and valid AND two candidates score within `0.05` on the base formula, the recommendation rationale cites strategy-alignment as the tiebreaker. The bonus never overrides a meaningful base-score difference.
10. When `STRATEGY.md` is absent or invalid, the skill completes without error and no strategy-alignment rationale appears in the output.
11. `harness validate` passes after all changes
## Rationalizations to Reject
| Rationalization | Reality |
| ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "The top-scored candidate is obviously correct, so I can transition without asking the human" | The Iron Law: never transition without the human confirming the recommendation first. |
| "I'll write the assignee now so the pick is recorded / the user is credited" | Selection never writes `assignee`. An assignee means _in-progress_ (set by harness-execution at execution start). Writing it at selection makes the orchestrator silently skip the item — the exact bug this skill must not reintroduce. |
| "Affinity data is not available so the scoring is degraded -- I should just pick the first planned item" | Proceed without affinity scoring by zeroing out the affinity weight. Position and dependents signals still produce meaningful rankings. |
| "The feature has no spec, but I can skip brainstorming and jump straight to planning since the summary is clear enough" | No spec routes to brainstorming, spec exists routes to autopilot. A one-line roadmap summary is not a spec. |
| "STRATEGY.md exists, so I should let it override the top-scored candidate when alignment is clear" | The alignment bonus is bounded (max `+0.75`) and only fires when base scores are within `0.05`. It is a tiebreaker, not a hard filter — a clearly higher-scored item still wins. |
## Examples
### Example: Pick Next Item from a Multi-Milestone Roadmap
**Context:** A roadmap with 3 milestones, 8 features. 2 are in-progress, 1 is done, 2 are blocked, 3 are planned/backlog and unblocked. User is @cwarner who completed "Core Library Design".
**Phase 1: SCAN**
```
ROADMAP PILOT -- Candidate Scoring
Top candidates:
# Feature Milestone Priority Score Breakdown
1. Graph Connector MVP Release P2 0.78 pos:0.8 dep:0.6 aff:1.0
2. Performance Baselines Q3 Hardening -- 0.45 pos:0.5 dep:0.3 aff:0.0
3. Push Notifications Backlog -- 0.30 pos:0.2 dep:0.2 aff:0.5
```
**Phase 2: RECOMMEND**
```
I recommend Graph Connector (MVP Release, P2, score: 0.78).
Reasoning:
- Only prioritized item among candidates (P2)
- You completed its blocker "Core Library Design" -- maximum affinity bonus
- Unblocks "API Integration" downstream
- Spec exists at docs/changes/graph-connector/proposal.md
Proceed? (y/n/pick another)
```
Human confirms **y**.
**Phase 4: TRANSITION**
```
Graph Connector stays planned, Assignee: — (not assigned at selection).
harness-execution will claim it (status=in-progress + assignee) at execution start.
Transitioning to harness:autopilot (spec exists)...
```
## Gates
- **No transition without human confirmation.** The CONFIRM phase must complete with explicit approval before transitioning.
- **No assignment at selection.** This skill never writes the `assignee` field — that field means _who is executing_ and is claimed at execution start by harness-execution. Writing it here would make the orchestrator silently skip the item.
- **No scoring without a parsed roadmap.** If `docs/roadmap.md` does not exist or fails to parse, stop with an error.
## Escalation
- **When no unblocked candidates exist:** Inform the human. Suggest reviewing blocked items to see if blockers can be resolved, or adding new features via `harness-roadmap --add`.
- **When affinity data is unavailable:** Proceed without affinity scoring (weight falls to 0 for all candidates). Note this in the output.
- **When the human asks you to assign the item to them at selection:** Explain that the `assignee` field means _who is executing_ and is claimed at execution start by harness-execution; assigning at selection makes the orchestrator silently skip the item (enforced by RMH005). Proceed with the transition instead.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!