{
  "contract_version": "gab_312_contract_v1",
  "gab_id": "GAB-312",
  "canonical_name": "RevisionLearningPriorityQueue",
  "module_owner": "EdTechRevisionLearning",
  "renderer_key": "choice_select",
  "required_fields": [
    "gab_id",
    "priority_queue_id",
    "queue_items"
  ],
  "optional_fields": [
    "title",
    "intro_label",
    "feedback_selected",
    "feedback_signal_prefix",
    "feedback_locked"
  ],
  "field_types": {
    "priority_queue_id": "string — identifiant unique de la file de priorité",
    "queue_items": "array<{item_id:string, label:string, priority_level:enum['haute','moyenne','basse'], priority_score:number, signal_source:string, teacher_override:boolean}>",
    "title": "string",
    "intro_label": "string",
    "feedback_selected": "string — template avec {label} et {priority_level}",
    "feedback_signal_prefix": "string",
    "feedback_locked": "string"
  },
  "constraints": [
    "queue_items doit contenir au moins 1 élément.",
    "Chaque item doit avoir item_id, label, priority_level, priority_score, signal_source.",
    "teacher_override:true = item verrouillé par le prof, ne peut pas être ignoré par l'élève.",
    "priority_score : entier positif, utilisé pour le tri visuel (plus grand = plus urgent).",
    "priority_level : enum ['haute','moyenne','basse'] — détermine la couleur de l'indicateur.",
    "signal_source : doit provenir de données réelles (erreurs répétées, échéance) — jamais inventé.",
    "Anti-invention : ne jamais générer de signal_source sans données utilisateur réelles."
  ],
  "blocked_conditions": [
    "queue_items absent ou tableau vide (BLOCKED)",
    "priority_queue_id absent (BLOCKED)"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "aria_labels_on_locked_items"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, file affichée, 0 erreur" },
    { "case": "queue_items vide", "expected": "BLOCKED listant le champ" },
    { "case": "priority_queue_id absent", "expected": "BLOCKED listant le champ" },
    { "case": "clic item normal", "expected": "feedback avec label et priority_level affiché" },
    { "case": "clic item teacher_override:true", "expected": "feedback verrouillé affiché, item non ignorable" },
    { "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-312",
    "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)."
  }
}
