{
  "contract_version": "gab_255_contract_v1",
  "gab_id": "GAB-255",
  "canonical_name": "CollaborationLearningGroupReflection",
  "module_owner": "EdTechCollaborationLearning",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "group_reflection_id",
    "title",
    "summary",
    "items"
  ],
  "optional_fields": [
    "reflection_type",
    "reflection_type_enum",
    "next_action",
    "next_action_label",
    "primary_cta",
    "metacognitive_note",
    "accessibility",
    "child_safety"
  ],
  "field_types": {
    "group_reflection_id": "string — identifiant unique de l'instance",
    "title": "string — titre de la synthèse collective",
    "summary": "string — sous-titre / instruction courte",
    "reflection_type": "enum['what_we_learned','what_to_review','what_worked_together','oral_debrief','parent_child_summary']",
    "reflection_type_enum": "array<string> — liste exhaustive des 5 valeurs de l'enum",
    "items": "array<{zone:enum['got','watch','next'], emoji:string, label:string, body:string}> — 3 items max",
    "next_action": "string — route vers SmartSelect ou PathMap",
    "next_action_label": "string — libellé descriptif du next_action",
    "primary_cta": "object{label:string, action:string}",
    "metacognitive_note": "string — note pédagogique sur la valeur de la synthèse",
    "accessibility": "object{keyboard_navigable:boolean, focus_visible:boolean, prefers_reduced_motion:boolean}",
    "child_safety": "object{max_items:number, no_user_generated_content:boolean, moderation_required:boolean}"
  },
  "constraints": [
    "items doit contenir au moins 1 entrée et au maximum 3 (max_items:3 selon child_safety).",
    "Chaque item doit avoir une zone parmi : got, watch, next.",
    "reflection_type doit appartenir à l'enum des 5 valeurs si présent.",
    "primary_cta : bouton structurel (HTML), libellé venant du JSON.",
    "next_action : route de navigation vers SmartSelect ou PathMap, jamais une URL absolue en dur."
  ],
  "blocked_conditions": [
    "group_reflection_id absent",
    "title absent",
    "summary absent",
    "items vides ou absents"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "fallback_text"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, 3 zones got/watch/next visibles, 0 erreur" },
    { "case": "champ requis manquant (ex: title)", "expected": "BLOCKED listant le champ absent" },
    { "case": "items vides ([])", "expected": "BLOCKED 'items vides'" },
    { "case": "instance externe injectée via init(ext)", "expected": "le rendu change sans modifier le HTML" },
    { "case": "responsive 375/768/1024", "expected": "aucun débordement horizontal, items en colonne sur mobile" },
    { "case": "next_action présent", "expected": "bloc next_action visible avec label et ref" },
    { "case": "next_action absent", "expected": "bloc next_action masqué (hidden)" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-255",
    "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). GAB-255 est le 5e et dernier maillon de la chaîne CollaborationLearning (251→252→253→254→255)."
  }
}
