> ⚠️ **GAB SENSIBLE — VALIDATION BOSS OBLIGATOIRE avant tout usage.** (child-safety / RGPD / orientation / career). Contenu extrait sans invention ; à relire par un humain.

# GAB-341 · SafetyFallbackLearningMissingContent — « Contenu manquant »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechSafetyFallbackLearning
**Critère validé :** changer le JSON change l'écran sans modifier le HTML. ✅ check.py 12/12.

> ⚠️ **GAB SENSIBLE — RELECTURE BOSS REQUISE** (child-safety / filets de sécurité élève).
> Tout le contenu textuel a été extrait **strictement** du HTML source `INDEX-300-safetyfallbacklearning-GAB-341-345-PLAYABLE.html` (stage `data-tpl="341"`, handlers `d341Act` / `d341Fake`). **Aucune invention.** Valider message élève + libellés filets avant prod.

## Pack (structure officielle par-GAB)
```
GAB-341/
  renderer.html            ← moteur « contenu manquant » (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` · `missing_content_id` · `diagnostic{state,label,rationale}` · `student_message{heading,body}` · `pedagogical_fallback[]{label,blocking,feedback,tone,is_admin?}`
Optionnels : `title`, `fallback_prompt`, `admin_debug`, `use_when[]`, `do_not_use_when[]`, `child_safety{...}`.

## Ce qui vient du JSON vs HTML
- **JSON** : l'état (`missing_detected`), le message élève (heading/body), le prompt « Filet proposé : », chaque filet (label + feedback + tone + blocking), les listes use_when / do_not_use_when.
- **HTML** : carte « doc-paper », rangée de chips, panneaux ok/warn/bad, grille usage, badge d'état, layout, fallback.

## Garde-fous (child_safety)
- **Jamais d'écran blanc** : `student_message` + `pedagogical_fallback` toujours rendus.
- **Anti-invention** : l'option « Générer un contenu de remplacement » porte `blocking:true` → panneau **bad** « on ne génère JAMAIS un faux contenu pour combler ». Source HTML : handler `d341Fake`.
- **Séparation message élève / debug admin** : l'erreur brute va dans `admin_debug` (log technique séparé), jamais affichée à l'élève.
- **BLOCKED** si `diagnostic.state` absent / `student_message` absent / `pedagogical_fallback` vide.

## QA à vérifier
1. Modifier un `label`/`feedback` → rendu change sans toucher au HTML (critère d'or). 2. `pedagogical_fallback:[]` → BLOCKED propre. 3. Clic option `blocking:true` → panneau « on n'invente pas ». 4. Clic filet non-bloquant → panneau ok + état `fallback_available`/`reported`. 5. Responsive 375/768/1024.

## external_refs / dependencies
- Lot frère : GAB-342 (réponse incertaine), GAB-343 (source nécessaire), GAB-344 (sujet sensible mineur), GAB-345 (escalade humain). Renvois croisés présents dans `do_not_use_when` (ex : « réponse incertaine (→ GAB-342) »). Aucune dépendance runtime ; chaque GAB est autonome.

## Source
`INDEX-300-safetyfallbacklearning-GAB-341-345-PLAYABLE.html` (stage `data-tpl="341"`, handlers `d341Act`, `d341Fake`).
