--- title: "Sprint execution modes — PER_TASK vs SPRINT_BATCH" status: active audience: [maintainer, contributor] language: nl last_updated: 2026-05-07 related: [project-structure.md](./project-structure.md), [data-model.md](./data-model.md) --- # Sprint execution modes (PBI-50) `Product.pr_strategy` bepaalt hoe een SprintRun wordt uitgevoerd. Drie waarden: | Waarde | Branch + PR | Worker-sessies | Wanneer | |---|---|---|---| | `STORY` | branch + PR per story | één claude-sessie per task | klassieke flow; iedere story landt onafhankelijk | | `SPRINT` | één draft-PR voor de hele sprint, mark-ready aan eind | één claude-sessie **per task** | werk wordt verzameld in één PR maar tasks blijven losse jobs | | `SPRINT_BATCH` | één draft-PR voor de hele sprint, mark-ready aan eind | **één claude-sessie voor de hele sprint** | snelste pad; vereist alle tasks in dezelfde repo | `STORY` en `SPRINT` triggeren beide het PER_TASK-pad: per TO_DO-task één `ClaudeJob` met `kind=TASK_IMPLEMENTATION`. Het verschil zit alleen in de PR-strategie van [`maybeCreateAutoPr`](https://github.com/madhura68/scrum4me-mcp/blob/main/src/tools/update-job-status.ts). `SPRINT_BATCH` triggert het PER_SPRINT-pad: één `ClaudeJob` met `kind=SPRINT_IMPLEMENTATION` die alle TO_DO-tasks van de sprint sequentieel afhandelt in één claude-sessie. --- ## Waarom SPRINT_BATCH Iedere task-claim onder PER_TASK is een verse `claude -p`-sessie. Setup-overhead per task: laden van Claude Code + MCP-tools, project-CLAUDE.md inlezen, codebase-oriëntatie. Bij een sprint van 12 tasks van elk 2-4 minuten effectief werk levert dat ~10-20% pure setup-overhead op én geen continuïteit tussen tasks. `SPRINT_BATCH` ruilt deze overhead in voor één lange sessie: ``` PER_TASK (STORY/SPRINT): SPRINT_BATCH: task1 → setup → werk → done setup → task1 → task2 → ... → done task2 → setup → werk → done [één heartbeat-loop, één branch, task3 → setup → werk → done één PR, één finalisering] ... ``` --- ## Trade-offs | Aspect | PER_TASK | SPRINT_BATCH | |---|---|---| | Setup-overhead per task | hoog | éénmalig | | Cross-repo task | toegestaan via `task.repo_url`-override | hard-fail in pre-flight (`task_cross_repo`-blocker) | | Mid-sprint task-plan-edit | wordt direct opgepikt door volgende claim | snapshot-frozen in `SprintTaskExecution.plan_snapshot` op claim-tijd | | Cancel/pause vanuit UI | werkt op task-niveau (volgende claim respecteert PAUSED-status) | werkt op SprintRun-niveau via `job_heartbeat`-respons (worker breekt task-loop bij `sprint_run_status !== 'RUNNING'`) | | Failure-mode | task → cancelPbiOnFailure cascade | cascade-stop op eerste fail; sprint → FAILED, branch wordt gepusht maar PR niet ready | | Quota-pause | niet gedefinieerd | per-task probe via `worker_heartbeat`; bij low → `QUOTA_PAUSE:`-prefix → SprintRun PAUSED met resume-instructions; resume creëert nieuwe SprintRun met `previous_run_id` + branch-hergebruik | --- ## Datamodel `SPRINT_BATCH` introduceert: - `ClaudeJobKind.SPRINT_IMPLEMENTATION` — één job per SprintRun. - `SprintTaskExecution` — frozen scope-snapshot per claim: `{ plan_snapshot, verify_required_snapshot, verify_only_snapshot, base_sha, head_sha, status, verify_result, verify_summary }`. Worker en gate werken uitsluitend op deze rows; latere wijzigingen aan Task-records hebben geen invloed op de lopende batch. - `ClaudeJob.lease_until` — heartbeat-driven anti-stale-reset (60s interval, 5min lease). - `SprintRun.previous_run_id` (self-relation `SprintRunChain`) — link naar de voorgaande run bij resume; worker hergebruikt `previous.branch` in plaats van `feat/sprint-`. --- ## MCP-tools per modus | Tool | PER_TASK | SPRINT_BATCH | |---|---|---| | `wait_for_job` | ✓ | ✓ (claim-filter discrimineert via `cj.kind`) | | `update_task_plan` | ✓ | n/a (frozen in snapshot) | | `verify_task_against_plan` | ✓ | n/a | | `verify_sprint_task` | n/a | ✓ (per execution, snapshot-aware) | | `update_task_status` | ✓ | ✓ (vereist `sprint_run_id` voor token-coupling) | | `update_task_execution` | n/a | ✓ | | `job_heartbeat` | ✓ (lease-extend, no sprint-fields) | ✓ (lease-extend + `sprint_run_status` poll) | | `update_job_status` | ✓ (per-task) | ✓ (aggregate `checkSprintVerifyGate` + `finalizeSprintRunOnDone`) | Volledige tool-catalogus: [scrum4me-mcp README](https://github.com/madhura68/scrum4me-mcp#readme). Worker-loop pseudocode: [scrum4me-docker CLAUDE.md](https://github.com/madhura68/scrum4me-docker/blob/master/CLAUDE.md).