--- title: "Branch, PR & Commit Strategy" status: active audience: [ai-agent, contributor] language: nl last_updated: 2026-05-03 when_to_read: "Before creating a branch, commit, or PR. Also before any agent-batch run." --- # Branch, PR & Commit Strategy ## Branch & PR Strategy (STRICT — kostenbeheersing) > **Core rule: één branch per milestone, PR alleen na gebruikerstest** Elke `git push` naar een feature-branch triggert een Vercel preview-deployment. Op het huidige Hobby-account zijn die schaars en kosten geld; we minimaliseren preview-builds tot er werkelijk iets te reviewen valt. ### Wel doen - Eén branch voor de hele milestone — `feat/M{N}-{slug}` (bv. `feat/M10-qr-login`); voor losse stories zonder milestone blijft `feat/ST-XXX-{slug}` geldig - Commits accumuleren lokaal volgens de Commit Strategy hieronder — één commit per stap, ST-code in de titel - Pushen + PR openen **pas nadat de gebruiker de milestone handmatig heeft getest en goedgekeurd** — vraag expliciet om bevestiging vóór `git push` - Tussentijdse "klaar voor jouw test"-momenten markeren met een lokale tag of een berichtje in chat, niet met een push ### Niet doen - Pushen na elke story of commit - Een PR per story openen tijdens de implementatie - "Just-in-case" pushen om backup te hebben — gebruik `git stash`, een lokale tag, of meerdere lokale branches - `--force-push` om eerdere preview-builds "weg te toveren" (kost dezelfde build opnieuw bij hercreatie) - **Direct pushen naar `main`** — die branch heeft protection rules; gebruik altijd een PR ### Wanneer wel commit-zonder-vragen, wanneer niet - **Tijdens een directed sprint-flow** (Track A: `mcp__scrum4me__implement_next_story` of een expliciete *"implementeer M{N}"*-opdracht): commit-per-laag conform de Commit Strategy hieronder is impliciet geautoriseerd — niet per commit vragen - **Bij ad-hoc / out-of-band werk** (bug-fix tussendoor, refactor, kleine wijziging op verzoek): toon de diff + voorgestelde commit-message en wacht op `"commit it"` voordat je `git commit` draait - **`git push` is altijd expliciet** — de scope van de policy gaat over preview-builds, dus push gebeurt alleen na gebruiker-test, ongeacht commit-context ### Uitzonderingen op de push-regel - Een **planning-PR** zonder code-wijzigingen (alleen docs in `docs/plans/` of `docs/`) mag direct gepusht worden — die triggert geen functional regressie en is goedkoop te bouwen - Een **bugfix-hotfix** op `main` met aantoonbare productie-impact mag direct gepusht worden (via een PR — zie boven) ### Wanneer aanpassen Zodra het Vercel-account naar Pro (of andere omgeving zonder per-build-kosten) gaat: vervang deze regel door "branch + PR per story" zoals oorspronkelijk in dit document stond. Werk deze sectie bij én documenteer de wijziging in `docs/decisions/agent-instructions-history.md`. ### Agent-batch flow (verplicht voor worker-runs) Wanneer de NAS-agent (`/opt/agent/`) een batch jobs uitvoert: | Moment | Actie | Verbod | |---|---|---| | Start run | `git checkout -b feat/` lokaal | `gh pr create` | | Na elke taak | `git add -A && git commit -m "(ST-XXX): "` | `git push` | | Queue leeg | `git push -u origin <branch>` + `gh pr create` | `gh pr merge` | | Na PR-create | `mcp__scrum4me__set_pbi_pr(pbi_id, pr_url)` → **STOP** | idem | - Alle commits accumuleren op dezelfde branch — lopende state blijft op disk tot de run klaar is. - Één PR per batch → één Vercel preview-deployment. - Single-task batch (1 job in queue): dezelfde flow — 1 commit → push + PR. - **De agent mergt nooit.** Na PR-create: `set_pbi_pr` aanroepen en stoppen. Wacht op handmatige merge door de PB-owner. - Als een volgende batch wordt geblokkeerd door de PBI-gate (open PR): toon de foutmelding (`open_pr_url`) aan de gebruiker. Niet opnieuw proberen. #### End-to-end verificatie: 1 batch = 1 Vercel-deploy Gebruik deze checklist om te verifiëren dat de batch-flow correct werkt na een agent-run: **Voorbereiding** 1. Seed ≥ 2 taken onder één story (bv. README-edits). 2. Trigger de batch via **"Voer alle uit"** op het Solo Board. 3. Wacht tot de agent alle jobs als `done` markeert. **GitHub-checks** - [ ] Er is precies **één PR** aangemaakt voor de batch-branch. - [ ] De PR bevat **één commit per taak** (geen squash, geen force-push). - [ ] Er zijn **geen losse pushes** op de branch vóór de definitieve push (check via `git log --all --graph` of GitHub's "commits" tab). **Vercel-checks** - [ ] In het Vercel-dashboard → **Deployments**: er is **exact één preview-deployment** voor de branch in het run-window. - [ ] Geen extra "cancelled" of "building" deployments voor dezelfde branch uit hetzelfde tijdsvenster (zou wijzen op tussentijdse pushes). **Alternatieve verificatie via Vercel MCP** (indien beschikbaar): ``` mcp__<vercel-plugin-id>__list_deployments → filter op branchName = feat/<batch-slug> → verwacht: 1 entry met state = READY of BUILDING ``` **Race-condition scenario**: als een nieuwe taak in de queue terechtkomt terwijl de agent de queue-check uitvoert, kan er een tweede push volgen. Dit is acceptabel — de tweede push triggert een tweede deployment voor de resterende commits. Documenteer dit afwijkend gedrag in de PR-description als het zich voordoet. --- ## Plan Mode - Voor simpele, goed-afgebakende file-edits: **niet** in plan mode gaan — gewoon de wijziging maken - Reserveer plan mode voor multi-step refactors, ambigue verzoeken, of milestone-planning waarbij design-keuzes vooraf bevestigd moeten worden - Plannen die uit plan mode komen: opslaan als `docs/plans/M{N}-{slug}.md` (zie memory `feedback_plan_location`), niet als ephemeral systeem-bestand --- ## Commit Strategy (STRICT) > **Core rule: één commit = één verantwoordelijkheid** ### Nooit doen - Database + API + UI in één commit mengen - Feature + documentatie combineren - Grote "alles gewijzigd" commits - Vage berichten zoals "update stuff" ### Verplichte structuur Splits werk op in logische lagen: 1. Database / Prisma 2. API / server actions 3. UI / components 4. Config / infra 5. Documentatie ### Commit-formaat ``` feat(ST-XXX): korte beschrijving fix(ST-XXX): korte beschrijving chore(ST-XXX): korte beschrijving docs(ST-XXX): korte beschrijving ``` ### Voorbeeld (verplicht patroon) In plaats van: ```bash feat: add profile system ``` Splits altijd op in: ```bash feat(ST-XXX): add user profile fields to Prisma schema feat(ST-XXX): add avatar upload endpoint feat(ST-XXX): add profile editor component chore(ST-XXX): configure sharp for avatar processing docs(ST-XXX): document profile feature ```