017 — Roadmap items are issues: named epics, no numbers, done means closed (#44)

Status: shipped (v0.12.0) Roadmap: #45

Why

ROADMAP.md is meant to say what tp might do next, grouped by functionality, and to catch an idea the moment it occurs, half-formed. Today it is a numbered tree (story 009) where a cited number never moves, so shipped items stay: 17 of its 27 items are ticked, two thirds of the file is history, and a new epic could not go where it belonged because shipped numbers held the slots. The numbers are the problem. They look like identifiers but are positions, and a position has no meaning once the item moves or ships.

The identifiers that mean something already exist: issue numbers on the forge, sequential and permanent, with labels that say what an issue is. A roadmap item is an issue labelled roadmap; a story is an issue labelled story; one roadmap item may inspire several stories, and it is done only when they all are. ROADMAP.md becomes the view that groups the open roadmap issues under named epics, in any order, and the changelog takes each item once its issue is closed (ADR 0004).

What changes

  • ROADMAP.md format: ## Epic name headings, in any order, no numbers; under each, one item per line, - #N text — the issue number first, then free text that may paraphrase or expand the issue. A short paragraph under a heading describes the epic. Nothing is ticked or stamped.
  • tp roadmap add TITLE... [--epic NAME] catches an idea: it creates the issue on the release remote with the roadmap label (creating the label if the repo lacks it) and appends - #N TITLE under the epic (the last one by default), so a half-formed idea costs one command.
  • tp roadmap check is the lint, run by tp check: the format above; every item's issue exists on the forge, is open and carries roadmap; a closed issue still listed is "done — archive it"; an open roadmap issue missing from the file is listed as uncaptured. Without the forge (offline, no token) it checks the format and says the forge part was skipped. renumber goes.
  • A story cites its roadmap item with a **Roadmap:** #N line under the status (none for a fix); tp story issue carries it into the issue body and labels the issue story. A roadmap item is done when every story citing it is shipped and the human says so.
  • tp roadmap archive, run on its own or by the prepare step of tp release: every item whose issue is closed moves from ROADMAP.md into CHANGELOG.md under the version being released, as a ### Roadmap list of the same - #N text lines. At code level 1 and up, where the batch refuses entries in [Unreleased], each item goes to a changes/<n>.roadmap.md fragment instead and the batch renders the list (#142). In the release this lands in the release commit, so no second pull request. The prepare step also offers, per open roadmap item whose stories are all shipped or shipping in this release, to count it done: yes moves the line now and closes the issue after the tag.
  • .tp-release-inflight, gitignored and never committed (like .tp-release-comment, story 013), is written by the prepare step with the version, branch, pull request, and the issues to close after the tag: the stories shipping and any roadmap items counted done. After the tag is pushed and the release published, each is closed with a comment linking the release, the story branch is tidied (story 016, which today only works in the one-run flow), and the file is deleted. Until then tp check names it.
  • Migration: tp roadmap check on a story 009 roadmap reports numbered items; the migration of this repo is by hand (an issue per open item, ticked items into the changelog under their stamps), once.

Acceptance

Command State Outcome
tp roadmap check - #44 text under ## Epic, #44 open with roadmap ok
tp roadmap check - **1.6** text or [x] error: numbered or ticked item; see story 017
tp roadmap check - text without #N error: item has no issue
tp roadmap check #N does not exist, or lacks roadmap error naming the line
tp roadmap check #N closed "done — run tp roadmap archive"
tp roadmap check open roadmap issue not in the file "uncaptured: #N title"
tp roadmap check no forge reachable format checked; "forge checks skipped"
tp roadmap add "idea" --epic Secrets label exists issue #N created with roadmap; - #N idea appended under ## Secrets
tp roadmap add "idea" no roadmap label label created, then as above; last epic
tp roadmap add "idea" --epic X no ## X error; nothing created
tp story issue 018 story has **Roadmap:** #44 issue labelled story, body cites #44
tp roadmap archive #44 closed, listed line moved under ## [Unreleased]'s ### Roadmap; removed from the roadmap
tp roadmap archive nothing closed "nothing to archive"
prepare run #44 closed, listed moved under the new version heading, in the release commit
prepare run #44 open; stories citing it all shipped or shipping asks "Count #44 done?"; yes: line moved, #44 in flight
prepare run #44 open; a story citing it is proposed not offered
prepare run, --dry-run any moves and questions printed; nothing written, no file
prepare fails before the push any release commit reset, in-flight file removed
tag run or one-run continuation in-flight file for this version after the publish: listed issues closed with the release link, story branch tidied, file deleted
tag run in-flight file for another version warning naming both versions; file left
tag run no in-flight file tags and publishes as today; says which issues it cannot close
tp check in-flight file present one line: version, branch, pull request

Out of scope

  • Dropping the story file's own number (017): the file name keeps it; the issue number is the one to cite.
  • Forgejo issue dependencies as the story–roadmap link: a line in the story is enough and works offline.
  • Rewriting old stories and issues that quote roadmap numbers.
  • tp adr.

Decisions

ADR 0004: roadmap items are issues labelled roadmap; epics are named, not numbered; done means closed. It retires story 009's numbering, frozen numbers and renumber.

Done when

  • tests express the acceptance table and pass
  • spec updated (docs/roadmap.md, docs/release-workflow.md, README.md, the story template)
  • ADR 0004 accepted
  • this repo's roadmap migrated
  • roadmap ticked and stamped; changelog entry
  • issue closed with a link to the release