{
  "contract_version": "gab_279_contract_v1",
  "gab_id": "GAB-279",
  "canonical_name": "MethodLearningTransferToNewExercise",
  "module_owner": "EdTechMethodLearning",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "transfer_id",
    "method_ref",
    "source_task",
    "target_task",
    "transfer_prompts",
    "success_criteria"
  ],
  "optional_fields": [
    "title",
    "subtitle",
    "support_level",
    "similarities",
    "differences",
    "trap_warnings",
    "help_level1",
    "why_explicit",
    "primary_cta",
    "secondary_cta",
    "source_metadata"
  ],
  "field_types": {
    "transfer_id": "string — identifiant unique du transfert",
    "method_ref": "string — nom/identifiant de la méthode transférée",
    "source_task": "object{label,title,body} — tâche source maîtrisée",
    "target_task": "object{label,title,body} — tâche target nouvelle",
    "transfer_prompts": "string — consigne de transfert affichée à l'élève",
    "success_criteria": "string — critère de réussite du transfert",
    "support_level": "enum['full_scaffold','partial_scaffold','minimal_scaffold','autonomous']",
    "similarities": "array<string> — points communs source/target",
    "differences": "array<string> — différences source/target",
    "trap_warnings": "string — pièges de transfert à signaler",
    "help_level1": "string — aide premier niveau si élève bloqué",
    "why_explicit": "string — justification pédagogique du transfert explicite",
    "primary_cta": "object{label,action}",
    "secondary_cta": "object{label,action}"
  },
  "constraints": [
    "source_task et target_task doivent appartenir au même domaine de méthode (method_ref identique).",
    "transfer_prompts est affiché à l'élève — doit être formulé pour lui, pas pour l'enseignant.",
    "success_criteria : critère observable, pas une note — décrit ce que l'élève doit démontrer.",
    "support_level : si absent, le rendu affiche le tag sans valeur (toléré)."
  ],
  "blocked_conditions": [
    "transfer_id absent",
    "method_ref absent",
    "source_task absent",
    "target_task absent",
    "transfer_prompts absent",
    "success_criteria absent"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "responsive_breakpoint_560px"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, 0 erreur, source+target+diff+trap affichés" },
    { "case": "transfer_id manquant", "expected": "BLOCKED listant le champ" },
    { "case": "similarities vide ([])", "expected": "colonne ≈ vide sans erreur JS" },
    { "case": "trap_warnings absent", "expected": "bloc pièges masqué (hidden), pas d'erreur" },
    { "case": "instance externe injectée via ENGINE.init(ext)", "expected": "rendu change sans modifier le HTML" },
    { "case": "responsive 375/768/1024", "expected": "grilles compare/diff passent en 1 colonne ≤560px" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-279",
    "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)."
  }
}
