{
  "schema_version": 1,
  "verified_on": "2026-09-21",
  "generated_at": "2026-09-21T21:00:02Z",
  "source_hash": "2445af1481647f37fe3ce82de81c424357e10f3d485b1988eb1f99f77a2fdfdb",
  "counts": {
    "N0": 3,
    "N1": 12,
    "N2": 9,
    "N3": 36,
    "total": 60,
    "qualified_n3": 34
  },
  "modules": [
    {
      "id": "N0-BLOCK",
      "level": "N0",
      "slug": "block",
      "name": "Allocation de stockage",
      "summary": "Réserver le budget de stockage qui porte les volumes persistants.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Allocation observée dans les applications qualifiées ; calcul de capacité testé en unité.",
      "limitations": [
        "Un volume et son bloc décrivent deux couches de la même allocation, sans double comptage.",
        "Le calcul de croissance ne prouve ni agrandissement physique, ni performance générale, ni quota physique."
      ],
      "parameters": [
        {
          "name": "provider",
          "label": "Fournisseur",
          "description": "Fournisseur explicitement admis pour la responsabilité du module."
        },
        {
          "name": "binding_ref",
          "label": "Raccordement",
          "description": "Référence de la liaison autorisée vers une ressource ou un service."
        },
        {
          "name": "backend_ref",
          "label": "Fournisseur de stockage",
          "description": "Référence du fournisseur de stockage associé à l’allocation."
        },
        {
          "name": "capacity_bytes",
          "label": "Capacité",
          "description": "Capacité demandée en octets dans les limites du profil publié."
        },
        {
          "name": "quota_bytes",
          "label": "Quota",
          "description": "Quota déclaré en octets ; sa présence ne prouve pas un quota physique mesuré."
        },
        {
          "name": "retention",
          "label": "Conservation",
          "description": "Politique de conservation des données après changement de consommateur."
        }
      ],
      "operations": [
        {
          "id": "prepare",
          "label": "Préparation",
          "status": "unit_verified",
          "status_label": "Testé en unité",
          "scope": "Calcul de capacité et absence de double comptage testés en unité."
        },
        {
          "id": "allocate",
          "label": "Allocation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Allocations réutilisées par les applications qualifiées, y compris ERPNext, Nextcloud, Discourse, Immich et Plausible, avec identités conservées ; les reçus physiques restent partiels dans certaines campagnes."
        },
        {
          "id": "resize",
          "label": "Agrandissement physique",
          "status": "not_implemented",
          "status_label": "Non implémenté",
          "scope": "L’augmentation physique d’une allocation nécessite une transition fournisseur non implémentée."
        },
        {
          "id": "typo3_consumer",
          "label": "Réutilisation par TYPO3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "TYPO3 14.3.7 : réservations et identités conservées pendant la création et la mise à jour compatible ; aucun agrandissement ni changement de fournisseur qualifié."
        }
      ],
      "dependencies": [],
      "consumers": [
        "N0-VOLUME"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n0-block"
    },
    {
      "id": "N0-CONTAINER",
      "level": "N0",
      "slug": "container",
      "name": "Conteneur",
      "summary": "Exécuter une image immuable avec une identité et une enveloppe CPU/mémoire explicites.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Installation et remplacement des images applicatives dans les profils Linux/amd64/OCI publiés.",
      "limitations": [
        "Profils observés selon recette : Debian 12, Alpine 3.24 et Wolfi 20230201.",
        "FreeBSD et les autres architectures ne sont pas qualifiés.",
        "Une mise à jour d’image applicative ne qualifie pas une migration majeure du système."
      ],
      "parameters": [
        {
          "name": "os",
          "label": "Système",
          "description": "Système d’exploitation admis par le contrat du conteneur."
        },
        {
          "name": "distribution",
          "label": "Distribution",
          "description": "Distribution système déclarée et couverte par la recette."
        },
        {
          "name": "release",
          "label": "Version système",
          "description": "Version de distribution prévue par la recette."
        },
        {
          "name": "architecture",
          "label": "Architecture",
          "description": "Architecture de processeur admise par la recette publiée."
        },
        {
          "name": "runtime",
          "label": "Runtime du conteneur",
          "description": "Contrat d’exécution du conteneur dans les profils admis."
        },
        {
          "name": "image_digest",
          "label": "Empreinte d’image",
          "description": "Image immuable désignée par son empreinte, jamais par une version flottante."
        },
        {
          "name": "cpu",
          "label": "Processeur",
          "description": "Enveloppe CPU du profil de ressources admis."
        },
        {
          "name": "memory",
          "label": "Mémoire",
          "description": "Enveloppe mémoire du profil de ressources admis."
        },
        {
          "name": "ephemeral_bytes",
          "label": "Stockage temporaire",
          "description": "Enveloppe du stockage temporaire, distincte des données persistantes."
        },
        {
          "name": "uid",
          "label": "Utilisateur d’exécution",
          "description": "Identité utilisateur des processus et des fichiers."
        },
        {
          "name": "gid",
          "label": "Groupe d’exécution",
          "description": "Identité de groupe utilisée pour les processus et les fichiers."
        },
        {
          "name": "placement_ref",
          "label": "Référence de placement",
          "description": "Référence du profil de placement autorisé."
        }
      ],
      "operations": [
        {
          "id": "prepare",
          "label": "Préparation",
          "status": "unit_verified",
          "status_label": "Testé en unité",
          "scope": "Rendu des ressources et refus des images non épinglées testés en unité."
        },
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Images Linux/amd64 servies dans les recettes qualifiées, y compris les nouvelles compositions PHP, Python, Ruby et Elixir, avec ressources et identité observées."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Remplacement d’image applicative avec conservation des montages et des données ; aucune migration majeure du système qualifiée."
        },
        {
          "id": "typo3_consumer",
          "label": "Réutilisation par TYPO3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "TYPO3 14.3.7 : création et mise à jour compatible servies avec compte, pages, média et réservations conservés, puis nouvelle page publiée."
        }
      ],
      "dependencies": [],
      "consumers": [
        "N1-ELIXIR",
        "N1-GO",
        "N1-JVM",
        "N1-NODE",
        "N1-PERSIST",
        "N1-PHP",
        "N1-PYTHON",
        "N1-RUBY",
        "N1-SERVICE",
        "N1-STATIC",
        "N1-WORKER"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n0-container"
    },
    {
      "id": "N0-VOLUME",
      "level": "N0",
      "slug": "volume",
      "name": "Volume persistant",
      "summary": "Monter les données persistantes avec leurs droits et leur identité de stockage.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Installation et conservation des volumes pendant les mises à jour qualifiées.",
      "limitations": [
        "Un stockage disparu ne peut pas être remplacé en déclarant les anciennes données conservées.",
        "Les droits hérités et les permissions des répertoires privés doivent être vérifiés.",
        "Agrandissement physique non implémenté ; restauration après sinistre non vérifiée."
      ],
      "parameters": [
        {
          "name": "block_ref",
          "label": "Bloc de stockage",
          "description": "Référence du budget de stockage portant le volume."
        },
        {
          "name": "allocation_ref",
          "label": "Allocation existante",
          "description": "Référence de l’allocation de stockage à conserver."
        },
        {
          "name": "size_bytes",
          "label": "Taille du volume",
          "description": "Taille déclarée en octets dans l’allocation existante."
        },
        {
          "name": "mount_path",
          "label": "Point de montage",
          "description": "Chemin où la recette attend le volume persistant."
        },
        {
          "name": "access_mode",
          "label": "Mode d’accès au stockage",
          "description": "Mode de montage accepté par le fournisseur publié."
        },
        {
          "name": "uid",
          "label": "Utilisateur d’exécution",
          "description": "Identité utilisateur des processus et des fichiers."
        },
        {
          "name": "gid",
          "label": "Groupe d’exécution",
          "description": "Identité de groupe utilisée pour les processus et les fichiers."
        },
        {
          "name": "retention",
          "label": "Conservation",
          "description": "Politique de conservation des données après changement de consommateur."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création ou réutilisation d’un volume réservé raccordé aux consommateurs qualifiés."
        },
        {
          "id": "preserve",
          "label": "Conservation des données",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Identités, contenus et nouvelles écritures contrôlés pendant les mises à jour des applications qualifiées, notamment les fichiers Nextcloud, les médias Immich et les données Plausible."
        },
        {
          "id": "resize",
          "label": "Agrandissement physique",
          "status": "not_implemented",
          "status_label": "Non implémenté",
          "scope": "Expansion physique du volume réservé non implémentée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucun exercice de restauration après sinistre qualifié."
        },
        {
          "id": "typo3_consumer",
          "label": "Réutilisation par TYPO3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "TYPO3 14.3.7 : stockage, image et pages conservés pendant une mise à jour compatible, puis nouvelle page vérifiée ; restauration non qualifiée."
        }
      ],
      "dependencies": [
        "N0-BLOCK"
      ],
      "consumers": [
        "N1-PERSIST"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n0-volume"
    },
    {
      "id": "N1-COMPOSE",
      "level": "N1",
      "slug": "compose",
      "name": "Composition",
      "summary": "Assembler plusieurs composants de construction ou processus web et de fond.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Compositions publiées Node/Go, Node/MongoDB, PHP, JVM/Node, Python/Node, Ruby et Elixir/Node vérifiées dans leurs consommateurs ; profil Multi-Agent distinct.",
      "limitations": [
        "Aucune compatibilité arbitraire entre langages n’est déduite de ces profils.",
        "Un composant jamais démarré n’est pas un service disponible ; les fournisseurs N2 gardent leur cycle de vie distinct.",
        "La construction Python/frontend d’Open WebUI reste bloquée au scan ; sa promotion n’est pas qualifiée.",
        "La composition PHP de FreshRSS ne requalifie pas la mise à jour complète de Multi-Agent."
      ],
      "parameters": [
        {
          "name": "members",
          "label": "Membres",
          "description": "Capacités composées dans le profil sélectionné."
        },
        {
          "name": "processes",
          "label": "Processus",
          "description": "Processus web ou de fond déclarés dans la composition."
        },
        {
          "name": "dependency_refs",
          "label": "Dépendances de composition",
          "description": "Références explicites des capacités membres de l’assemblage."
        },
        {
          "name": "placement",
          "label": "Placement",
          "description": "Organisation des membres selon les profils de composition disponibles."
        },
        {
          "name": "shared_paths",
          "label": "Chemins partagés",
          "description": "Montages partagés entre membres de la composition."
        },
        {
          "name": "recipe_id",
          "label": "Recette",
          "description": "Identifiant d’une recette effectivement publiée par le produit."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Processus web et worker issus de la même image, avec volumes partagés ; autres compositions décrites par leurs opérations propres."
        },
        {
          "id": "replacement",
          "label": "Remplacement",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Remplacement complet d’une composition initialement bloquée, puis accès web observé."
        },
        {
          "id": "upgrade_n3",
          "label": "Mise à jour N3 de référence",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Mise à jour fonctionnelle complète de Multi-Agent non exécutée."
        },
        {
          "id": "build_composition",
          "label": "Composition de construction",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Frontends Node assemblés avec les binaires Go de Listmonk ; création et mise à jour qualifiées."
        },
        {
          "id": "php_web_periodic",
          "label": "PHP web et tâches périodiques",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Serveur web et tâches PHP périodiques de FreshRSS composés ensemble ; durée et arrêt commun contrôlés."
        },
        {
          "id": "multiple_https_origins",
          "label": "Plusieurs origines HTTPS",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "CryptPad : origines principale et isolée, HTTPS, iframe, WebSocket et collaboration réelle dans un seul runtime Node ; limites du proxy conservées."
        },
        {
          "id": "jvm_frontend",
          "label": "JVM et frontend incorporé",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Metabase : backend JVM et frontend Node construits séparément, assets incorporés au JAR et un seul processus web livré."
        },
        {
          "id": "php_mysql_composition",
          "label": "Composition PHP et MySQL",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "PHP, MySQL privé et stockage composés pour PrestaShop, Nextcloud et MediaWiki ; mises à jour compatibles avec données conservées."
        },
        {
          "id": "python_node_composition",
          "label": "Composition Python et Node",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "ERPNext : Python et Node construits hors réseau, processus web, temps réel et tâches de fond supervisés ; MariaDB et Redis privés conservés."
        },
        {
          "id": "ruby_frontend",
          "label": "Ruby et frontend Node",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Discourse : serveur Ruby, tâches Sidekiq et frontend Ember construit avec Node ; données, invitations privées et rendu conservés."
        },
        {
          "id": "ruby_without_frontend",
          "label": "Ruby sans frontend Node obligatoire",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Redmine : serveur Ruby et tâches Sidekiq avec assets Propshaft, sans frontend Node obligatoire ; création et mise à jour compatibles vérifiées."
        },
        {
          "id": "node_python_media_composition",
          "label": "Composition Node, Python et médias",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Immich : serveur et frontend Node, workers et traitement Python privé local, supervision commune et ressources bornées ; continuité des médias et nouvel import vérifiés."
        },
        {
          "id": "elixir_frontend",
          "label": "Elixir et frontend Node",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Plausible : release Elixir/OTP et frontend Node issus de Git avec PostgreSQL et ClickHouse privés ; même assemblage lors de la mise à jour compatible."
        },
        {
          "id": "snappymail_consumer",
          "label": "Réutilisation par SnappyMail",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "SnappyMail 2.38.2 maintenu : compte, session, contacts et messages conservés, puis nouvel envoi privé relu ; aucune migration fournisseur qualifiée."
        },
        {
          "id": "joomla_consumer",
          "label": "Réutilisation par Joomla",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Joomla 6.1.3 : création après correction iconv puis mise à jour compatible, compte, contenu, média et réservations conservés, nouvel article relu."
        },
        {
          "id": "typo3_consumer",
          "label": "Réutilisation par TYPO3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "TYPO3 14.3.7 : création et mise à jour compatibles, compte, session, pages, média et réservations conservés, puis nouvelle page publiée."
        },
        {
          "id": "node_mongodb_runtime_build",
          "label": "Composition Node/MongoDB et génération des assets",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "NodeBB : un processus web Node, une réservation de fichiers et une liaison MongoDB privée ; assets construits à chaque démarrage dans la zone privée du volume, composant emoji préparé depuis l’image en lecture seule et liens statiques vérifiés. Création et mise à jour compatibles depuis Git."
        }
      ],
      "dependencies": [],
      "consumers": [
        "N3-BOOKSTACK",
        "N3-CRYPTPAD",
        "N3-DISCOURSE",
        "N3-DRUPAL",
        "N3-ERPNEXT",
        "N3-FILEBROWSER",
        "N3-FRESHRSS",
        "N3-IMMICH",
        "N3-JOOMLA",
        "N3-LISTMONK",
        "N3-MEDIAWIKI",
        "N3-METABASE",
        "N3-MULTI-AGENT",
        "N3-NEXTCLOUD",
        "N3-NODEBB",
        "N3-OPEN-WEBUI",
        "N3-OPENCART",
        "N3-PLAUSIBLE",
        "N3-PRESTASHOP",
        "N3-REDMINE",
        "N3-ROUNDCUBE",
        "N3-SNAPPYMAIL",
        "N3-TYPO3"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n1-compose"
    },
    {
      "id": "N1-ELIXIR",
      "level": "N1",
      "slug": "elixir",
      "name": "Elixir / OTP",
      "summary": "Compiler depuis Git une release Elixir avec dépendances fermées et runtime OTP compatible.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Plausible CE 3.2.1 maintenu créé puis code client compatible mis à jour avec Elixir 1.19.5 et OTP 27.3.4.17.",
      "limitations": [
        "Profil publié de Plausible uniquement ; autres applications, versions et ABI non qualifiées.",
        "Le frontend Node est une composition explicite ; la release applicative n’est pas stockée dans le cache des dépendances.",
        "Toute modification de verrou exige un nouvel ensemble de dépendances publié et revu.",
        "Aucune migration du compilateur Elixir ou du runtime OTP qualifiée."
      ],
      "parameters": [
        {
          "name": "application_git",
          "label": "Sources Git",
          "description": "Dépôt complet du code client réellement compilé, avec sa révision et ses verrous."
        },
        {
          "name": "elixir_version",
          "label": "Version Elixir",
          "description": "Version publiée du compilateur Elixir compatible avec la release et ses dépendances."
        },
        {
          "name": "erlang_version",
          "label": "Version Erlang/OTP",
          "description": "Version exacte du runtime OTP dans le profil Elixir publié."
        },
        {
          "name": "node_version",
          "label": "Version Node.js",
          "description": "Version du runtime dans la publication sélectionnée ; toute migration majeure exige une preuve dédiée."
        },
        {
          "name": "dependency_snapshot_sha256",
          "label": "Empreinte des dépendances",
          "description": "Empreinte de l’ensemble de dépendances publié et vérifié avant construction."
        },
        {
          "name": "argv",
          "label": "Arguments d’exécution",
          "description": "Arguments explicites du programme dans le profil publié."
        },
        {
          "name": "port",
          "label": "Port applicatif",
          "description": "Port privé écouté par le programme ou le service."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Release Elixir de Plausible construite hors réseau depuis le code Git client complet et servie dans le parcours natif."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Nouveau module Elixir et template HEEX compilés depuis le même Git, verrous et ABI inchangés ; code compatible réellement exécuté."
        },
        {
          "id": "offline_git",
          "label": "Compilation Git hors réseau",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Six manifestes et verrous, 10 586 fichiers de dépendances scellés et arbre Git complet ; compilation avec réseau désactivé."
        },
        {
          "id": "inventory",
          "label": "Inventaires de dépendances",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Inventaires complets des deux constructions, 608 composants dont 160 paquets Hex, formats CycloneDX et SPDX ; aucun avis HIGH ou CRITICAL dans les scans observés."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N3-PLAUSIBLE"
      ],
      "versions": [
        {
          "from": "1.19.5 / OTP 27.3.4.17",
          "to": "1.19.5 / OTP 27.3.4.17",
          "label": "Versions constantes pendant la mise à jour compatible de Plausible",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n1-elixir"
    },
    {
      "id": "N1-GO",
      "level": "N1",
      "slug": "go",
      "name": "Go",
      "summary": "Construire des binaires Go reproductibles et les exécuter dans une image minimale.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Recettes Listmonk et File Browser Quantum créées et mises à jour avec compilateurs publiés.",
      "limitations": [
        "CGO désactivé et linux/amd64 ; autres architectures ou profils CGO non qualifiés.",
        "Node peut construire le frontend, puis disparaît de l’image Go finale.",
        "Une compilation réussie ne qualifie ni migration SQL, ni mise à jour du fournisseur, ni changement de compilateur d’un client."
      ],
      "parameters": [
        {
          "name": "go_version",
          "label": "Version Go",
          "description": "Version du compilateur déjà publiée pour la recette."
        },
        {
          "name": "module_root",
          "label": "Racine du module",
          "description": "Répertoire du module Go dans les sources."
        },
        {
          "name": "platform",
          "label": "Plateforme",
          "description": "Cible système et architecture de la publication choisie."
        },
        {
          "name": "binaries",
          "label": "Binaires",
          "description": "Programmes Go à compiler et inclure dans l’image finale."
        },
        {
          "name": "ldflags",
          "label": "Options d’édition de liens",
          "description": "Options admises pour produire les binaires Go."
        },
        {
          "name": "runtime_files",
          "label": "Fichiers d’exécution",
          "description": "Fichiers supplémentaires requis avec les binaires Go."
        },
        {
          "name": "entrypoint",
          "label": "Point d’entrée",
          "description": "Programme ou module démarré dans l’image finale."
        },
        {
          "name": "port",
          "label": "Port applicatif",
          "description": "Port privé écouté par le programme ou le service."
        },
        {
          "name": "go_mod",
          "label": "Manifeste Go",
          "description": "Manifeste du module Go issu des sources versionnées."
        },
        {
          "name": "go_sum",
          "label": "Empreintes Go",
          "description": "Empreintes attendues des dépendances Go."
        }
      ],
      "operations": [
        {
          "id": "prepare",
          "label": "Préparation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Modules et dépendances vendoriées contrôlés pour Listmonk et File Browser, sans exécution du code client pendant l’acquisition."
        },
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Binaires statiques Listmonk et File Browser servis avec leurs ports et montages propres."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mise à jour applicative avec mêmes compilateur, montages et raccordements dans chacun des deux profils."
        },
        {
          "id": "compiler_upgrade",
          "label": "Changement de compilateur",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Go 1.26.8 et 1.27.1 sont employés par des recettes distinctes ; aucun changement de compilateur d’un même client qualifié."
        },
        {
          "id": "configuration_contract",
          "label": "Contrat de configuration",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Plans bornés et vérifiés, paramètres lus depuis paas.toml ; code personnalisé conservé et aucun LLM sur les pushes qualifiés."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N3-FILEBROWSER",
        "N3-LISTMONK"
      ],
      "versions": [
        {
          "from": "1.26.8",
          "to": "1.26.8",
          "label": "Compilateur de Listmonk, inchangé pendant sa mise à jour",
          "qualification": "verified"
        },
        {
          "from": "1.27.1",
          "to": "1.27.1",
          "label": "Compilateur de File Browser, inchangé pendant sa mise à jour",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n1-go"
    },
    {
      "id": "N1-JVM",
      "level": "N1",
      "slug": "jvm",
      "name": "JVM / Java",
      "summary": "Compiler le code JVM depuis Git avec outils et dépendances épinglés, puis exécuter l’artefact produit.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Base Java et consommateur Metabase 0.63.18 créés puis mis à jour avec Java 25.0.4+7 et Clojure CLI 1.12.0.1488.",
      "limitations": [
        "linux/amd64 ; Maven, Gradle et autres versions Java/Clojure non qualifiés.",
        "Le frontend éventuel compose N1-NODE ; aucun processus Node supplémentaire dans le runtime JVM.",
        "Les 24 contrats de dépendances initiaux sont verrouillés ; changer les dépendances exige une nouvelle publication revue.",
        "Mémoire de compilation Java et Node entre 256 et 4 096 Mio, parallélisme de 1 à 8 ; limite du constructeur distincte, sans ressources implicites.",
        "Une compilation locale seule ne prouve pas une livraison métier ; aucun changement de version du compilateur qualifié."
      ],
      "parameters": [
        {
          "name": "java_version",
          "label": "Version Java",
          "description": "Version publiée du compilateur et du runtime JVM."
        },
        {
          "name": "dependency_tool",
          "label": "Outil de dépendances JVM",
          "description": "Outil publié avec le profil JVM ; les autres outils nécessitent leur propre qualification."
        },
        {
          "name": "dependency_snapshot_sha256",
          "label": "Empreinte des dépendances",
          "description": "Empreinte de l’ensemble de dépendances publié et vérifié avant construction."
        },
        {
          "name": "dependency_patch_sha256",
          "label": "Empreinte des correctifs",
          "description": "Empreinte des correctifs explicites appliqués aux dépendances publiées."
        },
        {
          "name": "commands",
          "label": "Commandes de construction",
          "description": "Commandes admises dans le profil et exécutées sur les sources versionnées."
        },
        {
          "name": "artifact",
          "label": "Artefact JVM",
          "description": "Artefact issu de la construction contrôlée puis exécuté par le runtime."
        },
        {
          "name": "argv",
          "label": "Arguments d’exécution",
          "description": "Arguments explicites du programme dans le profil publié."
        },
        {
          "name": "port",
          "label": "Port applicatif",
          "description": "Port privé écouté par le programme ou le service."
        },
        {
          "name": "platform",
          "label": "Plateforme",
          "description": "Cible système et architecture de la publication choisie."
        },
        {
          "name": "build_java_heap_mb",
          "label": "Mémoire Java de construction",
          "description": "Taille du tas Java entre 256 et 4 096 Mio, dans la limite distincte du constructeur."
        },
        {
          "name": "build_node_heap_mb",
          "label": "Mémoire Node de construction",
          "description": "Taille du tas Node entre 256 et 4 096 Mio, dans la limite distincte du constructeur."
        },
        {
          "name": "build_parallelism",
          "label": "Parallélisme de construction",
          "description": "De 1 à 8 tâches de compilation, sans réservation de ressources implicite."
        }
      ],
      "operations": [
        {
          "id": "prepare",
          "label": "Préparation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Export Git borné et dépendances vérifiées hors réseau, puis construction complète et livraison native du consommateur Metabase."
        },
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Base Java construite hors réseau et Metabase compilé depuis Git avec frontend incorporé ; compte, question SQL et tableau de bord vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Deux artefacts de la base Java exercés, puis mise à jour compatible de Metabase : même ensemble de dépendances et services, code client modifié réellement servi sans appel LLM."
        },
        {
          "id": "compiler_upgrade",
          "label": "Changement de compilateur",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune montée de version Java ou Clojure d’un consommateur existant qualifiée."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N3-METABASE"
      ],
      "versions": [
        {
          "from": "25.0.4+7",
          "to": "25.0.4+7",
          "label": "Java constant ; Clojure CLI 1.12.0.1488, mise à jour du code client uniquement",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n1-jvm"
    },
    {
      "id": "N1-NODE",
      "level": "N1",
      "slug": "node",
      "name": "Node.js",
      "summary": "Construire et exécuter des applications Node avec des dépendances verrouillées et un gestionnaire publié.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Recettes Node, espaces de travail et frontends de construction vérifiés avec leurs paramètres publiés.",
      "limitations": [
        "Une recette glibc ne démontre pas la compatibilité d’un binaire natif avec musl.",
        "Les anciennes recettes restent historiques et doivent satisfaire les contrôles actuels pour être admises.",
        "Les scans conservent leur portée historique ; les métadonnées système doivent être présentes.",
        "Aucune migration majeure de Node ou du système qualifiée ; une version reste un paramètre du même N1."
      ],
      "parameters": [
        {
          "name": "archive_profile",
          "label": "Profil d’archive",
          "description": "Limites et règles de sécurité des archives explicitement admises."
        },
        {
          "name": "build_command",
          "label": "Commande de construction",
          "description": "Commande versionnée exécutée dans le profil de construction accepté."
        },
        {
          "name": "build_outputs",
          "label": "Sorties de construction",
          "description": "Fichiers ou répertoires à conserver dans l’image finale."
        },
        {
          "name": "complete_package_lock",
          "label": "Verrou complet des paquets",
          "description": "Graphe complet des dépendances, y compris les espaces de travail."
        },
        {
          "name": "dependency_lock",
          "label": "Verrou des dépendances",
          "description": "Versions et empreintes des dépendances réellement utilisées."
        },
        {
          "name": "embedded_archives",
          "label": "Archives embarquées",
          "description": "Archives fournies avec les sources et contrôlées avant leur utilisation."
        },
        {
          "name": "git_archives",
          "label": "Archives de dépendances Git",
          "description": "Archives Git épinglées par révision et empreinte dans l’ensemble de dépendances admis."
        },
        {
          "name": "healthcheck",
          "label": "Sonde de santé",
          "description": "Sonde définie par la recette ; son succès ne remplace pas les vérifications métier."
        },
        {
          "name": "lock_mode",
          "label": "Mode du verrou",
          "description": "Mode de lecture ou d’adaptation explicitement autorisé du verrou de dépendances."
        },
        {
          "name": "lock_patch_sha256",
          "label": "Empreinte d’adaptation du verrou",
          "description": "Empreinte du changement exact admis, sans résolution libre des dépendances."
        },
        {
          "name": "native_modules",
          "label": "Modules natifs",
          "description": "Dépendances binaires dont l’ABI et les bibliothèques doivent être compatibles."
        },
        {
          "name": "node_version",
          "label": "Version Node.js",
          "description": "Version du runtime dans la publication sélectionnée ; toute migration majeure exige une preuve dédiée."
        },
        {
          "name": "npm_version",
          "label": "Version npm",
          "description": "Version du gestionnaire npm publiée avec le profil."
        },
        {
          "name": "os_abi",
          "label": "ABI système",
          "description": "Compatibilité du système et des bibliothèques natives sélectionnées."
        },
        {
          "name": "package_manager",
          "label": "Gestionnaire de paquets",
          "description": "Gestionnaire de dépendances explicitement admis par la recette publiée, avec sa version et son verrou."
        },
        {
          "name": "package_manager_version",
          "label": "Version du gestionnaire",
          "description": "Version exacte du gestionnaire de paquets dans le profil publié."
        },
        {
          "name": "package_manifest",
          "label": "Manifeste des paquets",
          "description": "Manifestes des paquets inclus dans les sources versionnées."
        },
        {
          "name": "port",
          "label": "Port applicatif",
          "description": "Port privé écouté par le programme ou le service."
        },
        {
          "name": "recipe_id",
          "label": "Recette",
          "description": "Identifiant d’une recette effectivement publiée par le produit."
        },
        {
          "name": "recipe_version",
          "label": "Version de recette",
          "description": "Version de recette distincte de la version de logiciel et du contrat d’inventaire."
        },
        {
          "name": "registry_snapshot_sha256",
          "label": "Empreinte du registre de paquets",
          "description": "Empreinte du contenu de registre admis pour préparer les dépendances hors réseau."
        },
        {
          "name": "runtime_libraries",
          "label": "Bibliothèques d’exécution",
          "description": "Bibliothèques publiées présentes dans l’image finale."
        },
        {
          "name": "start_command",
          "label": "Commande de démarrage",
          "description": "Commande du programme après construction de l’image."
        },
        {
          "name": "workspace_metadata",
          "label": "Métadonnées des workspaces",
          "description": "Relations entre espaces de travail admises avec le verrou complet."
        },
        {
          "name": "workspace_roots",
          "label": "Racines des workspaces",
          "description": "Répertoires des espaces de travail versionnés et construits."
        }
      ],
      "operations": [
        {
          "id": "build",
          "label": "Construction",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Constructions hors réseau avec dépendances verrouillées pour Strapi, Ghost, Etherpad, Umami, LibreChat et frontends composés."
        },
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Runtime Node minimal avec point d’entrée, port et sonde définis par le consommateur."
        },
        {
          "id": "upgrade_recipe",
          "label": "Mise à jour de recette",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Changements de recettes et de gestionnaires vérifiés dans les mises à jour applicatives ; runtime Node conservé pour chaque client."
        },
        {
          "id": "upgrade_major",
          "label": "Migration majeure",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucun changement de version majeure de Node qualifié."
        },
        {
          "id": "base_without_services",
          "label": "Base sans service implicite",
          "status": "unit_verified",
          "status_label": "Testé en unité",
          "scope": "La base seule ne réserve ni base SQL ni stockage applicatif ; comportement testé en unité."
        },
        {
          "id": "npm_workspaces",
          "label": "Espaces de travail npm",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Six espaces de travail npm de LibreChat construits hors réseau avec verrou complet et métadonnées contrôlées."
        },
        {
          "id": "configuration_contract",
          "label": "Contrat de configuration",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Version, gestionnaire et espaces de travail configurés dans N3 sans dupliquer N1-NODE ; création et mise à jour par Git observées."
        },
        {
          "id": "npm_source_git",
          "label": "Dépendances npm issues de Git",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "CryptPad : verrou npm original, registre et archives Git épinglés, construction hors réseau et adaptation exacte du graphe ; création et mise à jour compatibles vérifiées. NodeBB 4.16.0 réutilise Node 24.20.0 et npm 11.19.0 avec le verrou du Git client : les scripts non exécutés restent contrôlés sur leurs violations, le build sélectionné garde ses contrôles et les attributs Git amont sont exportés comme données inertes."
        },
        {
          "id": "bun_frontend",
          "label": "Frontend construit avec Bun",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Metabase : Node 24.20.0 et Bun 1.3.14 pour construire le frontend, verrou, cache et correctifs explicites ; aucun processus Node dans le runtime JVM final."
        },
        {
          "id": "node_python_closed_composition",
          "label": "Dépendances fermées Node et Python",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Immich : Node 24.20.0, pnpm 11.22 et Python 3.12.14 avec verrous, ABI et modèles privés publiés ; code client compilé hors réseau, création et mise à jour compatibles qualifiées."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N3-CRYPTPAD",
        "N3-DISCOURSE",
        "N3-ERPNEXT",
        "N3-ETHERPAD",
        "N3-FILEBROWSER",
        "N3-GHOST",
        "N3-IMMICH",
        "N3-LIBRECHAT",
        "N3-LISTMONK",
        "N3-METABASE",
        "N3-MULTI-AGENT",
        "N3-NODEBB",
        "N3-OPEN-WEBUI",
        "N3-PLAUSIBLE",
        "N3-STRAPI",
        "N3-UMAMI"
      ],
      "versions": [
        {
          "from": "22.23.2",
          "to": "22.23.2",
          "label": "Runtime Ghost ; pnpm 12.2.1 → 12.4.0",
          "qualification": "verified"
        },
        {
          "from": "24.20.0",
          "to": "24.20.0",
          "label": "Node conservé pour les autres profils publiés ; gestionnaire selon recette",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n1-node"
    },
    {
      "id": "N1-PERSIST",
      "level": "N1",
      "slug": "persist",
      "name": "Persistance",
      "summary": "Associer volumes, montages et permissions aux applications et services consommateurs.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Raccordement et conservation des données des recettes qualifiées.",
      "limitations": [
        "Les chemins partagés utilisent les mêmes allocations, sans double comptage.",
        "Un statut de sauvegarde terminé ne prouve pas une restauration.",
        "La copie de révision reste sur le même volume ; sa qualification n’implique ni export externe ni instantané conjoint avec une base SQL."
      ],
      "parameters": [
        {
          "name": "volume_refs",
          "label": "Volumes",
          "description": "Références des volumes persistants raccordés au consommateur."
        },
        {
          "name": "container_refs",
          "label": "Conteneurs",
          "description": "Références des conteneurs composés par le module."
        },
        {
          "name": "mounts",
          "label": "Montages",
          "description": "Association explicite des volumes et des chemins consommateurs."
        },
        {
          "name": "ownership",
          "label": "Droits des fichiers",
          "description": "Propriétaires et permissions des montages persistants."
        },
        {
          "name": "retention",
          "label": "Conservation",
          "description": "Politique de conservation des données après changement de consommateur."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Raccordement des médias, fichiers et données privées aux volumes des consommateurs qualifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mêmes identités de stockage et anciennes données relues après mise à jour ; nouvelles écritures vérifiées."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Restauration complète non qualifiée."
        },
        {
          "id": "cold_revision_backup",
          "label": "Copie avant changement de révision",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Copie avant démarrage avec un seul écrivain : limites de 2 Gio, 100 000 fichiers et profondeur 32, empreintes source/copie et révisions vérifiées. Copie native sur le même volume ; export et restauration non qualifiés par cette opération."
        },
        {
          "id": "snappymail_consumer",
          "label": "Réutilisation par SnappyMail",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "SnappyMail : compte, session, contacts, messages et stockage conservés après mise à jour ; nouvel envoi privé relu."
        },
        {
          "id": "joomla_consumer",
          "label": "Réutilisation par Joomla",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Joomla : compte, articles, média et stockage conservés ; exports privés et archive préalable vérifiés, SQL et fichiers séparés."
        },
        {
          "id": "typo3_consumer",
          "label": "Réutilisation par TYPO3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "TYPO3 : réservations, données, image et session conservées, nouvelle page publiée ; aucun agrandissement ni restauration qualifié."
        },
        {
          "id": "node_runtime_export",
          "label": "Export de fichiers depuis un runtime Node",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Export de fichiers et répertoires depuis un runtime Node sans outil d’archive supplémentaire, chemins régénérables exclus et liens refusés. NodeBB : 12 puis 21 fichiers, propriétaire et image connue vérifiés avant et après la mise à jour ; export vivant non transactionnel, aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N0-VOLUME",
        "N0-CONTAINER"
      ],
      "consumers": [
        "N2-CLICKHOUSE",
        "N2-IMAP",
        "N2-INFERENCE",
        "N2-MONGODB",
        "N2-MYSQL",
        "N2-POSTGRESQL",
        "N2-REDIS",
        "N3-BOOKSTACK",
        "N3-CRYPTPAD",
        "N3-DISCOURSE",
        "N3-DOKUWIKI",
        "N3-DRUPAL",
        "N3-ERPNEXT",
        "N3-FILEBROWSER",
        "N3-FLARUM",
        "N3-FRESHRSS",
        "N3-GHOST",
        "N3-IMMICH",
        "N3-JOOMLA",
        "N3-KANBOARD",
        "N3-LIBRECHAT",
        "N3-LISTMONK",
        "N3-MEDIAWIKI",
        "N3-MULTI-AGENT",
        "N3-NEXTCLOUD",
        "N3-NODEBB",
        "N3-ODOO",
        "N3-OPEN-WEBUI",
        "N3-OPENCART",
        "N3-PIWIGO",
        "N3-PLAUSIBLE",
        "N3-PRESTASHOP",
        "N3-REDMINE",
        "N3-ROUNDCUBE",
        "N3-SNAPPYMAIL",
        "N3-STRAPI",
        "N3-TYPO3",
        "N3-WAGTAIL",
        "N3-WOOCOMMERCE",
        "N3-WORDPRESS"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n1-persist"
    },
    {
      "id": "N1-PHP",
      "level": "N1",
      "slug": "php",
      "name": "PHP",
      "summary": "Construire depuis Git et servir du PHP avec les extensions et paramètres d’une recette publiée.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "PHP/Apache avec distributions Git, Composer verrouillé, SQLite, tâches périodiques, calendar, GNU iconv et Imagick dans les profils publiés jusqu’à PHP 17.",
      "limitations": [
        "Aucune acquisition Composer automatique ni exécution de ses scripts ; dépendances fournies dans Git et contrôlées.",
        "Les modifications depuis un CMS ne changent pas la source Git ; publier code et extensions par Git.",
        "linux/amd64 uniquement ; composition de plusieurs langages dans une même racine non prise en charge.",
        "Le mode de bibliothèques embarquées exige le contrat publié ; il ne simule pas une résolution Composer.",
        "Les relais de confiance sont des adresses explicitement configurées ; aucun réseau entier n’est automatiquement approuvé.",
        "Migration de PHP/Apache non vérifiée ; les numéros de publication PHP sont des versions de recettes."
      ],
      "parameters": [
        {
          "name": "source_commit",
          "label": "Commit source",
          "description": "Révision Git exacte à construire, contrôler et servir."
        },
        {
          "name": "source_tree",
          "label": "Arbre source",
          "description": "Fichiers réellement fournis par la révision Git du client."
        },
        {
          "name": "recipe_id",
          "label": "Recette",
          "description": "Identifiant d’une recette effectivement publiée par le produit."
        },
        {
          "name": "recipe_version",
          "label": "Version de recette",
          "description": "Version de recette distincte de la version de logiciel et du contrat d’inventaire."
        },
        {
          "name": "platform",
          "label": "Plateforme",
          "description": "Cible système et architecture de la publication choisie."
        },
        {
          "name": "test_command",
          "label": "Commande de tests",
          "description": "Tests déclarés dans la configuration et exécutés avant la publication."
        },
        {
          "name": "resources",
          "label": "Ressources",
          "description": "Enveloppes CPU, mémoire et stockage prévues par le profil."
        },
        {
          "name": "composer_lock",
          "label": "Verrou Composer",
          "description": "Contrat des dépendances PHP fourni dans Git et contrôlé à la construction."
        },
        {
          "name": "vendor_ledger",
          "label": "Inventaire des bibliothèques",
          "description": "Empreintes des bibliothèques PHP effectivement fournies dans Git."
        },
        {
          "name": "http_private_paths",
          "label": "Chemins HTTP privés",
          "description": "Chemins dont la recette refuse l’exposition HTTP."
        },
        {
          "name": "extensions",
          "label": "Extensions PHP",
          "description": "Extensions proposées par la publication PHP sélectionnée."
        },
        {
          "name": "source_archive_contract",
          "label": "Contrat d’archive source",
          "description": "Structure et limites explicitement admises pour les sources PHP complètes."
        },
        {
          "name": "http_persistent_public_paths",
          "label": "Médias publics persistants",
          "description": "Chemins HTTP de données persistantes que la recette autorise à exposer."
        },
        {
          "name": "document_root",
          "label": "Racine publique",
          "description": "Répertoire servi par HTTP parmi ceux admis par la recette PHP."
        },
        {
          "name": "development_manifests",
          "label": "Manifestes de développement",
          "description": "Manifestes des outils de construction distincts des dépendances de production."
        },
        {
          "name": "dependency_mode",
          "label": "Mode des dépendances",
          "description": "Mode de fourniture des bibliothèques prévu par la recette publiée."
        },
        {
          "name": "scheduled_tasks",
          "label": "Tâches périodiques",
          "description": "Tâches prévues par la recette PHP publiée, avec durée et arrêt contrôlés."
        },
        {
          "name": "source_environment_files",
          "label": "Modèles d’environnement",
          "description": "Fichiers publics fournis dans les sources et épinglés ; aucun secret de production n’y est ajouté."
        },
        {
          "name": "jar_identities",
          "label": "Identités des archives JAR",
          "description": "Empreintes et métadonnées explicites des archives distribuées ; les classes restent inchangées."
        },
        {
          "name": "trusted_proxy_addresses",
          "label": "Relais de confiance",
          "description": "Adresses de relais explicitement admises pour déterminer le client, sans confiance implicite."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "PHP 8.4.25 avec Apache 2.4.68 et extensions publiées : création des applications PHP depuis leurs sources Git contrôlées."
        },
        {
          "id": "preserve_during_n3_upgrade",
          "label": "Conservation pendant la mise à jour N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même runtime et mêmes dépendances persistantes pendant les mises à jour applicatives qualifiées, notamment PrestaShop, Nextcloud et MediaWiki."
        },
        {
          "id": "upgrade_runtime",
          "label": "Migration du runtime",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Changement de version PHP/Apache à qualifier séparément."
        },
        {
          "id": "php_sqlite_periodic",
          "label": "PHP, SQLite et tâches périodiques",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Publication PHP 5 : SQLite, intl, pcntl, racine publique p et bibliothèques Git ; création et mise à jour compatible de FreshRSS vérifiées."
        },
        {
          "id": "composer_locked_git",
          "label": "Dépendances Composer verrouillées dans Git",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Roundcube : dépendances de production comparées au verrou et à leur inventaire, fichiers Git vérifiés et racine publique déclarée ; même base PHP."
        },
        {
          "id": "drupal_locked_git",
          "label": "Sources Drupal verrouillées",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Drupal : Composer exact, sources bornées à 30 000 fichiers et 4 Mio par fichier, adaptation du contrôleur HTTP limitée aux ressources statiques ; session, polices et refus d’exécuter PHP dans les médias vérifiés."
        },
        {
          "id": "composer_distribution_git",
          "label": "Distribution PHP complète dans Git",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "PrestaShop : distribution Git complète, dépendances de production exactes même sans manifeste racine, langues immuables et modèles publics épinglés ; limites explicites de 50 000 fichiers, 512 Mio au total et 8 Mio par fichier."
        },
        {
          "id": "jar_artifact_identity",
          "label": "Identité des archives distribuées",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Archives distribuées identifiées par empreinte : seule leur métadonnée de version est ajustée, classes intactes et originaux conservés hors exécution ; inventaire et admission complets exigés."
        },
        {
          "id": "trusted_proxy_transport",
          "label": "Transport via des relais déclarés",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Relais IPv4/IPv6 explicitement déclarés, adresse client résolue sans confiance implicite ; sessions, connexions répétées et navigation PrestaShop conservées."
        },
        {
          "id": "composer_layout_git",
          "label": "Inventaires PHP de distribution",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Nextcloud : 42 inventaires et verrous concordants, cinq inventaires sans verrou amont explicitement conservés, fichiers et licences contrôlés ; réutilisation aussi vérifiée par MediaWiki."
        },
        {
          "id": "calendar_php",
          "label": "Extension calendar",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Publication PHP 15 : extension calendar ajoutée à la base partagée, dépendances MediaWiki verrouillées et usages Parsoid/VisualEditor vérifiés ; anciennes recettes conservées."
        },
        {
          "id": "compressed_plan_transport",
          "label": "Transport compressé du plan",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Plan PHP compressé dès 16 Kio avec mêmes bornes et empreinte exacte ; matérialisation complète et nouvelles constructions vérifiées."
        },
        {
          "id": "snappymail_consumer",
          "label": "Réutilisation par SnappyMail",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "SnappyMail 2.38.2 maintenu : création et mise à jour compatibles avec compte, contacts, messages privés et session conservés, puis nouvel envoi relu."
        },
        {
          "id": "gnu_iconv",
          "label": "Conversions GNU iconv",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Publication PHP 16, variante iconv-v7 : conversions GNU libiconv 1.18 réelles avec PHP 8.4.25 ; anciennes images et recettes conservées."
        },
        {
          "id": "joomla_consumer",
          "label": "Réutilisation par Joomla",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Joomla 6.1.3 sur iconv-v7 : création réparée, édition native, médias, session et nouvel article après mise à jour compatibles vérifiés ; anciens consommateurs conservés."
        },
        {
          "id": "typo3_consumer",
          "label": "Réutilisation par TYPO3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "TYPO3 14.3.7 sur la publication PHP 17, variante imagick-v8 : pages, médias et session conservés, nouvelle page publiée ; quatorze recettes PHP historiques inchangées."
        },
        {
          "id": "imagick",
          "label": "Traitement d’images Imagick",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "PHP 8.4.25 avec Imagick 3.8.1 et ImageMagick 7.1.2.30 : construction hors réseau, exécution non privilégiée, redimensionnement et miniatures TYPO3 vérifiés."
        },
        {
          "id": "opencart_consumer",
          "label": "Réutilisation par OpenCart",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "OpenCart 4.1.0.4 réutilise la publication PHP 17 et iconv-v7 : racine upload, dépendances fermées et définition de construction amont épinglée ; création et mise à jour compatibles vérifiées."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N3-BOOKSTACK",
        "N3-DOKUWIKI",
        "N3-DRUPAL",
        "N3-FLARUM",
        "N3-FRESHRSS",
        "N3-JOOMLA",
        "N3-KANBOARD",
        "N3-MEDIAWIKI",
        "N3-NEXTCLOUD",
        "N3-OPENCART",
        "N3-PIWIGO",
        "N3-PRESTASHOP",
        "N3-ROUNDCUBE",
        "N3-SNAPPYMAIL",
        "N3-TYPO3",
        "N3-WOOCOMMERCE",
        "N3-WORDPRESS"
      ],
      "versions": [
        {
          "from": "8.4.25",
          "to": "8.4.25",
          "label": "PHP inchangé ; Apache 2.4.68, variantes de recettes jusqu’à PHP 17 sans migration du runtime",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n1-php"
    },
    {
      "id": "N1-PYTHON",
      "level": "N1",
      "slug": "python",
      "name": "Python",
      "summary": "Exécuter du Python avec un interpréteur, une ABI et des dépendances binaires fermées.",
      "contract_version": "1.0.0",
      "status": "partial",
      "status_label": "Partiel",
      "scope": "Consommateurs Odoo, Wagtail, ERPNext et composition Immich vérifiés ; recette autonome bloquée et profil Open WebUI partiel.",
      "limitations": [
        "Les ABI cp312, cp313 et musllinux ne sont pas interchangeables.",
        "Les outils de construction restent distincts du contenu signé de l’image de production.",
        "Le contrat d’archive doit être admis explicitement et borne le transport à une archive et seize parties.",
        "La construction d’Open WebUI ne qualifie pas son accès utilisateur : le scan bloque sa promotion."
      ],
      "parameters": [
        {
          "name": "python_version",
          "label": "Version Python",
          "description": "Version de l’interpréteur publiée et compatible avec les dépendances."
        },
        {
          "name": "abi",
          "label": "ABI Python",
          "description": "Interface binaire explicitement compatible avec la recette et ses dépendances."
        },
        {
          "name": "libc",
          "label": "Bibliothèque système",
          "description": "Famille de bibliothèque système compatible avec les binaires de la recette."
        },
        {
          "name": "wheel_manifest",
          "label": "Manifeste Python",
          "description": "Liste des paquets binaires Python et de leurs empreintes admises."
        },
        {
          "name": "requirements_lock",
          "label": "Verrou Python",
          "description": "Versions et empreintes des dépendances Python admises."
        },
        {
          "name": "entrypoint",
          "label": "Point d’entrée",
          "description": "Programme ou module démarré dans l’image finale."
        },
        {
          "name": "pythonpath",
          "label": "Chemins Python",
          "description": "Chemins de modules déclarés pour le programme exécuté."
        },
        {
          "name": "runtime_distribution",
          "label": "Distribution d’exécution",
          "description": "Distribution exacte de l’image de production."
        },
        {
          "name": "source_archives",
          "label": "Archives source",
          "description": "Archives verrouillées des sources, admises par le profil de construction."
        },
        {
          "name": "cpu_wheel_profile",
          "label": "Profil Python CPU",
          "description": "Dépendances binaires CPU et ABI admises, sans qualification GPU implicite."
        },
        {
          "name": "frontend_manifest",
          "label": "Manifeste du frontend",
          "description": "Description des assets construits et assemblés au backend."
        },
        {
          "name": "archive_profile",
          "label": "Profil d’archive",
          "description": "Limites et règles de sécurité des archives explicitement admises."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Runtimes Python observés dans les recettes consommatrices, avec dépendances binaires contrôlées."
        },
        {
          "id": "standalone_recipe",
          "label": "Recette autonome",
          "status": "blocked",
          "status_label": "Bloqué",
          "scope": "Recette Python autonome bloquée ; ne pas l’assimiler aux recettes N3 qualifiées."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mises à jour des consommateurs Python qualifiées dans leurs versions et ABI propres."
        },
        {
          "id": "automatic_git",
          "label": "Parcours Git",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Parcours Git et dépendances fermées exercés par les recettes Python publiées."
        },
        {
          "id": "source_archives",
          "label": "Archives source",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Archives source complètes et bornées contrôlées pour les consommateurs qualifiés."
        },
        {
          "id": "cpu_frontend_profile",
          "label": "Profil CPU et frontend",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Backend CPU et frontend Open WebUI construits ; qualification partielle car le scan refuse la promotion."
        },
        {
          "id": "composite_python_node",
          "label": "Construction Python et Node",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "ERPNext : Python 3.14.7 et Node 24.20.0, 147 paquets Python et cache Yarn fermés, compilation hors réseau du code client ; données conservées et nouvelles écritures, sans migration majeure du runtime."
        },
        {
          "id": "node_python_closed_composition",
          "label": "Dépendances fermées Node et Python",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Immich : Python 3.12.14 et Node 24.20.0 avec verrous, ABI et modèles privés publiés ; code client construit hors réseau, création et mise à jour compatibles vérifiées."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N3-ERPNEXT",
        "N3-IMMICH",
        "N3-MULTI-AGENT",
        "N3-ODOO",
        "N3-OPEN-WEBUI",
        "N3-WAGTAIL"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n1-python"
    },
    {
      "id": "N1-RUBY",
      "level": "N1",
      "slug": "ruby",
      "name": "Ruby",
      "summary": "Compiler le code Ruby client depuis des gems publiées et l’exécuter avec la même ABI.",
      "contract_version": "1.1.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Ruby 3.4.10 et Bundler 4.0.11 pour Discourse et Redmine ; frontend Node facultatif selon le consommateur.",
      "limitations": [
        "Profils Discourse 2026.8.0 maintenu et Redmine 7.0.1 uniquement ; applications Ruby arbitraires et autres ABI non qualifiées.",
        "Une architecture commune ne rend pas les extensions natives de distributions différentes compatibles.",
        "Chaque nouvelle dépendance ou manifeste exige un ensemble fermé publié et une qualification ; les incidents et compteurs antérieurs restent conservés.",
        "Images et paquets sont épinglés et hachés ; aucune migration de version Ruby qualifiée."
      ],
      "parameters": [
        {
          "name": "ruby_version",
          "label": "Version Ruby",
          "description": "Version publiée de Ruby et ABI commune à la compilation et à l’exécution."
        },
        {
          "name": "bundler_version",
          "label": "Version Bundler",
          "description": "Version publiée de l’outil qui prépare les dépendances Ruby verrouillées."
        },
        {
          "name": "dependency_snapshot_sha256",
          "label": "Empreinte des dépendances",
          "description": "Empreinte de l’ensemble de dépendances publié et vérifié avant construction."
        },
        {
          "name": "application_git",
          "label": "Sources Git",
          "description": "Dépôt complet du code client réellement compilé, avec sa révision et ses verrous."
        },
        {
          "name": "commands",
          "label": "Commandes de construction",
          "description": "Commandes admises dans le profil et exécutées sur les sources versionnées."
        },
        {
          "name": "argv",
          "label": "Arguments d’exécution",
          "description": "Arguments explicites du programme dans le profil publié."
        },
        {
          "name": "node_frontend",
          "label": "Frontend Node facultatif",
          "description": "Composition explicite avec Node si le consommateur Ruby nécessite une construction frontend."
        },
        {
          "name": "build_environment",
          "label": "Environnement de construction",
          "description": "Paramètres de construction admis par la recette Ruby ; les secrets restent privés."
        },
        {
          "name": "development_directories",
          "label": "Répertoires de développement",
          "description": "Répertoires exclus de l’image finale selon une liste bornée, avec sources complètes conservées pendant la construction."
        },
        {
          "name": "development_packages",
          "label": "Paquets de développement",
          "description": "Paquets réservés à la construction et distingués des dépendances de production."
        },
        {
          "name": "bundle_without",
          "label": "Groupes Bundler exclus",
          "description": "Groupes de dépendances exclus selon le contrat ; les gems nécessaires à la production restent présentes."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Ruby et Bundler exercés sur base vierge puis par la création native de Discourse ; variante Redmine sans frontend Node obligatoire, dépendances de production et fuseaux horaires conservés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Vrai code Ruby, vue et asset client compilés hors réseau et exécutés ; données conservées dans Discourse et Redmine, sans changement d’ABI ni de version Ruby."
        },
        {
          "id": "offline_git",
          "label": "Compilation Git hors réseau",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Sources Git complètes et caches scellés : 86 entrées et 99 799 fichiers pour Discourse, six entrées et 6 777 fichiers pour Redmine ; modifications non admises et liens sortants refusés."
        },
        {
          "id": "production_packaging",
          "label": "Contenu de production",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Gems, extensions, exécutables et assets nécessaires gardés dans l’image finale non privilégiée ; dépendances de développement explicitement bornées, scan sans exclusion, net-ldap et fuseaux horaires Redmine conservés."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N3-DISCOURSE",
        "N3-REDMINE"
      ],
      "versions": [
        {
          "from": "3.4.10",
          "to": "3.4.10",
          "label": "Ruby constant avec Bundler 4.0.11 ; contrat d’inventaire 1.1.0 distinct",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n1-ruby"
    },
    {
      "id": "N1-SERVICE",
      "level": "N1",
      "slug": "service",
      "name": "Modèle de service",
      "summary": "Décrire le runtime ou le raccordement externe d’un fournisseur de service N2.",
      "contract_version": "1.0.0",
      "status": "unit_verified",
      "status_label": "Testé en unité",
      "scope": "Préparation testée en unité et réutilisation observée par TYPO3 ; runtime applicatif autonome non implémenté.",
      "limitations": [
        "Des services N2 opérationnels n’ajoutent pas implicitement ce modèle au résolveur applicatif.",
        "Les caractéristiques physiques inconnues restent inconnues.",
        "Les fournisseurs MongoDB et inférence observés ne prouvent pas un provisionnement automatique de nouveaux fournisseurs par l’API."
      ],
      "parameters": [
        {
          "name": "container_refs",
          "label": "Conteneurs",
          "description": "Références des conteneurs composés par le module."
        },
        {
          "name": "external_binding_ref",
          "label": "Fournisseur existant",
          "description": "Référence du service existant ; ne déclenche pas un nouveau fournisseur implicite."
        },
        {
          "name": "external_binding_evidence_sha256",
          "label": "Empreinte du raccordement",
          "description": "Empreinte de la preuve d’un fournisseur externe déjà observé."
        }
      ],
      "operations": [
        {
          "id": "prepare",
          "label": "Préparation",
          "status": "unit_verified",
          "status_label": "Testé en unité",
          "scope": "Description des conteneurs ou du raccordement externe avec preuves, testée en unité."
        },
        {
          "id": "standalone_runtime",
          "label": "Runtime autonome",
          "status": "not_implemented",
          "status_label": "Non implémenté",
          "scope": "Aucune offre d’exécution applicative autonome implémentée pour ce modèle."
        },
        {
          "id": "typo3_consumer",
          "label": "Réutilisation par TYPO3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "TYPO3 : création et mise à jour compatibles avec réservations et données conservées ; cette réutilisation ne qualifie pas un runtime SERVICE autonome."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N2-CLICKHOUSE",
        "N2-IMAP",
        "N2-INFERENCE",
        "N2-MONGODB",
        "N2-MYSQL",
        "N2-POSTGRESQL",
        "N2-REDIS"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n1-service"
    },
    {
      "id": "N1-STATIC",
      "level": "N1",
      "slug": "static",
      "name": "Fichiers statiques",
      "summary": "Construire puis servir les fichiers publics d’un frontend.",
      "contract_version": "1.0.0",
      "status": "partial",
      "status_label": "Partiel",
      "scope": "Frontends de Multi-Agent, ERPNext, Discourse, Redmine et Immich observés ; recette autonome implémentée, mise à jour autonome non vérifiée.",
      "limitations": [
        "Le frontend de Multi-Agent est intégré à son serveur web ; aucun troisième serveur n’est obligatoire.",
        "La présence d’une recette autonome ne constitue pas sa qualification complète en mise à jour."
      ],
      "parameters": [
        {
          "name": "build_output",
          "label": "Sortie de construction",
          "description": "Répertoire des fichiers statiques produits par la construction."
        },
        {
          "name": "public_runtime_configuration",
          "label": "Configuration publique",
          "description": "Paramètres de frontend pouvant être exposés au navigateur, sans secret."
        },
        {
          "name": "serving_profile",
          "label": "Profil HTTP",
          "description": "Profil publié pour servir les fichiers statiques."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Frontend statique de Multi-Agent servi avec le web ; assets et continuité observés dans ERPNext, Discourse, Redmine et Immich."
        },
        {
          "id": "standalone_recipe",
          "label": "Recette autonome",
          "status": "implemented",
          "status_label": "Implémenté, qualification à compléter",
          "scope": "Recette statique autonome implémentée ; portée de qualification à compléter."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Réutilisation par ERPNext observée ; mise à jour autonome et mise à jour du frontend Multi-Agent non qualifiées."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N3-DISCOURSE",
        "N3-ERPNEXT",
        "N3-IMMICH",
        "N3-MULTI-AGENT",
        "N3-OPEN-WEBUI",
        "N3-REDMINE"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n1-static"
    },
    {
      "id": "N1-WORKER",
      "level": "N1",
      "slug": "worker",
      "name": "Processus de fond",
      "summary": "Exécuter des processus de fond ou des tâches périodiques avec des limites explicites.",
      "contract_version": "1.0.0",
      "status": "partial",
      "status_label": "Partiel",
      "scope": "Processus de fond et tâche PHP périodique observés, réutilisation dans ERPNext, MediaWiki, Discourse, Redmine et Immich ; tâche du moteur Multi-Agent bloquée.",
      "limitations": [
        "Un processus démarré ou une version d’outil ne prouvent pas une tâche agent réussie.",
        "Les profils privés proviennent de l’authentification normale de l’application.",
        "Sockets et profils de moteurs concernent Multi-Agent ; une tâche PHP périodique ne les exige pas.",
        "Mise à jour générique du worker non vérifiée."
      ],
      "parameters": [
        {
          "name": "command",
          "label": "Commande de fond",
          "description": "Commande du processus de fond dans le profil publié."
        },
        {
          "name": "tool_image_digest",
          "label": "Image des outils",
          "description": "Empreinte immuable des outils du processus de fond."
        },
        {
          "name": "private_socket",
          "label": "Socket privé",
          "description": "Canal privé du processus lorsque le profil consommateur le nécessite."
        },
        {
          "name": "profile_bindings",
          "label": "Profils raccordés",
          "description": "Références privées des profils nécessaires au processus."
        },
        {
          "name": "working_paths",
          "label": "Répertoires de travail",
          "description": "Répertoires privés nécessaires au processus de fond."
        },
        {
          "name": "resource_limits",
          "label": "Limites du processus",
          "description": "Enveloppes de ressources appliquées au processus de fond."
        },
        {
          "name": "periodic_script",
          "label": "Script périodique",
          "description": "Script de la recette exécuté à intervalles contrôlés."
        },
        {
          "name": "interval_seconds",
          "label": "Périodicité",
          "description": "Intervalle en secondes de la tâche périodique publiée."
        },
        {
          "name": "timeout_seconds",
          "label": "Durée maximale",
          "description": "Durée maximale en secondes de la tâche contrôlée."
        }
      ],
      "operations": [
        {
          "id": "start",
          "label": "Démarrage",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Processus de fond Multi-Agent observé ; réutilisation et usages vérifiés dans ERPNext, MediaWiki, Discourse, Redmine et Immich."
        },
        {
          "id": "engine_task",
          "label": "Tâche du moteur d’agent",
          "status": "blocked",
          "status_label": "Bloqué",
          "scope": "Tâche réelle du moteur d’agent bloquée par son authentification privée."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Continuité du travail du moteur Multi-Agent après mise à jour non vérifiée."
        },
        {
          "id": "periodic_php",
          "label": "Tâche PHP périodique",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Tâche PHP de FreshRSS exécutée avec intervalle, durée maximale et arrêt contrôlés."
        }
      ],
      "dependencies": [
        "N0-CONTAINER"
      ],
      "consumers": [
        "N3-DISCOURSE",
        "N3-ERPNEXT",
        "N3-FRESHRSS",
        "N3-IMMICH",
        "N3-MEDIAWIKI",
        "N3-MULTI-AGENT",
        "N3-NEXTCLOUD",
        "N3-REDMINE"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n1-worker"
    },
    {
      "id": "N2-CLICKHOUSE",
      "level": "N2",
      "slug": "clickhouse",
      "name": "ClickHouse",
      "summary": "Fournir une base analytique privée réservée avec TLS et stockage persistant.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "ClickHouse 25.8.33.6 dédié à Plausible : collecte, statistiques, conservation et export natif vérifiés.",
      "limitations": [
        "Instance dédiée sans haute disponibilité qualifiée ; budget distinct de 2 CPU, 2 Gio de mémoire et 3 Gio de stockage.",
        "Droits SQL et tables système limités au profil Plausible publié ; aucune disponibilité universelle déduite.",
        "Sauvegardes PostgreSQL et ClickHouse séparées ; atomicité entre bases non qualifiée.",
        "Mise à jour du moteur et restauration non qualifiées."
      ],
      "parameters": [
        {
          "name": "owner_app",
          "label": "Application propriétaire",
          "description": "Application à laquelle le fournisseur et les données sont réservés."
        },
        {
          "name": "binding_id",
          "label": "Identité du raccordement",
          "description": "Identité de la liaison privée à conserver pendant les reprises."
        },
        {
          "name": "image_digest",
          "label": "Empreinte d’image",
          "description": "Image immuable désignée par son empreinte, jamais par une version flottante."
        },
        {
          "name": "private_dns",
          "label": "Adresse privée",
          "description": "Nom privé de résolution du service autorisé."
        },
        {
          "name": "tls_identity",
          "label": "Identité TLS",
          "description": "Identité attendue du fournisseur et autorité de confiance du raccordement."
        },
        {
          "name": "storage_budget",
          "label": "Budget de stockage",
          "description": "Capacité réservée dans le profil admis ; elle ne prouve pas une mesure générale des quotas physiques."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Fournisseur ClickHouse 25.8.33.6 dédié sous TLS avec volume réservé ; collecte et statistiques Plausible vérifiées."
        },
        {
          "id": "reuse",
          "label": "Réutilisation du fournisseur",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Raccordement, confiance TLS, identités des ressources et données conservés pendant une mise à jour compatible de Plausible."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune montée de version ClickHouse qualifiée."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Export natif de 2 164 339 octets et 113 fichiers, intégrité, tables et identités vérifiées ; aucune restauration ni sauvegarde atomique conjointe avec PostgreSQL."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-SERVICE",
        "N1-PERSIST"
      ],
      "consumers": [
        "N3-PLAUSIBLE"
      ],
      "versions": [
        {
          "from": "25.8.33.6",
          "to": "25.8.33.6",
          "label": "Fournisseur conservé pendant la mise à jour compatible de Plausible",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n2-clickhouse"
    },
    {
      "id": "N2-IMAP",
      "level": "N2",
      "slug": "imap",
      "name": "IMAP privé",
      "summary": "Fournir une boîte privée par application avec lecture et écriture des messages sous TLS.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Fournisseur Dovecot 2.4.5-r0 utilisé par Roundcube et SnappyMail ; compte, messages et identités conservés pendant leurs mises à jour compatibles.",
      "limitations": [
        "Une boîte privée par application, sans réception Internet, MX, SMTP entrant ni exposition IMAP publique.",
        "Une seule réplique ; haute disponibilité et performance générale non qualifiées.",
        "Certificat initial valide un an ; renouvellement à qualifier séparément.",
        "Sauvegarder SQLite dans le webmail ne sauvegarde pas la boîte Maildir ; export et restauration de celle-ci non qualifiés.",
        "Aucune mise à jour du moteur qualifiée."
      ],
      "parameters": [
        {
          "name": "app_identity",
          "label": "Identité applicative",
          "description": "Identité propriétaire du service réservé et de ses données."
        },
        {
          "name": "account_reference",
          "label": "Référence du compte",
          "description": "Référence privée du compte de messagerie autorisé par le contrat."
        },
        {
          "name": "pinned_image",
          "label": "Image épinglée",
          "description": "Image du fournisseur identifiée par sa version et son empreinte immuables."
        },
        {
          "name": "tls_certificate",
          "label": "Certificat TLS",
          "description": "Référence au certificat et à sa chaîne de confiance privés, vérifiés par le consommateur."
        },
        {
          "name": "volume_identity",
          "label": "Identité du volume",
          "description": "Identité du stockage à conserver lors d’une reprise ou d’une mise à jour."
        },
        {
          "name": "authorized_consumer",
          "label": "Consommateur autorisé",
          "description": "Application autorisée à utiliser le service privé."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Fournisseur privé par application, TLS vérifié, compte Roundcube authentifié et message écrit puis relu."
        },
        {
          "id": "preserve_during_n3_upgrade",
          "label": "Conservation pendant la mise à jour N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même compte, raccordement, confiance TLS et identités des ressources pendant la mise à jour Roundcube ; ancien message relu et nouveau message créé."
        },
        {
          "id": "upgrade_engine",
          "label": "Mise à jour du moteur",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune montée de version du moteur IMAP qualifiée."
        },
        {
          "id": "backup_restore",
          "label": "Sauvegarde et restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Ni export de la boîte Maildir ni restauration qualifiés."
        },
        {
          "id": "snappymail_consumer",
          "label": "Réutilisation par SnappyMail",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "SnappyMail 2.38.2 maintenu : compte, session, contact et messages conservés, puis nouveau message relu ; fournisseur inchangé."
        }
      ],
      "dependencies": [
        "N1-SERVICE",
        "N1-PERSIST"
      ],
      "consumers": [
        "N3-ROUNDCUBE",
        "N3-SNAPPYMAIL"
      ],
      "versions": [
        {
          "from": "2.4.5-r0",
          "to": "2.4.5-r0",
          "label": "Dovecot constant pendant les mises à jour compatibles des webmails",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n2-imap"
    },
    {
      "id": "N2-INFERENCE",
      "level": "N2",
      "slug": "inference",
      "name": "Inférence privée",
      "summary": "Raccorder une application autorisée à un modèle d’inférence privé.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création, mise à jour du fournisseur et isolation observées avec qwen3:0.6b sur CPU.",
      "limitations": [
        "Profil limité à linux/amd64, CPU, stockage 2 Gio et modèle qwen3:0.6b.",
        "GPU, haute disponibilité, débit, quota physique et restauration non qualifiés.",
        "Une version du fournisseur ou un modèle supplémentaire reste un paramètre ; leur qualification doit être démontrée séparément.",
        "Le raccordement d’une application à un fournisseur existant ne prouve pas l’installation automatique d’un nouveau fournisseur."
      ],
      "parameters": [
        {
          "name": "image_digest",
          "label": "Empreinte d’image",
          "description": "Image immuable désignée par son empreinte, jamais par une version flottante."
        },
        {
          "name": "model_manifest",
          "label": "Manifeste du modèle",
          "description": "Description et versions exactes du modèle d’inférence privé."
        },
        {
          "name": "weights_sha256",
          "label": "Empreintes des poids",
          "description": "Empreintes attendues des fichiers du modèle d’inférence."
        },
        {
          "name": "license",
          "label": "Licence du modèle",
          "description": "Licence applicable au modèle d’inférence sélectionné."
        },
        {
          "name": "consumer_uuids",
          "label": "Consommateurs autorisés",
          "description": "Identités des applications autorisées à joindre le service privé."
        },
        {
          "name": "storage",
          "label": "Stockage persistant",
          "description": "Profil et volume de données du fournisseur ou du modèle."
        },
        {
          "name": "resources",
          "label": "Ressources",
          "description": "Enveloppes CPU, mémoire et stockage prévues par le profil."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Fournisseur Ollama 0.33.3 créé et modèle vérifié ; 0.34.0 ensuite utilisé par LibreChat."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Ollama 0.33.3 → 0.34.0 avec mêmes données, consommateurs et empreintes du modèle ; aucune mise à jour du modèle ni client N3 actif pendant cette transition."
        },
        {
          "id": "isolation",
          "label": "Isolation des consommateurs",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Inférence LibreChat autorisée, accès d’un consommateur étranger refusé, puis nouvelle génération dans la conversation conservée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Perte de volume, restauration des poids et reprise non qualifiées."
        },
        {
          "id": "configuration_contract",
          "label": "Contrat de configuration",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Raccordement N3 au fournisseur existant, accès privé limité à l’application propriétaire et conversation conservée après mise à jour."
        }
      ],
      "dependencies": [
        "N1-SERVICE",
        "N1-PERSIST"
      ],
      "consumers": [
        "N3-LIBRECHAT",
        "N3-OPEN-WEBUI"
      ],
      "versions": [
        {
          "from": "0.33.3",
          "to": "0.34.0",
          "label": "Fournisseur Ollama ; modèle qwen3:0.6b inchangé",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n2-inference"
    },
    {
      "id": "N2-MONGODB",
      "level": "N2",
      "slug": "mongodb",
      "name": "MongoDB",
      "summary": "Fournir une base privée avec TLS et une identité applicative limitée à son projet.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création, mise à jour 8.0.29 → 8.0.30 et raccordement applicatif vérifiés dans un groupe de réplication à un membre.",
      "limitations": [
        "Un seul membre : aucune haute disponibilité qualifiée.",
        "La transaction de référence opérateur et les opérations sous identité applicative ont des preuves distinctes.",
        "Les sauvegardes MongoDB et fichiers ne constituent pas un instantané conjoint.",
        "Quota physique, restauration et remplacement après perte du fournisseur non qualifiés.",
        "Le contrat N3 utilise le fournisseur existant ; aucun nouveau cluster automatique déduit du raccordement."
      ],
      "parameters": [
        {
          "name": "image_digest",
          "label": "Empreinte d’image",
          "description": "Image immuable désignée par son empreinte, jamais par une version flottante."
        },
        {
          "name": "database",
          "label": "Base de données",
          "description": "Base logique du projet dans le fournisseur autorisé."
        },
        {
          "name": "application_user",
          "label": "Identité applicative",
          "description": "Utilisateur du service limité au périmètre de l’application."
        },
        {
          "name": "private_dns",
          "label": "Adresse privée",
          "description": "Nom privé de résolution du service autorisé."
        },
        {
          "name": "tls_secret_ref",
          "label": "Identité TLS",
          "description": "Référence privée des certificats du service."
        },
        {
          "name": "replica_set",
          "label": "Groupe de réplication",
          "description": "Configuration MongoDB publiée ; le profil actuel comporte un seul membre."
        },
        {
          "name": "storage",
          "label": "Stockage persistant",
          "description": "Profil et volume de données du fournisseur ou du modèle."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "MongoDB 8.0.29 initialisé, TLS obligatoire, groupe de réplication à un membre et transaction de référence observée."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "8.0.29 → 8.0.30 après export avec compte, données et identités de service et stockage conservés."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Exports privés avant mises à jour avec taille et empreinte relevées ; restauration et cohérence conjointe avec fichiers non démontrées. NodeBB : exports logiques sous TLS de 293 865 puis 296 842 octets, sessions exclues et contenus relus, sans restauration qualifiée."
        },
        {
          "id": "application_binding",
          "label": "Raccordement applicatif",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Compte applicatif limité à sa base, authentification sous TLS, compte et conversation LibreChat persistés puis conservés ; transaction du parcours N3 sous identité applicative. NodeBB dispose d’une base, d’une identité applicative et d’une autorité de confiance propres au projet, sans accès au service d’inférence ; forum et liaison conservés pendant la mise à jour compatible."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Restauration et perte de fournisseur non qualifiées."
        },
        {
          "id": "configuration_contract",
          "label": "Contrat de configuration",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Raccordement natif à MongoDB 8.0.30 existant : base et compte par projet, accès TLS, identités conservées et export privé avant mise à jour LibreChat. Les profils sont distincts selon la recette : LibreChat conserve sa liaison avec inférence ; NodeBB utilise MongoDB seul. Le remplacement du fournisseur d’une liaison existante est refusé."
        }
      ],
      "dependencies": [
        "N1-SERVICE",
        "N1-PERSIST"
      ],
      "consumers": [
        "N3-LIBRECHAT",
        "N3-NODEBB"
      ],
      "versions": [
        {
          "from": "8.0.29",
          "to": "8.0.30",
          "label": "Mise à jour du fournisseur ; un seul membre",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n2-mongodb"
    },
    {
      "id": "N2-MYSQL",
      "level": "N2",
      "slug": "mysql",
      "name": "MySQL",
      "summary": "Fournir une base SQL privée avec identité, TLS et stockage persistant.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "MySQL 8.4.10 à un nœud et variante MariaDB 11.8.9 pour ERPNext ; création et conservation pendant les mises à jour compatibles.",
      "limitations": [
        "Variante réservée à un nœud, distincte des anciens profils en cluster ; aucune adoption implicite.",
        "Haute disponibilité et reprise après perte du nœud non qualifiées.",
        "La perte des secrets ou un changement d’identité observée font échouer la reprise.",
        "Mise à jour du moteur et rotation du certificat non implémentées ; restauration non vérifiée."
      ],
      "parameters": [
        {
          "name": "reserved_profile",
          "label": "Profil réservé",
          "description": "Profil de service effectivement publié et accepté par le fournisseur."
        },
        {
          "name": "reservation_ref",
          "label": "Réservation",
          "description": "Référence de la ressource réservée qui doit être conservée."
        },
        {
          "name": "tenant_id",
          "label": "Organisation propriétaire",
          "description": "Identité de l’organisation autorisée à utiliser la ressource."
        },
        {
          "name": "app_id",
          "label": "Application",
          "description": "Identité de l’application propriétaire de la ressource."
        },
        {
          "name": "observed_provider_uid",
          "label": "Identité du fournisseur",
          "description": "Identité observée à conserver pendant les reprises et mises à jour."
        },
        {
          "name": "storage",
          "label": "Stockage persistant",
          "description": "Profil et volume de données du fournisseur ou du modèle."
        },
        {
          "name": "resources",
          "label": "Ressources",
          "description": "Enveloppes CPU, mémoire et stockage prévues par le profil."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "MySQL 8.4.10 réservé, image épinglée, base sous TLS et raccordement observés dans les applications qualifiées."
        },
        {
          "id": "preserve_during_n3_upgrade",
          "label": "Conservation pendant la mise à jour N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même fournisseur, mêmes comptes et données conservés pendant les mises à jour N3, notamment Drupal, PrestaShop, Nextcloud et MediaWiki ; aucune recréation silencieuse de stockage."
        },
        {
          "id": "upgrade_engine",
          "label": "Mise à jour du moteur",
          "status": "not_implemented",
          "status_label": "Non implémenté",
          "scope": "Toute modification de version moteur exige une transition explicite encore non implémentée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Restauration des données et médias non qualifiée."
        },
        {
          "id": "rotate_certificate",
          "label": "Rotation du certificat",
          "status": "not_implemented",
          "status_label": "Non implémenté",
          "scope": "Rotation contrôlée du certificat privé non implémentée ; validité initiale de 365 jours."
        },
        {
          "id": "snapshot",
          "label": "Export SQL transactionnel",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export opérateur SQL transactionnel sous TLS, propriétaire et identités contrôlés avant et après ; export distinct des fichiers, route publique de sauvegarde MySQL et restauration non qualifiées."
        },
        {
          "id": "mariadb_variant",
          "label": "Variante MariaDB",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "MariaDB 11.8.9 réservée dans le même module N2-MYSQL : TLS strict, compte et stockage conservés pour ERPNext, commandes et export de 737 tables vérifiés ; aucune conversion MySQL ni migration du moteur."
        },
        {
          "id": "manual_backup_sha256",
          "label": "Transfert de sauvegarde avec empreinte",
          "status": "unit_verified",
          "status_label": "Testé en unité",
          "scope": "Transfert de sauvegarde avec empreinte SHA256 explicite et propagation des erreurs testé en unité ; la preuve native associée concerne PostgreSQL, sans nouvelle sauvegarde MySQL réelle déduite."
        },
        {
          "id": "joomla_consumer",
          "label": "Réutilisation par Joomla",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Joomla 6.1.3 : base privée avec certificat et nom vérifiés, données conservées et nouvel article relu ; export opérateur de 76 tables."
        },
        {
          "id": "typo3_consumer",
          "label": "Réutilisation par TYPO3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "TYPO3 14.3.7 : compte, pages, session et réservation conservés, nouvelle page et exports de 42 tables vérifiés ; aucune restauration ni sauvegarde conjointe qualifiée."
        }
      ],
      "dependencies": [
        "N1-SERVICE",
        "N1-PERSIST"
      ],
      "consumers": [
        "N3-BOOKSTACK",
        "N3-DRUPAL",
        "N3-ERPNEXT",
        "N3-FLARUM",
        "N3-GHOST",
        "N3-JOOMLA",
        "N3-KANBOARD",
        "N3-MEDIAWIKI",
        "N3-NEXTCLOUD",
        "N3-OPENCART",
        "N3-PIWIGO",
        "N3-PRESTASHOP",
        "N3-TYPO3",
        "N3-WOOCOMMERCE",
        "N3-WORDPRESS"
      ],
      "versions": [
        {
          "from": "8.4.10",
          "to": "8.4.10",
          "label": "MySQL conservé pendant les mises à jour N3 ; aucune mise à jour moteur qualifiée",
          "qualification": "verified"
        },
        {
          "from": "11.8.9",
          "to": "11.8.9",
          "label": "Variante MariaDB d’ERPNext, sans conversion depuis MySQL ni migration moteur",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n2-mysql"
    },
    {
      "id": "N2-OIDC",
      "level": "N2",
      "slug": "oidc",
      "name": "SSO / OIDC",
      "summary": "Raccorder l’application à un fournisseur d’identité existant et contrôler ses accès.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Raccordement, connexion, renouvellement et refus d’accès vérifiés ; fournisseur d’identité existant.",
      "limitations": [
        "Les ressources internes du fournisseur sont déléguées ; aucun nouveau serveur ou stockage implicite par application.",
        "L’accès web SSO reste distinct de l’authentification du moteur d’un agent.",
        "Obtenir un jeton ne suffit pas à prouver une autorisation API.",
        "Nouveau déploiement et mise à jour du fournisseur d’identité non qualifiés."
      ],
      "parameters": [
        {
          "name": "provider_https_url",
          "label": "URL du fournisseur SSO",
          "description": "Adresse HTTPS du fournisseur d’identité existant."
        },
        {
          "name": "realm",
          "label": "Domaine d’identité",
          "description": "Domaine logique du fournisseur SSO existant."
        },
        {
          "name": "issuer",
          "label": "Émetteur OIDC",
          "description": "Émetteur exact attendu lors de la vérification des jetons."
        },
        {
          "name": "client_id",
          "label": "Client OIDC",
          "description": "Identité du client associée à l’application chez le fournisseur SSO."
        },
        {
          "name": "origins",
          "label": "Origines autorisées",
          "description": "Origines web admises pour le client SSO de l’application."
        },
        {
          "name": "required_client_role",
          "label": "Rôle applicatif",
          "description": "Rôle requis pour autoriser l’accès au client et à son API."
        },
        {
          "name": "secret_references",
          "label": "Références de secrets",
          "description": "Références privées ; les valeurs ne sont jamais des paramètres publics du catalogue."
        }
      ],
      "operations": [
        {
          "id": "bind",
          "label": "Raccordement",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Client propre à l’application, émetteur et audience exacts, rôle applicatif requis."
        },
        {
          "id": "login_refresh",
          "label": "Connexion et renouvellement",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Connexion, renouvellement, cookies HttpOnly et accès à l’API authentifiée observés."
        },
        {
          "id": "negative_access",
          "label": "Refus des accès non autorisés",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Accès anonyme et audience étrangère refusés, protection CSRF vérifiée ; signature, expiration, émetteur et rôle également testés en unité."
        },
        {
          "id": "provider_upgrade",
          "label": "Mise à jour du fournisseur",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune mise à jour ou nouvelle installation du fournisseur d’identité qualifiée."
        }
      ],
      "dependencies": [],
      "consumers": [
        "N3-MULTI-AGENT"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n2-oidc"
    },
    {
      "id": "N2-POSTGRESQL",
      "level": "N2",
      "slug": "postgresql",
      "name": "PostgreSQL",
      "summary": "Raccorder les applications à une base privée PostgreSQL et conserver leurs données.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Profil PostgreSQL 16 : installation, conservation, reprise d’archives et téléchargement de sauvegardes vérifiés dans leurs scénarios.",
      "limitations": [
        "Migration PostgreSQL 16 → 17 non implémentée ; aucun PostgreSQL 17 qualifié dans ce parcours.",
        "Fournisseur externe et caractéristiques physiques inconnues restent explicitement distingués.",
        "Une reprise d’archives ou un export téléchargé ne qualifient pas une restauration."
      ],
      "parameters": [
        {
          "name": "major_version",
          "label": "Version majeure",
          "description": "Version majeure du service autorisée par le profil publié."
        },
        {
          "name": "reserved_profile",
          "label": "Profil réservé",
          "description": "Profil de service effectivement publié et accepté par le fournisseur."
        },
        {
          "name": "storage",
          "label": "Stockage persistant",
          "description": "Profil et volume de données du fournisseur ou du modèle."
        },
        {
          "name": "resources",
          "label": "Ressources",
          "description": "Enveloppes CPU, mémoire et stockage prévues par le profil."
        },
        {
          "name": "reservation_ref",
          "label": "Réservation",
          "description": "Référence de la ressource réservée qui doit être conservée."
        },
        {
          "name": "secret_binding_ref",
          "label": "Raccordement des secrets",
          "description": "Référence privée des identifiants nécessaires à l’application."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Profil PostgreSQL 16 réservé et accès TLS observés avec les applications qualifiées, notamment Discourse, Redmine et Plausible."
        },
        {
          "id": "preserve_during_n3_upgrade",
          "label": "Conservation pendant la mise à jour N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même fournisseur, identités et données SQL conservés pendant les mises à jour N3, dont Metabase, Discourse, Redmine et Plausible."
        },
        {
          "id": "upgrade_major",
          "label": "Migration majeure",
          "status": "not_implemented",
          "status_label": "Non implémenté",
          "scope": "Transition 16 → 17 absente ; modification directe et profil non accepté refusés."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration exécutée et qualifiée."
        },
        {
          "id": "archive_recovery",
          "label": "Reprise des archives",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Procédure opérateur distinguant des archives par identité SQL et conservant les objets historiques ; nouvelles sauvegardes terminées, sans restauration."
        },
        {
          "id": "backup_download",
          "label": "Téléchargement des sauvegardes",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Archives PostgreSQL téléchargées par API authentifiée et contenu inspecté pour Listmonk et Wagtail ; aucune restauration déduite."
        },
        {
          "id": "reserved_vector_extensions",
          "label": "Extensions vectorielles réservées",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Profil PostgreSQL 16 avec hstore 1.8, pg_trgm 1.6, unaccent 1.1 et vector 0.8.6 : identité applicative sans droits administrateur, TLS et conservation pendant la mise à jour Discourse."
        },
        {
          "id": "reserved_geovector_variant",
          "label": "Variante géographique et vectorielle",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Variante réservée avec cube, earthdistance, pg_trgm, unaccent, uuid-ossp et vector 0.8.6 : données, identité et réservation conservées pour Immich."
        },
        {
          "id": "manual_backup_sha256",
          "label": "Transfert de sauvegarde avec empreinte",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Sauvegarde native avec empreinte SHA256 et propagation des erreurs : archive de 18 635 756 octets et contenu de 72 tables vérifiés ; restauration non exécutée."
        }
      ],
      "dependencies": [
        "N1-SERVICE",
        "N1-PERSIST"
      ],
      "consumers": [
        "N3-DISCOURSE",
        "N3-ETHERPAD",
        "N3-IMMICH",
        "N3-LISTMONK",
        "N3-METABASE",
        "N3-ODOO",
        "N3-PLAUSIBLE",
        "N3-REDMINE",
        "N3-STRAPI",
        "N3-UMAMI",
        "N3-WAGTAIL"
      ],
      "versions": [
        {
          "from": "16",
          "to": "16",
          "label": "Profil majeur conservé pendant les mises à jour N3",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n2-postgresql"
    },
    {
      "id": "N2-REDIS",
      "level": "N2",
      "slug": "redis",
      "name": "Redis",
      "summary": "Assurer la coordination privée des consommateurs avec les commandes et droits requis.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Redis 7.4.5 et variante réservée 7.4.11 avec TLS, droits et journal persistant ; coordination, cache et tâches des consommateurs qualifiés.",
      "limitations": [
        "Un numéro de base seul ne constitue pas une isolation entre organisations.",
        "L’identité TLS doit correspondre au nom complet du service.",
        "Aucune substitution par Valkey sans campagne de compatibilité.",
        "Mise à jour, récupération après crash et restauration non vérifiées."
      ],
      "parameters": [
        {
          "name": "image_digest",
          "label": "Empreinte d’image",
          "description": "Image immuable désignée par son empreinte, jamais par une version flottante."
        },
        {
          "name": "reservation_ref",
          "label": "Réservation",
          "description": "Référence de la ressource réservée qui doit être conservée."
        },
        {
          "name": "acl_secret_ref",
          "label": "Référence des droits",
          "description": "Référence privée des autorisations ; aucune valeur de secret dans le catalogue."
        },
        {
          "name": "tls_ca_ref",
          "label": "Autorité TLS",
          "description": "Référence privée de l’autorité vérifiant l’identité du service."
        },
        {
          "name": "service_dns",
          "label": "Nom du service",
          "description": "Nom privé complet utilisé pour le service et sa vérification TLS."
        },
        {
          "name": "storage",
          "label": "Stockage persistant",
          "description": "Profil et volume de données du fournisseur ou du modèle."
        },
        {
          "name": "required_commands",
          "label": "Commandes requises",
          "description": "Commandes Redis nécessaires au consommateur et exercées par la qualification."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Redis 7.4.5 privé avec TLS, droits applicatifs et journal AOF configurés ; réutilisation observée par Discourse et Redmine."
        },
        {
          "id": "coordination",
          "label": "Coordination",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "PING, EVAL, Streams, groupes de consommateurs, reprises et acquittements exercés avec relecture après reconnexion."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune mise à jour du moteur Redis réalisée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Journal AOF configuré ; récupération après crash et restauration non qualifiées."
        },
        {
          "id": "reserved_variant",
          "label": "Variante Redis réservée",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Redis 7.4.11 réservé : TLS, droits et journal AOF pour cache, tâches et temps réel ERPNext ; identités conservées, usages Nextcloud et Immich vérifiés. Aucun remplacement par Valkey ni changement du moteur qualifié."
        }
      ],
      "dependencies": [
        "N1-SERVICE",
        "N1-PERSIST"
      ],
      "consumers": [
        "N3-DISCOURSE",
        "N3-ERPNEXT",
        "N3-IMMICH",
        "N3-MULTI-AGENT",
        "N3-NEXTCLOUD",
        "N3-REDMINE"
      ],
      "versions": [
        {
          "from": "7.4.5",
          "to": "7.4.5",
          "label": "Version installée ; aucune mise à jour moteur qualifiée",
          "qualification": "verified"
        },
        {
          "from": "7.4.11",
          "to": "7.4.11",
          "label": "Variante réservée, distincte d’une migration depuis la version 7.4.5",
          "qualification": "verified"
        }
      ],
      "page": "catalogue-standards.html#n2-redis"
    },
    {
      "id": "N2-SMTP",
      "level": "N2",
      "slug": "smtp",
      "name": "SMTP",
      "summary": "Raccorder une application à un service de courrier selon une portée explicitement autorisée.",
      "contract_version": "1.0.0",
      "status": "partial",
      "status_label": "Partiel",
      "scope": "Courrier reçu dans un collecteur privé avec Listmonk, Roundcube, SnappyMail, Discourse et Redmine ; aucun envoi Internet qualifié.",
      "limitations": [
        "La capture privée ne prouve ni délivrabilité Internet, ni SPF/DKIM/DMARC, ni TLS ou authentification réels d’un relais externe.",
        "Le fournisseur existant porte ses propres ressources ; aucun conteneur de relais automatique par application.",
        "Le profil Listmonk courant refuse tout raccordement autre que le collecteur privé autorisé.",
        "Envoi Internet et mise à jour du fournisseur non qualifiés."
      ],
      "parameters": [
        {
          "name": "host",
          "label": "Hôte du service",
          "description": "Nom du service autorisé par le raccordement."
        },
        {
          "name": "port",
          "label": "Port applicatif",
          "description": "Port privé écouté par le programme ou le service."
        },
        {
          "name": "tls_mode",
          "label": "Mode TLS",
          "description": "Mode de chiffrement admis par le raccordement au service."
        },
        {
          "name": "username",
          "label": "Utilisateur du service",
          "description": "Nom du compte autorisé par le raccordement."
        },
        {
          "name": "password_reference",
          "label": "Référence du mot de passe",
          "description": "Référence privée vers le secret, sans publication de sa valeur."
        },
        {
          "name": "from_address",
          "label": "Expéditeur",
          "description": "Adresse d’expédition autorisée dans la portée de courrier prévue."
        },
        {
          "name": "delivery_scope",
          "label": "Portée du courrier",
          "description": "Portée autorisée du raccordement, actuellement limitée à la capture privée qualifiée."
        }
      ],
      "operations": [
        {
          "id": "bind",
          "label": "Raccordement",
          "status": "unit_verified",
          "status_label": "Testé en unité",
          "scope": "Réutilisation du même raccordement, validation des paires d’identifiants et du mode TLS testées en unité ; métadonnées sans mot de passe."
        },
        {
          "id": "private_capture",
          "label": "Capture de courrier privée",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Campagnes Listmonk, messages Roundcube, invitations et notifications Discourse/Redmine reçus par un collecteur privé dans leurs scénarios."
        },
        {
          "id": "external_delivery",
          "label": "Courrier sur Internet",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucun destinataire externe ni envoi de courrier Internet qualifié."
        },
        {
          "id": "provider_upgrade",
          "label": "Mise à jour du fournisseur",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucun changement de version ou nouveau déploiement du fournisseur de capture qualifié."
        },
        {
          "id": "snappymail_consumer",
          "label": "Réutilisation par SnappyMail",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "SnappyMail 2.38.2 : envois privés reçus avant et après mise à jour compatible, message relu ; fournisseur conservé, sans délivrabilité Internet déduite."
        }
      ],
      "dependencies": [],
      "consumers": [
        "N3-DISCOURSE",
        "N3-LISTMONK",
        "N3-REDMINE",
        "N3-ROUNDCUBE",
        "N3-SNAPPYMAIL"
      ],
      "versions": [],
      "page": "catalogue-standards.html#n2-smtp"
    },
    {
      "id": "N3-BOOKSTACK",
      "level": "N3",
      "slug": "bookstack",
      "name": "BookStack",
      "summary": "Organiser une documentation en étagères, livres, chapitres et pages avec images et pièces jointes.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "BookStack 26.05.5 maintenu créé sur une application neuve, puis code client compatible mis à jour sans appel de modèle : compte, session, hiérarchie documentaire, image et pièce jointe conservés, nouvelle page créée.",
      "limitations": [
        "Version amont 26.05.5 constante ; aucune migration de version BookStack qualifiée.",
        "La création qualifiée et sa mise à jour utilisent zéro appel LLM. Le premier incident d’une autre instance conserve ses trois appels historiques et sa reprise après correctif ; cette reprise n’est pas comptée comme création qualifiée.",
        "La recette compile sa configuration pour éviter qu’une variable d’environnement masque son fichier .env. Une création interrompue reprend sans réinstallation seulement après vérification de la configuration propre à l’instance et d’un état limité aux données de l’installateur.",
        "SSO, stockage objet, courriel réel, recherche externe, charge et haute disponibilité non qualifiés.",
        "Exports SQL et fichiers séparés ; restauration et atomicité conjointe non qualifiées.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "composer_lock",
          "label": "Verrou Composer",
          "description": "Contrat des dépendances PHP fourni dans Git et contrôlé à la construction."
        },
        {
          "name": "bundled_vendor_inventory",
          "label": "Inventaire des dépendances distribuées",
          "description": "Inventaire exact des dépendances fournies dans Git avec la distribution."
        },
        {
          "name": "prebuilt_frontend_distribution",
          "label": "Frontend précompilé dans Git",
          "description": "Fichiers frontend déjà construits, versionnés et contrôlés avec la distribution livrée par la recette."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "private_mysql_binding",
          "label": "Raccordement MySQL privé",
          "description": "Base et identité privées avec certificat et nom du service vérifiés."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création sur une application neuve depuis Git avec zéro appel LLM : compte, étagère, livre, chapitre, page, image et pièce jointe vérifiés, accès privé refusé sans session. L’autre instance reprise après correction de recette reste un incident distinct."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet Git et version 26.05.5, contrôleur d’entrée et asset modifiés sans changer le TOML, zéro appel LLM ; compte, session, clé, contenus, image, pièce jointe et stockage conservés, nouvelle page créée."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "41 tables SQL et fichiers exportés avant et après ; archive native de 136 fichiers vérifiée par empreinte et intégrité, avec l’image connue. Copies distinctes, sans restauration ni instantané conjoint."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Restauration SQL et fichiers non exercée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N1-COMPOSE",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "26.05.5 maintenu",
          "to": "26.05.5 maintenu — révision client compatible",
          "label": "Version amont constante ; modification compatible du contrôleur et des assets",
          "qualification": "verified"
        }
      ],
      "page": "apps-bookstack.html"
    },
    {
      "id": "N3-CRYPTPAD",
      "level": "N3",
      "slug": "cryptpad",
      "name": "CryptPad",
      "summary": "Rédiger et retrouver des documents collaboratifs dans un espace privé.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "CryptPad 2026.5.1 créé après réparation revue, puis code client compatible mis à jour : compte et document conservés, nouvelle édition à deux navigateurs vérifiée.",
      "limitations": [
        "Même version amont 2026.5.1 ; aucune migration amont qualifiée.",
        "Deux origines HTTPS distinctes sont obligatoires. Drawio est réellement chargé, mais le contenu d’un diagramme n’est pas qualifié.",
        "OnlyOffice est exclu : tableur, traitement de texte et présentation correspondants désactivés ; les autres éditeurs n’ont pas tous un scénario métier qualifié.",
        "Quatre mises à jour npm explicites sont appliquées au contexte de construction ; verrou Git client conservé.",
        "Copie froide sur le même volume, sans export externe ni restauration qualifiés.",
        "Trois appels privés initiaux conservés ; l’agent a développé les capacités et fait revoir la configuration. Aucun appel LLM sur la mise à jour compatible.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "source_commit",
          "label": "Commit source",
          "description": "Révision Git exacte à construire, contrôler et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Git client conservé, deux origines HTTPS, compte créé, document édité par deux navigateurs isolés et retrouvé dans l’espace documentaire ; Drawio rendu."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même version 2026.5.1 et même projet : vrai code client modifié servi, compte, document et volume conservés, puis nouvelle édition partagée ; zéro appel LLM."
        },
        {
          "id": "configuration_repair",
          "label": "Réparation de configuration",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Trois appels privés restent comptés ; capacités et configuration développées puis revues avec CI et PR, échec métier rattaché au même incident et correction du proxy publiée séparément."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Copie froide de 43 fichiers et 137 461 octets avant mise à jour, empreintes vérifiées sur le même stockage ; aucun export externe ni restauration qualifié."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-NODE",
        "N1-PERSIST",
        "N1-COMPOSE"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "2026.5.1",
          "to": "2026.5.1 — révision client compatible",
          "label": "Même version amont ; modification du code client, sans migration CryptPad",
          "qualification": "verified"
        }
      ],
      "page": "apps-cryptpad.html"
    },
    {
      "id": "N3-DISCOURSE",
      "level": "N3",
      "slug": "discourse",
      "name": "Discourse",
      "summary": "Animer un forum avec discussions, réponses, images, invitations et notifications.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Discourse 2026.8.0 maintenu créé puis code Ruby compatible mis à jour ; comptes, sujet, image et stockage conservés, nouvelle réponse et notification privée vérifiées.",
      "limitations": [
        "Version 2026.8.0 avec maintenance réelle des dépendances Ruby et Node ; aucune migration de version amont qualifiée.",
        "Sept appels privés historiques restent conservés, dont trois sur la lignée maintenue ; zéro appel sur la mise à jour compatible ne les efface pas.",
        "Refus de scan conservés, sans exclusion du scanner ni remise à zéro de l’historique.",
        "Courrier Internet, fédération, plugins IA, charge et haute disponibilité non qualifiés.",
        "Exports PostgreSQL et fichiers séparés ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création après maintenance et configuration revue : deux comptes, catégorie, sujet, réponse, image, invitation privée reçue et acceptée, recherche et notification vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Vrai code Ruby et asset servis depuis le même Git, configuration inchangée et zéro LLM ; comptes, discussion, image et réservations conservés, nouvelle réponse et notification vérifiées."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Archive PostgreSQL contenant 357 tables et export opérateur de 54 fichiers contrôlés avec empreintes, propriétaire et image connue ; exports séparés sans restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-RUBY",
        "N1-NODE",
        "N1-WORKER",
        "N1-COMPOSE",
        "N1-STATIC",
        "N1-PERSIST",
        "N2-POSTGRESQL",
        "N2-REDIS",
        "N2-SMTP"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "2026.8.0 maintenu",
          "to": "2026.8.0 maintenu — révision client compatible",
          "label": "Version amont constante ; code Ruby et asset modifiés",
          "qualification": "verified"
        }
      ],
      "page": "apps-discourse.html"
    },
    {
      "id": "N3-DOKUWIKI",
      "level": "N3",
      "slug": "dokuwiki",
      "name": "DokuWiki",
      "summary": "Créer une base documentaire privée avec pages, historique et médias, sans serveur SQL.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création et mise à jour de 2026-07-14b corrigée vers 2026-07-14c ; compte, pages et médias conservés.",
      "limitations": [
        "Version de départ avec quatre correctifs officiels ; autres versions et migration majeure à qualifier.",
        "PHP 8.4.25 et stockage conservés ; changer de runtime exige une qualification propre.",
        "Code et extensions par Git ; modification de code depuis le CMS non qualifiée.",
        "Copie froide sur le même volume ; export externe complet et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Version corrigée créée depuis Git : compte, page, image et rendu authentifié vérifiés ; accès anonyme et chemins privés refusés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mise à jour vers 2026-07-14c dans le même projet : identités et contenus conservés, historique relu, page modifiée et nouvelle page créée."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Page de contrôle et dépôt Git exportés ; archive privée à froid de configuration et données sur le même volume."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis le Git personnalisé et paas.toml ; compte et ressources initialisés, usages vérifiés, aucun appel LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet, code personnalisé et données conservés puis nouvelle écriture vérifiée ; aucun appel LLM sur le push qualifié."
        },
        {
          "id": "configuration_repair",
          "label": "Réparation de configuration",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Configuration absente ou tests mal configurés : modification de paas.toml seulement, contrôles CI, PR et livraison ; plafond partagé de trois appels privés par incident."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "2026-07-14b corrigée",
          "to": "2026-07-14c",
          "label": "Quatre correctifs officiels dans la version de départ",
          "qualification": "verified"
        }
      ],
      "page": "apps-dokuwiki.html"
    },
    {
      "id": "N3-DRUPAL",
      "level": "N3",
      "slug": "drupal",
      "name": "Drupal",
      "summary": "Publier des articles et médias avec un CMS PHP et une base privée.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Drupal 11.4.7 créé après réparations puis code client compatible mis à jour ; compte, articles, image et réservations conservés, nouvel article et rendu connecté vérifiés.",
      "limitations": [
        "Drupal 11.4.7 avec PHP 8.4.25 et MySQL 8.4.10 constants ; migrations du cœur, des modules ou des fournisseurs non qualifiées.",
        "Deux lignées de création ont consommé trois appels privés chacune, soit six historiques ; les reprises revues conservent les compteurs.",
        "La dernière mise à jour compatible a utilisé zéro LLM ; ce résultat ne réécrit pas les réparations initiales.",
        "Export SQL et copie froide de fichiers distincts ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "composer_lock",
          "label": "Verrou Composer",
          "description": "Contrat des dépendances PHP fourni dans Git et contrôlé à la construction."
        },
        {
          "name": "installed_production_vendor",
          "label": "Dépendances PHP de production",
          "description": "Arbre des dépendances présent dans Git et comparé au verrou et à son inventaire."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "private_mysql_binding",
          "label": "Raccordement MySQL privé",
          "description": "Base et identité privées avec certificat et nom du service vérifiés."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création réparée puis revue par CI et PR : compte, article, image, thème et session connectée vérifiés, ressources CSS/JS et polices chargées."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même dépôt et configuration, vrai code client compatible servi sans LLM ; compte, articles, image et réservations conservés, nouvelle écriture et rendu connecté vérifiés."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export SQL transactionnel de 62 tables sous TLS et archive froide de 161 fichiers exportés et contrôlés séparément ; aucune restauration ni cohérence atomique conjointe démontrée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration MySQL ou fichiers qualifiée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N1-COMPOSE",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "11.4.7",
          "to": "11.4.7 — révision client compatible",
          "label": "Même version Drupal ; migration du cœur et des modules non qualifiée",
          "qualification": "verified"
        }
      ],
      "page": "apps-drupal.html"
    },
    {
      "id": "N3-ERPNEXT",
      "level": "N3",
      "slug": "erpnext",
      "name": "ERPNext",
      "summary": "Gérer clients, articles, commandes, imports et documents dans une application de gestion.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "ERPNext 16.35.0 avec Frappe 16.34.0 : création réparée et modification compatible du code qualifiées, compte, commandes et fichier conservés, nouvelle commande, PDF et temps réel vérifiés.",
      "limitations": [
        "Versions ERPNext et Frappe constantes ; aucune migration amont, SQL ou Redis qualifiée.",
        "MariaDB 11.8.9 est une variante du module N2-MYSQL ; aucun nouveau module par fournisseur compatible ou version.",
        "Trois appels privés historiques dans une seule lignée restent conservés ; zéro appel sur la mise à jour compatible.",
        "Courrier sortant, paiements externes, charge et haute disponibilité non qualifiés.",
        "Le navigateur embarqué possède un contrôle de vulnérabilités dédié, renouvelé lors de la publication de base ; la couverture des scanners n’est pas assimilée.",
        "Exports SQL et fichiers distincts ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "published_dependency_closure",
          "label": "Dépendances publiées",
          "description": "Ensemble fermé des dépendances déjà publié, compatible avec les verrous et ABI du code client."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création après capacités et configuration revues : compte, client, article, commande, fichier privé, import asynchrone, PDF et échange temps réel authentifié vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même Git, versions et configuration, code Python et asset client réellement servis sans LLM ; compte, client, article, commande, fichier, import et réservations conservés, seconde commande et PDF vérifiés."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export MariaDB de 737 tables avant le push, puis sauvegarde préalable SQL et archive de 18 fichiers ; exports, empreintes et intégrité contrôlés, sans instantané conjoint ni restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-PYTHON",
        "N1-NODE",
        "N1-STATIC",
        "N1-WORKER",
        "N1-COMPOSE",
        "N1-PERSIST",
        "N2-MYSQL",
        "N2-REDIS"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "16.35.0 / Frappe 16.34.0",
          "to": "16.35.0 / Frappe 16.34.0 — révision client compatible",
          "label": "Versions ERPNext et Frappe constantes ; code client personnalisé",
          "qualification": "verified"
        }
      ],
      "page": "apps-erpnext.html"
    },
    {
      "id": "N3-ETHERPAD",
      "level": "N3",
      "slug": "etherpad",
      "name": "Etherpad",
      "summary": "Rédiger à plusieurs dans un document partagé avec auteurs et révisions persistants.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Deux auteurs simultanés, création 3.3.2 corrigée et mise à jour 3.3.3 avec texte et révisions conservés.",
      "limitations": [
        "Version de départ avec sept correctifs officiels ; ne pas utiliser la distribution 3.3.2 non corrigée comme équivalent.",
        "Plugins verrouillés dans Git ; installation à chaud et mise à jour automatique désactivées.",
        "Export du document de contrôle seulement ; sauvegarde globale, restauration et retour arrière après migration non qualifiés.",
        "Charge multiutilisateur et chat réel non exercés ; connecteur optionnel SurrealDB absent du profil PostgreSQL.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "upstream_commit",
          "label": "Révision amont",
          "description": "Révision du logiciel fournisseur retenue et corrigée si nécessaire."
        },
        {
          "name": "security_backports",
          "label": "Correctifs rétroportés",
          "description": "Correctifs explicitement inclus dans la version de départ qualifiée."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Deux auteurs authentifiés, éditions simultanées et reconnexion observées avec PostgreSQL privé sous TLS."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "3.3.2 corrigée → 3.3.3 dans le même projet : auteurs, texte, révision et stockage conservés, puis nouvelles éditions simultanées."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Export officiel du document de contrôle : contenu, HTML, révisions, auteurs et chat vide sauvegardés."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création par paas.toml depuis le code personnalisé après correction produit et reprise du même projet ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mise à jour par configuration dans le même projet, contenu et identités conservés puis nouvelles écritures ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_repair",
          "label": "Réparation de configuration",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Configuration absente : un appel privé limité au TOML, CI, PR et reprise sur la dernière révision métier ; collaboration conservée."
        }
      ],
      "dependencies": [
        "N1-NODE",
        "N2-POSTGRESQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "3.3.2 corrigée",
          "to": "3.3.3",
          "label": "Sept correctifs officiels dans la version de départ",
          "qualification": "verified"
        }
      ],
      "page": "apps-etherpad.html"
    },
    {
      "id": "N3-FILEBROWSER",
      "level": "N3",
      "slug": "filebrowser",
      "name": "File Browser Quantum",
      "summary": "Déposer, éditer et partager des fichiers avec un compte et des partages protégés.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Quantum 1.5.5-stable corrigée → 1.5.6-stable ; fichiers, compte et partages conservés sans serveur SQL.",
      "limitations": [
        "Version de départ avec six fichiers correctifs officiels ; migration majeure et passage depuis le fournisseur historique non qualifiés.",
        "linux/amd64, CGO désactivé ; aperçus MuPDF/FFmpeg et intégrations bureautiques non qualifiés.",
        "Copie froide complète sur le même volume ; export externe de cette archive et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "distribution",
          "label": "Distribution",
          "description": "Distribution système déclarée et couverte par la recette."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Compte, téléchargement identique, édition et partage protégé vérifiés ; accès anonyme refusé et métadonnées publiques sans contenu privé."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mêmes compte, fichier, partages et identités de stockage conservés ; modification puis nouveau fichier vérifiés."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Document et dépôt Git exportés ; archive froide des données et fichiers sur le même volume, avec empreinte contrôlée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création par code Git personnalisé et configuration N3 ; fichier et partage protégé vérifiés, aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mise à jour par configuration dans le même projet ; compte et protection du partage conservés, fichier modifié, aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-GO",
        "N1-NODE",
        "N1-COMPOSE",
        "N1-PERSIST"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "1.5.5-stable corrigée",
          "to": "1.5.6-stable",
          "label": "Quantum ; correctifs officiels dans la version de départ",
          "qualification": "verified"
        }
      ],
      "page": "apps-filebrowser.html"
    },
    {
      "id": "N3-FLARUM",
      "level": "N3",
      "slug": "flarum",
      "name": "Flarum",
      "summary": "Animer un forum privé avec discussions, réponses, profils et avatars.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création 1.8.19 corrigée et migration vers 2.0.0-rc.8, explicitement en préversion.",
      "limitations": [
        "Cible 2.0.0-rc.8 en préversion ; version de départ avec Composer 2.10.3 corrigé.",
        "Runtime PHP et MySQL conservés ; leurs migrations exigent des preuves séparées.",
        "Sources et dépendances dans Git ; administration de code et extensions depuis le forum non qualifiée.",
        "Inscription désactivée et courrier dans le journal local ; envoi externe non qualifié.",
        "SQL puis fichiers exportés à des moments distincts ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Compte, discussion, réponse, avatar et connexion navigateur vérifiés sur la version corrigée."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Migration vers la préversion dans le même projet : compte, base, discussion, réponses, avatar et stockage conservés, nouvelle réponse créée."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Exports SQL, dépôt Git et archive froide de fichiers contrôlés ; aucune cohérence d’instantané conjoint démontrée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis Git personnalisé et paas.toml, compte et services initialisés ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet, code, compte, données et stockage conservés ; nouvelle opération métier et aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N2-MYSQL",
        "N1-PERSIST"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "1.8.19 corrigée",
          "to": "2.0.0-rc.8",
          "label": "Cible en préversion ; dépendances corrigées dans la référence",
          "qualification": "verified"
        }
      ],
      "page": "apps-flarum.html"
    },
    {
      "id": "N3-FRESHRSS",
      "level": "N3",
      "slug": "freshrss",
      "name": "FreshRSS",
      "summary": "Lire et organiser des flux RSS avec catégories, états de lecture et favoris.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "FreshRSS 1.30.0 installé après réparation revue ; mise à jour compatible du code client de la même version amont sans LLM.",
      "limitations": [
        "La mise à jour qualifiée change du code client compatible ; aucun changement de version amont n’est démontré.",
        "SQLite embarqué privé, sans serveur SQL N2 ; montée en charge avec plusieurs répliques non qualifiée.",
        "PHP 8.4.25 et linux/amd64 ; bibliothèques embarquées contrôlées par Git, sans résolution Composer reconstruite.",
        "Copie froide sur le même volume ; export externe et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "source_commit",
          "label": "Commit source",
          "description": "Révision Git exacte à construire, contrôler et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création après correction revue de paas.toml, CI et PR dans le même dépôt : compte, API, flux, catégorie, lecture et favori vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même version amont 1.30.0, code client compatible mis à jour par Git sans LLM ; états et identités conservés, nouveau flux et article lus."
        },
        {
          "id": "configuration_repair",
          "label": "Réparation de configuration",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Trois appels privés conservés, dont deux configurations refusées ; capacités développées par un agent autorisé puis configuration revue, CI et PR. Le modèle seul n’a pas terminé la réparation."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Archive froide avant migrations sur le même volume, reçue et reliée au commit avec empreinte contrôlée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N1-WORKER",
        "N1-COMPOSE"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "1.30.0",
          "to": "1.30.0 — révision client compatible",
          "label": "Même version amont ; modification du code client, sans changement de version FreshRSS",
          "qualification": "verified"
        }
      ],
      "page": "apps-freshrss.html"
    },
    {
      "id": "N3-GHOST",
      "level": "N3",
      "slug": "ghost",
      "name": "Ghost",
      "summary": "Publier un blog avec articles, compte administrateur et médias persistants.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création 6.62.0 puis mise à jour 6.63.0 dans le même projet avec compte et contenus conservés.",
      "limitations": [
        "Dépendances corrigées et verrouillées dans Git ; Node 22.23.2 conservé, pnpm 12.2.1 → 12.4.0.",
        "Archives limitées à 10 000 entrées, 128 Mio par fichier et 512 Mio au total ; liens et écrasements refusés.",
        "Export logique et média de contrôle seulement ; sauvegarde générale et restauration non qualifiées.",
        "Courrier non implémenté, notamment reconnexion par code email depuis un nouvel appareil ; contrôles d’authentification conservés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "official_archive_sha256",
          "label": "Empreinte de distribution",
          "description": "Empreinte de l’archive fournisseur complète retenue dans Git."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Ghost 6.62.0 depuis Git avec compte, contenus, média et base privée vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "6.62.0 → 6.63.0 : même projet, compte, contenus et identités persistantes conservés puis nouvelles écritures."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export logique et média de contrôle ; portée partielle, sans sauvegarde générale ni restauration qualifiée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "email",
          "label": "Courrier applicatif",
          "status": "not_implemented",
          "status_label": "Non implémenté",
          "scope": "Courrier et reconnexion par code email non implémentés dans cette recette."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création par configuration depuis le code personnalisé avec compte et services initialisés ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mise à jour par configuration, code client et données conservés puis nouvelle opération métier ; aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-NODE",
        "N1-PERSIST",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "6.62.0",
          "to": "6.63.0",
          "label": "Dépendances corrigées dans Git, runtime Node conservé",
          "qualification": "verified"
        }
      ],
      "page": "apps-ghost-blog.html"
    },
    {
      "id": "N3-IMMICH",
      "level": "N3",
      "slug": "immich",
      "name": "Immich",
      "summary": "Conserver photos et vidéos, organiser des albums et partager des médias.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Immich 3.2.2 maintenu créé puis code client compatible mis à jour ; compte, trois médias, album et partage conservés, nouvelle photo importée et relue.",
      "limitations": [
        "Même version amont 3.2.2 ; aucune migration de version Immich qualifiée.",
        "Quatre appels privés historiques, répartis en 1 + 3, dépassent le total annoncé de trois : écart conservé sans effacement de compteur. La reprise revue et la mise à jour n’ajoutent pas d’appel.",
        "Formats, clients mobiles, ensemble des fonctions amont, performance et haute disponibilité non généralisés depuis les usages vérifiés.",
        "Quota physique par application non qualifié : l’interface indique la capacité du système de fichiers sous-jacent.",
        "Exports PostgreSQL et fichiers séparés ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création après CI et PR : compte, trois médias originaux, miniatures, métadonnées, lecture vidéo, album, partage et recherche privée vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même Git et configuration, nouvelle page Svelte et asset servis avec zéro LLM ; compte, médias, album, partage et réservations conservés, quatrième photo importée et relue."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Archive PostgreSQL de 18 635 756 octets contenant les données de 72 tables et export de 16 fichiers ; contenu, propriétaire et originaux vérifiés séparément, sans restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "discovery_budget",
          "label": "Budget de découverte",
          "status": "blocked",
          "status_label": "Bloqué",
          "scope": "Quatre appels privés historiques ont dépassé le total annoncé de trois ; l’écart reste bloqué et visible, reprise revue sans appel supplémentaire ni modification des compteurs."
        }
      ],
      "dependencies": [
        "N1-NODE",
        "N1-PYTHON",
        "N1-STATIC",
        "N1-COMPOSE",
        "N1-WORKER",
        "N1-PERSIST",
        "N2-POSTGRESQL",
        "N2-REDIS"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "3.2.2 maintenu",
          "to": "3.2.2 maintenu — révision client compatible",
          "label": "Version amont constante ; personnalisation compatible du frontend",
          "qualification": "verified"
        }
      ],
      "page": "apps-immich.html"
    },
    {
      "id": "N3-JOOMLA",
      "level": "N3",
      "slug": "joomla",
      "name": "Joomla",
      "summary": "Publier des catégories, articles et images avec une édition riche dans un CMS PHP.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Joomla 6.1.3 créé après correction iconv, puis code client compatible mis à jour ; compte, session, contenu et média conservés, nouvel article publié.",
      "limitations": [
        "Version amont 6.1.3 constante ; aucune migration Joomla qualifiée.",
        "Distribution complète sans verrou Composer amont : inventaire embarqué réel, sans résolution des dépendances au démarrage.",
        "Un avis local MEDIUM CVE-2024-39912 sur web-auth/webauthn-lib 4.5.2 reste déclaré ; aucun seuil d’admission natif modifié.",
        "Création initialement livrée puis refusée au téléversement, trois appels privés sans progrès et incident de capacité disque conservés ; correction et reprise revues avant qualification.",
        "Courrier désactivé ; extensions tierces, charge et haute disponibilité non qualifiées.",
        "SQL et fichiers exportés séparément ; restauration et atomicité conjointe non qualifiées.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "bundled_vendor_inventory",
          "label": "Inventaire des dépendances distribuées",
          "description": "Inventaire exact des dépendances fournies dans Git avec la distribution."
        },
        {
          "name": "frontend_inventory",
          "label": "Inventaire du frontend",
          "description": "Fichiers frontend distribués et identités vérifiées ; leur présence ne prouve pas un graphe transitif complet."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "private_mysql_binding",
          "label": "Raccordement MySQL privé",
          "description": "Base et identité privées avec certificat et nom du service vérifiés."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création réparée dans le même projet Git, configuration revue, 19 contrôles et admission native ; compte, catégorie, article, éditeur TinyMCE et image vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Code PHP et asset client réellement servis, configuration inchangée et zéro LLM ; compte, session, catégorie, article, média et réservations conservés, nouvel article publié."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Export opérateur sous TLS de 76 tables et exports privés de fichiers contrôlés ; archive native préalable vérifiée par empreinte, intégrité, configuration et média connu. Copies séparées, sans restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Restauration SQL et fichiers non exercée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N1-COMPOSE",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "6.1.3",
          "to": "6.1.3 — révision client compatible",
          "label": "Version amont constante ; correction iconv de la base PHP et code client compatible",
          "qualification": "verified"
        }
      ],
      "page": "apps-joomla.html"
    },
    {
      "id": "N3-KANBOARD",
      "level": "N3",
      "slug": "kanboard",
      "name": "Kanboard",
      "summary": "Suivre des projets et tâches dans des tableaux avec pièces jointes persistantes.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création 1.2.53 et mise à jour 1.2.54 avec comptes, tâches et fichiers conservés.",
      "limitations": [
        "PHP et MySQL conservés ; autres versions ou migrations de moteur à qualifier.",
        "Sources et bibliothèques dans Git ; acquisition Composer et installation de plugins depuis l’interface désactivées.",
        "Notifications externes non qualifiées.",
        "Exports SQL/Git avant mise à jour et fichiers après arrêt ; instantané conjoint et restauration non qualifiés.",
        "Connexion persistante et reconnexion par mot de passe vérifiées ; invalidation forcée de toutes les sessions non qualifiée.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Compte, projet, tâches et pièces jointes observés dans la version créée depuis Git."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "1.2.53 → 1.2.54 : même projet et stockage, anciennes données relues et nouvelles écritures métier vérifiées."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Exports SQL, dépôt Git et fichiers vérifiés ; prises à des instants distincts, sans restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis le Git personnalisé et paas.toml, compte et services initialisés ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet, compte, code personnalisé et données conservés ; nouvelle opération métier et aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N2-MYSQL",
        "N1-PERSIST"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "1.2.53",
          "to": "1.2.54",
          "label": "Mise à jour applicative ; PHP et MySQL inchangés",
          "qualification": "verified"
        }
      ],
      "page": "apps-kanboard.html"
    },
    {
      "id": "N3-LIBRECHAT",
      "level": "N3",
      "slug": "librechat",
      "name": "LibreChat",
      "summary": "Converser avec un modèle privé et conserver comptes, conversations et avatars.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création 0.8.8-rc1 puis mise à jour 0.8.8-rc2, toutes deux en préversion, avec MongoDB et inférence existants.",
      "limitations": [
        "Les deux versions sont des préversions.",
        "Profil conversation et avatar ; RAG non raccordé et planification indisponible en rc2 dans ce profil.",
        "MongoDB et inférence restent épinglés ; le raccordement par projet ne qualifie pas l’installation d’un nouveau fournisseur.",
        "Copie froide sur le même volume ; export externe complet, instantané conjoint MongoDB/fichiers et restauration non qualifiés.",
        "Audit des dépendances de développement et scan de l’image finale portent sur des objets distincts.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "complete_source",
          "label": "Sources complètes",
          "description": "Ensemble du code et des fichiers nécessaires à une construction reproductible."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "mongodb_binding",
          "label": "Raccordement MongoDB",
          "description": "Base et identité du projet sur le fournisseur MongoDB existant."
        },
        {
          "name": "private_inference",
          "label": "Inférence privée",
          "description": "Raccordement du consommateur au modèle privé autorisé."
        },
        {
          "name": "paas_toml_n3_configuration",
          "label": "Configuration N3",
          "description": "Bloc N3 versionné dans paas.toml pour une recette publiée."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Compte, avatar et conversation persistés avec MongoDB privé ; génération par inférence privée vérifiée."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "rc1 → rc2 : compte, messages et avatar conservés dans le même projet, puis seconde génération persistée."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Export MongoDB et copie froide des fichiers avec empreintes contrôlées ; copie froide sur le même volume, sans instantané conjoint ni restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis Git et configuration N3 ; raccordements par projet aux fournisseurs existants, génération et persistance vérifiées sans LLM d’installation."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Code personnalisé, compte, conversations et identités conservés ; nouvelles opérations vérifiées sans LLM d’installation."
        }
      ],
      "dependencies": [
        "N1-NODE",
        "N1-PERSIST",
        "N2-MONGODB",
        "N2-INFERENCE"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "0.8.8-rc1",
          "to": "0.8.8-rc2",
          "label": "Deux préversions ; profil sans RAG ni planification rc2",
          "qualification": "verified"
        }
      ],
      "page": "apps-librechat.html"
    },
    {
      "id": "N3-LISTMONK",
      "level": "N3",
      "slug": "listmonk",
      "name": "Listmonk",
      "summary": "Gérer listes et campagnes de courrier, qualifiées ici avec un collecteur privé.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création 6.1.0 corrigée puis mise à jour 6.2.0 ; campagnes reçues uniquement dans le collecteur privé.",
      "limitations": [
        "Six correctifs officiels et dépendances corrigées dans la référence ; la version de départ n’est pas le tag amont intact.",
        "Courrier limité à un destinataire de contrôle dans un collecteur privé ; aucune délivrabilité Internet qualifiée.",
        "Sauvegarde, restauration et changement de fournisseur ont des qualifications distinctes.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "upstream_commit",
          "label": "Révision amont",
          "description": "Révision du logiciel fournisseur retenue et corrigée si nécessaire."
        },
        {
          "name": "security_backports",
          "label": "Correctifs rétroportés",
          "description": "Correctifs explicitement inclus dans la version de départ qualifiée."
        },
        {
          "name": "dependency_security_profile",
          "label": "Profil des dépendances",
          "description": "Corrections et versions de dépendances admises dans le scénario."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "private_capture_binding",
          "label": "Collecteur de courrier privé",
          "description": "Raccordement au collecteur privé qualifié ; aucun destinataire Internet implicite."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Version corrigée créée depuis Git ; compte, liste, abonné, campagne et réception dans le collecteur privé vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "6.1.0 corrigée → 6.2.0 dans le même projet : identités et données conservées, nouvelle campagne reçue dans le même collecteur privé."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Archive PostgreSQL téléchargée, contenu inspecté et fichiers de référence conservés ; aucune restauration déduite."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création par configuration N3 depuis le Git personnalisé, services et compte initialisés ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mise à jour par configuration avec code, compte, données et stockage conservés ; nouveau scénario métier et aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-GO",
        "N1-NODE",
        "N1-COMPOSE",
        "N1-PERSIST",
        "N2-POSTGRESQL",
        "N2-SMTP"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "6.1.0 corrigée",
          "to": "6.2.0",
          "label": "Six correctifs officiels dans la référence ; courrier en capture privée",
          "qualification": "verified"
        }
      ],
      "page": "apps-listmonk.html"
    },
    {
      "id": "N3-MEDIAWIKI",
      "level": "N3",
      "slug": "mediawiki",
      "name": "MediaWiki",
      "summary": "Créer un wiki avec pages, historique, images, recherche et éditeur visuel.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "MediaWiki 1.46.0 maintenu créé puis code compatible mis à jour ; compte, page, historique et image conservés, nouvelle page, recherche et VisualEditor vérifiés.",
      "limitations": [
        "Version amont 1.46.0 constante, dépendances Guzzle 7.15.2, Promises 2.5.1 et PSR-7 2.13.0 maintenues ; aucune migration MediaWiki qualifiée.",
        "Distribution initiale refusée pour un avis HIGH ; refus et trois appels privés historiques conservés. L’audit Composer maintenu signale un avis LOW et le paquet pear/net_socket abandonné.",
        "Courrier Internet, fédération, extensions supplémentaires, charge et haute disponibilité non qualifiés.",
        "Exports SQL et fichiers séparés ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis Git après maintenance des dépendances et revue CI/PR : compte, page, deux révisions, recherche, image et VisualEditor vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Vrai code PHP et asset client servis, même Git et configuration, zéro LLM ; compte, page, révisions, image et réservations conservés, nouvelle page, recherche et rendu Parsoid vérifiés."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export SQL de 64 tables et archive de 11 fichiers avant mise à jour, empreintes et intégrité vérifiées ; exports distincts, sans instantané conjoint ni restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-WORKER",
        "N1-COMPOSE",
        "N1-PERSIST",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "1.46.0 maintenu",
          "to": "1.46.0 maintenu — révision client compatible",
          "label": "Version amont constante avec dépendances maintenues ; code client personnalisé",
          "qualification": "verified"
        }
      ],
      "page": "apps-mediawiki.html"
    },
    {
      "id": "N3-METABASE",
      "level": "N3",
      "slug": "metabase",
      "name": "Metabase",
      "summary": "Interroger des données SQL et composer des tableaux de bord avec graphiques.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Metabase 0.63.18 créé après réparation puis code client compatible mis à jour ; compte, question SQL, tableau et résultats conservés, nouveau tableau et graphique navigateur vérifiés.",
      "limitations": [
        "Version amont 0.63.18 constante ; aucune migration de version Metabase qualifiée.",
        "Adaptation déclarée du pilote SQL Server JDBC 13.2.1.jre11 vers 13.4.0.jre11 dans la copie de construction ; sources clientes conservées.",
        "Base de démonstration SQLite reconstruite depuis l’artefact ; métadonnées applicatives persistantes dans PostgreSQL privé.",
        "Trois appels privés initiaux restent consommés ; capacités développées puis configuration revue dans le même incident. La mise à jour compatible utilise zéro LLM.",
        "Identité du JAR vérifiée et inventaire des composants conservé ; export PostgreSQL contrôlé, restauration non qualifiée.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "jvm_parameters",
          "label": "Paramètres JVM",
          "description": "Paramètres bornés de construction et d’exécution acceptés par la recette."
        },
        {
          "name": "dependency_closure",
          "label": "Ensemble fermé des dépendances",
          "description": "Ensemble complet des dépendances, outils et empreintes admis pour une construction hors réseau."
        },
        {
          "name": "postgresql_binding",
          "label": "Raccordement PostgreSQL",
          "description": "Base privée et identité du service PostgreSQL réservées au projet."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "encryption_secret",
          "label": "Secret de chiffrement",
          "description": "Secret privé d’application à conserver ; sa valeur n’est jamais publiée ni exposée au navigateur."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création native après CI et admission : compte, question SQL, quatre résultats et tableau de bord rendus dans le navigateur."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même Git et version 0.63.18, code client modifié réellement servi sans LLM ; compte, question, tableau, résultats et PostgreSQL conservés, nouveau tableau créé et graphique vérifié."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Archive PostgreSQL de 912 355 octets exportée avant mise à jour, empreinte et inventaire de 159 tables vérifiés ; compte, question et tableau présents, sans restauration qualifiée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-JVM",
        "N1-NODE",
        "N1-COMPOSE",
        "N2-POSTGRESQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "0.63.18",
          "to": "0.63.18 — révision client compatible",
          "label": "Même version Metabase ; code client modifié, sans migration amont",
          "qualification": "verified"
        }
      ],
      "page": "apps-metabase-bi.html"
    },
    {
      "id": "N3-MULTI-AGENT",
      "level": "N3",
      "slug": "multi-agent",
      "name": "Multi-Agent",
      "summary": "Coordonner des agents et consulter leur activité depuis une interface web.",
      "contract_version": "1.0.0",
      "status": "partial",
      "status_label": "Partiel",
      "scope": "Version 3.2.21 servie et composants web observés ; tâche du moteur bloquée par son authentification privée.",
      "limitations": [
        "Version 3.2.22 préparée ; mise à jour fonctionnelle non exécutée.",
        "Un accès web ou un composant démarré ne qualifient pas une tâche réelle du moteur.",
        "Le compte web SSO et le profil privé du moteur ont des authentifications distinctes.",
        "Une authentification privée normale doit être terminée pour reprendre la tâche ; un code expiré n’est pas réutilisable.",
        "Restauration non qualifiée ; aucune installation N3 complète ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "private_engine_profile",
          "label": "Profil privé du moteur",
          "description": "Profil issu de l’authentification normale du moteur d’agent, distinct du compte web."
        },
        {
          "name": "dependency_lock",
          "label": "Verrou des dépendances",
          "description": "Versions et empreintes des dépendances réellement utilisées."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Interface web, authentification et composants servis en 3.2.21 ; installation fonctionnelle complète encore partielle."
        },
        {
          "id": "engine_task",
          "label": "Tâche du moteur d’agent",
          "status": "blocked",
          "status_label": "Bloqué",
          "scope": "Tâche réelle du moteur bloquée tant que son profil privé n’est pas authentifié."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Cible 3.2.22 préparée, sans exécution de la mise à jour dans le projet."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-COMPOSE",
        "N2-REDIS",
        "N2-OIDC",
        "N1-NODE",
        "N1-STATIC",
        "N1-PYTHON",
        "N1-WORKER",
        "N1-PERSIST"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "3.2.21",
          "to": "3.2.22 préparée",
          "label": "3.2.21 servie partiellement ; cible préparée, mise à jour non exécutée",
          "qualification": "not_verified"
        }
      ],
      "page": "apps-multi-agent.html"
    },
    {
      "id": "N3-NEXTCLOUD",
      "level": "N3",
      "slug": "nextcloud",
      "name": "Nextcloud",
      "summary": "Déposer, consulter et partager des fichiers avec accès DAV et liens protégés.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Nextcloud 35.0.0 créé après reprises revues, puis code client compatible mis à jour ; compte, instance, fichiers et partage protégés conservés, nouveau fichier relu.",
      "limitations": [
        "Version amont 35.0.0 constante ; aucune migration Nextcloud qualifiée.",
        "Cinq inventaires Composer sans verrou de production amont : identités installées et Git complet contrôlés.",
        "Adaptation PDO explicite depuis une préimage vérifiée et classification exacte d’une valeur publique dans le scanner ; autres valeurs et fichiers toujours contrôlés.",
        "Trois appels privés historiques de la même lignée conservés ; aucun appel sur la mise à jour compatible.",
        "Courrier Internet, fédération externe, acquisition d’applications, charge et haute disponibilité non qualifiés.",
        "Exports SQL et fichiers séparés ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création par Git après capacités développées et reprises revues : compte, document, image DAV, partage protégé et refus d’écriture publique vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Vrai code PHP et asset client servis, configuration inchangée et zéro LLM ; compte, instance, fichiers, partage et réservations conservés, nouveau fichier et affichage navigateur vérifiés."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export SQL de 139 tables avant le push et archive de 106 fichiers avant démarrage de la nouvelle révision, empreintes et intégrité contrôlées ; copies distinctes, sans restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-WORKER",
        "N1-COMPOSE",
        "N1-PERSIST",
        "N2-MYSQL",
        "N2-REDIS"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "35.0.0",
          "to": "35.0.0 — révision client compatible",
          "label": "Version Nextcloud constante ; personnalisation compatible du code PHP",
          "qualification": "verified"
        }
      ],
      "page": "apps-nextcloud.html"
    },
    {
      "id": "N3-NODEBB",
      "level": "N3",
      "slug": "nodebb",
      "name": "NodeBB",
      "summary": "Animer un forum avec catégories publiques et privées, discussions, réponses, images et droits d’accès.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "NodeBB 4.16.0 maintenu créé sur une application neuve puis code client compatible mis à jour, avec zéro appel LLM aux deux étapes ; compte, session, catégories, discussion, image et liaison MongoDB conservés, nouvelle réponse créée.",
      "limitations": [
        "Version amont 4.16.0 constante ; aucune migration de version NodeBB qualifiée.",
        "MongoDB privé à un seul membre, sans service d’inférence, Redis ni PostgreSQL ; aucun nouveau cluster fournisseur ni haute disponibilité déduit du raccordement.",
        "Les assets sont régénérés à chaque démarrage dans une zone privée persistante. Ces sorties régénérables sont exclues des exports de fichiers ; les sessions sont exclues de l’export logique MongoDB.",
        "La relance de l’installateur exige une absence de contenu métier prouvée ; une interruption ne permet pas une réinstallation arbitraire.",
        "Fédération ActivityPub et inscription publique désactivées par la recette ; courriel réel, web-push, SSO, plugins supplémentaires et charge non qualifiés.",
        "Exports MongoDB et fichiers distincts ; restauration et atomicité conjointe non qualifiées.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "package_lock_source",
          "label": "Verrou npm du dépôt",
          "description": "Verrou source versionné avec le code client complet et contrôlé lors de la préparation des dépendances."
        },
        {
          "name": "dependency_maintenance_commit",
          "label": "Révision de maintenance des dépendances",
          "description": "Commit qui maintient explicitement les dépendances du code livré ; cette maintenance reste distincte d’une réparation de configuration."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "private_mongodb_binding",
          "label": "Raccordement MongoDB privé",
          "description": "Base, identité applicative et autorité de confiance propres au projet ; TLS et droits d’accès contrôlés."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création sur une application neuve depuis Git avec zéro appel LLM : contrôles natifs, compte, catégories publique et privée, discussion avec emoji et image, réponse et refus d’accès sans session vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet Git et version 4.16.0, fichier public client ajouté sans changer le TOML, zéro appel LLM ; copie froide et génération des assets exécutées, compte, session, contenus, image, réservation et liaison conservés, nouvelle réponse créée."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export logique MongoDB sous TLS sans les sessions, et archives de 12 puis 21 fichiers sans les sorties de build régénérables ; relecture des contenus avant et après la mise à jour. Copie froide native de quatre fichiers vérifiée, sans restauration ni instantané conjoint."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Restauration MongoDB et fichiers non exercée."
        }
      ],
      "dependencies": [
        "N1-NODE",
        "N1-PERSIST",
        "N1-COMPOSE",
        "N2-MONGODB"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "4.16.0 maintenu",
          "to": "4.16.0 maintenu — révision client compatible",
          "label": "Version amont constante ; ajout compatible d’un fichier public client",
          "qualification": "verified"
        }
      ],
      "page": "apps-nodebb.html"
    },
    {
      "id": "N3-ODOO",
      "level": "N3",
      "slug": "odoo",
      "name": "Odoo Community",
      "summary": "Gérer contacts, commandes et documents métier dans une application de gestion intégrée.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Community 19.0.post20260911 → 19.0.post20260912 dans la même série, avec contacts, commandes confirmées et pièce jointe conservés.",
      "limitations": [
        "Aucune migration majeure d’Odoo qualifiée.",
        "LDAP, OFX, libmagic, montants en lettres, rendu PDF, paiement, courrier externe et charge non qualifiés.",
        "Sauvegarde SQL et média de contrôle ; un seul média ne couvre pas tout le stockage de fichiers.",
        "Candidats précédents non promus et reprises conservés dans le même projet ; restauration non qualifiée.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "official_archive_sha256",
          "label": "Empreinte de distribution",
          "description": "Empreinte de l’archive fournisseur complète retenue dans Git."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Odoo Community créé depuis Git avec compte, contact, commande confirmée et pièce jointe de contrôle vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mise à jour dans la même série et le même projet : comptes, données et stockage conservés puis nouvelles opérations métier."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export SQL complet, média de contrôle et dépôt Git conservés ; couverture partielle du stockage de fichiers."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis le Git personnalisé et paas.toml avec compte et services initialisés ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet, code personnalisé, compte, données et stockage conservés ; nouvelle opération métier et aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-PYTHON",
        "N1-PERSIST",
        "N2-POSTGRESQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "19.0.post20260911",
          "to": "19.0.post20260912",
          "label": "Édition Community, mise à jour de la même série 19.0",
          "qualification": "verified"
        }
      ],
      "page": "apps-odoo.html"
    },
    {
      "id": "N3-OPEN-WEBUI",
      "level": "N3",
      "slug": "open-webui",
      "name": "Open WebUI",
      "summary": "Prévoir une interface web de conversation avec un modèle privé ; livraison actuellement bloquée.",
      "contract_version": "1.0.0",
      "status": "blocked",
      "status_label": "Bloqué",
      "scope": "0.11.2 préparée, construite et testée, puis refusée au scan ; aucune application servie. Cible 0.11.3 préparée seulement.",
      "limitations": [
        "La preuve historique relève 11 vulnérabilités critiques et 107 élevées ; ces chiffres ne proviennent pas d’un nouveau scan.",
        "Des avis de dépendances relevés n’offraient pas de version corrigée ; la reprise requiert un candidat admis par les contrôles.",
        "Tests unitaires et construction ne qualifient ni accès utilisateur, ni inférence depuis l’application, ni mise à jour dans le projet.",
        "Aucune promotion, installation partiellement servie ou disponibilité générale déduite.",
        "Restauration non qualifiée."
      ],
      "parameters": [
        {
          "name": "complete_source",
          "label": "Sources complètes",
          "description": "Ensemble du code et des fichiers nécessaires à une construction reproductible."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "private_inference",
          "label": "Inférence privée",
          "description": "Raccordement du consommateur au modèle privé autorisé."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "blocked",
          "status_label": "Bloqué",
          "scope": "0.11.2 : préparation, construction et tests réussis, puis scan bloquant ; aucune release promue ni application servie."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "unit_verified",
          "status_label": "Testé en unité",
          "scope": "0.11.2 → 0.11.3 préparé, conservation et opérations testées en unité seulement ; aucune exécution dans le projet client."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune installation disponible pour qualifier sauvegarde ou restauration."
        }
      ],
      "dependencies": [
        "N1-PYTHON",
        "N1-NODE",
        "N1-STATIC",
        "N1-COMPOSE",
        "N1-PERSIST",
        "N2-INFERENCE"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "0.11.2 construite",
          "to": "0.11.3 préparée",
          "label": "Création bloquée au scan ; mise à jour seulement testée en unité",
          "qualification": "unit_verified"
        }
      ],
      "page": "apps-open-webui.html"
    },
    {
      "id": "N3-OPENCART",
      "level": "N3",
      "slug": "opencart",
      "name": "OpenCart",
      "summary": "Gérer une boutique avec produits, images, panier, commandes et mouvements de stock.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "OpenCart 4.1.0.4 maintenu créé puis code compatible mis à jour ; compte, session, produit, image et commande conservés, nouveau produit, commande et stock vérifiés.",
      "limitations": [
        "Version amont 4.1.0.4 constante ; aucune migration OpenCart qualifiée.",
        "Commandes de test avec paiement hors ligne ; paiement externe, courrier, livraison réelle, extensions tierces, charge et haute disponibilité non qualifiés.",
        "Inventaire des fichiers frontend distribués et de leurs identités ; aucun graphe npm transitif complet revendiqué.",
        "CKEditor 4.22.1 conserve cinq avis MEDIUM à la date du scan ; aucun avis HIGH ou CRITICAL dans la source maintenue observée.",
        "Trois appels privés initiaux restent conservés ; le défaut d’image a été réparé dans le même incident, puis mise à jour compatible sans LLM.",
        "Répertoire d’administration immuable conservé ; l’avertissement natif de renommage reste disponible.",
        "Exports SQL et fichiers distincts ; restauration et atomicité conjointe non qualifiées.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "composer_lock",
          "label": "Verrou Composer",
          "description": "Contrat des dépendances PHP fourni dans Git et contrôlé à la construction."
        },
        {
          "name": "bundled_vendor_inventory",
          "label": "Inventaire des dépendances distribuées",
          "description": "Inventaire exact des dépendances fournies dans Git avec la distribution."
        },
        {
          "name": "frontend_inventory",
          "label": "Inventaire du frontend",
          "description": "Fichiers frontend distribués et identités vérifiées ; leur présence ne prouve pas un graphe transitif complet."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "private_mysql_binding",
          "label": "Raccordement MySQL privé",
          "description": "Base et identité privées avec certificat et nom du service vérifiés."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis Git maintenu puis image réparée avec CI et PR dans le même incident : compte, produit, image, commande hors ligne et stock de 12 à 10 vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même Git et version 4.1.0.4, contrôleur PHP et asset modifiés, configuration inchangée et zéro LLM ; compte, session, produit, image, commande et réservations conservés, nouveau produit et commande, stock de 10 à 9."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "159 tables SQL et fichiers exportés avant et après ; archive native de 206 fichiers contrôlée par empreinte, intégrité, configuration et média connus. Copies distinctes, sans restauration ni instantané conjoint."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Restauration SQL et fichiers non exercée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N1-COMPOSE",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "4.1.0.4 maintenu",
          "to": "4.1.0.4 maintenu — révision client compatible",
          "label": "Version amont constante ; modification compatible du contrôleur et des assets",
          "qualification": "verified"
        }
      ],
      "page": "apps-opencart.html"
    },
    {
      "id": "N3-PIWIGO",
      "level": "N3",
      "slug": "piwigo",
      "name": "Piwigo",
      "summary": "Organiser et publier des albums photo avec originaux, miniatures et métadonnées.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "16.3.0 corrigée → 16.4.0 avec comptes, albums, photos et miniatures conservés.",
      "limitations": [
        "Sept correctifs officiels dans la version de départ ; Smarty 5.8.4 dans les deux versions.",
        "PHP et MySQL conservés ; migrations de moteurs non qualifiées.",
        "Distribution complète dans Git ; mises à jour du cœur, des plugins et des thèmes depuis l’interface désactivées.",
        "Photo PNG, GD et métadonnées de base vérifiés ; EXIF/IPTC, vidéos et courrier externe non qualifiés.",
        "SQL et fichiers exportés à des instants distincts ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Distribution corrigée créée depuis Git avec compte, album, photo, miniature et métadonnées vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "16.3.0 corrigée → 16.4.0 dans le même projet : originaux, miniatures, comptes et données conservés ; description modifiée et nouvelle photo créée."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Tables SQL exportées sous un même verrou, dépôt Git et archive des fichiers contrôlés ; SQL et fichiers pris à des moments distincts."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis le Git personnalisé et paas.toml, compte et services initialisés ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet, code, compte, données et stockage conservés ; nouvelle opération métier et aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N2-MYSQL",
        "N1-PERSIST"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "16.3.0 corrigée",
          "to": "16.4.0",
          "label": "Sept correctifs officiels dans la référence ; Smarty 5.8.4 conservé",
          "qualification": "verified"
        }
      ],
      "page": "apps-piwigo.html"
    },
    {
      "id": "N3-PLAUSIBLE",
      "level": "N3",
      "slug": "plausible",
      "name": "Plausible Analytics",
      "summary": "Mesurer les pages vues, objectifs et conversions d’un site avec des statistiques consultables.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Plausible CE 3.2.1 maintenu créé puis code client compatible mis à jour ; compte, site, objectif, statistiques et réservations conservés, nouvelle visite et conversion vérifiées.",
      "limitations": [
        "Version amont CE 3.2.1 constante ; aucune migration Plausible qualifiée.",
        "Trois appels privés historiques sur le même incident restent conservés ; reprises revues et mise à jour compatible sans nouvel appel.",
        "PostgreSQL et ClickHouse sont des fournisseurs distincts ; leurs sauvegardes sont séparées, sans atomicité conjointe ni restauration qualifiée.",
        "Charge, haute disponibilité et fonctions amont non exercées ne sont pas déduites du scénario de pages, objectifs et conversions.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_git",
          "label": "Sources Git",
          "description": "Dépôt complet du code client réellement compilé, avec sa révision et ses verrous."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "account_identity",
          "label": "Identité du compte",
          "description": "Identité applicative conservée lors des reprises et mises à jour ; aucune donnée personnelle n’est publiée."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création après deux reprises de plateforme revues, dans le même incident ; compte, site et statistiques livrés, trois appels privés historiques conservés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même Git et configuration, nouveau module Elixir, template et asset client construits puis servis sans LLM ; compte, site, objectif, données et réservations conservés, nouvelle visite et conversion."
        },
        {
          "id": "business",
          "label": "Usages métier",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Compte, site, page vue, objectif personnalisé et conversion contrôlés à la création et après mise à jour ; historique relu à sa date UTC, session conservée et sept captures inspectées."
        }
      ],
      "dependencies": [
        "N1-ELIXIR",
        "N1-NODE",
        "N1-COMPOSE",
        "N1-PERSIST",
        "N2-POSTGRESQL",
        "N2-CLICKHOUSE"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "CE 3.2.1 maintenu",
          "to": "CE 3.2.1 maintenu — révision client compatible",
          "label": "Même version amont ; code Elixir, template et asset client modifiés",
          "qualification": "verified"
        }
      ],
      "page": "apps-plausible-analytics.html"
    },
    {
      "id": "N3-PRESTASHOP",
      "level": "N3",
      "slug": "prestashop",
      "name": "PrestaShop",
      "summary": "Administrer une boutique avec catalogue, images, commandes et suivi du stock.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "PrestaShop 9.1.5 Classic créé après maintenance et réparations, puis code compatible mis à jour ; compte, produit, image et commande conservés, seconde commande et stock vérifiés.",
      "limitations": [
        "Version 9.1.5 Classic, PHP 8.4.25 et MySQL 8.4.10 constants ; migrations du cœur, des modules ou des fournisseurs non qualifiées.",
        "Dépendances de la source réellement maintenues avant correction de configuration ; source initiale et scan refusé conservés. Sentry 1.11.0 a été vérifié sur son usage local avec exception de borne PHP limitée à cette maintenance.",
        "Deux lignées de création ont consommé trois appels privés chacune, soit six historiques ; compteurs conservés, zéro appel sur la mise à jour compatible.",
        "Commandes hors ligne seulement : paiements externes, services de livraison et courrier Internet non qualifiés.",
        "Adresses exactes des relais de confiance dans la configuration ; elles doivent être revues si le trajet réseau change.",
        "Export SQL et copie froide de fichiers distincts ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "composer_lock",
          "label": "Verrou Composer",
          "description": "Contrat des dépendances PHP fourni dans Git et contrôlé à la construction."
        },
        {
          "name": "installed_production_vendor",
          "label": "Dépendances PHP de production",
          "description": "Arbre des dépendances présent dans Git et comparé au verrou et à son inventaire."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "private_mysql_binding",
          "label": "Raccordement MySQL privé",
          "description": "Base et identité privées avec certificat et nom du service vérifiés."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création après maintenance des sources et configuration revue : compte, produit, image et commande hors ligne vérifiés ; connexions répétées, catalogue, commandes et boutique inspectés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Vrai code compatible servi dans le même dépôt, configuration inchangée et zéro LLM ; compte, produit, image, commande et réservations conservés, seconde commande et stock de 18 à 17 vérifiés."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export SQL transactionnel de 272 tables sous TLS et archive des fichiers avant mise à jour exportés et contrôlés séparément ; aucune restauration ni sauvegarde atomique conjointe."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration MySQL ou fichiers qualifiée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N1-COMPOSE",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "9.1.5 Classic",
          "to": "9.1.5 Classic — révision client compatible",
          "label": "Version amont constante avec dépendances maintenues ; code client modifié",
          "qualification": "verified"
        }
      ],
      "page": "apps-prestashop.html"
    },
    {
      "id": "N3-REDMINE",
      "level": "N3",
      "slug": "redmine",
      "name": "Redmine",
      "summary": "Suivre projets, demandes, pièces jointes, wiki et temps passé.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Redmine 7.0.1 créé puis contrôleur, vue et asset client mis à jour ; deux comptes, projet, demande, wiki et pièce jointe conservés, nouvelles notes et notification privée vérifiées.",
      "limitations": [
        "Version amont 7.0.1 constante ; aucune migration Redmine qualifiée.",
        "Trois appels privés historiques et refus locaux conservés, dont un appel sur la lignée livrée ; aucun scanner exclu ni compteur réinitialisé.",
        "Courrier Internet, authentification LDAP, export Gantt PNG, plugins, charge et haute disponibilité non qualifiés.",
        "Exports PostgreSQL et fichiers opérateur séparés ; instantané conjoint et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création après CI et PR : deux comptes, projet, demande, pièce jointe, wiki, temps, recherche, PDF et notification privée vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même Git et configuration, contrôleur, vue et asset client réellement modifiés, zéro LLM ; comptes, données, fichier et réservations conservés, nouvelles notes et notification privée distincte vérifiées."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Archive PostgreSQL de 165 600 octets contenant les données de 61 tables et export opérateur de deux fichiers ; contenu, propriétaire et pièce jointe contrôlés, sans instantané conjoint ni restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        }
      ],
      "dependencies": [
        "N1-RUBY",
        "N1-WORKER",
        "N1-COMPOSE",
        "N1-STATIC",
        "N1-PERSIST",
        "N2-POSTGRESQL",
        "N2-REDIS",
        "N2-SMTP"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "7.0.1",
          "to": "7.0.1 — révision client compatible",
          "label": "Version Redmine constante ; contrôleur, vue et asset personnalisés",
          "qualification": "verified"
        }
      ],
      "page": "apps-redmine.html"
    },
    {
      "id": "N3-ROUNDCUBE",
      "level": "N3",
      "slug": "roundcube",
      "name": "Roundcube",
      "summary": "Consulter une boîte privée, gérer des contacts et envoyer des messages dans le périmètre autorisé.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Roundcube 1.7.4 créé après découverte et réparation de plateforme, puis code compatible mis à jour ; compte, contacts et messages conservés, nouvel envoi privé reçu et relu.",
      "limitations": [
        "Version amont 1.7.4 constante ; aucune migration Roundcube qualifiée.",
        "IMAP privé dédié, sans intégration qualifiée à une boîte externe existante.",
        "SMTP limité au collecteur privé et aux destinataires de contrôle ; aucune réception ou délivrabilité Internet qualifiée.",
        "Trois appels privés consommés dans la même lignée, correction de plateforme par un agent et configuration revue ; zéro appel sur la mise à jour compatible.",
        "Export SQLite des contacts distinct des messages Maildir ; ni sauvegarde Maildir ni restauration qualifiées.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "composer_lock",
          "label": "Verrou Composer",
          "description": "Contrat des dépendances PHP fourni dans Git et contrôlé à la construction."
        },
        {
          "name": "installed_production_vendor",
          "label": "Dépendances PHP de production",
          "description": "Arbre des dépendances présent dans Git et comparé au verrou et à son inventaire."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "private_imap_binding",
          "label": "Raccordement IMAP privé",
          "description": "Compte et service de lecture des messages sous TLS, limités au consommateur autorisé."
        },
        {
          "name": "private_smtp_binding",
          "label": "Raccordement SMTP privé",
          "description": "Service de capture privée autorisé ; aucun envoi Internet implicite."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création après découverte, configuration revue, CI et PR : connexion, contact, lecture IMAP et réception SMTP privée vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même Git et version 1.7.4, code client réellement modifié servi sans LLM ; compte, contacts, message et raccordements conservés, nouveau message envoyé, lu et reçu en privé."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Copie SQLite de 200 704 octets avant migration, téléchargée et contrôlée par empreinte et intégrité ; compte et contacts présents, sans copie de la boîte Maildir ni restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Ni restauration SQLite ni restauration Maildir qualifiées."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N1-COMPOSE",
        "N2-IMAP",
        "N2-SMTP"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "1.7.4",
          "to": "1.7.4 — révision client compatible",
          "label": "Version Roundcube constante ; code client modifié, courrier limité au périmètre privé",
          "qualification": "verified"
        }
      ],
      "page": "apps-roundcube.html"
    },
    {
      "id": "N3-SNAPPYMAIL",
      "level": "N3",
      "slug": "snappymail",
      "name": "SnappyMail",
      "summary": "Lire et organiser une boîte privée avec contacts, dossiers, brouillons et envois contrôlés.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "SnappyMail 2.38.2 maintenu créé puis code compatible mis à jour sans LLM ; session, compte, contact, dossier, brouillon et message conservés, nouvel envoi privé reçu et relu.",
      "limitations": [
        "Version amont 2.38.2 constante ; aucune migration SnappyMail qualifiée.",
        "SMTP limité à la capture privée et au destinataire de contrôle ; aucune livraison ou réception Internet qualifiée.",
        "Bibliothèques embarquées et forks identifiés par les sources réelles ; aucun verrou Composer racine fourni par l’amont.",
        "Export de fichiers et copie SQLite distincts du Maildir ; aucune sauvegarde Maildir, restauration ni atomicité entre stockages qualifiée.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "bundled_source_inventory",
          "label": "Inventaire des sources distribuées",
          "description": "Inventaire vérifié des bibliothèques et sources embarquées dans la distribution."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "private_imap_binding",
          "label": "Raccordement IMAP privé",
          "description": "Compte et service de lecture des messages sous TLS, limités au consommateur autorisé."
        },
        {
          "name": "private_smtp_binding",
          "label": "Raccordement SMTP privé",
          "description": "Service de capture privée autorisé ; aucun envoi Internet implicite."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création déterministe depuis Git maintenu avec zéro LLM : connexion réelle, contact, dossier, brouillon, corps du message IMAP et réception SMTP privée vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même Git et version 2.38.2, code PHP et asset servis avec zéro LLM ; compte, session, contacts, dossiers, brouillon, message et raccordements conservés, nouvel envoi relu et reçu en privé."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Exports privés de fichiers vérifiés et copie SQLite de 40 960 octets téléchargée, empreinte, intégrité et contact contrôlés ; configuration et secret applicatif copiés en privé, Maildir et restauration non qualifiés."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Restauration SQLite, fichiers et Maildir non exercée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N1-COMPOSE",
        "N2-IMAP",
        "N2-SMTP"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "2.38.2 maintenu",
          "to": "2.38.2 maintenu — révision client compatible",
          "label": "Version amont constante ; création et mise à jour compatible sans LLM",
          "qualification": "verified"
        }
      ],
      "page": "apps-snappymail.html"
    },
    {
      "id": "N3-STRAPI",
      "level": "N3",
      "slug": "strapi",
      "name": "Strapi",
      "summary": "Gérer des contenus et médias puis les exposer via les API d’un CMS.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création 5.52.3 puis mise à jour 5.53.0 avec administrateur, article, média et base conservés.",
      "limitations": [
        "Une reprise conserve le dépôt et l’état du même projet ; elle ne recrée pas silencieusement l’application.",
        "La sauvegarde déclarée terminée n’a pas qualifié le téléchargement de son archive ni sa restauration.",
        "Contrat N3 limité aux deux configurations publiées ; restauration et charge supplémentaire non qualifiées.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "dependency_lock",
          "label": "Verrou des dépendances",
          "description": "Versions et empreintes des dépendances réellement utilisées."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "install",
          "label": "Installation",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Strapi 5.52.3 servi avec compte administrateur, article, média et données SQL vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "5.52.3 → 5.53.0 par Git dans le même projet ; données conservées et nouvelles écritures vérifiées."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Sauvegarde cliente déclarée terminée ; téléchargement du dump et restauration non testés."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création par paas.toml depuis le code personnalisé après correction produit et reprise du même projet ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Mise à jour par configuration, code client, compte, contenus et identités conservés puis nouvelles écritures ; aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-NODE",
        "N1-PERSIST",
        "N2-POSTGRESQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "5.52.3",
          "to": "5.53.0",
          "label": "Mise à jour applicative dans le même projet",
          "qualification": "verified"
        }
      ],
      "page": "apps-strapi-cms.html"
    },
    {
      "id": "N3-TYPO3",
      "level": "N3",
      "slug": "typo3",
      "name": "TYPO3",
      "summary": "Publier des pages, contenus riches et images avec un CMS PHP.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "TYPO3 14.3.7 créé puis code compatible mis à jour sans LLM ; compte, session, pages, média et réservations conservés, nouvelle page publiée.",
      "limitations": [
        "Version amont 14.3.7 constante ; aucune migration TYPO3 qualifiée.",
        "La variante Imagick de la base PHP qualifie un redimensionnement réel et les miniatures ; quatorze recettes PHP historiques conservées.",
        "Courrier désactivé ; extensions tierces, charge et haute disponibilité non qualifiées.",
        "Inventaire frontend conservateur du graphe de production amont, avec empreintes distinctes des fichiers distribués.",
        "Exports SQL et fichiers distincts ; restauration et atomicité conjointe non qualifiées.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "client_git_revision",
          "label": "Révision Git cliente",
          "description": "Commit exact du code personnalisé à construire et servir."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        },
        {
          "name": "composer_lock",
          "label": "Verrou Composer",
          "description": "Contrat des dépendances PHP fourni dans Git et contrôlé à la construction."
        },
        {
          "name": "bundled_vendor_inventory",
          "label": "Inventaire des dépendances distribuées",
          "description": "Inventaire exact des dépendances fournies dans Git avec la distribution."
        },
        {
          "name": "frontend_inventory",
          "label": "Inventaire du frontend",
          "description": "Fichiers frontend distribués et identités vérifiées ; leur présence ne prouve pas un graphe transitif complet."
        },
        {
          "name": "initial_account",
          "label": "Compte initial",
          "description": "Compte initialisé par la recette puis conservé ; identifiants et secrets restent privés."
        },
        {
          "name": "private_mysql_binding",
          "label": "Raccordement MySQL privé",
          "description": "Base et identité privées avec certificat et nom du service vérifiés."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis le Git client : compte, page, contenu riche, image originale et miniature natifs ; 18 contrôles et admission native, zéro appel LLM."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Code PHP et asset client modifiés dans le même Git, configuration inchangée et zéro LLM ; compte, session, pages, média, clé et réservations conservés, nouvelle page publiée."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Exports SQL de 42 tables et fichiers privés contrôlés avant et après ; archive native préalable de 211 fichiers vérifiée par empreinte, intégrité, configuration et image connues. Copies distinctes, sans restauration."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Restauration SQL et fichiers non exercée."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N1-COMPOSE",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "14.3.7",
          "to": "14.3.7 — révision client compatible",
          "label": "Version TYPO3 constante ; création et code client compatible sans LLM",
          "qualification": "verified"
        }
      ],
      "page": "apps-typo3.html"
    },
    {
      "id": "N3-UMAMI",
      "level": "N3",
      "slug": "umami",
      "name": "Umami",
      "summary": "Consulter les statistiques de pages et d’événements d’un site.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "3.3.0 corrigée → 3.3.1 avec compte, site et statistiques conservés, puis nouveaux événements consultables.",
      "limitations": [
        "Deux correctifs officiels d’authentification renforcée dans la référence ; dépendances corrigées sur les deux versions.",
        "Géolocalisation DB-IP City Lite septembre 2026 épinglée et attribuée ; actualisation par Git, couverture commerciale non supposée.",
        "Export agrégé du site de contrôle ; sauvegarde SQL complète, restauration et retour arrière non qualifiés.",
        "Charge, courrier, SSO et fonctions analytiques avancées non qualifiés par le seul scénario pages/événements.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "upstream_commit",
          "label": "Révision amont",
          "description": "Révision du logiciel fournisseur retenue et corrigée si nécessaire."
        },
        {
          "name": "security_backports",
          "label": "Correctifs rétroportés",
          "description": "Correctifs explicitement inclus dans la version de départ qualifiée."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "verified_static_assets",
          "label": "Assets vérifiés",
          "description": "Fichiers frontend dont l’origine et les empreintes ont été contrôlées."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Version corrigée créée par Git avec compte, refus du compte usine, site, page et événement consultables sur PostgreSQL privé."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "3.3.0 corrigée → 3.3.1 : compte, site, statistiques et identités conservés ; nouvelle page et nouvel événement consultables."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Export officiel agrégé du site de contrôle en CSV, contenu et empreinte vérifiés ; aucune sauvegarde SQL complète qualifiée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création neuve depuis Git personnalisé et paas.toml ; ressources et compte initialisés, usages vérifiés, aucun appel LLM."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet, code personnalisé, compte, données et identités conservés ; nouvelle écriture vérifiée, aucun appel LLM."
        }
      ],
      "dependencies": [
        "N1-NODE",
        "N2-POSTGRESQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "3.3.0 corrigée",
          "to": "3.3.1",
          "label": "Deux correctifs officiels d’authentification dans la référence",
          "qualification": "verified"
        }
      ],
      "page": "apps-umami.html"
    },
    {
      "id": "N3-WAGTAIL",
      "level": "N3",
      "slug": "wagtail",
      "name": "Wagtail",
      "summary": "Publier des pages et médias avec un CMS Python et des données persistantes.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "7.4.3 → 8.0 avec compte, page publiée et image originale conservés puis nouvelle publication lue.",
      "limitations": [
        "Des tests utilisant SQLite ne qualifient pas à eux seuls une migration PostgreSQL.",
        "Distribution et ABI sont explicites ; aucune version flottante d’image admise.",
        "Courrier externe, changement de fournisseur et restauration non qualifiés.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "published_wheels",
          "label": "Paquets Python publiés",
          "description": "Paquets binaires Python déjà préparés pour la recette."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Compte authentifié, image téléversée puis originale relue, page publiée puis consultée avec PostgreSQL privé."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "7.4.3 → 8.0 dans le même projet : compte, page, image et stockage conservés ; nouvelle publication lue."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Archive PostgreSQL téléchargée et contenu inspecté, média original et dépôt Git conservés ; aucune restauration exécutée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis le Git personnalisé et paas.toml, compte et services initialisés ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet, compte, données, code et identités conservés ; nouvelle opération métier et aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-PYTHON",
        "N1-PERSIST",
        "N2-POSTGRESQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "7.4.3",
          "to": "8.0",
          "label": "Mise à jour applicative avec PostgreSQL et médias conservés",
          "qualification": "verified"
        }
      ],
      "page": "apps-wagtail.html"
    },
    {
      "id": "N3-WOOCOMMERCE",
      "level": "N3",
      "slug": "woocommerce",
      "name": "WooCommerce",
      "summary": "Gérer produits et commandes dans une boutique WordPress.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "11.0.1 → 11.1.0 sur WordPress 7.1 ; scénario qualifié avec produit virtuel gratuit, commande et stock.",
      "limitations": [
        "Le scénario utilise un produit gratuit, sans paiement ni courrier externe.",
        "Taxes, paiement, livraison, charge et suite fonctionnelle complète non qualifiés.",
        "Distribution fournisseur complète dans Git ; versions, thèmes et plugins restent des paramètres ou personnalisations à vérifier.",
        "Export SQL, média de contrôle et Git conservés ; sauvegarde de portée limitée et restauration non qualifiée.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "official_archive_sha256",
          "label": "Empreinte de distribution",
          "description": "Empreinte de l’archive fournisseur complète retenue dans Git."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "11.0.1 sur WordPress 7.1 : compte, média, produit virtuel gratuit, commande invitée et stock vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "11.0.1 → 11.1.0 dans le même projet : migration de schéma terminée, identités et données conservées, nouvelle commande et stock vérifiés."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Tables de la boutique exportées avec commande de référence contrôlée ; média et dépôt Git conservés avec empreintes."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création depuis le Git personnalisé et paas.toml, compte et services initialisés ; aucun LLM sur le push qualifié."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet, compte, données, code et stockage conservés ; nouvelle opération métier et aucun LLM sur le push qualifié."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "11.0.1",
          "to": "11.1.0",
          "label": "Sur WordPress 7.1 ; paiement et courrier externes non qualifiés",
          "qualification": "verified"
        }
      ],
      "page": "apps-woocommerce.html"
    },
    {
      "id": "N3-WORDPRESS",
      "level": "N3",
      "slug": "wordpress",
      "name": "WordPress",
      "summary": "Publier articles et médias dans un CMS, avec code et configuration versionnés dans Git.",
      "contract_version": "1.0.0",
      "status": "verified",
      "status_label": "Vérifié dans la portée indiquée",
      "scope": "Création 7.0.4 puis mise à jour 7.1 dans le même projet, administrateur, contenus et médias conservés.",
      "limitations": [
        "Cœur, plugins et thèmes livrés par Git ; installation et modification automatiques depuis le CMS désactivées.",
        "Sauvegarde logique bornée à 16 Mio et média de contrôle ; sauvegarde générale de tous les médias et restauration non qualifiées.",
        "Contrat N3 limité aux deux configurations publiées ; autres versions, forks et courses entre reprises exigent leurs propres preuves.",
        "Scénarios vérifiés, sans certification indépendante ni disponibilité générale déduite."
      ],
      "parameters": [
        {
          "name": "application_source",
          "label": "Sources applicatives",
          "description": "Code personnalisé réellement versionné dans Git et soumis aux contrôles."
        },
        {
          "name": "baseline_version",
          "label": "Version de départ",
          "description": "Version exacte, correctifs compris, du scénario de référence."
        },
        {
          "name": "target_version",
          "label": "Version cible",
          "description": "Version ou révision client exacte visée par la mise à jour."
        },
        {
          "name": "official_archive_sha256",
          "label": "Empreinte de distribution",
          "description": "Empreinte de l’archive fournisseur complète retenue dans Git."
        },
        {
          "name": "client_account",
          "label": "Compte applicatif",
          "description": "Compte créé ou conservé par le parcours de la recette ; ses secrets restent privés."
        },
        {
          "name": "single_project_state",
          "label": "État du même projet",
          "description": "Identités et données conservées pendant la mise à jour ou la reprise."
        },
        {
          "name": "capability_lock",
          "label": "Verrou des capacités",
          "description": "Versions et dépendances exactes de la composition retenue."
        },
        {
          "name": "paas_toml",
          "label": "Configuration versionnée",
          "description": "Configuration paas.toml du même dépôt Git que le code client."
        }
      ],
      "operations": [
        {
          "id": "create",
          "label": "Création",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "WordPress 7.0.4 créé depuis Git avec compte administrateur, article, média, MySQL privé et volumes vérifiés."
        },
        {
          "id": "upgrade",
          "label": "Mise à jour",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "7.0.4 → 7.1 dans le même projet : administrateur, contenu, média, base et volumes conservés puis nouvelles écritures."
        },
        {
          "id": "backup",
          "label": "Sauvegarde ou export",
          "status": "partial",
          "status_label": "Partiel",
          "scope": "Tables SQL téléchargées en sauvegarde logique et média de contrôle copié avec empreinte vérifiée ; restauration non testée."
        },
        {
          "id": "restore",
          "label": "Restauration",
          "status": "not_verified",
          "status_label": "Non vérifié",
          "scope": "Aucune restauration qualifiée."
        },
        {
          "id": "configuration_create",
          "label": "Création par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Création neuve depuis Git personnalisé et paas.toml ; ressources et compte initialisés, usages vérifiés, aucun appel LLM."
        },
        {
          "id": "configuration_upgrade",
          "label": "Mise à jour par configuration N3",
          "status": "verified",
          "status_label": "Vérifié dans la portée indiquée",
          "scope": "Même projet, code client, compte, données et identités conservés ; nouvelle écriture vérifiée et aucun appel LLM."
        }
      ],
      "dependencies": [
        "N1-PHP",
        "N1-PERSIST",
        "N2-MYSQL"
      ],
      "consumers": [],
      "versions": [
        {
          "from": "7.0.4",
          "to": "7.1",
          "label": "Mise à jour applicative avec PHP et MySQL conservés",
          "qualification": "verified"
        }
      ],
      "page": "apps-wordpress.html"
    }
  ]
}
