Product Item (backlog artifact scaffolder)
Creates one product-management artifact — Epic, User Story, Task, or
Implementation Plan — from the templates in docs/product/templates/, with correct
numbering and links. It is the backlog counterpart to [[decision-record]] (ADRs) and pairs
with [[changelog]] when the work ships something user-facing.
The deterministic part (next id, template fill, no-overwrite) is done by
scripts/new_product_item.py. This skill handles the judgement: which type, the title, which
parent to wire up, and the roadmap pointer.
When to invoke
- Graduating a
docs/roadmap.md item (Now/Next/Later) into a tracked artifact.
- Creating any Epic, User Story, Task, or Implementation Plan.
- Breaking an Epic into Stories, or a Story into Tasks.
See docs/product/README.md for the workflow this fits into (Epic → Story → Task → Plan →
code + CHANGELOG (+ ADR)) and the status lifecycle.
Inputs
Gather from the invocation; only ask for what's missing, and ask concisely:
- type (required) —
epic | story | task | plan.
- title (required).
- parent (optional) — the epic id for a story, the story id for a task.
- covers (optional) — for a plan, the
EPIC-/STORY-/TASK- id it plans.
- roadmap-ref (optional) — the
docs/roadmap.md row id, e.g. X4 (fills the Epic's
roadmap_ref frontmatter field).
- owner (optional) — defaults to leaving the template placeholder.
- status (optional) — initial lifecycle state (
Proposed | Ready | In Progress |
In Review | Done | Archived); defaults to Proposed. Use --status to skip a manual edit.
- standalone (optional, story/task only) — no parent; sets
epic:/story: to none. Use
--standalone instead of --parent for an orphaned item.
- with-plan (optional, not for
plan) — also create the paired Implementation Plan and
cross-wire plan: ↔ covers: in one step. Use --with-plan.
Never invent a required field. If it's missing, ask — briefly.
Procedure
Bootstrap the workflow if missing (idempotent). This skill is self-contained: it bundles the
canonical templates, scripts, README, and a roadmap seed under assets/ (next to this file) so it
works in any repo. If docs/product/ is absent, seed the repo from the bundle without
overwriting anything that already exists (confirm first):
assets/templates/* → docs/product/templates/
assets/scripts/* → scripts/
assets/README.md → docs/product/README.md
assets/roadmap-template.md → docs/roadmap.md (only if no roadmap exists yet)
The scripts depend only on pyyaml (no application-package import), so they run as-is — this
includes scripts/validate_product_items.py, the self-contained integrity gate (see step 5).
Then continue. If docs/product/ already exists, skip bootstrap.
Create the artifact. Run the scaffolder and capture the printed path:
uv run python scripts/new_product_item.py <type> --title "<title>" \
[--parent <ID> | --standalone] [--covers <ID>] [--roadmap-ref <ID>] \
[--owner "<name>"] [--status "<status>"] [--with-plan]
It computes the next gap-safe id, copies the right template, fills
id/title/created/status/parent, and refuses to overwrite an existing file. Titles
containing YAML-significant characters (a # PR reference like "PR #30", or a :) are
emitted quoted so the frontmatter round-trips instead of truncating. --with-plan prints two
paths (the item and its plan).
Wire the parent link — with confirm, and only if the target exists. Never duplicate an
existing link. After confirming with the user:
- story under an epic: add the new
STORY-NNN to the epic's stories: frontmatter list
and its ## Child stories checklist.
- task under a story: add the new
TASK-NNN to the story's tasks: list and its
## Tasks checklist.
- plan covering an item: set that item's
plan: frontmatter field to the new PLAN-NNN.
Check for the link first; if it's already present, skip (idempotent).
Add the roadmap pointer — with confirm. If --roadmap-ref was given and that row exists
in docs/roadmap.md, append a one-line "→ <ID>" pointer to that row so the backlog links
forward to the artifact. Skip if already present.
Report the created path. Do not commit — leave that to the user.
Run the integrity gate. Validate the backlog is still self-consistent (no duplicate ids,
dangling links, or invalid statuses):
uv run python scripts/validate_product_items.py
It is structural and lenient — a freshly-scaffolded Proposed artifact passes. Report any
violation it surfaces rather than silently proceeding.
The closure check
Every artifact this skill creates carries a Definition of Done (Tasks) / Verification (Plans)
that must clear this bar before the work is called done — the same bar we hold our own work
to:
- Converged — the end state is more ordered than the start (one source of truth, not two).
- Legible — the result maps 1:1 to the stated intent, with no "sort of".
- Closed — it was verified by running something, not asserted.
- Edges surfaced — remaining rough bits are named, not hidden.
When helping complete a Task or Plan, hold it to these four before ticking it done.
Closing out shipped work
When an Epic is genuinely finished it graduates out of the active backlog: set status: Done
on the epic and its whole subtree, git mv that subtree into the per-type archive/ dirs
(docs/product/<type>/archive/), regenerate the shipped index, and drop its docs/roadmap.md
row (the roadmap tracks outstanding work only; the CHANGELOG keeps the narrative). The bundled
scripts/generate_shipped_index.py derives docs/product/shipped.md from every Done epic —
it recurses epics/archive/, so never hand-edit that file, just re-run it. Archive one epic
by hand; to sweep all completed epics in one pass, use [[close-out-sweep]].
Archiving is safe for numbering and links: both scripts/new_product_item.py and
scripts/validate_product_items.py recurse into archive/, so archived ids still count (never
reused) and cross-links resolve across the active/archive boundary.
Acceptance checklist
- Numbering is max + 1 per type and gap-safe — a missing middle number is never reused;
an empty type-dir starts at
001. The scan is archive-aware (recurses <type>/archive/),
so an archived id is still counted and never reused.
- Re-running never overwrites an existing artifact (the scaffolder refuses).
- Parent/roadmap links are added only to pre-existing files and are never duplicated.
- The created artifact's frontmatter is accurate (id, title, created, status, parent) — a title
with a
# or : is quoted, not truncated.
- The created Task/Plan carries the closure check.
scripts/validate_product_items.py reports no violations after the artifact is created.
Related: pairs with [[decision-record]] (ADRs) and [[changelog]] (release notes);
[[close-out-sweep]] retires the Epics this skill creates once they ship.
1---2name: product-item3description: Use when creating or scaffolding a backlog artifact — an Epic, User Story, Task, or Implementation Plan — or when graduating a docs/roadmap.md item into a tracked artifact. Scaffolds the next-numbered file from docs/product/templates/, wires parent/child links, and adds a roadmap pointer — the same shape as /decision-record but for backlog artifacts.4---56# Product Item (backlog artifact scaffolder)78Creates one product-management artifact — **Epic**, **User Story**, **Task**, or9**Implementation Plan** — from the templates in `docs/product/templates/`, with correct10numbering and links. It is the backlog counterpart to `[[decision-record]]` (ADRs) and pairs11with `[[changelog]]` when the work ships something user-facing.1213The deterministic part (next id, template fill, no-overwrite) is done by14`scripts/new_product_item.py`. This skill handles the judgement: which type, the title, which15parent to wire up, and the roadmap pointer.1617## When to invoke1819- Graduating a `docs/roadmap.md` item (Now/Next/Later) into a tracked artifact.20- Creating any Epic, User Story, Task, or Implementation Plan.21- Breaking an Epic into Stories, or a Story into Tasks.2223See `docs/product/README.md` for the workflow this fits into (Epic → Story → Task → Plan →24code + CHANGELOG (+ ADR)) and the status lifecycle.2526## Inputs2728Gather from the invocation; **only ask for what's missing**, and ask concisely:2930- **type** (required) — `epic` | `story` | `task` | `plan`.31- **title** (required).32- **parent** (optional) — the epic id for a story, the story id for a task.33- **covers** (optional) — for a plan, the `EPIC-`/`STORY-`/`TASK-` id it plans.34- **roadmap-ref** (optional) — the `docs/roadmap.md` row id, e.g. `X4` (fills the Epic's35 `roadmap_ref` frontmatter field).36- **owner** (optional) — defaults to leaving the template placeholder.37- **status** (optional) — initial lifecycle state (`Proposed` | `Ready` | `In Progress` |38 `In Review` | `Done` | `Archived`); defaults to `Proposed`. Use `--status` to skip a manual edit.39- **standalone** (optional, story/task only) — no parent; sets `epic:`/`story:` to `none`. Use40 `--standalone` instead of `--parent` for an orphaned item.41- **with-plan** (optional, not for `plan`) — also create the paired Implementation Plan and42 cross-wire `plan:` ↔ `covers:` in one step. Use `--with-plan`.4344Never invent a required field. If it's missing, ask — briefly.4546## Procedure47480. **Bootstrap the workflow if missing (idempotent).** This skill is self-contained: it bundles the49 canonical templates, scripts, README, and a roadmap seed under `assets/` (next to this file) so it50 works in *any* repo. If `docs/product/` is absent, seed the repo from the bundle **without51 overwriting anything that already exists** (confirm first):52 - `assets/templates/*` → `docs/product/templates/`53 - `assets/scripts/*` → `scripts/`54 - `assets/README.md` → `docs/product/README.md`55 - `assets/roadmap-template.md` → `docs/roadmap.md` (only if no roadmap exists yet)5657 The scripts depend only on `pyyaml` (no application-package import), so they run as-is — this58 includes `scripts/validate_product_items.py`, the self-contained integrity gate (see step 5).59 Then continue. If `docs/product/` already exists, skip bootstrap.601. **Create the artifact.** Run the scaffolder and capture the printed path:6162 ```bash63 uv run python scripts/new_product_item.py <type> --title "<title>" \64 [--parent <ID> | --standalone] [--covers <ID>] [--roadmap-ref <ID>] \65 [--owner "<name>"] [--status "<status>"] [--with-plan]66 ```6768 It computes the next gap-safe id, copies the right template, fills69 `id`/`title`/`created`/`status`/parent, and refuses to overwrite an existing file. Titles70 containing YAML-significant characters (a `#` PR reference like "PR #30", or a `:`) are71 emitted quoted so the frontmatter round-trips instead of truncating. `--with-plan` prints two72 paths (the item and its plan).732. **Wire the parent link — with confirm, and only if the target exists. Never duplicate an74 existing link.** After confirming with the user:75 - **story under an epic:** add the new `STORY-NNN` to the epic's `stories:` frontmatter list76 **and** its `## Child stories` checklist.77 - **task under a story:** add the new `TASK-NNN` to the story's `tasks:` list **and** its78 `## Tasks` checklist.79 - **plan covering an item:** set that item's `plan:` frontmatter field to the new `PLAN-NNN`.80 Check for the link first; if it's already present, skip (idempotent).813. **Add the roadmap pointer — with confirm.** If `--roadmap-ref` was given and that row exists82 in `docs/roadmap.md`, append a one-line "→ `<ID>`" pointer to that row so the backlog links83 forward to the artifact. Skip if already present.844. **Report the created path.** Do **not** commit — leave that to the user.855. **Run the integrity gate.** Validate the backlog is still self-consistent (no duplicate ids,86 dangling links, or invalid statuses):8788 ```bash89 uv run python scripts/validate_product_items.py90 ```9192 It is structural and lenient — a freshly-scaffolded `Proposed` artifact passes. Report any93 violation it surfaces rather than silently proceeding.9495## The closure check9697Every artifact this skill creates carries a Definition of Done (Tasks) / Verification (Plans)98that must clear this bar before the work is called *done* — the same bar we hold our own work99to:100101- **Converged** — the end state is more ordered than the start (one source of truth, not two).102- **Legible** — the result maps 1:1 to the stated intent, with no "sort of".103- **Closed** — it was verified by *running something*, not asserted.104- **Edges surfaced** — remaining rough bits are named, not hidden.105106When helping complete a Task or Plan, hold it to these four before ticking it done.107108## Closing out shipped work109110When an Epic is genuinely finished it graduates *out* of the active backlog: set `status: Done`111on the epic and its whole subtree, `git mv` that subtree into the per-type `archive/` dirs112(`docs/product/<type>/archive/`), regenerate the shipped index, and drop its `docs/roadmap.md`113row (the roadmap tracks outstanding work only; the CHANGELOG keeps the narrative). The bundled114`scripts/generate_shipped_index.py` derives `docs/product/shipped.md` from every `Done` epic —115it recurses `epics/archive/`, so **never hand-edit** that file, just re-run it. Archive one epic116by hand; to sweep **all** completed epics in one pass, use `[[close-out-sweep]]`.117118Archiving is safe for numbering and links: both `scripts/new_product_item.py` and119`scripts/validate_product_items.py` recurse into `archive/`, so archived ids still count (never120reused) and cross-links resolve across the active/archive boundary.121122## Acceptance checklist123124- Numbering is **max + 1** per type and **gap-safe** — a missing middle number is never reused;125 an empty type-dir starts at `001`. The scan is **archive-aware** (recurses `<type>/archive/`),126 so an archived id is still counted and never reused.127- Re-running never overwrites an existing artifact (the scaffolder refuses).128- Parent/roadmap links are added **only to pre-existing files** and are **never duplicated**.129- The created artifact's frontmatter is accurate (id, title, created, status, parent) — a title130 with a `#` or `:` is quoted, not truncated.131- The created Task/Plan carries the closure check.132- `scripts/validate_product_items.py` reports no violations after the artifact is created.133134Related: pairs with `[[decision-record]]` (ADRs) and `[[changelog]]` (release notes);135`[[close-out-sweep]]` retires the Epics this skill creates once they ship.