---
title: Workflow — Risques & vigilance : Story tracking
domain: workflow
bucket: risques
tags: [bmad, story, file-list, review, completion]
applies_to: [analysis, implementation, review]
severity: high
validated_on: 2026-06-25
source_projects: [app-alexandrie, app-template-resto, RL799_V2]
---
# Workflow — Risques & vigilance : Story tracking
> Extrait de la base de connaissance Lead_tech. Voir `knowledge/workflow/risques/README.md` pour l'index complet.
---
## Story "completed" avec tâches ❌ auto-déclarées
### Risques
- Un agent sette `Status: completed` alors que son propre Dev Agent Record liste des items ❌ non implémentés
- Le store mobile, service ou tests peuvent être déclarés manquants par l'agent lui-même mais la story semble terminée
### Symptômes
- Dev Agent Record contient `❌ store mobile non implémenté` mais `Status: completed`
- Code review découvre des ACs non satisfaits
### Bonnes pratiques / mitigations
- Avant de setter `Status: completed`, vérifier que le Dev Agent Record ne contient aucun ❌
- En cas de doute ou d'item manquant, setter `Status: review` pour déclencher la code review
- **Règle** : `Status: completed` = zéro ❌ auto-déclaré dans le Dev Agent Record
- Contexte technique : BMAD / workflow agent — app-alexandrie 20-03-2026
---
## Story "done" sans aucun fichier source dans la File List
### Risques
- Un agent peut halluciner la completion d'une story en produisant une note générique sans écrire de code
- La File List ne contient que des fichiers `_bmad-output/` mais aucun `src/`, `prisma/`, `tests/`
### Symptômes
- Completion note générique du type "Ultimate context engine analysis completed"
- File List réduite à 2 fichiers meta (story file, sprint-status)
- `git log --follow src/` ne montre aucun commit lié à la story
### Bonnes pratiques / mitigations
- Lors d'une code review, si la File List ne contient aucun fichier source : traiter comme non implémentée
- Vérifier avec `git log --follow src/` avant d'accepter le `Status: done`
- Ne pas faire confiance au status `done` sans preuve dans le code
- Contexte technique : BMAD / agent Codex — app-template-resto 21-03-2026
---
## Story validée avec changements hors périmètre non documentés
### Risques
- Le reviewer valide un faux scope ou rejette à tort une story correcte.
- Des changements source non tracés (working tree dirty) peuvent masquer une implémentation partielle ou des effets de bord.
### Symptômes
- Tâches `[x]` et File List propre, mais `git status` montre des fichiers modifiés hors story
- Aucun bloc "hors périmètre" dans le Dev Agent Record alors que des fichiers non liés ont été touchés
### Bonnes pratiques / mitigations
- Si des changements hors story sont présents dans le working tree, documenter un bloc **"hors périmètre"** explicite dans le Dev Agent Record (liste courte + justification).
- Ne marquer `done` qu'après clarification de périmètre.
- **Règle** : le reviewer croise systématiquement `git diff --name-only` avec la File List avant d'accepter.
- Contexte technique : BMAD / workflow agent — 30-03-2026
---
## File List approximative — chemins faux ou fichiers source absents
### Risques
- Validation d'une implémentation avec traçabilité mensongère.
- Chemins fictifs dans la File List non détectés si le reviewer ne croise pas avec `git`.
### Symptômes
- File List courte ou générique alors que le diff réel touche de nombreux fichiers source
- Fichier listé avec un chemin qui n'existe pas dans le repo
### Bonnes pratiques / mitigations
- **Règle review** : comparer la File List du Dev Agent Record au `git diff --name-only` réel.
- Tout fichier source modifié absent de la File List → signaler en **MEDIUM**.
- Tout fichier listé avec un chemin inexistant en git → signaler en **HIGH**.
- Contexte technique : BMAD / workflow agent — app-template-resto 31-03-2026
---
## Story "review" non alignée avec la réalité du diff
### Risques
- La File List, les Completion Notes et les tâches `[x]` ne reflètent pas la réalité de `git diff` / `git status`
- Des régressions de tests passent inaperçues si le statut `review` est accordé sans croisement avec le diff
- Des fichiers créés dans un commit antérieur (ex: commit de refonte UI) sont listés dans la story sans traçabilité explicite
### Symptômes
- `git diff --name-only` montre des fichiers absents de la File List (ou inversement)
- Completion Notes contenant des déclarations contredites par le diff réel
- Tâches `[x]` "tests impactés passent" alors que des tests cassent sur des fichiers modifiés dans la story
- Fichiers listés dans la File List absents de `git diff HEAD~1..HEAD` pour le commit story
### Bonnes pratiques / mitigations
- **Avant passage en review** : comparer `File List` vs `git diff --name-only` + `git status --porcelain`
- Refuser le statut `review` si un fichier source de la story manque de la File List
- Exiger une section "preuves de validation" quand une tâche mentionne une validation UX/Dev
- Exiger un run de tests sur le périmètre touché, avec mention explicite des échecs non liés
- Si des fichiers sont répartis sur plusieurs commits, mentionner explicitement dans la File List le commit d'introduction de chaque fichier
- Contexte technique : BMAD / workflow agent — RL799_V2 02-04-2026
---
## Quality gate déclaratif non exécutable
### Risques
- Une story impose un gate process (PR template, checklist obligatoire) mais aucun mécanisme de contrôle vérifiable n'existe
- En review, cela crée un faux sentiment de contrôle et laisse passer des PR non conformes
### Symptômes
- Story qui déclare un quality gate via documentation/template sans CI check, script de validation, ni evidence review tracée
- AC marqués ✅ sur la base d'un template rempli mais sans preuve d'exécution
### Bonnes pratiques / mitigations
- La review doit vérifier au moins un mécanisme de contrôle actionnable (CI check, script de validation, required field policy, ou evidence review tracée)
- Sans ce mécanisme, classer les AC comme PARTIAL et repasser la story en `in-progress`
- Contexte technique : BMAD / workflow agent — RL799_V2 02-04-2026
---
## AC dépendante d'une capacité non supportée par le contrat technique
### Risques
- Un AC demande un comportement impossible avec le contrat courant (ex: multi-rôles alors que le JWT expose un rôle scalaire)
- Sans clarification explicite dans la story, la review crée des allers-retours et des faux écarts
### Symptômes
- AC mentionnant une capacité que le token, le schéma ou l'API ne supporte pas actuellement
- Dev qui implémente un workaround non documenté pour satisfaire l'AC
### Bonnes pratiques / mitigations
- Si un AC dépend d'une capacité non supportée par le contrat actuel (token, schéma, API), documenter explicitement la contrainte dans la story
- Marquer la capacité hors-scope tant que le contrat n'est pas migré
- Exiger une note Dev Notes + alignement Tasks/Tests sur cette contrainte
- Contexte technique : BMAD / workflow agent — RL799_V2 02-04-2026
---
## Tâches [x] validées par tests textuels au lieu de tests comportementaux
### Risques
- Une story passe en review avec des tâches `[x]` dont la preuve repose uniquement sur des assertions textuelles (`content.includes(...)`) sans exécuter le flux réel
- Les tests de présence textuelle valident des labels mais pas les cibles de navigation, ni les transitions d'état
### Symptômes
- Tests qui passent en vérifiant uniquement la présence de chaînes dans les fichiers source
- AC fonctionnels non réellement garantis (toast, mise à jour réactive, soumission) malgré un statut story en `review`
- Tests `content.includes(...)` valident des labels mais pas les `to`/`href` de navigation
### Bonnes pratiques / mitigations
- Toute tâche de test marquée `[x]` doit inclure au moins un test comportemental exécutable (pas seulement `content.includes(...)`)
- En cas de tests purement textuels, classer la tâche comme non validée et repasser la story en `in-progress`
- Pour toute AC mentionnant "clic" ou "navigation", imposer une vérification des cibles (`:to`, `href`, route name)
- **Règle** : un test qui ne vérifie que des helpers adjacents ou des chaînes statiques ne peut pas clôturer une tâche d'intégration
- Contexte technique : BMAD / workflow agent — RL799_V2 02-04-2026
---
## Agents autonomes et dérive des contrats partagés
### Risques
- Après une session multi-agents, les types/DTOs sont redéfinis localement dans chaque service au lieu d'utiliser le package shared
- La dérive est détectée uniquement lors d'une review globale de cohérence, pas pendant l'implémentation
### Symptômes
- Types définis localement dans `apps/frontend/src/services/` au lieu d'être importés depuis `packages/shared`
- Plusieurs services avec le même type défini indépendamment, avec des divergences subtiles
- Détection : `grep -r 'type.*=' apps/frontend/src/services/ | grep -v 'import'`
### Bonnes pratiques / mitigations
- Inclure dans le prompt d'agent une instruction explicite : "créer les DTOs dans `packages/shared` AVANT d'écrire le service frontend"
- Ajouter une review globale de cohérence après toute session multi-stories
- **Règle review** : tout type défini localement qui correspond à un DTO existant dans shared est une régression
- Contexte technique : BMAD / agents autonomes — RL799_V2 07-04-2026
---
## Incohérence entre Completion Notes et réalité du code
### Risques
- Les dev agents documentent des métriques dans les Completion Notes (nombre de tests, nombre de routes) sans les vérifier en fin d'implémentation
- Le reviewer passe du temps à réconcilier des chiffres qui ne matchent pas
### Symptômes
- "20 tests RBAC" revendiqués dans les Completion Notes alors que le fichier test n'en contient que 11
- Route `DELETE /api/favorites` listée dans le rapport d'audit mais inexistante dans le code
### Bonnes pratiques / mitigations
- Avant de passer une story en `review`, le dev agent doit vérifier que les chiffres dans les Completion Notes correspondent exactement au code
- `grep -c 'test(' fichier.test.ts` pour le nombre de tests
- `grep -c 'export' fichier.routes.ts` pour le nombre de routes
- **Règle** : toute métrique dans les Completion Notes doit être vérifiable par une commande simple
- Contexte technique : BMAD / workflow agent — RL799_V2 08-04-2026
---
## Story impose une convention absente du code projet
### Risques
- Divergence silencieuse entre specification story et implémentation réelle.
### Symptômes
- Le dev adapte une convention introuvable sans la tracer dans la story/notes de review.
### Bonnes pratiques / mitigations
- Si une convention prescrite n'existe pas dans le repo, documenter explicitement l'adaptation retenue.
- Mettre à jour la story (Change Log / Completion Notes) avec justification et impact.
- Contexte technique : BMAD / traçabilité adaptation story — RL799_V2 15-04-2026
---
## Stratégie de fix d'une suite E2E qui rote en masse (post-refactor)
### Risques
- Quand un projet enchaîne plusieurs refactors UI/lifecycle sans run E2E entre chaque, on découvre souvent N fails (10-20) d'un coup
- Tentation de fixer fail-by-fail dans l'ordre où ils apparaissent — erreur : on se disperse sur N causes-racines mélangées et chaque commit n'est pas reviewable
- Sans capitalisation immédiate des patterns, on perd le bénéfice de la session pour les futurs refactors
### Symptômes
- 13 fails d'un coup après une période de refactor intense
- Tentative de fix fail-par-fail qui produit un commit géant difficile à reviewer
- Capitalisation reportée → patterns oubliés à la session suivante
### Bonnes pratiques / mitigations
**Process recommandé** :
1. **Run complet en mode list** d'abord : `playwright test --reporter=list`. On veut **la liste exhaustive** des fails, pas un comptage one-shot par fichier (qui peut masquer des fails qui apparaissent uniquement quand on lance la suite entière à cause d'effets de bord seed).
2. **Catégoriser par cause-racine** plutôt que par fichier (cf. `knowledge/frontend/risques/tests.md` — Tests E2E qui rotent — 6 causes-racines récurrentes) :
- testid changé sans MAJ tests
- label métier changé (lifecycle, statut)
- menu/dropdown conditionnel
- feature supprimée (query param, route)
- refactor visuel (texte → icône)
- cleanup post-test à rendre best-effort
3. **1 commit = 1 cause-racine**. Pas "fix 19 fails" en un commit géant. Permet :
- Review plus simple (chaque commit a un thème clair)
- Revert chirurgical si une cause-racine s'avère mal diagnostiquée
- Capitalisation : chaque commit message documente le pattern
4. **Validation entre commits** : run la suite complète après chaque commit pour savoir avant le push que le commit n'a pas régressé d'autres tests.
5. **Capitaliser les patterns à > 2 occurrences** : si on voit le même type de fail 3 fois sur 3 fichiers différents, c'est un pattern. Le poser dans `knowledge/frontend/risques/tests.md` immédiatement, pas plus tard.
**Anti-pattern à éviter** : "je fixe les 5 fails P1 d'abord, je verrai les P2 après". Si la cause-racine est la même (ex : labels lifecycle v3), on perd 30 min à re-comprendre quand on retourne sur les P2 plus tard. Mieux : grouper par cause-racine, pas par priorité.
**Métrique de référence** : 19 fails fixés en 4 commits / ~3 h dont 1 h de capitalisation. Effort par fail : ~6 min de fix + 4 min de validation.
- Contexte technique : Playwright / refactor UI — RL799_V2 25-04-2026
---
## Statut BMAD correct mais sections narratives obsolètes
### Risques
- Une story peut afficher `Status: done` ou `review` tout en conservant des sections narratives (`Story Completion Status`, `Completion Notes`) qui contredisent le statut courant
- Le reviewer lit alors un fichier BMAD incohérent : seul le champ `Status` a été mis à jour, pas le récit qui résume l'état réel de la story
- Risque d'accepter une story dont les notes décrivent un état antérieur (génération de contexte) plutôt que l'implémentation finale
### Symptômes
- `Status: done` mais `Story Completion Status` mentionne encore `ready-for-dev`
- `Completion Notes` décrivant une simple génération de contexte au lieu de l'implémentation réalisée
- Contradiction entre `Status`, `Senior Developer Review` et `Change Log`
### Bonnes pratiques / mitigations
- En code review, recroiser systématiquement `Status`, `Story Completion Status`, `Completion Notes`, `Senior Developer Review` et `Change Log` : ces cinq sources doivent raconter le même état
- **Règle** : toute transition BMAD (`ready-for-dev` → `in-progress` → `review` → `done`) doit mettre à jour aussi les sections narratives qui résument l'état de la story, pas seulement le champ `Status`
- Traiter une divergence narrative comme un signal de doute sur la complétion réelle, pas comme un simple oubli cosmétique
- Contexte technique : BMAD / workflow agent — app-alexandrie 01-04-2026
---
## Story enabler avec AC coûteux non-bloquant
### Risques
- Une story "foundations" / "infrastructure" reste `in-progress` des semaines/mois alors que les stories métier qu'elle débloquait sont toutes livrées
- Le sprint-status est pollué durablement, la vraie progression est masquée
### Symptômes
- Story enabler `in-progress` depuis > 14 jours ; ≥ 2 epics métier postérieurs en `done`/`in-progress` ; la majorité des AC de l'enabler sont cochés (preuve par les faits que l'AC coûteux n'était pas bloquant)
### Bonnes pratiques / mitigations
- **Correction rétroactive** : identifier les AC réellement bloquants (les epics suivants ont-ils pu être livrés sans ?), clore l'enabler en `done` avec Completion Note de dérogation, extraire les AC déférés vers une story enabler hors-epic métier (`epic-infra/...`).
- **Prévention** : au sizing, appliquer le test "si cet AC n'était pas livré, pourrais-je démarrer la story 1.2 ?" → si oui, c'est une story séparée. CI mobile E2E (Maestro/Detox) Android+iOS = **toujours** une story enabler séparée (coût runner macOS + flakiness).
- Contexte technique : BMAD — app-alexandrie 13-05-2026 (story 1.1 bloquée 68 jours par AC4 CI Maestro)
---
## Tests d'AC en mode "plumbing" plutôt que "scénario"
### Risques
- Un AC de seuil ("au 4e", "au 21e") est testé en mockant directement la valeur de retour (`incrWithExpireAt.mockResolvedValue(4)`) au lieu de simuler le parcours réel
- Régression silencieuse si la limite change (le mock continue de mentir) ou si l'incrément se casse (l'INCR n'est jamais appelé)
### Symptômes
- Le test valide le code d'erreur (`POST_QUOTA_EXCEEDED`) mais PAS que 1+2+3 passent et que 4 est rejeté
### Bonnes pratiques / mitigations
- Pour un AC de seuil, le test e2e doit : (1) simuler un compteur qui incrémente réellement (`mockImplementation` avec map d'état, pas `mockResolvedValue` constant) ; (2) effectuer les N appels + le N+1 ; (3) vérifier que les N premiers passent ET le N+1 est rejeté ET (si applicable) que la compensation a décrémenté.
- Contexte technique : BMAD / Redis quota — app-alexandrie 13-05-2026 (story 8.4)
---
## "Test forwarding" confondu avec "test intersection"
### Risques
- Une task qui revendique tester une combinaison de filtres / un AND backend n'a comme seul test qu'un mock service client vérifiant que les params transitent
- Refacto futur = régression silencieuse de l'intersection
### Symptômes
- `expect(mockService).toHaveBeenCalledWith(token, { A: true, B: ['x'] })` → prouve uniquement que le store forward, PAS que le backend fait le AND
### Bonnes pratiques / mitigations
- Pour toute intersection/combinaison logique serveur, exiger un test e2e backend avec seed couvrant les 4 quadrants : match (A && B), A seul, B seul, ni l'un ni l'autre — vérifier que seul "match" remonte.
- Bonus discriminant AND vs OR : un filtre B incompatible doit renvoyer `items=[]`.
- Review : pour chaque task "combinaison X+Y testée", ouvrir le test et vérifier qu'il SEED des données différenciées et ASSERT le filtre, pas le forwarding.
- Contexte technique : BMAD — app-alexandrie 14-05-2026 (story 11.3)
---
## Reformat / changement de fichiers hors scope dans un commit de story
### Risques
- Une story embarque silencieusement un reformat prettier ou un changement sur des fichiers non listés (ex. ~32 fichiers, ~2400 insertions de pur reformatage)
- Une régression réelle se noie dans le bruit ; surface de merge conflict énorme ; diff de revue faussé
### Symptômes
- `git status --porcelain` / `git diff --stat` montrent des fichiers absents de la File List ; un `prettier --write .` ou un auto-format on save a fait dériver le scope
### Bonnes pratiques / mitigations
- **Règle** : "un commit de story = la File List ± 0 fichier". Avant tout commit : vérifier `git status --porcelain` + `git diff --stat` ; tout fichier non listé → (a) l'ajouter à la File List avec justification, soit (b) `git checkout HEAD -- ` avant commit.
- Pour un reformat global voulu : story chore dédiée (`chore/prettier-pass`) sur sa propre branche.
- Contexte technique : BMAD / prettier — app-alexandrie 13-05-2026 (story 10.1)
---
## Code de "préparation" non testé (anticipation des stories suivantes)
### Risques
- Une story implémente du code spéculatif pour les stories suivantes ("préparation Story X.Y", "déjà câblé pour la suite") sans tests pour ces chemins
- Si la story suivante change de design, le code mort traîne
### Symptômes
- Dev Agent Record contient "Préparation Story X.Y" ; des branches logiques `if (opts.x)` n'ont aucun test
### Bonnes pratiques / mitigations
- **Règle** : toute branche logique introduite doit avoir AU MOINS un test l'adressant, même si la story qui l'utilisera arrive plus tard. Sinon on n'introduit pas le code maintenant (YAGNI strict).
- Review : compter les tests couvrant chaque `if (opts.x)` du nouveau code. Tests = AC, pas plus, pas moins.
- Contexte technique : BMAD — app-alexandrie 14-05-2026 (story 11.1)
---
## "Fix CI" qui devient un refacto architectural
### Risques
- Une story enabler (CI, deploy, infra) déclare un scope limité (5 fichiers) ; au premier run CI des steps préexistantes échouent ; le dev débloque le pipeline dans la même branche en touchant 40-70 fichiers sous un commit massif "fix(ci): débloquer pipeline"
- La File List ment, le commit message ment (un "fix lint" cache une refacto DI), les enablers parallèles deviennent ambigus, les rétros perdent leur valeur
### Symptômes
- Un commit "fix CI" touche > 10 fichiers / plus d'un module / des fichiers de production (pas seulement tests/config)
### Bonnes pratiques / mitigations
- **Option A (préférée)** : stop, créer une story sœur `infra-N+1`, traiter sur branche séparée puis cherry-pick — ou conditionner la step CI cassée et déférer.
- **Option B (acceptable)** : tout faire dans la branche MAIS commits séparés (1 = scope original, 1 = "fix lint préexistant", 1 = "refacto DI" message clair) + documenter l'extension de scope dans le Change Log.
- **Option C (interdite)** : commit géant unique "fix CI". Si déjà commis : créer rétroactivement les stories sœurs (status `done` immédiat + File List pointant vers le commit géant).
- Détection review : un "fix CI" qui touche > 10 fichiers ou > 1 module → exiger un re-split ou une story rétroactive avant merge.
- Contexte technique : BMAD / CI — app-alexandrie 20-05-2026 (infra-1, 5 → 73 fichiers)
---
## `xit` / skip qui supprime de la couverture critique sans story de suivi
### Risques
- Un test e2e est marqué `xit` avec un commentaire `xit-reason:` honnête, mais la couverture du comportement critique disparaît
- Le commentaire donne l'illusion d'avoir tracé la dette ; aucun outil ne signale qu'un comportement n'est plus couvert
### Symptômes
- `xit('bloque une écriture community avec session PENDING (423)')` avec un `xit-reason:` qui ne cite aucune story de restauration
### Bonnes pratiques / mitigations
- Tout `xit`/`skip` doit déclencher soit (a) un fix immédiat avec setup ad-hoc (souvent 10-30 lignes de mock dynamique), soit (b) la création d'une story dédiée explicite qui le restaure.
- Le commentaire doit citer la story qui le ressuscitera (`xit-reason: HealthModule retiré, restauré par story infra-4`).
- Un `xit` sans story de suivi nommée = blocker en code review.
- Contexte technique : BMAD / e2e — app-alexandrie 20-05-2026 (infra-5)
---
## AC déféré vers une story fantôme
### Risques
- Un AC est marqué `[DEFERRED]` avec référence à une story qui n'existe pas dans le tracking → l'AC est "tracé" mais en réalité perdu
### Symptômes
- `[DEFERRED AC5] ... (story infra-1-phase-2)` où `infra-1-phase-2` n'existe pas dans `_bmad-output/` ni dans `sprint-status.yaml`
### Bonnes pratiques / mitigations
- Ne JAMAIS déférer un AC vers une story inexistante. Si on défère, créer **immédiatement** la story cible (titre + AC repris + status `ready-for-dev`) et l'ajouter à `sprint-status.yaml`.
- Détection review : grep `DEFERRED|TODO|à faire dans` dans la story et vérifier que les références pointent vers des fichiers existants.
- Contexte technique : BMAD — app-alexandrie 21-05-2026 (infra-5/infra-6)
---
## Re-scope mid-PR — renommer AVANT de merger
### Risques
- Une story/PR change de scope en cours de route mais le titre PR, le nom de fichier story et la clé sprint-status gardent l'ancien intitulé
- Le titre de PR se propage dans le merge commit et le displayTitle de TOUS les runs CI — historique GitHub durablement trompeur, non corrigeable après merge
### Symptômes
- Code et corps de la story re-scopés, mais slug `infra-7-reactivation-…` qui contient en réalité un "retrait"
### Bonnes pratiques / mitigations
- Checklist re-scope (les quatre ensemble, AVANT le merge) : titre PR + nom de fichier story (`git mv`) + clé `story_key` dans `sprint-status.yaml` + corps de la story.
- Contexte technique : BMAD / CI — app-alexandrie 22-05-2026 (infra-7)
---
## "Writer + reader" décorrélés dans une feature à état partagé
### Risques
- Une feature reposant sur un store / event bus / queue partagée nécessite DEUX intégrations (writer qui produit l'état, reader qui le consomme) ; si seul l'un est livré, l'AC est cassé alors que toutes les subtasks sont cochées
- Les tests unitaires en isolation passent (store + bouton OK séparément) ; l'intégration ne marche pas car personne n'alimente le store
### Symptômes
- Store créé + spec verte, reader appelle `lastRoutes[tab]`, mais le writer manque dans `_layout.tsx` → `lastRoutes` reste `{}` à vie
### Bonnes pratiques / mitigations
- À la rédaction de story : nommer explicitement les DEUX callsites ("créer le store" + "brancher le writer dans X" + "brancher le reader dans Y").
- Au dev : un test d'intégration minimal exerçant writer→reader.
- À la review : grep le nom de l'action mutator (`setLastRoute`, `enqueue`, `publish`). Si UN SEUL match (= le store lui-même), la feature est cassée même si toutes les tâches sont cochées.
- Contexte technique : BMAD — app-alexandrie 28-05-2026 (IA-v2.8)
---
## Écart AC ↔ implémentation "à confirmer" qui n'est jamais confirmé
### Risques
- Un dev s'écarte d'un AC pour une raison légitime, documente l'écart dans les Completion Notes mais ne met PAS à jour l'AC → l'AC reste formellement non respecté et l'écart sera oublié à la prochaine relecture
### Symptômes
- AC dit "CTA vers `/(tabs)/feed`" alors que le code pousse `/(tabs)/explore`, avec une note "cosmétique, à confirmer"
### Bonnes pratiques / mitigations
- Documenter dans Completion Notes ne suffit PAS. **Amender l'AC lui-même** avec justification inline (l'AC est le contrat) OU créer un follow-up daté ("à confirmer d'ici 2026-XX-XX, sinon AC réécrit").
- Garde-fou : "écart à confirmer" = finding MEDIUM ; la review doit trancher, pas laisser vivre l'ambigu.
- Contexte technique : BMAD — app-alexandrie 29-05-2026 (ux-cleanup-4)
---
## Story (enabler) sans sections de traçabilité
### Risques
- Une story dont les AC contiennent une checklist ("vérifier écran par écran", "smoke 5 écrans") est livrée sans Dev Agent Record, File List ni Change Log (fichier resté `Status: draft`)
- La review ne peut pas distinguer "pas fait" de "fait mais non documenté" → pression à passer en `done` sans preuve, ou revue manuelle linéaire (coût ×10)
### Symptômes
- 14 commits livrés, 0 trace structurée dans la story ; AC checklist non prouvables sans reconstitution a posteriori
### Bonnes pratiques / mitigations
- Toute story à AC-checklist doit comporter **dès le draft** : Dev Agent Record (tableau par phase commit), File List (ou pointer `git diff --name-only`), Change Log chronologique, et une checklist par AC avec statut (✓/⚠️/❌) par item.
- Garde-fou Bob/SM avant `ready-for-dev` : la story expose-t-elle ces 4 sections (au moins en placeholder) ?
- Contexte technique : BMAD — app-alexandrie 29-05-2026 (ux-cleanup-8)
---
## Statut "✅ X% migré" non vérifié par grep en fin de story
### Risques
- Le rapport d'audit de début de story ("110 occurrences") est repris tel quel dans le README final sans re-grep → le statut ment par optimisme (17 résiduelles)
- Un futur dev fait confiance au statut et n'audite plus jamais
### Symptômes
- README "✅ 110 occurrences remplacées" alors qu'un grep serré en révèle 17 résiduelles
### Bonnes pratiques / mitigations
- Ajouter en fin de workflow de migration un step "audit de vérification" : grep après migration DOIT être ≤ 0 (ou documenter chaque exception en code). Le statut README doit refléter ce grep, pas le rapport initial. Si 17 résiduelles → écrire "100/117 (85 %) migrées, 17 documentées".
- Contexte technique : BMAD / migration — app-alexandrie 30-05-2026 (ux-cleanup-12)
---
## Bump de dépendance non déclaré dans une story
### Risques
- Une story bumpe `package.json` / `pnpm-lock.yaml` "en passant" sans le déclarer dans la File List ni les Dev Notes → pollution du commit, surprise du reviewer, risque silencieux sur d'autres stories utilisant la lib
### Symptômes
- Story "a11y touch targets" qui bumpe `react-native-reanimated` ; le reviewer le découvre en grep
### Bonnes pratiques / mitigations
- Bump **nécessaire** au scope → le déclarer (Dev Notes/Risques + File List). Bump **opportuniste** → story chore dédiée ou justification explicite. Changement de **pinning** (exact → `~`/`^`) → décision d'archi méritant une mention explicite ou une story dédiée.
- Garde-fou : le reviewer doit pouvoir grep `package.json` dans le diff et tracer chaque ligne modifiée.
- Contexte technique : BMAD — app-alexandrie 31-05-2026 (ux-cleanup-14/17)
---
## Statut `done`/`review` non atomique avec un commit Git pushé
### Risques
- Une story est marquée `done`/`review` dans `sprint-status.yaml` AVANT que son code soit commité/pushé : statut trompeur (WIP local cru en prod), perte si rollback d'une story partageant un fichier, tracking story → commit cassé
- Cas subtil : fichiers cœur jamais `git add` (untracked discrets `??`) alors que tests/lint/typecheck passent via le filesystem → repo orphelin, prod down
### Symptômes
- `sprint-status.yaml` dit `done` mais `git log --grep "story-name"` ne retourne aucun commit pushé
- `git status` montre des `??` non vus (concentration sur les `M`)
### Bonnes pratiques / mitigations
- Ordre atomique : implémenter (`in-progress`) → tests/lint/typecheck verts → **commit isolé** → **push origin** → PUIS changer le statut.
- Stories partageant un fichier : la story #1 doit être commit-push AVANT que #2 ne touche au fichier.
- Garde-fou : à la transition `review → done`, `git status --porcelain` ne doit laisser AUCUN `??` dans les répertoires de la story ; chaque "Nouveau fichier" du Dev Agent Record doit passer `git ls-files --error-unmatch `.
- Contexte technique : BMAD / git — app-alexandrie 31-05-2026 (ux-cleanup-17/18/22)
---
## Suppression de feature et artefacts de planning orphelins
### Risques
- Une story SUPPRIME une feature ; le code est propre mais les artefacts de planning (wireframes, specs UX, PRD) qui la décrivaient "à créer" deviennent des pièges qu'un agent futur rejouera
### Symptômes
- Wireframe daté décrit toujours la feature supprimée comme cible (composants, routes, props) ; la code review du code seul ne le détecte pas
### Bonnes pratiques / mitigations
- Toute story de suppression doit inclure un AC "cohérence documentaire" : grep le nom de la feature dans `_bmad-output/planning-artifacts/` et annoter/invalider (bandeau "ABANDONNÉ ") tout doc qui la décrit encore. Ne pas se contenter du grep dans `src/`.
- Contexte technique : BMAD — app-alexandrie 02-06-2026 (classroom-0)
---
## Lot soudé = revue et commit groupés (contrats partagés)
### Risques
- Plusieurs stories d'un lot touchent un MÊME contrat partagé et y ajoutent des champs **requis** consommés des deux côtés → elles forment une unité de compilation indivisible ; un commit story-par-story ne compile pas
### Symptômes
- Au moment de committer seulement les stories revues, le découpage est techniquement impossible (champs de contrat ajoutés par une story non incluse mais référencés par le code inclus)
### Bonnes pratiques / mitigations
- Quand plusieurs stories d'un lot modifient le même schéma Zod partagé avec des champs requis : soit (a) reviewer tout le lot et committer en bloc, soit (b) imposer dès le cadrage que les champs partagés soient `.optional()` tant que toutes les stories ne sont pas mergées (permet le commit incrémental).
- Détecter tôt : deux stories "can-run-with" qui modifient le même fichier de contrat → le découpage commit sera bloqué, l'anticiper au sprint-planning.
- Contexte technique : BMAD / contracts-first — app-alexandrie 05-06-2026
---
## Review = suite COMPLÈTE, pas le sous-ensemble de la story
### Risques
- Le dev lance des sous-ensembles ciblés (la suite du module touché), pas la suite entière → les fichiers de test transverses/partagés (mocks e2e d'autres modules, gardes d'exhaustivité jumelles) restent périmés et cassent en silence
- Une story qui annonce "e2e 78/78" sans avoir lancé la suite globale donne un faux signal de complétude
### Symptômes
- En review, lancer la suite complète révèle des fails dans des fichiers que la story N'A PAS touchés (mock e2e d'un autre module consommant une signature changée, garde "couvre exactement les N types" jumelle non mise à jour)
### Bonnes pratiques / mitigations
- **Règle review** : toujours lancer la suite entière (unit + e2e + mobile), jamais seulement la File List.
- Corollaire dev : après tout changement de signature publique (provider/service) ou ajout d'une valeur d'enum, `grep` tous les consommateurs de tests + lancer la suite complète avant de déclarer "tests verts".
- Contexte technique : BMAD — app-alexandrie 08-06-2026 (ux-parcours-3, bo-6, ux-parcours-7)
---
## Story infra/ops : distinguer VERSIONNÉ de EXÉCUTÉ-SUR-CIBLE
### Risques
- Sur une story infra (déploiement, backup, config service externe), l'agent produit des artefacts reproductibles mais ne peut PAS exécuter les gestes sur l'environnement réel (créer le realm, exécuter/TESTER le backup, smoke-test prod)
- Piège : marquer ces sous-tâches `[x]` parce que la PROCÉDURE est documentée alors que l'ACTION n'a pas eu lieu → la story surestime son achèvement, le geste à plus forte valeur ("restauration TESTÉE") reste un trou non signalé
### Symptômes
- Story dit `[x]` (theme appliqué, smoke-test, restauration testée) alors que la table de preuve du runbook est `(à remplir)` / `[ ]`
### Bonnes pratiques / mitigations
- **3 états, pas 2** : `[x]` = versionné/documenté ET vérifiable par l'agent ; `[~]` = artefact versionné mais exécution cible pending ; `[ ]` = geste ops non fait.
- Un AC "TESTÉE" (restauration, smoke-test, login réel) n'est JAMAIS satisfait par une procédure documentée — il exige une preuve d'exécution consignée (date/étapes/résultat).
- En review, croiser les `[x]` de la story avec le runbook ; lister les gestes hors-repo dans un Dev Agent Record dédié. La story reste `review` (artefacts prêts), `done` au déploiement réel prouvé.
- Contexte technique : BMAD / Keycloak prod — RL799_V2 15-06-2026 (K1.9)
---
## Auto-déclaration de périmètre d'une story (à vérifier contre `git diff --stat`)
### Risques
- Une étiquette "contenu uniquement" / "fix minimal" / "pas de code applicatif" est une CLAIM, pas un fait. Une story ainsi étiquetée peut livrer une refonte UI substantielle (+461 lignes nettes) documentée comme "2 fixes de typage minimaux", avec File List incomplète et "test:frontend vert" alors qu'il est rouge
### Symptômes
- Un "fix de typage minimal" qui touche un fichier passant de 274 à 735 lignes — l'écart entre la description et le `wc -l` est le tell
### Bonnes pratiques / mitigations
- Procédure review : (1) identifier le commit de référence (`Depends-on`/`Previous`), (2) `git diff --stat [..HEAD` + working tree, (3) tout fichier > ~50 lignes de delta non listé dans la File List = finding MEDIUM minimum, (4) toute affirmation "suite X verte" = à REJOUER (un fichier de logique partagée qui change de signature casse un test préexistant non mis à jour en silence).
- Quand une refonte se glisse dans une story de contenu : exiger commit séparé + File List fidèle + tests propres.
- Contexte technique : BMAD — RL799_V2 22-06-2026
---
## Completion Notes vs code, surtout quand deux options d'implémentation existaient
### Risques
- Quand une story propose une approche A et une alternative B, la Completion Notes peut affirmer avoir fait A alors que le dev a silencieusement choisi B (souvent le meilleur choix)
- Un reviewer qui croit la note sur parole rate l'écart ; la prochaine personne partira sur une fausse hypothèse
### Symptômes
- Completion Notes "ROLES_X étendu avec 'hospitalier'" alors que le bypass est réalisé autrement (au niveau repo) ; comportement réel correct mais note factuellement fausse
### Bonnes pratiques / mitigations
- Pour chaque tâche `[x]` mentionnant un fichier/symbole précis ("étendu le set X", "ajouté le champ Y"), ouvrir CE fichier et vérifier la présence réelle du changement — ne jamais cocher sur la foi de la note.
- L'écart "note dit A / code fait B" est un finding MEDIUM (doc trompeuse) même quand B est correct : c'est une note à corriger, pas du code à changer.
- Contexte technique : BMAD — RL799_V2 23-06-2026 (v2-5-3)
---
## Divergence d'emplacement create-story vs dev-story (fichiers homonymes)
### Risques
- `create-story` génère la story dans l'arborescence sprint sous-dossiée (`implementation-artifacts/version-X//`, committée), mais `dev-story` écrit un fichier homonyme à PLAT dans `implementation-artifacts/` → deux fichiers : l'un committé/vierge, l'autre untracked/rempli (la vraie story)
- Une review peut se baser sur le mauvais fichier ou laisser un doublon désynchronisé
### Symptômes
- `find -name '*.md'` retourne > 1 fichier ; l'un en `ready-for-dev`/tasks `[ ]`, l'autre en `review`/tasks `[x]`/Dev Record rempli
### Bonnes pratiques / mitigations
- Avant toute code-review : vérifier l'unicité du fichier de story (`find`). En cas de doublon, identifier la vraie story (status `review`/`done` + tasks cochées + File List), copier son contenu réel vers l'emplacement sprint COMMITTÉ, supprimer l'orphelin plat — préserver l'arborescence sprint comme source de vérité git.
- Contexte technique : BMAD — RL799_V2 23-06-2026 (v2-6-1)
---
## Composant "livré" sans point d'entrée dans l'UI (fonctionnalité mort-née)
### Risques
- Un composant créé (service + composable + vue + tests) mais non intégré dans aucune page/route est invisible : l'utilisateur ne peut pas y accéder
- Les tests passent (composant présentationnel monté isolément), ce qui masque l'absence d'intégration ; une tâche peut être `[x]` alors que le composant est orphelin
### Symptômes
- `SeasonReportView.vue` présent, testé, mais non importé dans aucune page ni dans le router
### Bonnes pratiques / mitigations
- Checklist revue frontend (si l'une des 3 est non → finding HIGH) : (1) le composant est-il importé dans au moins une page parente ? (2) la page parente est-elle accessible via une route ? (3) existe-t-il un chemin de navigation visible pour l'utilisateur cible ?
- Pattern de correction : intégrer dans la page parente existante (onglet) plutôt que créer une nouvelle page ; ajouter un sélecteur de contexte (saison, période) si besoin.
- Contexte technique : BMAD / Vue — RL799_V2 19-06-2026 (v2-3-1)
---
## Page/module livré sans câblage de navigation (dette fonctionnelle invisible)
### Risques
- Une page/module peut être 100% fonctionnel (backend gardé, page, service, tests verts, CI verte) et pourtant TOTALEMENT inaccessible faute de câblage navigation
- Classe de bug invisible : aucun test ne vérifie "ce module est atteignable"
### Symptômes
- "Je ne vois plus mon module X" alors que tout le code existe et que la CI est verte ; seul le câblage navigation manque
### Bonnes pratiques / mitigations
- Maillons à câbler (sur une app multi-surface mobile + desktop, ils sont SÉPARÉS — câbler l'un ne suffit pas) : (1) constante de rôles/permissions partagée + son ré-export (attention `export *` vs exports explicites) ; (2) route (path + name + meta de garde) ; (3) nav desktop (sidebar) + icône ; (4) nav mobile (liste/computed distincts) ; (5) tout hub/plan/menu de découverte secondaire qui mappe entité→route.
- Détection : à chaque nouvelle page, vérifier qu'une route Y MÈNE et qu'une entrée de nav LA RÉFÉRENCE, sur TOUTES les surfaces. Idéalement un test de garde "toute page de module a une route nommée + une entrée de nav".
- Prévention : la DoD d'un module inclut "accessible depuis la navigation sur mobile ET desktop", pas seulement "page + back + tests".
- Contexte technique : Vue / app multi-surface — RL799_V2 21-06-2026 (Epic v2-4)
]