{
  "contract_version": "gab_305_contract_v1",
  "gab_id": "GAB-305",
  "canonical_name": "DocumentLearningInterpretEvidence",
  "module_owner": "EdTechDocumentLearning",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "interpret_id",
    "evidence_ref",
    "interpretation_prompt",
    "inference_levels"
  ],
  "optional_fields": [
    "title",
    "document_ref",
    "interpretation_rules",
    "synthesis_on_success",
    "source_notice",
    "fallback_text_summary"
  ],
  "field_types": {
    "interpret_id": "string (id stable de l'écran d'interprétation)",
    "document_ref": "object{src,kind,alt}",
    "evidence_ref": "object{kind_label,text} — la PREUVE observée, extraite du document, jamais inventée",
    "interpretation_prompt": "string — consigne posée à l'élève",
    "interpretation_rules": "object{link_to_question_required:boolean,max_safe_level:number,note}",
    "inference_levels": "array<{level:number,label,verdict:enum['interpreted','partial','overinterpreted'],tone:enum['ok','note','warn','bad'],message}>",
    "synthesis_on_success": "string — synthèse affichée quand le niveau sûr (max_safe_level) est choisi"
  },
  "constraints": [
    "ANTI-INVENTION : la preuve (evidence_ref.text) et chaque niveau d'inférence viennent du document ; le moteur n'ajoute aucune interprétation.",
    "Un niveau verdict='overinterpreted' DOIT être signalé (tone 'bad') — on ne valide jamais une surinterprétation.",
    "max_safe_level désigne le seul niveau récompensé par synthesis_on_success (inférence prudente reliée à la question).",
    "Une inférence n'est valide que prudente ET reliée à la question."
  ],
  "blocked_conditions": [
    "evidence_ref absent ou sans text",
    "interpretation_prompt absent",
    "inference_levels absent ou vide"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "fallback_text"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, 0 erreur" },
    { "case": "champ requis manquant", "expected": "BLOCKED listant le champ" },
    { "case": "élève choisit le niveau 'Fort' (overinterpreted)", "expected": "feedback 'bad' : tu dépasses ce que la preuve montre — pas de validation, pas de synthèse" },
    { "case": "élève choisit le niveau 'Moyen' (partial)", "expected": "feedback 'note' : plausible mais précise le lien au document — pas de synthèse finale" },
    { "case": "élève choisit le niveau sûr (max_safe_level)", "expected": "feedback 'ok' + synthesis_on_success affichée" },
    { "case": "document_ref cassé", "expected": "la preuve textuelle (evidence_ref.text) reste lisible, pas d'écran vide" },
    { "case": "instance externe injectée", "expected": "le rendu change sans modifier le HTML" },
    { "case": "responsive 375/768/1024", "expected": "aucun débordement horizontal" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-305",
    "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 (évite la duplication)."
  }
}
