003 — tp story: number, scaffold, and file a story's issue (#23)
Status: shipped (v0.2.1)
Why
Running stories 001 and 002 by hand repeated the same mechanical steps
each time: find the next number, copy the template from docs/method.md,
then create the forge issue from the story's title and first paragraph and
write (#N) back into the heading. Those steps are identical in every
project and easy to get subtly wrong (a skipped number, an issue body that
drifts from the file), so they belong in task-plus. tp issue now exists
to do the forge half.
What changes
- New command
tp storywith two subcommands:new TITLE— writesdocs/stories/NNN-slug.mdfrom the method's story template, NNN one above the highest existing number (001 in an empty or missing directory), statusproposed. Prints the path.issue NNN— creates the forge issue from the story file and stamps(#N)onto the file's heading. Prints#N url.
- The issue is titled
Story NNN: <title>; its body is the first paragraph of Why and a link to the file on the release remote's forge (<web>/<owner>/<repo>/src/branch/<current branch>/<path>). Forge and token come fromtp issue's resolution. - The template is embedded in tp;
docs/method.mdstays the description of it. Newinternal/storypackage; docs pagedocs/story.md; README row.
Acceptance
new TITLE, given the files in docs/stories/:
| Existing stories | TITLE | Writes |
|---|---|---|
| none, or no directory | First thing |
001-first-thing.md |
001-a.md, 003-b.md |
Next |
004-next.md |
001-a.md, notes.md, 002-b.html |
Next |
002-next.md (only NNN-*.md count) |
| any | `tp foo`: do X & Y! |
slug tp-foo-do-x-y |
| any | a title slugging past 50 characters | slug cut at a word boundary, ≤ 50 |
| any | empty, or nothing sluggable | error, nothing written |
The written file has heading # NNN — TITLE, **Status:** ready, and
the template's sections (Why, What changes, Acceptance, Out of scope,
Decisions, Done when).
issue NNN, given the story file:
| Heading | Why section | Outcome |
|---|---|---|
# 004 — Title |
has a first paragraph | issue Story 004: Title, body = paragraph + link; heading becomes # 004 — Title (#N) |
# 004 — Title (#12) |
any | error: "story 004 already has issue #12"; nothing sent |
# 004 — Title |
missing or empty | error: "story 004 has no Why paragraph"; nothing sent |
| no story numbered 004 | — | error naming the directory |
| issue creation fails | — | forge error; file unchanged |
Only the heading line changes; the rest of the file is byte-for-byte kept.
Out of scope
- Closing a story's issue on release and stamping
shipped (vX.Y.Z)— the roadmap'stp releaseitem. - Re-syncing an issue after the story is edited, listing stories, and configurable story directories or templates.
tp adr.
Decisions
None: numbering, slug and issue shape follow what stories 001 and 002 did by hand.
Done when
- tests express the acceptance tables and pass
- spec updated (
docs/story.md, README command table,docs/method.mdtooling section) - ADR written if a fork was resolved
- roadmap ticked and stamped; changelog entry
- issue closed with a link to the release