docs(t1-live): contrat WS T1 + dette technique (Sprint 7a)

- Prompt_t1live.md : spec prompt examinateur T1, note anti-TD-22 (regle 7 du T2 non propagee), contrat WS complet (messages + close codes) pour le frontend 7b, comportement de fin (activityEnd final + relance terminale coupee).
- TECH_DEBT-backend.md : TD-23 (non-determinisme Gemini Live T1 + decouverte flush inputTranscription a activityEnd en VAD manuel), TD-24 (dette nommage gate oral_t2_live couvrant aussi T1), TD-25 (dette DRY runT1LiveCorrection ~= runT2LiveCorrection, report conscient).
This commit is contained in:
Hermann_Kitio 2026-06-29 22:10:15 +03:00
parent 868bd09397
commit 3722e2aaf5
2 changed files with 271 additions and 0 deletions

View file

@ -256,6 +256,71 @@ Gate de qualité actuel : npm run test.
---
### TD-23 — Comportement Gemini Live T1 non déterministe + contrainte VAD manuel
**Priorité :** 🟡 Important
**Statut :** Ouvert — introduit au Sprint 7a
**Description :** Deux risques distincts sur le flux T1 Live (`geminiLiveT1.ts`) :
1. **Relance non garantie.** Comme pour le T2 (TD-22), le modèle Gemini Flash
Live n'offre aucune garantie déterministe : sur le signal d'injection
(`clientContent` de relance), il peut ignorer la consigne, formuler une
relance hors-sujet, enchaîner plusieurs questions, ou commenter la langue du
candidat malgré l'interdiction du prompt.
2. **Découverte spike — flush VAD manuel.** En VAD manuel
(`realtimeInputConfig.automaticActivityDetection.disabled = true`), Gemini ne
flushe `inputTranscription` (texte candidat) **qu'à l'envoi d'un
`activityEnd`**, pas en continu. Le backend doit donc envoyer `activityEnd`
aux bornes de tour pour récupérer le transcript. **Effet de bord :**
`activityEnd` déclenche AUSSI une réponse audio de l'examinateur (relance
« terminale »), qu'il faut couper en fin de session (audio non forwardé,
texte jeté — cf. `Prompt_t1live.md §5`).
**À faire :** Surveiller en tests manuels (Groupe D étendu) la pertinence des
relances et l'absence de relance terminale audible. Pistes si dérive :
renforcement du prompt, post-filtrage des sorties, ajustement du grace delay
(`T1_TERMINAL_FLUSH_GRACE_MS`).
**Session concernée :** T1 Live — Sprint 7a.
---
### TD-24 — Dette de nommage : `oral_t2_live` gate aussi le T1 Live
**Priorité :** 🟢 Mineur
**Statut :** Ouvert — introduit au Sprint 7a
**Description :** La route `WS /t1/live` réutilise `authenticate` de
`t2live.ts`, qui gate sur la permission `checkFeatureAccess(plan, 'oral_t2_live')`.
La feature `oral_t2_live` contrôle donc **aussi** l'accès au T1 Live, ce qui est
sémantiquement trompeur. Le couplage casserait si une différenciation d'accès
T1 vs T2 était souhaitée un jour (ex. T1 ouvert à Standard, T2 réservé Premium).
**À faire :** Renommer en `oral_live` (générique) ou introduire `oral_t1_live`
distinct. C'est une décision d'architecture + une migration `lib/access.ts`
(et potentiellement l'enum de features). Hors scope Sprint 7a.
**Session concernée :** T1 Live — Sprint 7a.
---
### TD-25 — Dette DRY : `runT1LiveCorrection``runT2LiveCorrection`
**Priorité :** 🟢 Mineur
**Statut :** Ouvert — report conscient (Sprint 7a)
**Description :** `runT1LiveCorrection` (`t1live.ts`) est à ~90 % identique à
`runT2LiveCorrection` (`t2live.ts`) : même pipeline (guard transcript vide →
insert `productions` → DeepSeek `correctEO` → phonologie stub → update → frame
`report` + close), mêmes codes d'erreur (`EMPTY_TRANSCRIPT`,
`PERSISTENCE_FAILED`, `CORRECTION_FAILED`) et de fermeture (1000 / 1011). Les
seules divergences : `tache` (`EO_T1` vs `EO_T2_LIVE`), `sujet_id` (`null` vs
`sujet.id`), arguments DeepSeek (`'EO_T1', 9, null` vs `'EO_T2', 9,
sujet.consigne`), signature (présence ou non de `sujet`), préfixe de log.
**À faire :** Factoriser en un helper partagé
`runEoLiveCorrection({ clientWs, profile, transcript, tache, sujetId, consigne, logTag })`.
**Report assumé :** factoriser à 2 cas seulement risque l'abstraction prématurée
et touche `t2live.ts` (stable, déjà commité). À factoriser quand un **3e cas
live** apparaîtra (ex. T3 Live).
**Session concernée :** T1 Live — Sprint 7a.
---
## 5. Historique des résolutions
| ID | Description | Résolu le | Comment |