{
  "contract_version": "gab_280_contract_v1",
  "gab_id": "GAB-280",
  "canonical_name": "MethodLearningAutonomyCard",
  "module_owner": "EdTechMethodLearning",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "autonomy_card_id",
    "method_ref",
    "autonomy_status",
    "evidence_items",
    "next_action"
  ],
  "optional_fields": [
    "card_title",
    "card_subtitle",
    "autonomy_levels",
    "confidence_level",
    "review_due",
    "teacher_note",
    "anti_certification_title",
    "anti_certification_text",
    "reason_block",
    "parent_summary",
    "source_metadata"
  ],
  "field_types": {
    "autonomy_status": "object{label,description,acquired_date,review_due}",
    "evidence_items": "array<{text,date}>  — au moins 1 élément requis",
    "autonomy_levels": "array<{key,icon,label,state:enum['unlocked','current','locked']}>  — 4 niveaux attendus",
    "next_action": "object{label,feedback}",
    "reason_block": "object{title,text}",
    "confidence_level": "number(0..1) | null",
    "teacher_note": "string | null",
    "parent_summary": "string | null",
    "source_metadata": "object | null"
  },
  "constraints": [
    "evidence_items doit contenir au moins 1 élément — BLOCKED si vide ou absent.",
    "autonomy_status doit avoir un label non vide — BLOCKED si absent.",
    "next_action.label est le libellé du bouton CTA primaire — vient exclusivement du JSON.",
    "autonomy_levels : si présent, exactement 1 niveau state='current' attendu.",
    "anti_certification_text : champ structurel de garde-fou anti-surcertification — afficher si présent.",
    "La carte expire : review_due dans autonomy_status oriente la re-vérification — jamais supprimé si présent."
  ],
  "blocked_conditions": [
    "autonomy_status absent",
    "evidence_items vides",
    "next_action absent"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "fallback_text"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, 0 erreur" },
    { "case": "champ requis manquant (ex: evidence_items vide)", "expected": "BLOCKED listant le champ" },
    { "case": "instance externe injectée via ENGINE.init(ext)", "expected": "le rendu change sans modifier le HTML" },
    { "case": "next_action.label modifié dans le JSON", "expected": "libellé du bouton CTA mis à jour sans toucher au HTML" },
    { "case": "autonomy_levels avec 4 états dont 1 current", "expected": "grille 4 cases, current mis en évidence" },
    { "case": "responsive 375/768/1024", "expected": "aucun débordement horizontal" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-280",
    "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)."
  }
}
