Qualification hors ligne des applications AGILAB
Le harnais tools/testing/agilab_offline_app_qualification.py exécute des
contrôles explicitement choisis avec des environnements déjà provisionnés. Il
n’installe aucune dépendance. Les manifestes, les données et les reçus privés
restent dans un répertoire de qualification extérieur au dépôt public.
Manifeste et commande
Le schéma est agilab.offline_app_qualification_manifest.v1. Chaque source
déclare un root absolu, sa révision Git exacte de 40 caractères et des
paths relatifs. Chaque contrôle fournit id, app, layer, scope,
argv et cwd. Les couches sont science, web et notebook.
Utiliser un Python absolu propre à l’environnement isolé dans argv et
control_python. env complète son environnement ; timeout vaut entre
1 et 1800 secondes. network choisit deny_all ou loopback.
{output} est remplacé dans les arguments par le répertoire de preuves.
Un junit désigne un XML de tests exécutés ; json_evidence désigne un JSON
dont status doit valoir passed. artifacts déclare les autres fichiers
à conserver et à vérifier. Ces chemins de preuves sont relatifs à la sortie.
Exemple de commande, après création d’un manifeste contenant de vrais contrôles scientifiques et des chemins absolus résolus :
tokki run -- uv run --no-sync python tools/testing/agilab_offline_app_qualification.py \
--manifest "$QUALIFICATION_ROOT/agilab_offline_science_manifest.json" \
--output-dir "$QUALIFICATION_ROOT/agilab_offline_science_evidence"
La sortie doit être nouvelle. Une session agent gérée emploie le préfixe authentifié fourni par son hook pour cette commande. Un nom de test, un import réussi ou une sortie zéro ne suffit pas à établir une fonction scientifique.
Sources et reçus
Le harnais vérifie la révision, l’absence de modifications suivies et les hashes
des sources avant et après exécution. Il refuse les entrées non suivies dans les
périmètres déclarés, y compris le code masqué par des règles Git d’exclusion.
Les caches Python canoniques sont liés à une source suivie et leurs octets sont
hashés, même pour un périmètre limité à un fichier. Les caches de test et de
typage non exécutables, les métadonnées de construction reconnues et uv.lock
restent des sous-produits exclus. Le bytecode sans source et le code ajouté dans
un répertoire portant un nom de cache sont refusés.
Le hash du manifeste correspond aux octets lus avant le calcul. Une modification
du manifeste, du harnais ou des entrées liées invalide la qualification. Les
preuves JSON imbriquées gardent leur chemin relatif complet. Vérifier aussi les
modules effectivement chargés, leur __file__ et le bundle des vues : une
révision déclarée ne choisit pas automatiquement les imports de l’environnement.
Chaque reçu conserve les contrôles réseau, la portée annoncée, les sorties et leurs hashes. Les tests entièrement ignorés restent bloqués. Les couches non exécutées restent non qualifiées. Une reprise crée de nouveaux reçus ; les échecs et les contrôles ignorés précédents restent intacts.
Réseau et processus
Le backend actuel nécessite macOS et sandbox-exec. deny_all refuse le
réseau, y compris la boucle locale. loopback autorise la boucle locale et les
sockets Unix nécessaires au navigateur et au noyau Jupyter ; les connexions IP
externes restent refusées. Les sondes vérifient le refus externe dans le
processus et un enfant avant les contrôles. Cela décrit une exécution contrainte
par le système, sans établir un isolement physique du poste.
Le nettoyage lie les descendants observés à leur PID et à leur instant de création. Un enfant détaché observé est arrêté et vérifié ; une erreur concernant un processus vivant reste un échec. Ce mécanisme ne garantit pas le confinement d’un descendant très rapidement daemonisé avant son observation.
Provisionnement et portée vérifiée le 8 octobre 2026
Provisionner les fermetures de dépendances des gestionnaires, travailleurs et contrôles choisis dans des environnements et caches dédiés hors dépôt. Les téléchargements appartiennent à cette phase préalable. En exécution, le réseau externe reste bloqué et aucune installation n’est effectuée. Conserver les logs, les versions, les contrôles de cohérence et les hashes ; préserver les environnements de l’utilisateur et les données absentes.
Les preuves existantes couvrent 14 projets intégrés et 9 projets privés par des périmètres scientifiques réels explicitement nommés. Au total, les périmètres réussis contiennent 212 cas JUnit exécutés sans cas ignoré, dont 96 contrôles de planification et de contrôle du CLI privé. Des travailleurs réels et un dispatch multi-application produisent également des artefacts vérifiés hors JUnit.
Ces résultats ne qualifient pas toutes les fonctions de chaque application. Le dataplane réel du CLI reste bloqué sur macOS : il exige un noyau Linux, les outils réseau et les privilèges nécessaires au contrôle réel. Les contrôles de planification ne remplacent pas cette exécution.
La vue native spécialisée et l’export spécialisé commun exécuté dans un noyau frais disposent de preuves séparées. Les anciens notebooks de test avec des données externes absentes ne constituent pas des workflows exposés qualifiés. Le bundle d’un nouveau candidat doit recevoir sa propre vérification de parité web et notebook avant de reprendre les résultats d’une version précédente.