Bevestigt het huidige datamodel (Product.repo_url is single) en kiest "duplicate-PBI per product" voor cross-repo werk; markeert een Initiative-laag (boven PBI) als toekomstige uitbreiding zodra de duplicatie-pijn te groot wordt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
120 lines
5.4 KiB
Markdown
120 lines
5.4 KiB
Markdown
---
|
|
status: accepted
|
|
date: 2026-05-03
|
|
decision-makers: Janpeter Visser
|
|
consulted: Claude (planning agent)
|
|
informed: alle Scrum4Me-gebruikers die met meerdere repos werken
|
|
---
|
|
|
|
# ADR-0010: Eén product = één repo; cross-product planning vereist (later) een Initiative-laag
|
|
|
|
## Context and Problem Statement
|
|
|
|
Een feature kan meerdere repositories raken — bv. de "agent merge-policy"-feature
|
|
heeft tegelijk werk nodig in `Scrum4Me` (schema, server actions, UI) én in
|
|
`scrum4me-mcp` (twee nieuwe MCP-tools). Het Scrum4Me-datamodel kent op dit
|
|
moment één `repo_url` per `Product`, en stories hangen aan één PBI dat aan één
|
|
product hangt. Hoe modelleren we werk dat structureel meerdere repos raakt?
|
|
|
|
## Decision Drivers
|
|
|
|
- Per-repo PR-volgorde en deploy-pipeline blijft simpel (1 PR = 1 repo).
|
|
- Auditbaarheid: de link tussen "wat is gemerged" en "in welke repo" moet
|
|
triviaal te leggen zijn.
|
|
- Het datamodel moet niet de complexiteit van een feature dragen die in 80% van
|
|
de gevallen toch single-repo is.
|
|
- Plannen wel kunnen overspannen: een idee kan zonder fricted tegelijk taken
|
|
in twee repo's beschrijven.
|
|
|
|
## Considered Options
|
|
|
|
- **A. Eén product = één repo, plan-overspanning via duplicate-PBI per product.**
|
|
Een feature die twee repos raakt wordt als twee PBIs vastgelegd (één in elk
|
|
product), met handmatige verwijzing tussen de twee in de description.
|
|
- **B. Multi-repo per product (`Product.repo_urls: String[]`).**
|
|
Eén product representeert een logisch "systeem" en heeft N repo's; PBIs en
|
|
stories blijven onder dat product.
|
|
- **C. Initiative-laag boven PBI**, product-onafhankelijk; een Initiative bundelt
|
|
PBIs uit verschillende producten onder één plan.
|
|
|
|
## Decision Outcome
|
|
|
|
**Gekozen: optie A — voor nu**, met optie C als geïdentificeerde toekomstige
|
|
uitbreiding zodra cross-repo werk regelmatig genoeg voorkomt.
|
|
|
|
Rationale: optie B vermengt het datamodel rond een conceptueel troebele eenheid
|
|
("product = systeem" vs. "product = repo") en breekt de 1:1-aanname in
|
|
batch-enqueue, PR-gating en CI-flow. Optie C is structureel het juiste antwoord,
|
|
maar verdient een eigen feature-traject (datamodel, UI, gating-semantiek per
|
|
initiative) en wordt nu niet bevroren in een ad-hoc implementatie.
|
|
|
|
### Consequences
|
|
|
|
- Goed, omdat: per-repo flow simpel blijft (1 product = 1 repo = 1 PR-stack);
|
|
bestaande gating-logica (`pr_url`/`pr_merged_at` op PBI, sequentiële PBI's)
|
|
werkt zonder aanpassing.
|
|
- Goed, omdat: cross-repo werk wordt expliciet zichtbaar als gespiegelde PBIs
|
|
in beide producten — geen verborgen koppelingen.
|
|
- Slecht, omdat: voor cross-repo features moet een mens nu zelf twee PBIs
|
|
aanmaken en de afhankelijkheidsvolgorde tussen ze (bv. "MCP eerst, Scrum4Me
|
|
daarna") in de descriptions documenteren. Plan-drift tussen de twee PBIs is
|
|
een reëel risico.
|
|
- Slecht, omdat: er komt geen "één klik = één feature klaar" flow voor
|
|
cross-repo werk; de PB-owner moet over twee producten heen schedulen en
|
|
mergen.
|
|
|
|
### Confirmation
|
|
|
|
Bevestiging dat deze ADR effectief is:
|
|
|
|
1. Producten in Scrum4Me hebben elk precies één `repo_url`. Geen
|
|
schema-wijziging die `repo_urls` introduceert.
|
|
2. PBIs voor cross-repo werk verwijzen in hun description expliciet naar de
|
|
spiegel-PBI in het andere product (id-link).
|
|
3. Er staat een open backlog-item `Cross-product planning via Initiative-laag`
|
|
in product Scrum4Me als trigger om optie C te realiseren wanneer de pijn
|
|
van duplicatie te groot wordt.
|
|
|
|
## Pros and Cons of the Options
|
|
|
|
### A. Eén product = één repo, duplicate-PBI
|
|
|
|
- Goed: minimaal datamodel-veranderingen.
|
|
- Goed: PR-flow, batch-gating, deploy-pijplijn blijven 1:1 met repo.
|
|
- Goed: per-product permissies en token-scoping blijven simpel.
|
|
- Neutraal: cross-product werk vereist twee PBIs (zichtbaar werk, niet verborgen).
|
|
- Slecht: dubbel onderhoud aan plan-tekst; risico op divergentie.
|
|
|
|
### B. Multi-repo per product
|
|
|
|
- Goed: één plek voor alles wat bij een "systeem" hoort.
|
|
- Slecht: PR-gating per PBI moet plotseling N repos tegelijk modelleren.
|
|
- Slecht: deploy-volgorde (eerst MCP, dan Scrum4Me) zit niet in het datamodel
|
|
→ ad-hoc encoded in description of CI.
|
|
- Slecht: vervaagt wat een "product" is — repo-technisch of business-technisch.
|
|
|
|
### C. Initiative-laag boven PBI
|
|
|
|
- Goed: structureel correct — werk dat de scope van één product overstijgt
|
|
krijgt zijn eigen niveau.
|
|
- Goed: per-product gating en flow blijven simpel; alleen de Initiative
|
|
orkestreert.
|
|
- Slecht: feature op zich (UI, datamodel, gating-semantiek per initiative,
|
|
velocity-rapportage) — significante investering vóór de eerste praktische
|
|
payoff.
|
|
- Slecht: introduceert een vierde hiërarchielaag (Initiative → PBI → Story →
|
|
Task), met UI-druk om die zichtbaar te maken.
|
|
|
|
## More Information
|
|
|
|
- Verwante PBIs:
|
|
- Scrum4Me product, PBI `Agent merge-policy: geen auto-merge, sequentieel per
|
|
PBI` (id `cmoppwpwu000evt17ev2c4oo4`) — gebruikt deze ADR als grondvest voor
|
|
de gating per single-repo PR.
|
|
- scrum4me-mcp product, PBI `MCP: set_pbi_pr & mark_pbi_pr_merged voor
|
|
sequentiële PBI-gating` (id `cmoprewcf000qvt17pf42t0ig`) — concrete
|
|
spiegel-PBI van bovenstaande, in het MCP-repo.
|
|
- Wanneer optie C overwegen: zodra er tegelijk drie of meer "spiegel-PBIs" open
|
|
staan op verschillende producten, of wanneer de afhankelijkheidsvolgorde
|
|
tussen ze leidt tot meer dan één gemiste merge per maand.
|
|
- Re-visit: in de retro na de eerste vier cross-repo features.
|