Roadmap: Add Task ยท diff
git:20260813.874484b to git:20260813.f1ed50f
1 added, 1 removed. Audit A to A.
---
name: "Roadmap: Add Task"
description: "{{ ๐๐๐ }} Add a single well-formed task to a rich-format roadmap โ ID assignment, dependency wiring in both directions, graph integrity"
when_to_use: "Whenever the user wants to add a task, feature, or work item to a roadmap โ even phrased as 'add this to the roadmap', 'put this in the plan', or 'track this as a task'. For a batch of half-formed ideas, run roadmap-create-interview first and feed its proposal here one task at a time."
model: sonnet
effort: medium
disable-model-invocation: false # invocable by Claude so "add this to the roadmap" loads this skill instead of hand-editing the JSON; Step 7's approval gate still applies
allowed-tools: ["Read", "Glob", "Grep", "Edit", "Bash(python3:*)"]
- argument-hint: [task description (optional)]
+ argument-hint: "[task description (optional)]"
---
# Roadmap Task Adder
Adds a well-formed task to an existing rich-format roadmap. The job is not appending a line โ it is placing the task correctly in the dependency graph, wiring its relationships in **both** artefacts (`.claude/roadmaps.json` and the PHASE file it names), and leaving the roadmap coherent.
Shared conventions: `~/.claude/library/references/roadmap-conventions.md`. The CLI is `python3 "$HOME"/.claude/library/scripts/roadmap.py`.
---
## Step 1 โ Locate the roadmap and check the format
Run `python3 "$HOME"/.claude/library/scripts/roadmap.py detect`. Exit **3** = old simple format โ **stop and tell the user to run `roadmap-migrate` first**. Exit **2** = could not locate/parse โ ask the user for the path. Only proceed on exit 0.
Read the full `roadmaps.json` and the active phase's PHASE file before adding โ you need the existing task graph, milestone IDs, gates, and categories.
---
## Step 2 โ Understand what to add
Extract: **description**; **milestone** (which milestone โ ask if unclear); **category** (2โ3 letter prefix, reuse an existing one in that milestone where it fits); **dependencies** (what must be done first; what it unblocks); **assignee** (ask the user directly โ never infer it from the description, the git author, the category owner, or who is running this skill; leave it unset if the user doesn't say). Ask before proceeding if any is ambiguous โ a badly placed task is worse than a delayed one.
---
## Step 3 โ Assign a task ID
`{MilestoneNum}{Category}.{Seq}` โ find the highest sequence in that category and use `next = highest + 1`. Sub-tasks: alpha suffix (`2TI.15a`). **Never reuse an ID**, even a removed one.
---
## Step 4 โ Identify dependencies
**Incoming** (`dependsOn`): tasks this new task requires. An entry may be a **task ID**, a **milestone ID** (`M1` โ resolves done only when all its tasks are done), or an **external gate ID** (from `externalGates`). If a gate is an incoming dependency, the gate's `blocks[]` must gain this task ID (parity).
**Outgoing**: existing tasks that this new task should now block โ add the new ID to their `dependsOn` (and mirror any gate parity). Completing this task may change those tasks' computed status (the recompute handles that).
**Soft (`softDependsOn`):** an optional, best-effort link worth drawing but not worth blocking on โ ask if the relationship is a real dependency or a soft one before defaulting to `dependsOn`. Renders dotted, imposes no status, no cycle constraint (see conventions reference for direction).
---
## Step 5 โ Graph integrity checks (before writing)
**Orphan check.** A task with no dependency edges in or out is orphaned. Warn (`"This task has no connections to the existing graph โ intentional?"`), suggest the most plausible connection, and proceed on the user's call. Some tasks genuinely stand alone.
**Childless check.** If nothing depends on the new task but its nature clearly unlocks future work, create a placeholder child in the appropriate milestone: `- [ ] **{NewID}** โ {unlocked capability} _(blocked โ depends on {NewTaskID})_`, `status: "blocked"`, with the dependency edge. Skip placeholders for obviously terminal tasks (deploy, final release notes). Tell the user what placeholder was created and why.
---
## Step 6 โ Compute the new task's status (mechanical)
The mechanical status rule applies (see conventions reference): empty `dependsOn` โ `todo`; any non-`done` dependency โ `blocked`; behind a gate that `imposes: paused`/`deferred` โ `paused`/`deferred`. `softDependsOn` never feeds this rule. After wiring, confirm the new task's status and any downstream changes with `python3 "$HOME"/.claude/library/scripts/roadmap.py recompute --check` (preview, no write).
---
## Step 7 โ Prepare the proposal (do not edit yet)
```text
New task: {ID} โ {description}
Milestone: {N} โ {Milestone Name} Status: {todo|blocked|paused|deferred}
Assignee: {name, or "unassigned"}
Dependencies (in): {IDs / milestone / gate, or "none"}
Dependencies (out): {task IDs this gets added to, or "none"}
Placeholder child: {ID and description, or "none"}
Graph changes:
+ roadmaps.json: new task object; edits to {existing tasks' dependsOn}; gate blocks[] updates
+ diagram: regenerated from the JSON (node {ID}; edges {list})
```
Then ask: *"Does this look right? I'll write to the roadmap on your say-so."*
---
## Step 8 โ Write to both artefacts (once approved)
1. **`roadmaps.json`** โ insert the task object in its milestone's `tasks[]` (field order `id, description, status, dependsOn, softDependsOn, iterative, notes, assignee`; tabs; British spelling). Include `assignee`/`softDependsOn` only when the user gave one โ omit them entirely otherwise, exactly like `notes`. Update any existing tasks' `dependsOn`. Update any gate's `blocks[]` for parity. Add the placeholder task if any.
2. **PHASE file** โ add the task line under its milestone with the status annotation (`_(blocked โ depends on {IDs})_` etc.); update any existing task lines whose dependency clause changed; add the placeholder line.
3. **Mermaid diagram** โ replace the entire fenced `mermaid` block with the output of `python3 "$HOME"/.claude/library/scripts/roadmap.py graph --mermaid --direction LR`. Never hand-edit edges, sinks or class lines โ the generator recomputes milestone sinks (including any former sink displaced by the new task) and the canonical colours.
4. **`ROADMAP_OVERVIEW.md`** โ the task total changed, so update `**N tasks across M milestones.**` (get N from `roadmap.py stats`).
---
## Step 9 โ Validate and confirm
Run `python3 "$HOME"/.claude/library/scripts/roadmap.py validate` โ it must report clean (parity, acyclicity, status recompute). If an HTML dashboard exists (`docs/artefacts/roadmap-*.html`), refresh it with `roadmap.py render`. Then report: task added; status; edges added; existing tasks modified; placeholder created; any orphan warning.
---
## Conventions
- Task line: `- [ ] **{ID}** โ {description}` + annotation. Completed: `- [x] **{ID}** โ {description}`.
- roadmaps.json is the source of truth; the PHASE file and overview are projections.
- Everything else (statuses, colours, graph/edge rules, formatting): `~/.claude/library/references/roadmap-conventions.md`.