{
  "contract_version": "gab_286_contract_v1",
  "gab_id": "GAB-286",
  "canonical_name": "WritingLearningEvidenceIntegration",
  "module_owner": "EdTechWritingLearning",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "evidence_integration_id",
    "claim_ref",
    "evidence_ref",
    "integration_rules",
    "explanation_required"
  ],
  "optional_fields": [
    "title",
    "subtitle",
    "tag_label",
    "sentence_patterns",
    "reason_block",
    "primary_cta",
    "secondary_cta",
    "quote_policy",
    "source_context",
    "citation_format",
    "feedback_ref",
    "source_metadata"
  ],
  "field_types": {
    "claim_ref": "object{label,text}",
    "evidence_ref": "object{header,text,cite}",
    "integration_rules": "object{label,intro,quote,explanation,closing}",
    "explanation_required": "object{header,text}",
    "sentence_patterns": "array<string> — formules d'insertion réutilisables",
    "reason_block": "object{label,text}",
    "primary_cta": "object{label,reveal_text}",
    "secondary_cta": "object{label,reveal_text}",
    "source_metadata": "object{author,year,title,page}"
  },
  "constraints": [
    "integration_rules.quote doit être la citation exacte extraite de la source, jamais inventée.",
    "explanation_required est obligatoire : anti-collage = pilier pédagogique du GAB.",
    "sentence_patterns : liste non vide si fournie (min 2 formules).",
    "primary_cta.reveal_text : texte de feedback affiché au clic, jamais vide si primary_cta présent.",
    "citation_format doit respecter le standard auteur-date si fourni."
  ],
  "blocked_conditions": [
    "claim_ref absent",
    "evidence_ref absent",
    "integration_rules absent",
    "explanation_required absent"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "fallback_text"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet avec claim + source + sandwich + anti-collage + CTAs, 0 erreur" },
    { "case": "champ requis manquant (ex: claim_ref)", "expected": "BLOCKED listant le champ manquant" },
    { "case": "CTA primaire cliqué", "expected": "panel reveal avec reveal_text de primary_cta" },
    { "case": "CTA secondaire cliqué", "expected": "panel reveal avec reveal_text de secondary_cta" },
    { "case": "instance externe injectée via init(ext)", "expected": "rendu change sans modifier le HTML" },
    { "case": "responsive 375/768/1024", "expected": "aucun débordement horizontal" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-286",
    "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)."
  }
}
