# GAB-299 · OralLearningAnswerFollowUp — « Relance, pas piège »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechOralLearning
**Critère validé :** changer le JSON change le thread et le compteur sans modifier le HTML. ✅ check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-299/
  renderer.html            ← moteur relance bienveillante (ne pas modifier par instance)
  instance.example.json    ← SOURCE DE VÉRITÉ (contenu réel, à plat)
  schema.contract.json     ← contrat de validation
  README-contract.md       ← ce fichier
```

## Champs requis (instance, à plat)
`gab_id` · `follow_up_id` · `initial_answer_ref` · `follow_up_question` · `follow_up_type` · `expected_improvement`

Optionnels : `title`, `subtitle`, `exchange_thread[]{role,label,text,tag?}`, `follow_up_counter`, `max_follow_ups`, `anti_trap_rules[]`, `why_max_3`, `primary_cta{label,action}`, `secondary_cta{label,action}`, `hint_allowed`, `difficulty`, `feedback_ref`, `answer_frame`, `source_metadata`.

## Ce qui vient du JSON vs HTML
- **JSON** : contenu du thread (bulles élève/jury), compteur, plafond max_follow_ups, règles anti-piège, libellés des boutons, hint, explication why_max_3.
- **HTML** : layout thread, bulles colorées par rôle, counter-row, safety block magenta, boutons structurels, moteur BLOCKED.

## Archétype pédagogique
GAB-299 modélise une **relance bienveillante anti-piège** dans un contexte d'oral scolaire. La doctrine de sécurité est double :
1. **Plafond max_follow_ups** (valeur par défaut : 3) — au-delà, le bouton "Continuer" est désactivé pour éviter l'intimidation.
2. **Types de relances limités** — uniquement `clarify`, `deepen`, `example` : chaque relance part de la réponse de l'élève, jamais d'un agenda du jury.

## Garde-fous (child_safety / anti-piège)
- `max_follow_ups` ne peut pas dépasser 3 (doctrine anti-intimidation).
- Relances interdites : piège avec fausse question, contradiction systématique, punition d'un "je ne sais pas" sincère.
- **BLOCKED** si l'un des champs requis est absent (`follow_up_id`, `initial_answer_ref`, `follow_up_question`, `follow_up_type`, `expected_improvement`).

## QA à vérifier
1. Modifier une bulle dans `exchange_thread` → rendu change sans toucher au HTML (critère d'or).
2. Supprimer `follow_up_question` → BLOCKED propre affiché.
3. `follow_up_counter == max_follow_ups` → bouton "Continuer" désactivé.
4. Instance externe injectée via `ENGINE.init(ext)` → rendu mis à jour.
5. Responsive 375/768/1024 — bulles lisibles sans débordement horizontal.

## external_refs / dependencies
Ce GAB s'inscrit dans la chaîne Oral vague 2 (module 21) :
- **296** OralLearningVoiceClarity → **297** StressSupport → **298** ImprovisationPrompt → **299** AnswerFollowUp (ce GAB) → **300** FinalRehearsal.
- Aucune dépendance de rendu sur les autres GAB du lot (moteur autonome).

## Source
`INDEX-300-orallearning-GAB-296-300-PLAYABLE.html` (stage `data-tpl="299"`, section `.fu-*`, `.fu-thread`, `.fu-counter`, `.safety-block`).
