Scrum4Me/docs/runbooks/plan-to-pbi-flow.md
Madhura68 b7c3516027 docs(PBI-12 T-55): promote plan-to-pbi-flow.md naar active
- frontmatter status: draft → active
- ⚠️-tooling-banner verwijderd; tools live sinds adbea3f in scrum4me-mcp
- korte note die naar mcp-integration.md verwijst voor tool-reference

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 21:08:30 +02:00

206 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "Plan → Sprint/PBI/Story/Task workflow"
status: active
audience: [ai-agent, maintainer]
language: nl
last_updated: 2026-05-11
when_to_read: "Wanneer de gebruiker een plan goedkeurt en je het werk via Scrum4Me-MCP wilt vastleggen — inclusief sprint-lifecycle."
---
# Plan → Sprint / PBI / Story / Task workflow
Hoe je een **goedgekeurd plan** omzet naar een hiërarchie van Sprint + PBI + Story + Task(s) via de Scrum4Me-MCP, zónder de taken meteen uit te voeren. Eén PBI = één increment = één sprint.
Dit is de **creatie-kant** van het werk. De **uitvoer-kant** staat in [CLAUDE.md → "Hoe werk vinden"](../../CLAUDE.md) en [docs/runbooks/mcp-integration.md → Batch-loop](./mcp-integration.md).
> Sprint-tools `create_sprint` en `update_sprint` zijn live in scrum4me-mcp (PBI-12). Tool-reference: [mcp-integration.md](./mcp-integration.md).
---
## Wanneer wel — wanneer niet
| Type werk | Sprint + PBI maken? |
|---|---|
| Nieuwe feature, refactor, UX-aanpassing, performance-fix | **Ja** |
| Bug-fix die meer dan een trivial-edit vereist | **Ja** |
| Doc-only edit (CLAUDE.md, runbook, README) | Nee — direct edit, commit, klaar |
| Typo, format-fix, dead-code verwijdering (<10 regels) | Nee |
| Spike / verkenning zonder concrete output | Nee log eventueel als Idea (M12) |
Sprint volgt PBI: **geen PBI → geen sprint**. Twijfel? Vraag het.
---
## De vier-laagse flow
```
plan goedgekeurd
├─ create_sprint → Sprint-record (status=OPEN, start_date=vandaag)
│ │
│ └─ create_pbi → PBI-record onder dat product
│ │
│ └─ create_story → Story-record, koppelt aan de actieve sprint
│ │
│ └─ create_task (× N) → sprint_id geërfd van story
├─ stop — wachten op uitvoer-instructie
├─ … execution-fase via "Hoe werk vinden" …
└─ PR merged + verify groen → update_sprint(status=CLOSED, end_date=vandaag)
```
### 0. `create_sprint` (vóór alle andere create-calls)
```
{ product_id, code, sprint_goal, status: 'OPEN', start_date? }
```
- **`code`** kort label, max 30 chars. Suggestie: `S-{YYYY-MM-DD}-{kebab-PBI-titel}` of een lopende teller (`S-2026-05-11-web-push`).
- **`sprint_goal`** één regel, het increment in mensen-taal (komt uit de "Context" van het goedgekeurde plan).
- **`status`** start op `OPEN`.
- **`start_date`** vandaag; leeg laten als de server dit zelf invult.
- **Geen reuse:** altijd nieuw record. Bestaande OPEN-sprints van eerder werk blijven naast deze nieuwe leven; niet automatisch sluiten.
> Eén PBI per sprint is de afgesproken één-op-één-koppeling. Als een plan logisch in meerdere onafhankelijke PBI's uiteenvalt, maak je ook meerdere sprints.
### 1. `create_pbi`
```
{ product_id, title, description?, priority, sort_order? }
```
- **`title`** korte feature-naam, geen PBI-nummer als prefix (DB kent al een id)
- **`description`** markdown, het "wat & waarom" uit de Context-sectie van het plan
- **`priority`** `LOW | NORMAL | HIGH` (default `NORMAL`); pas op `HIGH` zetten als de gebruiker het zelf zegt
- **`sort_order`** leeg laten; server zet `last + 1` binnen de priority-groep
- Status start automatisch op `OPEN`
### 2. `create_story`
```
{ pbi_id, title, description?, acceptance_criteria?, priority, sort_order? }
```
- **`title`** concreet, in user-story stijl als dat past ("Als developer wil ik …")
- **`description`** technische context, scope-grenzen, niet-doelen
- **`acceptance_criteria`** markdown checklist (`- [ ] …`); bepaalt wanneer de Story `DONE` is
- `product_id` wordt afgeleid uit de PBI niet meegeven
- **Sprint-koppeling:** de story wordt aan de actieve OPEN-sprint gehangen (de zojuist aangemaakte). Als er meerdere OPEN-sprints bestaan: bevestig eerst met de gebruiker welke sprint geldt, of breidt `create_story` uit met een expliciete `sprint_id` parameter (apart PBI).
- Status start op `OPEN`
> **Eén story per PBI** is de gebruikelijke verhouding. Splits alleen op in meerdere stories als het plan logisch in onafhankelijk-shipbare delen valt — let op dat dit dan ook meerdere sprints betekent.
### 3. `create_task` (één call per taak)
```
{ story_id, title, description?, implementation_plan?, priority, sort_order? }
```
- **`title`** werkwoord-vorm: "Implementeer …", "Verplaats …", "Voeg test toe voor …"
- **`description`** wat de taak afdekt, in 1-3 zinnen
- **`implementation_plan`** **belangrijk**: markdown met de daadwerkelijke stappen + file-paths + reuse-pointers; dit is wat de Implementation-agent later inleest
- **`sort_order`** leeg laten voor de eerste call; daarna server-side `last + 1`, of expliciet meegeven om volgorde af te dwingen
- `sprint_id` wordt geërfd van de Story niet meegeven
- Status start op `TO_DO`
> De gebruiker werkt taken af in **sort_order**. Zet voorbereidende taken (data-model, types) vóór UI-taken; tests komen ná de feature-implementatie tenzij TDD expliciet is afgesproken.
---
## Hardstop — wachten op uitvoer-instructie
Na `create_task` (de laatste): **stop**. Niet:
- Branch aanmaken
- Code wijzigen
- `update_task_status` naar `IN_PROGRESS` zetten
- `get_claude_context` aanroepen om "vast te beginnen"
De gebruiker leest de aangemaakte items, eventueel via de UI, en geeft expliciet de instructie *"voer de taken uit"* / *"pak deze story"* / *"begin met taak 1"*. Pas dan schakelt de flow over naar de **execution-loop** uit [CLAUDE.md → "Hoe werk vinden"](../../CLAUDE.md).
---
## Sprint sluiten — `update_sprint`
Na de execution-fase (laatste taak `DONE` branch gepusht PR aangemaakt) wordt de sprint pas `CLOSED` als **beide** condities waar zijn:
1. **PR merged op `main`** detecteer met `gh pr view <num> --json mergedAt` (niet-leeg = merged) of een GitHub-merge-webhook
2. **Verify groen** `gh pr checks <num>` allemaal ✅, óf de bestaande [`mcp__scrum4me__verify_sprint_task`](./mcp-integration.md) tool slaagt voor de laatste taak
Pas dan:
```
update_sprint({ sprint_id, status: 'CLOSED', end_date: today })
→ status = CLOSED
```
**Wat als één van beide rood is?**
| Situatie | Handmatige flow | Cron-flow (auto) |
|---|---|---|
| PR merged, verify rood | Sprint blijft `OPEN`. Hot-fix taak/PR, daarna close-check herhalen. | Cron mag de sprint na *N* mislukte verify-runs (drempel TBD) op `FAILED` zetten. |
| Verify groen, PR niet merged | Sprint blijft `OPEN`. Wacht op review/merge. | Cron mag na *X* dagen zonder merge op `FAILED` (stale-detectie). |
| PR gesloten zonder merge | Sprint blijft `OPEN` totdat gebruiker beslist. | Cron mag direct op `FAILED` zetten PR-`closed && !merged` is een eindstatus. |
| Werk geannuleerd door gebruiker | Sprint `ARCHIVED` (handmatig). | Niet door cron vereist gebruikersactie. |
> **Cron-trigger:** een geplande job mag dus zowel `CLOSED` zetten (happy-path: merge + verify groen) als `FAILED` (sad-path: stale PR, blijvend rode verify, PR-closed zonder merge). De drempels (*N*, *X*) en transitie-policy komen in het vervolg-PBI voor de MCP-tools — zie [docs/plans/sprint-mcp-tools.md](../plans/sprint-mcp-tools.md).
---
## Verhouding tot de planning-agent
[docs/plans/tweede-claude-agent-planning.md](../plans/tweede-claude-agent-planning.md) (status: `proposal`) beschrijft een **automatische planning-agent** die deze flow uit een `PLANNING`-job zelfstandig uitvoert. Tot die agent er is, doet de Claude-Code-sessie het handmatig zoals hierboven. De toolchain (`create_sprint`/`create_pbi`/`create_story`/`create_task` + `update_sprint`) blijft identiek de agent zal dezelfde MCP-tools gebruiken.
---
## Korte voorbeeld-sessie
```
Gebruiker: "plan goedgekeurd"
Claude: create_sprint({ product_id, code: "S-2026-05-11-web-push",
sprint_goal: "Web-Push end-to-end voor open vragen",
status: "OPEN" })
→ sprint_id: 73
create_pbi({ product_id, title: "Web-Push notifications voor open vragen",
description: "<plan-context>", priority: "NORMAL" })
→ pbi_id: 142
create_story({ pbi_id: 142,
title: "PBI-142: web-push end-to-end",
description: "<scope>",
acceptance_criteria: "- [ ] Service worker geregistreerd\n- [ ] …",
priority: "NORMAL" })
→ story_id: 988 (gekoppeld aan sprint 73)
create_task({ story_id: 988, title: "Voeg VAPID-keys toe aan env-schema",
implementation_plan: "1. lib/env.ts uitbreiden …",
priority: "NORMAL" })
create_task({ story_id: 988, title: "Server action: subscribe-endpoint",
implementation_plan: "…", priority: "NORMAL" })
create_task({ story_id: 988, title: "Vitest: subscribe-endpoint smoke",
implementation_plan: "…", priority: "NORMAL" })
"Sprint 73 (OPEN), PBI 142, Story 988 met 3 taken aangemaakt.
Klaar om uit te voeren zodra je 'voer uit' zegt."
Gebruiker: "voer uit"
Claude: <execution-loop volgens 'Hoe werk vinden' — branch, code, commit, push, PR>
…na PR-merge + verify groen…
Claude: update_sprint({ sprint_id: 73, status: "CLOSED", end_date: "2026-05-12" })
→ sprint 73 status = CLOSED
"Sprint 73 gesloten. Increment shipped."
```
---
## Verwante docs
- [docs/runbooks/mcp-integration.md](./mcp-integration.md) volledige MCP-tool reference + execution-loop
- [docs/runbooks/branch-and-commit.md](./branch-and-commit.md) git-discipline bij uitvoer
- [docs/runbooks/worker-idempotency.md](./worker-idempotency.md) job-status protocol (uitvoer-fase)
- [docs/plans/tweede-claude-agent-planning.md](../plans/tweede-claude-agent-planning.md) toekomstige planning-agent (proposal)