- Rewrite docs/patterns/sort-order.md: float-insertion PBI only; story/task sort_order = parseCodeNumber(code), never drag/membership mutated - Update plan-to-pbi-flow.md: sort_order auto, sprint_id param, priority=label - Update make-plan.md: priority=label, array order = execution order - Update rest-contract.md: fix sprint-tasks ordering, remove reorder endpoint - Add ADR-0011: code is bindende volgordesleutel voor stories/taken - Regenerate docs/INDEX.md via npm run docs - Remove reorderStoriesAction/reorderTasksAction mocks from backlog tests - Remove dnd-kit mocks from task-panel test (panel no longer uses dnd) - Extend materializeIdeaPlanAction test: assert sort_order=parseCodeNumber(code) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
10 KiB
| title | status | audience | language | last_updated | when_to_read | ||
|---|---|---|---|---|---|---|---|
| Plan → Sprint/PBI/Story/Task workflow | active |
|
nl | 2026-05-11 | 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" en docs/runbooks/mcp-integration.md → Batch-loop.
Sprint-tools
create_sprintenupdate_sprintzijn live in scrum4me-mcp (PBI-12). Tool-reference: 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 opOPEN.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 planpriority—LOW | NORMAL | HIGH(defaultNORMAL); pas opHIGHzetten als de gebruiker het zelf zegtsort_order— leeg laten; server zetlast + 1binnen de priority-groep- Status start automatisch op
OPEN
2. create_story
{ pbi_id, sprint_id, title, description?, acceptance_criteria?, priority }
title— concreet, in user-story stijl als dat past ("Als developer wil ik …")description— technische context, scope-grenzen, niet-doelenacceptance_criteria— markdown checklist (- [ ] …); bepaalt wanneer de StoryDONEisproduct_idwordt afgeleid uit de PBI — niet meegevensprint_id— geef de zojuist aangemaakte sprint mee. Als er meerdere OPEN-sprints bestaan: bevestig eerst met de gebruiker welke sprint geldt.sort_order— NIET meegeven. De server berekentsort_order = parseCodeNumber(code)automatisch. De volgorde van stories = de volgorde van hun codes (= aanroep-volgorde); niet priority.- 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 }
title— werkwoord-vorm: "Implementeer …", "Verplaats …", "Voeg test toe voor …"description— wat de taak afdekt, in 1-3 zinnenimplementation_plan— belangrijk: markdown met de daadwerkelijke stappen + file-paths + reuse-pointers; dit is wat de Implementation-agent later inleestsort_order— NIET meegeven. De server berekentsort_order = parseCodeNumber(code)automatisch. De uitvoervolgorde = de aanroep-volgorde (= code-volgorde); niet priority.sprint_idwordt geërfd van de Story — niet meegeven- Status start op
TO_DO
De uitvoervolgorde van taken is gelijk aan de aanroep-volgorde van
create_task(= code-volgorde).priorityis een label (urgentie), géén sorteerkriteria. 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_statusnaarIN_PROGRESSzetten - ❌
get_claude_contextaanroepen 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".
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:
- PR merged op
main— detecteer metgh pr view <num> --json mergedAt(niet-leeg = merged) of een GitHub-merge-webhook - Verify groen —
gh pr checks <num>allemaal ✅, óf de bestaandemcp__scrum4me__verify_sprint_tasktool 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
CLOSEDzetten (happy-path: merge + verify groen) alsFAILED(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.
Verhouding tot de planning-agent
docs/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 — volledige MCP-tool reference + execution-loop
- docs/runbooks/branch-and-commit.md — git-discipline bij uitvoer
- docs/runbooks/worker-idempotency.md — job-status protocol (uitvoer-fase)
- docs/plans/tweede-claude-agent-planning.md — toekomstige planning-agent (proposal)