{
  "contract_version": "gab_272_contract_v1",
  "gab_id": "GAB-272",
  "canonical_name": "MethodLearningStepByStepMethod",
  "module_owner": "EdTechMethodLearning",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "method_id",
    "steps",
    "step_order",
    "completion_rules",
    "current_step_index"
  ],
  "optional_fields": [
    "title",
    "subtitle",
    "common_errors",
    "progressive_hints",
    "skip_policy",
    "remediation_refs",
    "reason_block",
    "primary_cta",
    "secondary_cta",
    "source_metadata"
  ],
  "field_types": {
    "method_id": "string — identifiant unique de la méthode",
    "steps": "array<{index:number, title:string, body:string}> — au moins 1 entrée",
    "step_order": "enum['sequential','parallel'] — sequential = ordre strict imposé",
    "current_step_index": "number — index (0-based) de l'étape courante dans steps[]",
    "completion_rules": "string — critère de validation de l'étape courante",
    "common_errors": "array<{step_index:number, error:string}> — erreurs fréquentes par étape",
    "progressive_hints": "array<{step_index:number, level:number, hint:string}> — indices progressifs",
    "reason_block": "object{title:string, text:string} — explication pédagogique de la validation par étape",
    "primary_cta": "object{label:string, action:string}",
    "secondary_cta": "object{label:string, action:string}"
  },
  "constraints": [
    "steps[] doit contenir au moins 1 élément.",
    "current_step_index doit être un index valide dans steps[] (0 <= current_step_index < steps.length).",
    "step_order='sequential' : passage à l'étape suivante bloqué sans validation de l'étape courante.",
    "primary_cta : bouton structurel (HTML), libellé venant du JSON.",
    "Les titres/corps des étapes non disponibles dans la source doivent porter _TODO — jamais inventés."
  ],
  "blocked_conditions": [
    "steps vide ou absent",
    "step_order absent",
    "completion_rules absent"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "fallback_text"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, 0 erreur, barre de progression visible" },
    { "case": "champ requis manquant (steps vide)", "expected": "BLOCKED listant le champ" },
    { "case": "steps avec _TODO", "expected": "affichage du placeholder _TODO, jamais d'invention" },
    { "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-272",
    "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)."
  }
}
