To Stories — Conversation or Intent into Wiki Stories
Two inputs, one output shape. From the current conversation, a thin orchestration plan plus per-story files. From a promoted intent, one story under the active plan. Does not interview — synthesizes what is already established. If intent isn't clear, suggest $intent first and stop.
Input B — a promoted intent
When $triage promotes an intent, or the user names one:
- Read
projects/<scope>/intent/intent-<slug>.mdin full, thenglossary.mdand the ADRs it links. - Derive the story from the intent's sections — Problem and Proposed outcome become the User Story and the Problem line; the Falsification path becomes the first scenario, since it already names an observable outcome; Affected names the code paths for the slices; Constraints and Open questions land in the story's Decisions and scenarios respectively.
- Write
projects/<scope>/plan/<active-plan>/story-N-<slug>.md— next N in that plan — with[[intent-<slug>]]under References. No new plan for one story. triage_stateis what the operator chose at promotion:ready-for-agentwhen the brief is complete,needs-triageotherwise.- Add the Story Index row to the plan, then report the story slug back so triage writes
promoted_toand archives the intent (the intent's frontmatter is triage's to close, not this skill's).
Everything below is Input A — the conversation.
Prerequisites
WIKI_SCOPE: <scope>declared in the project instructions. If missing, suggest$wikiand stop.projects/<scope>/index.mdexists. If missing, suggest$intentand stop.- The conversation has discussed a concrete piece of work (a feature, a refactor, a phase). If only abstract intent has been discussed, suggest
$intentto nail it down first.
What this skill produces
projects/<scope>/
├── plan/
│ ├── plan-<name>.md ← thin orchestration (~60-100 lines)
│ └── <name>/
│ ├── story-1-<slug>.md ← Gherkin + slices (~40-60 lines)
│ ├── story-2-<slug>.md
│ └── story-3-<slug>.md
Each story file ships with triage_state: needs-triage. The user runs $triage next to evaluate readiness.
Process
1. Read the wiki context
- Call
prime(<scope>)via the wiki MCP, orkmd prime <scope>where the harness exposes no MCP tools — get identity, primer, active ADRs, top tags, current plan. - Read
projects/<scope>/glossary.mdif it exists — use canonical vocabulary throughout. - Read recent ADRs under
projects/<scope>/adr/to respect existing decisions. - Note any active plan — the new plan should not duplicate an in-flight one.
2. Synthesize (do not interview)
From the conversation, extract:
Plan slug — kebab-case, descriptive, ≤4 words. e.g. billing-mvp, void-and-amend, auth-rewrite. The slug becomes both the parent file (plan-{slug}.md) and the sub-folder ({slug}/).
Problem — 1-3 sentences from the user's perspective. Use vocabulary from glossary.md. If you can't write this without inventing, the conversation hasn't established the problem — stop and suggest $intent.
Solution — 2-3 sentences describing the approach. Reference existing specs/ADRs by wikilink ([[spec-cart-model]], [[adr-postgres]]).
User stories — extract from the conversation. Each story:
- Has a clear actor, capability, benefit
- Maps to a discrete piece of user value
- Will fit in 1-5 vertical slices
If you can identify <3 stories, the workstream may be too small. Two paths: (a) still create the parent plan-{slug}.md + {slug}/ sub-folder + the 1-2 story files — architectural consistency wins (skills downstream don't have a special-case path), or (b) skip the plan entirely and write a single standalone story under an existing related plan. Default to (a) unless the user prefers (b).
If you can identify >12 stories, the workstream is too large for one plan — propose splitting into multiple plans (plan-billing-foundation + plan-billing-rollout).
Out of Scope — 3-5 bullets capturing things explicitly not part of this plan. Lift these from the conversation.
3. Identify spec/ADR gaps
Walk the synthesized plan and ask:
- Does the solution describe a system that doesn't yet have a
spec-{topic}.md? → propose creating one. - Does the solution rely on a hard-to-reverse decision not yet captured in an ADR? → propose creating one (apply Matt's three-test: hard-to-reverse + surprising + real trade-off).
Don't write specs/ADRs in this skill — flag the gaps and reference future skill work. Or, if the gap is small enough to fill inline (a single new term in glossary.md), do it now.
4. Write the parent plan
Write projects/<scope>/plan/plan-<slug>.md using wiki://template/project/plan (MCP resource, or kmd resource <uri>) as the frontmatter base, with body:
# <Plan Title>
## Problem
<1-3 sentences from the user's perspective.>
## Solution
<2-3 sentences. Reference [[spec-X]] and [[adr-Y]] by wikilink.>
## Stories
| # | Story | State | Category |
|---|---|---|---|
| 1 | [[story-1-<slug-1>]] | needs-triage | enhancement |
| 2 | [[story-2-<slug-2>]] | needs-triage | enhancement |
| 3 | [[story-3-<slug-3>]] | needs-triage | enhancement |
## Out of Scope
- <bullet 1>
- <bullet 2>
- <bullet 3>
## References
- [[glossary]] — vocabulary
- [[spec-<topic>]] — system overview
- [[adr-<decision>]] — relevant decision
Frontmatter:
---
title: <Plan Title>
kind: plan
scope: <scope>
status: active
summary: "<one-sentence summary>"
tags: [...]
created: "<today>"
updated: <today>
---
5. Write each story file
For each user story, write projects/<scope>/plan/<slug>/story-N-<story-slug>.md using wiki://template/project/story (MCP resource, or kmd resource <uri>). Body:
# <Story Title>
## User Story
As a <actor>, I want <capability>, so that <benefit>.
## Scenarios
**Scenario: <happy path name>**
- Given <precondition>
- When <action>
- Then <expected outcome>
**Scenario: <edge case name>**
- Given <precondition>
- When <action>
- Then <expected outcome>
## Slices
- [ ] **Slice 1** — <description> · `AFK` · [[spec-<related>]]
- [ ] **Slice 2** — <description> · `AFK` · [[adr-<related>]]
## References
- [[spec-<related>]]
- [[adr-<related>]]
Frontmatter:
---
title: <Story Title>
kind: story
scope: <scope>
parent: plan-<slug>
status: active
triage_state: needs-triage
category: enhancement
blocked_by: []
tags: [...]
sources: []
created: "<today>"
updated: <today>
---
Rules for scenarios:
- Each scenario describes ONE behavior end-to-end.
- Use Given/When/Then, not free-form prose.
- Cover the happy path first, then 1-2 edge cases per story.
- Don't try to be exhaustive — the user can add scenarios during
$triageif a story needs more clarity.
Rules for slices:
- A slice is a tracer-bullet vertical through every layer (schema · API · UI · tests).
- Each slice should be independently demoable.
- Mark each slice
AFK(autonomous-runnable) orHITL(needs human judgment). - Default to AFK — push back if a user describes a slice that requires unavoidable human judgment.
- 1-5 slices per story is normal. If a story needs 6+, the story is too coarse — split it.
Slice ownership across skills: $to-stories writes a rough slice draft (1-3 slices, coarse, mostly to ground the story shape). $to-issues is the refinement pass — it validates vertical-slice rules, splits coarse slices into proper tracer bullets, sets blocked_by between stories, and (in GH/GitLab mode) mirrors ready-for-agent slices to remote issues. Don't over-invest in slice quality here; that's $to-issues's job.
6. Sync the wiki
After writing, confirm the resync: the posttool hook syncs automatically; if kmd config's synced line did not advance, run kmd validate then kmd sync.
This makes the new plan and stories searchable via prime and search (MCP tools, or kmd prime / kmd search).
7. Done — suggest next step
"Wrote
plan-<slug>with N stories, all atneeds-triage. Run$triageto evaluate readiness and move stories toready-for-agent(AFK) orready-for-human."
Rules
- Do not interview. Synthesize from conversation. If intent is unclear, suggest
$intent. - Do not auto-trigger
$triage. Stories ship atneeds-triageand wait for the user to invoke triage explicitly. - Use canonical vocabulary from
glossary.md. Don't invent terms. - Reference existing specs and ADRs via wikilinks rather than restating their content.
- One story file per user story. Even if a story has just one slice, it gets its own file (architectural consistency).
- Quote prose-bearing frontmatter scalars (
summary: "...") to avoid breaking the sync walker. - Do not write specs or ADRs in this skill — flag gaps and let
$intentfill them. - Update plan/story
updated:field after every edit. - Set
createdonce at creation; never bump it — onlyupdatedchanges on later edits.