{
  "contract_version": "gab_306_contract_v1",
  "gab_id": "GAB-306",
  "canonical_name": "DocumentLearningCompareDocuments",
  "module_owner": "EdTechDocumentLearning",
  "renderer_key": "compare_grid",
  "required_fields": [
    "gab_id",
    "compare_id",
    "documents",
    "compare_axes",
    "evidence_per_doc"
  ],
  "optional_fields": [
    "title",
    "instruction",
    "contradictions",
    "_note_dev"
  ],
  "field_types": {
    "documents": "array<{id,label,excerpt}> — longueur min 2",
    "compare_axes": "array<{id,label,relation,feedback}> — relation: enum['concordance','difference','warning']",
    "evidence_per_doc": "object<doc_id:string> — une entrée par document listé dans documents",
    "contradictions": "array<string> — liste des tensions ou contradictions entre les docs (peut être vide)"
  },
  "constraints": [
    "documents doit contenir au moins 2 entrées (sinon BLOCKED).",
    "compare_axes doit contenir au moins 1 axe (sinon BLOCKED).",
    "evidence_per_doc doit référencer chaque id présent dans documents.",
    "relation='warning' signifie que l'information est absente ou insuffisante pour conclure — le feedback DOIT commencer par ⚠.",
    "Anti-invention : si une info est absente des documents, relation='warning', jamais inventer de valeur."
  ],
  "blocked_conditions": [
    "documents absent ou longueur < 2 (BLOCKED)",
    "compare_axes absent ou vide (BLOCKED)",
    "evidence_per_doc absent (BLOCKED)"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "aria_labels_on_buttons"
  ],
  "qa_cases": [
    { "case": "instance conforme", "expected": "rendu complet, axes cliquables, feedback correct, 0 erreur" },
    { "case": "documents absent ou < 2", "expected": "BLOCKED listant le champ" },
    { "case": "compare_axes vide", "expected": "BLOCKED listant le champ" },
    { "case": "evidence_per_doc absent", "expected": "BLOCKED listant le champ" },
    { "case": "axe relation=warning", "expected": "feedback panel en style warn (gold), pas de marquage ready" },
    { "case": "axe relation=concordance ou difference", "expected": "feedback panel en style note, marquage ready après clic" },
    { "case": "instance externe injectée via init(ext)", "expected": "le rendu change sans modifier le HTML" },
    { "case": "responsive 375/768/1024", "expected": "colonnes docs passent en 1 colonne sur mobile, aucun débordement" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-306",
    "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). renderer_key 'compare_grid' à concevoir — pas de moteur kit de référence dans EdTechDocumentLearning pour ce renderer."
  }
}
