{
  "gab_id": "GAB-204",
  "renderer_key": "text_cta",
  "bridge_id": "bridge-playengine-ref-resolver-demo",
  "_note_dev": "SOURCE DE VÉRITÉ. Bridge architectural PlayEngine : résolution ref→module_owner via allowlist. Données extraites de INDEX-300-playengine-composite-GAB-201-205-PLAYABLE.html. Anti-invention : les allowlist_families et owners_map correspondent EXACTEMENT aux constantes JS de la source. Les presets de test sont issus du HTML source.",
  "title": "Bridge ref → module_owner",
  "subtitle": "Composant architectural critique · point de sécurité",
  "warning_text": "Sécurité non négociable : module_owner = source de vérité (pas \"provider\"). Refs allowlistées strictement. AccessGate/RLS respecté. Fallback contrôlé. Aucun contournement autorisé.",
  "flow_title": "Flow de résolution d'une ref",
  "flow_steps": [
    { "num": 1, "title": "Parse la ref", "detail": "interactive/brevet-3e/revolution-cause-effect-lab", "status": "OK", "state": "ok" },
    { "num": 2, "title": "Vérifie allowlist", "detail": "Famille \"interactive/\" autorisée", "status": "ALLOWED", "state": "ok" },
    { "num": 3, "title": "Résout module_owner", "detail": "→ EdTechInteractiveLearning", "status": "OK", "state": "ok" },
    { "num": 4, "title": "Vérifie permissions (AccessGate/RLS)", "detail": "user_id × ref × subject autorisés ?", "status": "CHECK", "state": "test" },
    { "num": 5, "title": "Renvoie composant React", "detail": "<InteractiveLab refId={...} />", "status": "RENDER", "state": "ok" }
  ],
  "test_block_title": "Test de résolution interactive",
  "test_placeholder": "ref à tester...",
  "test_default_ref": "interactive/brevet-3e/revolution-cause-effect-lab",
  "allowlist_families": [
    "story/", "visual/", "memory/", "exercise/", "interactive/",
    "game/", "audio/", "level-test/", "path/", "play/"
  ],
  "owners_map": {
    "story/": "EdTechStoryLearning",
    "visual/": "EdTechVisualLearning",
    "memory/": "EdTechMemoryLearning",
    "exercise/": "EdTechExerciseLearning",
    "interactive/": "EdTechInteractiveLearning",
    "game/": "EdTechGameLearning",
    "audio/": "EdTechAudioLearning",
    "level-test/": "EdTechLevelTest",
    "path/": "EdTechPathMap",
    "play/": "EdTechPlayEngine"
  },
  "test_presets": [
    { "label": "story valide", "ref": "story/brevet-3e/revolution-crise" },
    { "label": "memory valide", "ref": "memory/brevet-3e/flashcards" },
    { "label": "eval (refusée)", "ref": "eval/admin/exam-secret-2026" },
    { "label": "ref inexistante", "ref": "story/brevet-3e/inexistant" },
    { "label": "tentative injection", "ref": "http://malicious.com/x" }
  ],
  "primary_cta": { "label": "▶ Résoudre", "action": "resolve_ref" }
}
