# GAB-250 · AssessmentLearningEmptyState — « État vide anti-fake-assessment »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechAssessmentLearning
**Critère validé :** changer le JSON change l'état vide sans modifier le HTML.

## Pack (structure officielle par-GAB)
```
GAB-250/
  renderer.html            <- moteur état vide (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` · `empty_state_id` · `title` · `body` · `primary_cta{label,action}`

Optionnels : `empty_reason` · `empty_reason_enum[]` · `anti_fake_title` · `anti_fake_text` · `parallel_note` · `fallback_options[]{icon,color_key,title,description,module_label,action}` · `distinction_note` · `secondary_cta{label,action}`

## Ce qui vient du JSON vs HTML
- **JSON** : titre affiché à l'élève, corps de l'état vide, raison (enum), options de secours (icône, titre, description, action), texte doctrine anti-fake, libellés des CTAs.
- **HTML** : layout de la carte dashed-gold, grille options, barre reason-chips, boutons structurels, fallback.

## Archétype
État vide **anti-fake** : GAB-250 s'affiche quand `AssessmentLearning` ne dispose pas d'un pool de questions validé pour une notion donnée. Il refuse activement de générer un test inventé et propose des alternatives dignes (fiche méthode, exercices guidés, SmartSelect fallback).

### Parallèle doctrinaire (3 gabarits, même doctrine)
| GAB | Nom | Périmètre |
|-----|-----|-----------|
| GAB-250 | AssessmentLearningEmptyState | anti-fake côté **évaluation** |
| GAB-230 | SmartSelectEmptyChoice | anti-fake côté **sélection** |
| GAB-209 | SessionQualityGuard | quality-gate côté **session** |

### Distinction EmptyState vs ErrorFallbackBlock
- **GAB-250 EmptyState** = absence légitime d'évaluation (pool manquant, niveau non couvert). Pas de bug, log QA de contenu.
- **ErrorFallbackBlock** = erreur technique (500, indexation cassée). Log d'erreur distinct.
- Si le pool est vide alors qu'il devrait exister → c'est un bug contenu, **pas** un EmptyState.

## Garde-fous
- **Anti-invention** : aucun contenu pédagogique en dur dans le renderer. Titre, corps, options, CTAs viennent tous du JSON.
- **Anti-fake-assessment** : jamais générer un test avec des questions inventées ou non validées.
- **BLOCKED** si `title` / `body` / `primary_cta` absents.
- `empty_reason` enum à 5 valeurs : `no_assessment` · `not_available_level` · `questions_missing` · `not_ready` · `access_limited`.
- `fallback_options.color_key` : parmi `visual` / `exercise` / `smartselect` (détermine la couleur de l'icône).

## QA à vérifier
1. Modifier `title`/`body` → rendu change sans toucher au HTML (critère d'or).
2. `primary_cta` absent → BLOCKED propre.
3. `fallback_options:[]` ou absent → zone options masquée, pas de crash.
4. Clic CTA → panel ok affiché avec label + action.
5. Clic option → panel ok affiché.
6. Responsive 375/768/1024 → aucun débordement.

## external_refs / dependencies
- **GAB-230** (SmartSelectEmptyChoice) : parallèle doctrinaire direct — anti-fake côté sélection.
- **GAB-209** (SessionQualityGuard) : parallèle doctrinaire — quality-gate côté session.
- **GAB-224** : référencé dans l'option SmartSelect fallback (`Contenu adapté au niveau via GAB-224`).
- **ErrorFallbackBlock** : gabarit distinct pour les erreurs techniques (hors périmètre de ce lot).

## Source
`INDEX-300-assessmentlearning-GAB-246-250-PLAYABLE.html` (stage `data-tpl="250"`, section `<!-- GAB-250 EMPTY STATE -->`).
