# Lotissement des issues ouvertes — arbitrage du 24 août 2026

Arbitrage rendu par Enguerran sur le **bulletin de lotissement**, dépouillé et
appliqué le 24/08. Ce document est la trace de ce qui a été décidé et de ce qui a
été écrit dans GitHub — il ne remplace pas les issues, il dit **qui a tranché quoi**.

⚠️ Document daté. Vérifier au code avant de s'en servir.

## 1. Le cadre

Trois lots, et une **bascule en deux temps** (décision d'Enguerran, 24/08) :

1. **Bascule** = déploiement de la production sur un **nouveau serveur, URL non
   diffusée**. Répétition en conditions réelles, invisible des utilisateurs.
2. **Ouverture** = début/mi-septembre, l'ancienne URL pointe vers le nouveau serveur.

⚠️ **« Post-bascule » n'est donc PAS « après l'ouverture aux utilisateurs »** : il reste
une fenêtre de développement et d'épreuve sur le nouveau serveur entre les deux
étapes. Et l'ancien serveur reste le serveur public pendant toute cette fenêtre.

Cadre de travail confirmé le 24/08 : **jalons + étiquettes `statut:*` restent la
source de vérité jusqu'à la bascule** ; GitHub Projects est différé post-bascule.

## 2. Méthode — comment l'état de chaque issue a été établi

La première version du bulletin classait les issues d'après leur **étiquette**.
Enguerran l'a refusée : *« c'est pourtant bien ce qu'on a demandé : sur preuve ! Une
étiquette dans une issue n'est pas une preuve. »* La classification a donc été refaite
**au code** :

| signal | ce qu'il établit |
|---|---|
| PR fusionnée dont la branche ou le titre porte le numéro | livraison |
| commit non documentaire de `development` citant le numéro | livraison |
| dernier `deploy-staging` vert, et son SHA ancêtre du commit | déploiement |
| lecture du fichier concerné sur `origin/development` | conformité au CA |

**Pièges rencontrés, et écartés** : branches `docs/`, `sync/`, `dependabot/` et datées
(`-18-03-26`) produisent de faux positifs ; une PR FRONT citant « #148 » désigne
souvent BACK#148 — **trois faux positifs FRONT écartés ainsi**.

⚠️ **La limite qui a coûté le plus cher** : une sonde fondée sur les traces GitHub ne
voit pas un travail livré **sous un autre numéro d'issue**. C'est Enguerran qui a
trouvé le cas (BACK#351, livrée par son volet FRONT#153). Le crible croisé qui a suivi
— références qualifiées `BACK#N`/`FRONT#N` dans les commits de l'autre dépôt, et
jumelles fermées par titre — n'a trouvé qu'**un seul** autre cas. Mais ce crible ne
voit que les liens **écrits** : 71 paires front↔back n'en expriment aucun.

## 3. Neuf issues fermées sur preuve au code (24/08)

| fermée | livrée par | preuve |
|---|---|---|
| BACK#351 | FRONT#153 | `ApprentissageLayout` appliqué par la route, `EspaceTabs` supprimé |
| BACK#359 | FRONT#144 | `isSearchable` + « Rechercher une balise… » dans `AdminNouveauTuto` |
| BACK#164 | FRONT#105 | `SupportTypesPanel.jsx` — l'écran existe |
| BACK#38 | #148 + #456 | migrations durées ; `duration_seconds` (EA-028) documenté comme existant |
| BACK#373 | paire #313 | migration `ea313` : défaut par type + dérogation par support |
| BACK#121 | #44 | `mediaSource.js` sert `video_url` quand aucun embed |
| FRONT#26 | paire #313 | `pedagogical_role.label` rendu au sommaire |
| FRONT#340 | FRONT#339 | le « Cancel » ne vide plus titre ni description |
| FRONT#326 | #332 | CI en `--no-file-parallelism` (13 % → 0 % mesuré) |

⚠️ La responsabilité de ces fermetures est celle de la session, sur ses preuves au
code. Enguerran a marqué ces issues « supprimer » au bulletin **sans re-vérifier**,
sur indication de la session — ce n'est pas une double validation.

**Et le contrôle a joué dans les deux sens** : cinq candidates que la trace GitHub
disait livrées sont **restées ouvertes parce que le code dit non** — BACK#560 (double
calcul du verdict toujours présent, `LearnerCourseController` l.311), FRONT#341 (motif
sans `/i`), BACK#488 (« le CHOIX du premier accès n'a pas de route », écrit dans le
fichier), FRONT#165 (aucun champ), FRONT#148 (contournée en CI, pas résolue).

Deux cas instruits séparément et **maintenus ouverts** : **BACK#395** (la fenêtre front
qui chiffre est le « En attendant » écrit dans l'issue ; le volet back manque) et
**BACK#398** (le code front la cite nommément : *« en attente de BACK#398 […] il est
demandé côté serveur »* — les compteurs actuels sont un contournement à 4 appels).

## 4. L'arbitrage — 75 décisions

**70 issues** rangées à l'unité, plus deux jalons validés en bloc.

| lot | issues | jalon GitHub appliqué |
|---|---:|---|
| **Lot actuel** | 13 | `V1 · L4 — Pilotage & organisation (31 août-6 sept)` |
| **L5 — avant la bascule** | 19 | `V1 · L5 — Finition & mise en prod (7-13 sept)` |
| **Post-bascule** | 38 | `V2 — après septembre` |

Jalons validés en bloc : **V1 · L5** (17 jamais commencées) et **V2** (42) — déjà en
place, rien à écrire.

### Les 15 écarts à la proposition

Enguerran a surtout **allégé le Lot actuel**. Le pont studio↔LMS et le chat passent
après la bascule, les actions groupées aussi ; trois défauts fonctionnels remontent en L5.

| issue | proposé | arbitré |
|---|---|---|
| BACK#125 | Lot actuel | **Post-bascule** |
| BACK#139 | Lot actuel | **Post-bascule** |
| BACK#261 | Lot actuel | **L5 — avant la bascule** |
| BACK#64 | Lot actuel | **Post-bascule** |
| BACK#311 | Lot actuel | **Post-bascule** |
| BACK#312 | Lot actuel | **Post-bascule** |
| BACK#458 | L5 — avant la bascule | **Post-bascule** |
| BACK#459 | L5 — avant la bascule | **Post-bascule** |
| BACK#462 | L5 — avant la bascule | **Post-bascule** |
| BACK#613 | Lot actuel | **L5 — avant la bascule** |
| BACK#599 | Lot actuel | **L5 — avant la bascule** |
| FRONT#345 | Lot actuel | **Post-bascule** |
| BACK#614 | L5 — avant la bascule | **Post-bascule** |
| BACK#581 | Post-bascule | **L5 — avant la bascule** |
| BACK#560 | Post-bascule | **L5 — avant la bascule** |

### Le détail, lot par lot

#### Lot actuel — 13 issues

- **BACK#17** — EA-008 · Gardes de routes par rôle
- **BACK#607** — Déploiement staging : un échec de droits laisse l'arbre à moitié mis à jour
- **BACK#608** — Huit PR bloquées pour toujours : ouvertes avant la CI, elles ne porteront jamais le contrôle requis
- **BACK#617** — Trois familles de routes d'écriture n'ont aucune garde de rôle : un apprenant peut inviter et supprimer la taxonomie
- **BACK#618** — 🔴 VITAL · 150 certificats nominatifs téléchargeables sans authentification EN PRODUCTION
- **BACK#619** — AVANT PROD · Le serveur ne signale rien : le DSN Sentry n'est posé sur aucun environnement
- **BACK#623** — SÉCURITÉ · dompdf 3.1.5 sur `development` : six avis publiés non corrigés, sur le générateur des certificats nominatifs
- **BACK#624** — Le déploiement n'installe pas les dépendances : toute nouvelle bibliothèque casse staging en silence
- **BACK#625** — Le contrôle de santé du déploiement valide une application cassée : il ne touche aucun modèle
- **BACK#628** — Supprimer un cours vierge laisse ses quiz, questions et options orphelins
- **BACK#630** — Déplacer l'étiquette de statut automatiquement à la fusion — 18 issues livrées étaient restées « ouvertes »
- **BACK#631** — Le cycle de statuts n'est appliqué qu'à moitié : 120 issues bloquées « en recette », 59 sans statut
- **FRONT#148** — La suite de tests est non déterministe en parallèle : 3 puis 7 échecs sans recouvrement sur le même code

#### L5 — avant la bascule — 19 issues

- **BACK#261** — BLOQUANT RECETTE · Délivrabilité e-mail : Gmail jette les mails d'invitation (SPF/DKIM absents pour Brevo sur le domaine expéditeur)
- **BACK#460** — « Relancer » un collaborateur n'existe nulle part : le pilotage sait compter les retards, pas les rappeler
- **BACK#461** — Exporter une SÉLECTION : l'export ne sait rejouer que la vue courante, pas une liste d'identifiants
- **BACK#560** — Quiz : le calcul du verdict existe en DEUX endroits depuis #557 — converger `attempt/question` sur `DepotDeReponse`
- **BACK#581** — Un php.ini complet de 74 Ko est committé dans tests/Feature/ — sans effet, et trompeur
- **BACK#582** — La garantie « les jointures gauches ne retirent aucun cours » n'est plus éprouvée : l'état à tester est devenu inconstructible
- **BACK#592** — Un aperçu de quiz dans le studio écrit une vraie tentative — décider si elle compte
- **BACK#593** — `ReglageDesCommentaires` se dit chargeur unique mais `OptionResource` ne le consulte pas
- **BACK#595** — SÉCURITÉ · `GET /learner/quiz/result/{id}` n'a pas de garde de périmètre explicite
- **BACK#599** — Un lien vidéo de plus de 125 caractères rend une 500 (1406) au lieu d'un refus — et la garde du studio tuto borne à 255 contre une colonne varchar(125)
- **BACK#600** — SÉCURITÉ · `POST enroll` n'inscrit jamais : elle renvoie toujours vers un paiement Stripe « Test Product »
- **BACK#605** — Le contrat publié ne couvre que 209 des 346 routes API, et en annonce 14 qui n'existent pas — dont 5 constructeurs
- **BACK#609** — Contrat d'interface : ce que couvrent vraiment les 209 opérations, et ce qui manque
- **BACK#613** — Supprimer un cours retire silencieusement son étape des parcours qui le contiennent
- **BACK#626** — Une migration en attente après déploiement n'est signalée nulle part
- **BACK#627** — `GET /learner/quiz` ignore ses filtres : 519 options et 263 Ko servis à chaque appel
- **FRONT#237** — Reste-à-faire des actions groupées : les cinq gestes dont la route back n'existe pas encore
- **FRONT#241** — L'écran des apprenants sans manager n'a pas de barre latérale : il monte sa propre barre du haut au lieu de recevoir l'enveloppe
- **FRONT#341** — Écran et serveur en DÉSACCORD sur la casse d'une URL vidéo : le motif client est sensible à la casse, la règle serveur ne l'est pas

#### Post-bascule — 38 issues

- **BACK#64** — EA-054 · Liste apprenants formateur enrichie
- **BACK#125** — ÉVOL · Chat de cours apprenant = conversation privée apprenant ↔ formateur (aujourd'hui : forum ouvert du cours)
- **BACK#139** — EA-028 · Durées absentes sur 366 des 414 supports en production — l'avancement pondéré est faussé
- **BACK#221** — L5 · Export du dashboard de pilotage (bouton présent en maquette, non câblé)
- **BACK#311** — L4.6·C1 — Alignement du modèle de données studio ↔ LMS (notions, modules, supports, reminder_plan)
- **BACK#312** — L4.6·C2 — Importeur LMS du package studio (idempotent par notion_id, rapport coverage/gaps)
- **BACK#390** — Relances automatiques paramétrables + rapport périodique au manager (volet BACK)
- **BACK#398** — L'API ne sert pas à l'apprenant de quoi reprendre : dernière activité, prochain support, compteurs
- **BACK#403** — Les bornes de l'invitation (5 destinataires, 400 caractères) ne sont posées que par l'écran : le serveur n'en valide aucune
- **BACK#405** — Inscrire sans notifier : `invite-mail` envoie toujours un e-mail, sans option
- **BACK#458** — Actions groupées sur les utilisateurs : aucune route n'accepte plusieurs identifiants, sauf l'affectation — qui ne réaffecte pas
- **BACK#459** — Actions groupées sur les cours : publier, dépublier et changer de catégorie n'existent qu'à l'unité
- **BACK#462** — Le contrat de listes ne sait pas exprimer « ce champ est nul » : « 49 sans manager » ne peut pas filtrer la liste des utilisateurs
- **BACK#562** — La libération progressive des sections existe dans le code mais DORT — aucun réglage, aucune garde vérifiée (sprint post-L5)
- **BACK#564** — Sur quoi se fonde la PROPRIÉTÉ d'un cours ? `manager_id` porte une garde de sécurité mais n'a AUCUN porteur réel (post-L5, à instruire avec le pilote SaaS)
- **BACK#573** — INFRA CLOUD · É1 — script d'environnement de session : il ne reste que MySQL 8 à poser (PHP et Node de la session conviennent)
- **BACK#575** — INFRA CLOUD · É7 — la CD ne joue aucune migration : une PR de schéma exige encore un ssh (étape idempotente, verte sans migration)
- **BACK#576** — INFRA CLOUD · É10 — éprouver le critère de réussite sur une session cloud jetable
- **BACK#577** — INFRA CLOUD · É8 — lire les journaux du serveur sans ssh (hors lot : établir le besoin d'abord)
- **BACK#584** — Propriété d'un cours : la rendre explicite, transférable et partageable (co-propriétaires) — post-L5
- **BACK#585** — INFRA CLOUD · É11 — Docker : chantier déjà instruit (06/08), et la question qui décide de la forme de #573
- **BACK#589** — Vidéos YouTube : format refusé avant L5, à rétablir avec sa recette post-L5
- **BACK#594** — SaaS — commercialiser des formations (tarif, encaissement) : besoin reporté, pas un sujet LMS V1
- **BACK#596** — Générateur du modèle de données : clés comptées en double, et le nom de la base fait dériver le document
- **BACK#598** — Annotations OpenAPI : 20 FormRequests déclarent obligatoire ce que rules() n'applique pas
- **BACK#610** — Post-L5 — un manager peut-il créer une formation, et que voit-il exactement ?
- **BACK#614** — Les points d'inscription ne se gagnent qu'UNE fois dans une vie, tous cours confondus — est-ce voulu ?
- **FRONT#139** — Relances : écran d'administration des règles et du rapport périodique (volet FRONT)
- **FRONT#165** — Paramètres : quatre réglages administrables n'ont aucun champ, et l'écran écrit par l'endpoint qui ne valide rien
- **FRONT#170** — Onglet Inscrire : deux fonctions de la maquette v3 suspendues (interrupteur de notification, second niveau des sélecteurs)
- **FRONT#172** — Onglet Demandes : trois fonctions de la maquette v3 suspendues (filtres chiffrés + export, auteur de la décision, actions en lot)
- **FRONT#177** — Cockpit apprenant : un vrai fil d'Ariane à la place du « Retour » qui rejoue l'historique (C-1)
- **FRONT#178** — Cockpit apprenant : retard et abandon disparaissent au niveau 1, là où on décide d'agir (C-6)
- **FRONT#179** — Cockpit apprenant : aucune action possible depuis le dossier — lesquelles y mettre ? (C-7)
- **FRONT#180** — Cockpit apprenant : « tout l'historique » rend des centaines de lignes sans pagination ni plafond (C-8)
- **FRONT#242** — Référentiels : aucune barre de filtres, sur les cinq panneaux — la maquette en dessine une par panneau
- **FRONT#327** — INFRA CLOUD · É3 — Playwright n'est pas tracé comme dépendance : le banc de recette visuelle est inopérant sur machine neuve
- **FRONT#345** — « Dration en heures », « Image du parcours » sur une fenêtre qui crée un cours : cinq libellés fautifs ou trompeurs du catalogue français

## 5. Les 26 étiquettes remises au vrai statut

Travail livré, fusionné et déployé, mais l'étiquette disait encore « à faire » ou
« PR ouverte » — le motif de **#630** (rien ne déplace l'étiquette à la fusion).
Toutes passées à `statut: en recette`, **aucune fermeture**. Contrôlé sur DEUX mesures :
l'ancienne absente ET la nouvelle présente, 26/26.

| issue | ancienne étiquette | preuve de livraison |
|---|---|---|
| BACK#301 | à faire | PR #621 |
| BACK#349 | à faire | PR #354 |
| BACK#389 | à faire | PR #615 |
| BACK#391 | à faire | PR #444 |
| BACK#393 | à faire | PR #440 |
| BACK#412 | à faire | PR #612 |
| BACK#439 | à faire | PR #441 |
| BACK#445 | à faire | PR #611 |
| BACK#477 | (sans statut) | PR #479 |
| BACK#521 | à faire | PR #523 |
| BACK#530 | (sans statut) | PR #556 |
| BACK#532 | (sans statut) | PR #556 |
| FRONT#50 | à faire | PR #51 |
| FRONT#140 | à faire | PR #214 |
| FRONT#143 | à faire | PR #211 |
| FRONT#168 | (sans statut) | PR #174 |
| FRONT#225 | PR ouverte | PR #234 |
| FRONT#227 | PR ouverte | PR #233 |
| FRONT#229 | à faire | PR #236 |
| FRONT#230 | à faire | PR #236 |
| FRONT#232 | PR ouverte | PR #234 |
| FRONT#310 | à faire | PR #325 |
| FRONT#312 | PR ouverte | PR #316 |
| FRONT#320 | à faire | PR #337, #333 |
| FRONT#321 | à faire | PR #325 |
| FRONT#334 | PR ouverte | PR #335 |

## 6. Ce qui reste, et qui n'a pas été tranché

**70 issues sans jalon et jamais instruites** — la file d'instruction. Aucune
proposition n'a été faite pour elles : les ranger de mémoire fabriquerait 70 jugements
que personne ne peut tenir. **C'est un chantier, pas une case à cocher.**

⚠️ **#649** (ouverte le 24/08) : les jalons ont divergé — **12 côté BACK, 8 côté FRONT**
(il manque `V1 · L0` à `L3` côté FRONT). Aucune des issues arbitrées n'en a souffert —
elles ne visaient que L4, L5 et V2, qui existent des deux côtés — mais **tout comptage
croisé par jalon reste faux** tant que ce n'est pas corrigé. Jumelle de **#646**
(étiquettes divergentes), liée dans les deux sens.

## 7. Ce que la session a appris — à ne pas réapprendre

**Une page à décisions doit PROUVER sa persistance avant qu'on y investisse des clics.**
Le bulletin déclarait mémoriser les votes ; le mécanisme n'avait été éprouvé qu'en
local, jamais sur la page publiée. Enguerran a traversé 75 décisions, et la relecture
du document publié n'en portait **aucune trace**. Les votes n'ont été récupérés que
parce que son onglet était resté ouvert — au prix d'une heure perdue.

Le geste qui manquait : publier, cliquer UN vote sur la page réelle, **relire depuis la
session**, et seulement alors inviter l'utilisateur.

**Corollaire de la même famille** : ne pas chercher un chemin compliqué quand un
raccourci existe. Trois échanges ont été perdus à décrire des menus avant de donner le
raccourci clavier qui ouvrait la console.


## 8. Instruction de la file sans jalon — 25/08 (go d'Enguerran)

Les 72 issues restées sans jalon et jamais instruites ont été lues une par une et
rangées selon la **règle du 25/08** (Enguerran, 15h) : *aucune issue sans jalon —*
*tout se rattache à L5 (avant bascule) ou V2 (post-bascule)*. Appliqué et contrôlé
72/72 par relecture `gh`.

**La même règle vaut désormais à la CRÉATION de toute issue.** Verrou déterministe
proposé à la conversation structure (commentaire sur #649) : la porte
`conformite-issues.yml` peut refuser une issue sans milestone.

### Avant la bascule — 11 issues versées en `V1 · L5`

| issue | motif |
|---|---|
| BACK#464 — CI v1 — AVANT L5 : tests + non-régression seuls, PHP 8.2, co | se déclare elle-même « AVANT L5 » — décision Enguerran 18/08 : CI minimale avant la bascule |
| BACK#465 — AVANT L5 — Inventaire des écarts fonctionnels prod → refonte | se déclare elle-même « AVANT L5 » — l'inventaire des écarts prod→refonte conditionne ce qu'on ose remplacer |
| BACK#466 — Décision formelle — péremption de mot de passe et codes de r | écart fonctionnel prod→refonte (la prod fait vieillir les mots de passe, la refonte non) : à trancher avant de remplacer la prod |
| BACK#549 — Dashboard pilotage : rates.start est un taux d'INSCRIPTIONS  | le dashboard de pilotage sert un taux FAUX (taux d'inscriptions comme taux unique) : chiffres faux visibles des managers à l'ouverture |
| BACK#646 — Les étiquettes des deux dépôts ont divergé : « statut: en re | instrument de pilotage — étiquettes divergentes faussent les comptes pendant la préparation de bascule (jumelle de #649, déjà en L5) |
| BACK#658 — Staging alimenté par release/** avec garde RELEASE_COURANTE  | chantier actif au go d'Enguerran du 24/08 (staging sur release/**) : stabilité de la recette pendant la fenêtre de bascule |
| FRONT#18 — Anciennes URLs cassées après la refonte du routage : page bl | toute ancienne URL = page blanche : frappera chaque lien historique des utilisateurs au moment de l'OUVERTURE |
| FRONT#238 — Smoke post-déploiement joué SUR le serveur : assertions par  | le smoke post-déploiement est un dispositif de la bascule elle-même (dernière marche du script) |
| FRONT#298 — Page cours : l'icône de téléchargement d'un support PDF est  | retour de recette Lilian (P2.5), correctif d'une ligne : se solde avant la contre-recette |
| FRONT#308 — Route /pilotage/tous-les-collaborateurs : ProtectedRoute aut | KO de recette Lilian (P3.10) : défense en profondeur sans fuite, mais l'étape reste KO tant que ce n'est pas fait |
| FRONT#362 — Volet FRONT de BACK#658 — staging sur release/** avec garde  | volet FRONT de BACK#658 — même chantier, même fenêtre |

### Post-bascule — 61 issues versées en `V2`

Dominantes : les quatre chantiers CI « post-L5 » auto-déclarés (#467-470), la dette
design system FRONT (#277-294), les volets back d'omissions assumées des écrans
formateur (#434-438), la famille parcours (#480/481/489/490), les cadrages SaaS
(#514/517/519/520), le pont MICROLEARNING↔LMS (#184, #355 — suit l'arbitrage du 24/08
qui a placé le pont post-bascule), et les correctifs de confort.

Motifs particuliers :

- **BACK#471** — montée PHP 8.3/8.4 : échéance décembre 2026 — ⚠️ le CHOIX de version du serveur cible est à signaler à la session bascule (#181)
- **BACK#355** — visionneuse famille « page » HTML : suit le pont studio↔LMS, que l'arbitrage du 24/08 a placé post-bascule
- **BACK#186** — journal d'audit volet 2/2 (consultation/rétention) : la CAPTURE (#389) est livrée et se pose à la bascule ; la consultation peut suivre
- **BACK#184** — cadrage du contrat MICROLEARNING↔LMS : même logique — le pont est post-bascule
- **FRONT#49** — 3,3 Mo de JS : réel pour l'expérience à l'ouverture, mais chantier de découpage — à caler dans la fenêtre post-bascule pré-ouverture si possible

⚠️ **Signal à la session bascule (#181)** : choisir PHP **8.3/8.4** pour le serveur
cible (au lieu de 8.2 dont le support s'éteint en décembre) réglerait #471 au passage.

### Ce qui reste sans jalon, et pourquoi c'est normal

**19 issues** — toutes déjà **développées** (en recette ou en cours), aucune à
développer : elles se ferment par la recette, pas par un lot. La file d'instruction
est **vide**.

### L'état final du registre (25/08, contrôlé)

| jalon | ouvertes |
|---|---:|
| V2 — après septembre | 141 |
| V1 · L5 (avant bascule) | 61 |
| V1 · L4 (lot actuel) | 50 |
| L0→L4.8 (recette en cours) | 78 |
| sans jalon (toutes développées) | 19 |

Une finition signalée par la conversation chapeau — **« texte d'aide sur le champ
catégorie »** (attente de testeur, décision produit du 21/08 différée) — sera créée en
V2 au traitement des finitions ; sa trace vit en commentaire de l'issue du contrat de
création de cours côté FRONT.

**Proposition en attente d'arbitrage** : renommer les jalons `V1 · L5 — Finition &
mise en prod (7-13 sept)` → « avant bascule » et `V2 — après septembre` →
« post-bascule », et réviser les dates du jalon L5 — les intitulés actuels ne
correspondent plus à la bascule en deux temps.

## 9. Renommage des jalons (25/08, validé par Enguerran) et état détaillé d'« Avant bascule »

Les 4 décisions validées, appliquées dans **les deux dépôts** (leçon de #649) et
contrôlées par lecture brute (61 / 141 issues ont suivi les renommages) :

1. `V1 · L5 — Finition & mise en prod (7-13 sept)` → **« Avant bascule »** ;
2. `V2 — après septembre` → **« Post-bascule »** ;
3. les dates sortent des titres — l'échéance vit dans le champ *due date*
   (13/09, indicatif, révisable par la session bascule sans renommer) ;
4. les jalons hérités L0→L4.8 ne sont **pas touchés** : ils ne portent plus que du
   travail développé en attente de recette et se ferment quand la recette les vide.
   L4.8 compris — les NOUVEAUX bugs de recette vont en « Avant bascule », la future
   typologie (étiquette « bug de recette ») reprend le rôle discriminant.

### « Avant bascule » — 61 issues, par état de développement (mesuré le 25/08)

| état | combien |
|---|---:|
| développées, **mergées ET déployées** staging (en recette) | 10 |
| mergées staging **non déployées** | **0** — écart `development`↔staging re-mesuré : zéro fichier de code, dans les deux dépôts |
| en cours | 3 — #136 (InnoDB), #141 (category_id), #181 (bascule git/serveur) : les chantiers de la session bascule |
| **à développer** | **48** |

⚠️ Parmi les 48 « à développer », une dizaine sont des gestes **serveur/exploitation**
plus que du développement applicatif — #156 (répétition générale), #261/#302 (SPF/DKIM,
MAIL_FROM), #303 (Composer), #305 (sauvegardes), #210 (caches), #334 (réécriture SPA),
F#114 (.htaccess) — c'est la matière de la session bascule, pas d'un fil de dev.

## 10. Affinage du 25/08 (arbitrages d'Enguerran) — groupes de nature dans « Avant bascule »

Quatre arbitrages rendus sur le détail des 61 :

- **#600 (Stripe) → Post-bascule** — la route de paiement n'est atteignable d'aucun
  écran, le paiement n'est pas un sujet V1 ;
- **#16 (ZegoCloud) reste Avant bascule** — décision ancienne confirmée : on COUPE la
  visio (et le secret exposé part avec) ;
- **Le fonctionnel V1 hérité → Post-bascule** : #34, #35 (notifications), #49
  (badge→certificat), #67 (vue Documents), **#460 et #461** — ⚠️ ces deux dernières
  inversent le vote du 24/08 (validées L5 au bulletin) ; le mot du 25/08 prime ;
- **Regroupement par NATURE à l'intérieur du jalon** : trois étiquettes posées à
  l'IDENTIQUE dans les deux dépôts (leçon #646) — le jalon dit QUAND, l'étiquette dit
  QUOI. La typologie d'issues en instruction côté structure devra s'y aligner.

### « Avant bascule » après affinage — 55 issues, trois groupes (contrôlé 55/55)

| groupe | issues | contenu |
|---|---:|---|
| `lot: serveur-prod` | 20 | schéma/données de prod (#137, #141-144, #190), bascule git/serveur (#181, #301, #304), InnoDB (#136, #156, #157), messagerie (#261, #302, #316), réglages serveur (#210, #303, #305, #334, F#114) |
| `lot: ci-cd-structure` | 11 | CI v1 (#464), inventaire écarts prod→refonte (#465), contrat d'interface (#605, #609), divergences dépôts (#646, #649), staging release/** (#658, F#362), smoke (F#238), migrations silencieuses (#626), hygiène (#581) |
| `lot: défauts-fonctionnels` | 24 | sécurité (#16, #368, #375, #595), quiz (#384, #560, #592, #593, #627), données/API (#345, #549, #582, #599, #613, #466, #477), écrans (F#18, F#237, F#241, F#298, F#308, F#341, F#357, F#364) |

FRONT#364 (née le 25/08, jalonnée « Avant bascule » à la création — la règle de 15h
appliquée par sa session) a été rangée en défauts-fonctionnels au passage.
