---
title: "Aanbeveling — Claude VM jobflow en gitstrategie"
status: draft
audience: [product-owner, maintainer, ai-agent]
language: nl
last_updated: 2026-05-09
---

# Aanbeveling — Claude VM jobflow en gitstrategie

## Managementsamenvatting

Scrum4Me heeft inmiddels een duidelijke jobarchitectuur: de app maakt jobs aan, de Docker-runner claimt jobs en start Claude op een VM, en `scrum4me-mcp` bewaakt de lifecycle, worktrees, branches, pushes en PR's. De huidige implementatie is daarmee sterker en veiliger dan een prompt-gestuurde agent die zelf jobs ophaalt, pusht of PR's maakt.

De belangrijkste aanbeveling is om deze servergestuurde lijn expliciet leidend te maken:

- Claude implementeert en commit lokaal, maar bepaalt niet de branch-, push- of PR-strategie.
- `scrum4me-mcp` blijft de enige partij die jobs claimt, worktrees koppelt, branches pusht, PR's maakt en auto-merge activeert.
- Productinstellingen bepalen bewust de PR-strategie: `SPRINT` als veilige default, `STORY` voor kleine auto-mergebare changes, `SPRINT_BATCH` alleen voor goed afgebakende single-repo sprints.
- De documentatie en prompts moeten worden bijgewerkt, omdat sommige oudere docs nog een handmatige "niet pushen tot user-test"-flow beschrijven terwijl de actuele VM-flow al automatisch pusht na een succesvolle job.

## Huidige Flow

```mermaid
flowchart TD
  U["Gebruiker start sprint, idee of plan"] --> A["Scrum4Me app voert preflight uit"]
  A --> Q["ClaudeJob wordt QUEUED"]
  Q --> S{"Product.pr_strategy"}

  S -->|STORY| J1["TASK_IMPLEMENTATION jobs<br/>branch per story"]
  S -->|SPRINT| J2["TASK_IMPLEMENTATION jobs<br/>branch per sprint"]
  S -->|SPRINT_BATCH| J3["1 SPRINT_IMPLEMENTATION job<br/>hele sprint"]
  Q --> J4["IDEA_GRILL / IDEA_MAKE_PLAN / PLAN_CHAT<br/>geen git PR-flow"]

  J1 --> R["scrum4me-docker runner<br/>quota, claim, payload, claude -p"]
  J2 --> R
  J3 --> R
  J4 --> R

  R --> C["Claude op VM<br/>wijzigt code, commit lokaal, logt, verifieert"]
  C --> M["scrum4me-mcp update_job_status<br/>verify gate, push, PR, statuspropagatie, cleanup"]

  M --> P{"PR-strategie"}
  P -->|STORY| PS["PR per story<br/>auto-merge na groene checks"]
  P -->|SPRINT| PP["draft PR per sprint<br/>ready bij sprint DONE"]
  P -->|SPRINT_BATCH| PB["draft PR per sprint<br/>ready na batch DONE"]
```

## Rollen en Verantwoordelijkheden

| Actor | Verantwoordelijkheid | Mag niet doen |
|---|---|---|
| Gebruiker / product owner | Productinstellingen kiezen, sprint starten, review/merge bij sprint-PR's | Impliciete gitregels in prompts laten zweven |
| Scrum4Me app | Preflight, jobcreatie, strategie snapshotten op SprintRun | Zelf VM-werk orkestreren |
| scrum4me-docker | Job claimen, Claude starten, lease vernieuwen bij batchjobs | Zelf branch/PR-beleid bepalen |
| Claude op VM | Implementeren, lokaal committen, logs schrijven, verificatie draaien | Pushen, PR's maken, jobs ophalen |
| scrum4me-mcp | Claimprotocol, worktrees, branchnaam, push, PR, auto-merge, cleanup | Beslissingen overlaten aan losse prompttekst |
| GitHub | Branch protection, status checks, auto-merge, merge queue | Onbeschermde main-merge toestaan |

## Beslissingspunten

| Moment | Beslissing | Eigenaar | Advies |
|---|---|---|---|
| Productconfiguratie | `pr_strategy` en `auto_pr` | Gebruiker / product owner | Maak dit expliciet zichtbaar als operationele keuze |
| Sprint-start | Welke jobs worden aangemaakt | Scrum4Me app | Blijf blokkeren op ontbrekende plannen, open vragen en cross-repo batchrisico |
| Jobclaim | Welke job mag draaien | scrum4me-mcp | Houd atomic claim met lease en stale reset centraal |
| Runtime | Model, thinking budget, permissions | Job-config resolver | Snapshot bij enqueue en log de gekozen configuratie |
| Implementatie | Welke codewijziging en commits | Claude | Commit lokaal per logische laag, geen push |
| Verify gate | `EMPTY`, `PARTIAL`, `DIVERGENT` acceptabel? | scrum4me-mcp | Maak gate-regels testbaar en documenteer per jobkind |
| Push | Branch pushen of no-changes | scrum4me-mcp | Push alleen na succesvolle terminale status en geldige verify gate |
| PR | Geen PR, draft PR, ready PR, auto-merge | scrum4me-mcp + GitHub | Gebruik branch protection en required checks als harde randvoorwaarde |
| Failure | Retry, fail, skip, pause, cascade | scrum4me-mcp | Houd foutafhandeling server-side, niet prompt-side |

## Git- en PR-strategie

| Strategie | Jobs | Branch | PR | Mergebeleid | Aanbevolen gebruik |
|---|---:|---|---|---|---|
| `STORY` | Een job per taak | `feat/story-<story-id>` | PR per story | Auto-merge na groene checks | Kleine, onafhankelijke stories met betrouwbare CI |
| `SPRINT` | Een job per taak | `feat/sprint-<sprint-run-id>` | Een draft PR per sprint | Ready bij sprint DONE, menselijke merge | Veilige default voor productwerk |
| `SPRINT_BATCH` | Een job voor hele sprint | `feat/sprint-<sprint-run-id>` | Een draft PR per sprint | Ready na batch DONE, menselijke merge | Single-repo sprint met stabiele scope en contextvoordeel |
| Idee/plan jobs | Een job | Geen normale featurebranch | Geen PR | Alleen status/docs/logs | Ideevorming en planvorming |

Belangrijk: in de huidige implementatie betekent `auto_pr=false` niet automatisch "niet pushen". MCP pusht nog steeds branches wanneer een job succesvol afrondt en er commits zijn. `auto_pr` bepaalt vooral of daarna automatisch een PR wordt gemaakt.

## Aanbevolen Default

Gebruik `SPRINT` als standaardstrategie voor Scrum4Me-productwerk.

Redenen:

- Er is maar één PR per sprint, dus review en deployment blijven overzichtelijk.
- Claude kan per taak draaien en falen zonder dat de hele sprintcontext in één lange sessie hoeft te blijven leven.
- De PR blijft draft totdat de sprint klaar is, wat goed past bij menselijke review.
- Het voorkomt dat veel kleine story-PR's automatisch deployments of reviewprocessen starten.

Gebruik `STORY` alleen wanneer:

- De repository sterke branch protection heeft.
- Required checks verplicht zijn.
- De story klein genoeg is om automatisch te mergen.
- Auto-merge gewenst is en deploymentkosten acceptabel zijn.

Gebruik `SPRINT_BATCH` alleen wanneer:

- Alle taken in dezelfde repository zitten.
- De sprintscope stabiel is.
- Er weinig kans is op tussentijdse gebruikersvragen.
- Contextbehoud belangrijker is dan kleine herstelbare stappen.

## Concrete Acties

### 1. Maak MCP de formele orchestrator

Leg in de docs vast dat `scrum4me-mcp` de enige eigenaar is van:

- jobclaim en lease;
- worktree-aanmaak;
- branchnamen;
- push;
- PR-creatie;
- auto-merge;
- statuspropagatie;
- cleanup.

Claude mag alleen lokaal committen en via MCP-tools status/logs/verificatie doorgeven.

### 2. Trek documentatie gelijk

Werk minimaal deze stukken bij:

- `CLAUDE.md`: onderscheid maken tussen handmatige lokale agentflow en VM-jobflow.
- `docs/runbooks/branch-and-commit.md`: verouderde "push pas na user-test"-regel beperken tot handmatige runs.
- `docs/runbooks/auto-pr-flow.md`: expliciet maken dat MCP na `done` pusht en daarna optioneel PR maakt.
- `scrum4me-docker/README.md`: beschrijven dat de runner één job per `claude -p` uitvoert.
- `scrum4me-mcp/README.md`: branchnamen actualiseren naar `feat/story-*` en `feat/sprint-*`.

### 3. Fix prompt/tool-contracten

Los deze inconsistenties op:

- Task prompt: `update_job_status(skipped)` vereist een `error`, niet alleen een `summary`.
- Sprint prompt: `verify_required` wordt gebruikt als enum/gate, niet als boolean.
- Sprint prompt: verduidelijk wanneer een task binnen een batch echt `SKIPPED` mag worden.
- Docker docs: verwijder de oude instructie dat Claude zelf `wait_for_job` blijft aanroepen.

### 4. Maak de state machine expliciet

Documenteer en test de lifecycle als state machine:

```text
QUEUED -> CLAIMED -> RUNNING -> DONE
                         |-> FAILED
                         |-> SKIPPED
                         |-> CANCELLED
```

Aanbevolen start: een pure TypeScript transition table met tests. XState is pas nodig als visualisatie, model-based testing of complexere parallelle staten belangrijk worden.

### 5. Versterk GitHub-randvoorwaarden

Voor repositories waar `STORY` auto-merge gebruikt:

- Require status checks before merging.
- Require pull request reviews of CODEOWNERS voor risicovolle paden.
- Disable force pushes op beschermde branches.
- Gebruik `gh pr merge --auto --squash --match-head-commit` of equivalent met head-SHA guard.
- Overweeg merge queue zodra meerdere workers tegelijk PR's kunnen laten landen.

### 6. Beperk VM-risico

De VM-runner moet blijven werken met:

- least-privilege tokens;
- expliciete allowed tools;
- worktrees per job;
- geen secrets in logs;
- geïsoleerde runtime;
- duidelijke retry- en stale-claimregels;
- optioneel netwerkbeleid per repository of jobtype.

## Governance-Regel

De centrale regel voor Scrum4Me zou moeten zijn:

> Claude mag code veranderen en lokaal committen. Alleen Scrum4Me MCP mag bepalen wanneer werk klaar is, welke branch wordt gepusht, of er een PR komt, en of die PR automatisch mag mergen.

Deze regel voorkomt dat prompts, docs en runtimegedrag uit elkaar gaan lopen.

## Bronnen en Lokale Referenties

Lokale referenties:

- `actions/sprint-runs.ts` — sprint-start, preflight en jobcreatie.
- `components/products/pr-strategy-select.tsx` — productkeuze voor `STORY`, `SPRINT`, `SPRINT_BATCH`.
- `scrum4me-docker/bin/run-one-job.ts` — runner claimt één job en start Claude.
- `scrum4me-mcp/src/tools/wait-for-job.ts` — claimprotocol, worktree en branchresolutie.
- `scrum4me-mcp/src/tools/update-job-status.ts` — verify gate, push, PR, auto-merge, statuspropagatie.
- `scrum4me-mcp/src/git/push.ts` — branch push.
- `scrum4me-mcp/src/git/pr.ts` — GitHub PR-create, PR-ready en auto-merge.

Externe bronnen:

- GitHub Docs — Protected branches: <https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches>
- GitHub Docs — Required status checks: <https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches#require-status-checks-before-merging>
- GitHub Docs — Auto-merge: <https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-auto-merge>
- GitHub CLI — `gh pr merge`: <https://cli.github.com/manual/gh_pr_merge>
- GitHub Docs — Merge queue: <https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue>
- Trunk Based Development — Short-lived branches: <https://trunkbaseddevelopment.com/short-lived-feature-branches/>
- DORA — Trunk-based development capability: <https://dora.dev/capabilities/trunk-based-development/>
- Temporal Docs — Durable workflows: <https://docs.temporal.io/>
- XState Docs — State machines: <https://stately.ai/docs/state-machines>
- Anthropic Docs — Claude Code headless mode: <https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-headless>
- Anthropic Docs — Secure deployment guidance: <https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-secure-deployment>
