{
  "contract_version": "gab_344_contract_v1",
  "gab_id": "GAB-344",
  "canonical_name": "SafetyFallbackLearningAgeSensitiveTopic",
  "module_owner": "EdTechSafetyFallbackLearning",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "sensitive_topic_id",
    "context_notice",
    "prompt",
    "response_options"
  ],
  "optional_fields": [
    "title",
    "topic_label",
    "state",
    "use_when",
    "do_not_use_when",
    "child_safety"
  ],
  "field_types": {
    "context_notice": "string — bandeau de mise en garde affiché à l'élève",
    "prompt": "string — invite décrivant la situation",
    "response_options": "array<{kind,label,icon,blocked:boolean,feedback,result_state}> — au moins UNE option blocked:false (réponse sûre)",
    "state": "enum['sensitive_detected','safe_answer','blocked']",
    "child_safety": "object{audience,non_diagnostic:boolean,adult_redirect:boolean,block_inappropriate:boolean,review_required}"
  },
  "constraints": [
    "Public mineur : ton prudent obligatoire, jamais de diagnostic posé à l'élève.",
    "Au moins une response_options avec blocked:false (la voie sûre : message prudent + orientation adulte).",
    "Les options blocked:true sont des choix pédagogiques à refuser ; le moteur affiche un feedback 'Bloqué' et ne révèle aucun contenu inadapté.",
    "Aucune métadonnée ni contenu inventé : tout vient du HTML source converti."
  ],
  "blocked_conditions": [
    "context_notice absent",
    "prompt absent",
    "response_options vides",
    "aucune réponse sûre disponible (aucune option blocked:false)"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "fallback_text"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, 0 erreur, bandeau + 3 options" },
    { "case": "champ requis manquant", "expected": "BLOCKED listant le champ" },
    { "case": "aucune option sûre", "expected": "BLOCKED 'aucune réponse sûre'" },
    { "case": "clic option safe", "expected": "panneau ok + state safe_answer" },
    { "case": "clic option diag/detail", "expected": "panneau bad 'Bloqué' + state blocked, aucun contenu inadapté affiché" },
    { "case": "responsive 375/768/1024", "expected": "aucun débordement horizontal" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-344",
    "note": "Ce schema VALIDE l'instance. Le contrat pédagogique complet (input_contract/validation_logic/feedback_scoring_logic) vit dans le CORE-GAB officiel, pas ici. GAB SENSIBLE child-safety : revue Boss requise avant prod."
  }
}
