Version 1.0.0
Les garde-fous d'exécution
Ce qui borne une session d'agent : bac à sable, politique, validation humaine, bornes de session, détection de boucle et délégation.
Une session d’agent est une suite d’actions proposées par le modèle et exécutées, ou non, par le système. Lemniscate part du principe que l’agent peut mal se comporter, par erreur ou sous l’effet d’un contenu piégé, et construit l’environnement de sorte que ce comportement reste sans conséquence hors du bac à sable (livre blanc sécurité V3, section 4).
Le confinement borne ce que l’agent peut atteindre. La politique borne ce qu’il peut faire à l’intérieur. Cette page décrit les deux, puis les garde-fous qui arrêtent un agent qui tourne trop longtemps, tourne en rond ou sort du projet.
Les sept garanties d’une session
Section intitulée « Les sept garanties d’une session »Sept garanties sont tenues par la passerelle et le bac à sable, et non par le modèle. Elles sont indépendantes les unes des autres (livre blanc sécurité V3, section 4.1).
| Garantie | Énoncé | Où elle est décrite |
|---|---|---|
| G01 | périmètre limité à la copie du dépôt autorisé par la politique du projet | Ce que l’agent voit |
| G02 | validation humaine de chaque écriture retenue, présentée en différence | La validation humaine |
| G03 | politique de commandes définie par l’administrateur, appliquée par la passerelle | La politique de projet et de commandes |
| G04 | exécution confinée dans un bac à sable jetable | Le bac à sable d’exécution |
| G05 | aucune destination réseau accessible, ni externe ni interne | Le bac à sable d’exécution |
| G06 | traçabilité : consigne, actions proposées, décisions, résultats | Le cycle d’une session agentique |
| G07 | arrêt par le développeur et révocation par l’administrateur, à tout moment | L’arrêt et la révocation |
Le bac à sable d’exécution
Section intitulée « Le bac à sable d’exécution »La frontière de sécurité est le bac à sable, non la liste des commandes autorisées. Une liste de commandes relève de l’hygiène : un interpréteur autorisé exécute n’importe quoi. Ce qui borne l’agent est l’environnement dans lequel il s’exécute (livre blanc sécurité V3, section 4.2).
| Aspect | Ce que le bac à sable impose |
|---|---|
| Isolation | un bac à sable par session, créé à la demande et détruit en fin de session ; aucun état partagé entre sessions ni entre projets ; exécution sans privilège, sous profils seccomp et AppArmor |
| Fichiers | la copie de travail du dépôt est le seul volume en écriture ; le système de fichiers racine est en lecture seule ; les écritures sont restituées sous forme de différence |
| Réseau | aucune interface, aucune sortie, aucune résolution de noms ; les échanges avec le modèle sont relayés par la passerelle ; un seul canal de contrôle, ouvert par la passerelle |
| Ressources | durée, processeur, mémoire et processus plafonnés ; arrêt automatique au dépassement, journalisé ; rien ne subsiste après la session |
L’absence de sortie réseau est imposée par l’isolation elle-même, non par une configuration que l’agent pourrait modifier. Les profils de confinement sont fournis et s’adaptent à vos standards. Sur un hôte d’exécution partagé entre plusieurs projets, l’isolation peut être portée par une micro-machine virtuelle ou un noyau en espace utilisateur, selon votre référentiel.
La préparation de l’image utilisée par le bac à sable est décrite dans Préparer le conteneur de session.
Ce que l’agent voit, ce qu’il ne porte pas
Section intitulée « Ce que l’agent voit, ce qu’il ne porte pas »Un agent qui ne détient aucun secret ne peut pas en faire fuiter (livre blanc sécurité V3, section 4.3).
| Ce que l’agent voit | Ce qu’il ne porte pas |
|---|---|
| les fichiers du dépôt ouvert, hors exclusions de contexte | aucun compte, aucune identité sur la forge |
| les sorties des commandes qu’il exécute | aucune clé, aucun jeton, aucun secret monté |
| la consigne du développeur | aucune variable d’environnement du poste |
| rien d’autre sur l’hôte ni sur le poste | aucun accès à un autre dépôt ou à un autre projet |
Les exclusions de contexte désignent les fichiers que l’agent ne voit pas dans la copie de travail : fichiers d’environnement, répertoires de secrets, certificats. Le répertoire personnel du développeur, ses clés, ses identifiants de forge et ses variables d’environnement ne sont pas montés dans le bac à sable.
L’agent n’a pas de compte et ne pousse rien. La différence validée est appliquée au dépôt du développeur, qui l’intègre sous sa propre identité, par ses outils habituels et dans ses circuits de revue.
Hôte d’exécution dédié ou poste
Section intitulée « Hôte d’exécution dédié ou poste »Le bac à sable s’exécute sur un hôte dédié ou sur le poste. Le mode de référence est l’hôte dédié (livre blanc sécurité V3, section 4.4).
| Hôte d’exécution dédié, mode de référence | Bac à sable sur le poste, variante |
|---|---|
| bacs à sable sur un hôte distinct de la passerelle | conteneur sans privilège et sans réseau, sur le poste |
| aucun moteur de conteneurs sur les postes | dépôt local monté, seul volume en écriture |
| environnement unique, durci par l’administrateur | chaînes de compilation du poste disponibles |
| retenu pour les périmètres sensibles et Diffusion Restreinte | pour les socles qui admettent un moteur de conteneurs |
Dans le mode de référence, l’agent n’a pas les droits de l’utilisateur sur son poste, et le poste ne porte que l’extension. L’hôte d’exécution ne conserve aucun état. La contrepartie : l’hôte concentre les bacs à sable de plusieurs projets, ce qui justifie une isolation renforcée, et une copie du dépôt y transite le temps de la session. Le choix se fait par périmètre, avec le responsable de la sécurité. Le réglage qui porte ce choix est décrit dans Le cycle d’une session agentique.
La politique de projet et de commandes
Section intitulée « La politique de projet et de commandes »La politique est écrite par l’administrateur dans la console, évaluée par la passerelle avant chaque action, et n’est pas interprétée par le modèle. Elle ne peut pas être désactivée depuis un poste (livre blanc sécurité V3, section 5.1).
| Libres, si l’administrateur le décide | Soumises à la validation du développeur |
|---|---|
| compilation, tests unitaires, formatage et analyse | toute commande absente de la liste |
| lecture de fichiers du dépôt ouvert | toute écriture retenue, présentée en différence |
| commandes listées par l’administrateur | tout outil marqué sensible par la politique |
| commande déjà validée, si la politique le permet | toute modification d’un fichier exécuté par un tiers |
Par défaut, aucune commande n’est libre : chaque modification et chaque commande sont présentées au développeur. L’administrateur de projet peut :
- autoriser les commandes usuelles de compilation, de test et d’analyse, et toute commande qu’il liste ;
- désactiver un outil de l’agent pour un projet, sans redéploiement ;
- autoriser le développeur à ne pas revalider une commande déjà validée, ou interdire cette dispense.
Toute modification de politique est journalisée. La façon de l’écrire est dans Régler la politique des postes depuis la console.
Le contrôle séparé des données
Section intitulée « Le contrôle séparé des données »La défense contre l’injection d’instructions est structurelle : elle ne repose pas sur un filtre (livre blanc sécurité V3, section 5.2).
- La consigne du développeur est la seule source de contrôle.
- Le contenu lu dans le dépôt, dans une sortie de commande ou dans une dépendance est marqué comme non fiable et présenté au modèle dans une zone distincte.
- Les outils disponibles sont fixés par la politique avant toute lecture. Un contenu lu ne peut pas en activer de nouveaux.
- La politique s’applique à chaque appel d’outil.
Le modèle raisonne sur tout le contexte, mais il ne tient pas les droits. Une injection reste possible : l’architecture garantit que son effet ne sort pas du bac à sable et passe devant un humain (livre blanc sécurité V3, section 11.4).
Les fichiers exécutés par des tiers
Section intitulée « Les fichiers exécutés par des tiers »Un agent confiné peut modifier un fichier que quelqu’un d’autre exécutera plus tard, avec d’autres droits. Ces fichiers forment une classe à part (livre blanc sécurité V3, section 5.3) :
- la configuration d’intégration continue et les scripts de build ;
- les hooks du gestionnaire de versions et les fichiers de configuration du dépôt ;
- les manifestes de dépendances et les fichiers de verrouillage ;
- les fichiers binaires et les différences au-delà d’un seuil de taille.
Leur modification est interdite par défaut, ou soumise à une validation dédiée, distincte de la validation ordinaire d’une différence et signalée comme telle au développeur. La liste des classes est définie par projet dans la politique.
La validation humaine
Section intitulée « La validation humaine »Toute action à effet de bord est validée par un humain (livre blanc sécurité V3, section 5.4) :
- toute écriture retenue est présentée sous forme de différence et acceptée par le développeur ;
- toute commande non listée par l’administrateur est soumise à validation avant exécution ;
- l’administrateur peut retirer un outil à l’agent, par projet, sans redéploiement ;
- le développeur peut arrêter la session à tout moment, et l’administrateur peut la révoquer.
La demande de validation montre la différence ou la commande exacte, et signale les fichiers exécutés par des tiers.
Le code proposé peut contenir des vulnérabilités : la revue humaine reste nécessaire, et le code accepté suit les mêmes circuits de revue que toute contribution (livre blanc sécurité V3, section 11.4).
L’arrêt et la révocation
Section intitulée « L’arrêt et la révocation »Le développeur dispose d’un arrêt en un geste depuis son environnement. Il interrompt le travail en cours, détruit le bac à sable et rejette les écritures non validées. L’administrateur dispose d’une révocation depuis la console, par session ou par utilisateur, effective sans redémarrage et journalisée (livre blanc sécurité V3, section 4.5).
Tourner trop longtemps : les bornes de session
Section intitulée « Tourner trop longtemps : les bornes de session »Toute session a une fin prévue. Quatre budgets la bornent : la durée, le volume d’échanges avec le modèle, le nombre de commandes et les ressources du bac à sable. Leur dépassement provoque un arrêt propre (livre blanc sécurité V3, section 4.5).
Chaque message de l’utilisateur ouvre une session bornée en actions (appels d’outils et compactions de contexte confondus, 150 par défaut) et en durée (45 minutes par défaut). Le message suivant repart avec un budget entier.
Quand une borne est atteinte :
- En session interactive, une extension peut être demandée à l’humain. Chaque extension accorde une dotation limitée (50 actions ou 15 minutes), leur nombre est plafonné (5 par défaut), et chacune laisse une trace dans le journal d’audit.
- Sans extension, l’agent produit un résumé de son travail (fait, en cours, reste à faire) dans un dernier tour de modèle où aucun outil n’est disponible : rien ne s’exécute après l’épuisement.
- Le message d’arrêt dit qu’il s’agit d’une borne, pas d’une fin de tâche.
En mode non interactif (lemni -p), il n’y a personne à qui demander une
extension : la session s’arrête avec le code de sortie 3, distinct d’une
réussite (0) et d’un plantage (1). Un script sait ainsi que le travail n’est
pas fini sans le confondre avec une erreur.
Les bornes se règlent dans le fichier de configuration, sous la clé execution :
execution: sessionMaxActions: 150 sessionMaxMinutes: 45 sessionMaxExtensions: 5Les variables d’environnement LEMNISCATE_SESSION_* sont lues en repli, et la
configuration prend le pas. Ce repli vaut sur les deux surfaces : dans l’éditeur
comme au terminal, la précédence est défauts, puis environnement, puis
configuration. Une valeur illisible est refusée avec un message ; elle n’est pas
remplacée par le défaut. Le repli d’environnement est résolu une fois par
processus : après avoir corrigé la variable, redémarrez l’éditeur pour qu’elle
soit relue.
Tourner en rond : la détection de boucle
Section intitulée « Tourner en rond : la détection de boucle »Le plafond borne la longueur ; il ne voit pas un agent qui relit vingt fois le même fichier. La détection de boucle attrape ce cas : quand le même appel d’outil, avec exactement les mêmes arguments, revient une quatrième fois de suite, l’appel est bloqué avant de s’exécuter et la session est rendue à l’utilisateur, avec ce qui bouclait.
Deux choix sont à connaître :
- Le modèle reçoit un message explicite, « bloqué pour répétition, ne réessaie pas ». Sans ce message, il réessaierait et le garde-fou deviendrait lui-même la boucle.
- La fenêtre est consécutive : relire un fichier après l’avoir modifié, ou le relire trois fois au fil d’une longue session, ne déclenche rien.
En mode non interactif, le code de sortie est le même, 3 : du point de vue d’un script, un garde-fou a arrêté l’agent.
execution: toolLoopThreshold: 3 # répétitions identiques consécutives tolérées toolLoopDetection: false # désactivation possible, mais toujours expliciteSortir du projet : les périmètres fichier
Section intitulée « Sortir du projet : les périmètres fichier »Le périmètre de l’agent est la copie du dépôt autorisé par la politique du projet (garantie G01). Les outils de fichiers appliquent ce périmètre avant toute lecture ou écriture, en plus du confinement du bac à sable. « Le projet » est la racine du dépôt git (le répertoire de travail hors dépôt), les liens symboliques sont résolus avant contrôle, et un fichier à créer est jugé sur son chemin.
- En écriture comme en lecture (
Read,List,Search), un chemin hors du projet est refusé, avec la raison, sans demande de permission : le terminal tourne souvent sans personne pour répondre, et une demande sans interlocuteur est un blocage. - Les commandes shell (
Bash) ne passent pas par ce contrôle de chemin : elles sont analysées par leur propre garde-fou (@lemniscate/terminal-security), et bornées par le bac à sable.
Les agents : un seul format, des droits qui se restreignent
Section intitulée « Les agents : un seul format, des droits qui se restreignent »Un agent est un fichier Markdown : le frontmatter YAML porte la configuration, le corps du fichier est le prompt système.
---description: Relit le code avant une PRtools: Read, SearchsessionMaxActions: 25---
Tu es un relecteur de code exigeant…- Le nom du fichier est le nom de l’agent.
revue.mds’invoque parlemni --agent revue. Un champnamedans le frontmatter est ignoré avec un avertissement, et une version future le refusera. - Les agents sont découverts dans
.lemniscate/agents/du projet et dans~/.lemniscate/agents/. En cas de collision de noms, celui du dépôt l’emporte. Un agent découvert est disponible ; il n’est pas actif de lui-même. - Charger un agent n’élargit pas les droits. Un agent sans clé
toolshérite des permissions de l’utilisateur, une listetoolsdéclarée ferme le catalogue au lieu de l’ouvrir, et le modeplansurvit au chargement d’un agent. sessionMaxActionsdans le frontmatter surcharge le plafond global pour les sessions que cet agent pilote.disable: trueretire un agent sans supprimer son fichier ;hidden: truele masque de l’autocomplétion tout en le laissant invocable par son nom.
Activer un agent dans l’éditeur
Section intitulée « Activer un agent dans l’éditeur »Depuis VS Code et JetBrains, un agent découvert s’active par le sélecteur d’agent de la barre de saisie, à côté des sélecteurs de mode et de modèle. Le sélecteur affiche le nom de l’agent actif tant qu’il pilote la session, et No agent au repos. Il ne propose que les agents activables, et ne s’affiche pas quand aucun agent n’est découvert.
Une activation applique, à parité avec lemni --agent :
- la persona (le corps du fichier), qui devient le prompt système de la session ;
- la liste
tools, qui ferme le catalogue : un outil non listé, outils MCP compris, n’est pas proposé au modèle, et l’agent ne peut que restreindre (un outil désactivé par vos réglages reste exclu quoi que déclare l’agent, le mode chat reste sans outils, le mode plan reste en lecture seule) ; sessionMaxActions, qui borne la session pilotée, avec la même précédence qu’au terminal (défauts, environnement, configuration, agent) ;- le
modeldéclaré, sélectionné s’il correspond à un modèle configuré. S’il est introuvable, un avertissement s’affiche et le modèle courant est conservé.
Les refus sont ceux du terminal : un agent mode: subagent est réservé à
l’outil de délégation, disable: true n’est ni listé ni activable, et un
homonyme des noms réservés general et explore est écarté et signalé.
L’activation est un état de session : une nouvelle session repart sans agent,
et un rechargement de configuration qui fait disparaître l’agent actif (fichier
supprimé, passé disable, devenu mode: subagent) le désactive en l’annonçant.
Deux limites sont annoncées à l’activation :
- la clé
rules(paquets de règles du registre) n’est pas chargée par l’éditeur : la persona et les restrictions d’outils s’appliquent, les règles du registre non ; - une référence MCP de la liste
tools(owner/paquetou URL) est résolue par l’éditeur contre le nom du serveur configuré, pas contre le slug du registre comme au terminal. Si aucun serveur configuré ne porte ce nom, tous les outils de la référence restent exclus : la fermeture joue dans le sens de la restriction.
La délégation à des sous-agents
Section intitulée « La délégation à des sous-agents »L’agent dispose d’un outil de délégation (Task) : il confie une consigne à un
sous-agent, qui tourne dans sa propre session, avec son propre contexte et ses
propres garde-fous, et rend un rapport final. Le modèle mental est développé dans
Déléguer à des sous-agents, et la
marche à suivre dans
Déléguer une tâche à un sous-agent.
Les règles :
- Rien n’est délégable sans
modeexplicite. Un agent découvert dans un dépôt ou sur le poste n’est pas délégable par sa seule présence : son frontmatter doit déclarermode: subagent(délégable par un agent seulement) oumode: all(délégable et invocable par l’utilisateur). Sansmode, un agent reste invocable par l’utilisateur seulement. - Deux sous-agents intégrés au produit sont délégables sans installation :
general(généraliste) etexplore(explorateur en lecture seule, qui ne déclare queRead,List,Search). Leurs noms sont réservés sur les deux entonnoirs : un fichier découvert homonyme est signalé et écarté de la délégation, et il n’est pas non plus invocable par--agent general. Charger un tel fichier reste possible en passant son chemin.mdexplicite. - Un sous-agent n’élargit pas les droits du parent. Sa politique est celle du
parent, restreinte par sa persona : un outil exclu chez le parent reste exclu
chez lui quoi que déclare son frontmatter, le mode
plandu parent le laisse en lecture seule, et un serveur MCP non déclaré ne lui est ni décrit ni accessible. - La cascade est bornée par des filets globaux, réglables sous la clé
execution:subagentMaxDepth(profondeur, défaut 3 ;1interdit toute imbrication),subagentMaxPerSession(défaut 200) etsubagentMaxConcurrent(défaut 20). Quand une limite est atteinte, l’agent reçoit une erreur explicite et finit le travail lui-même. Zéro est refusé sur ces clés : un filet de cascade se règle, il ne se retire pas. - Le budget d’un sous-agent est propre (rien ne se décompte du parent) et sans
plafond d’actions par défaut ; un
sessionMaxActionsposé dans son frontmatter s’applique, et la détection de boucle reste active dans chaque sous-agent. Un arrêt sur garde-fou dans le sous-agent est marqué dans le rapport rendu au parent, qui distingue « travail coupé » de « travail fini ». - La borne de durée d’un sous-agent vient de la configuration du poste (défaut 45 minutes), pas du temps déjà consommé par le parent : chaque session fille repart avec son budget de durée entier, et sans extension possible, faute d’humain dans la session fille.
- Les demandes de permission remontent à vous, pas au modèle. En session
interactive, un outil en
askchez un sous-agent s’affiche sur l’écran d’approbation habituel, le point d’approbation unique : il n’y a qu’une surface humaine par processus, toutes les demandes de l’arbre y convergent, et chacune est étiquetée du nom de l’agent qui demande. Ce nom est le nom de fichier de l’agent, tel quel : seuls les deux noms intégrés (general,explore) sont protégés contre l’homonymie ; un agent découvert au nom trompeur reste affiché sous ce nom. En non-interactif (mode-p,lemni serve, tâche d’arrière-plan), la demande devient un refus sec et annoncé, sans auto-approbation par le modèle, et le journal des appels d’outils attribue ce refus à l’automate. - L’outil
Questionest offert à la session principale, dans un terminal interactif ; un agent délégué ne l’a pas dans son catalogue. Face à une ambiguïté, la session principale vous pose une question au point d’approbation, avec des options proposées ou une réponse libre. Échap la rejette, et l’agent annonce alors son hypothèse et continue. Sans utilisateur joignable, la réponse est un défaut annoncé, qui demande au modèle d’énoncer son hypothèse et de poursuivre. - Arrière-plan :
Taskavecbackground: truerend immédiatement untask_idet le sous-agent tourne détaché. La fin est annoncée dans la conversation (cloche du terminal en opt-in :LEMNISCATE_NOTIFY_BELL=1), et le rapport se lit avec l’outilTaskResultou dans la session fille persistée. En exécution ponctuelle (lemni -p), l’arrière-plan se replie en exécution synchrone annoncée, parce que le processus ne survit pas au tour. Surlemni serve, processus durable même sans écran, le détachement est réel et les événementstask/startedettask/settledl’annoncent sur le flux d’événements ; les demandes de permission d’une tâche détachée y restent au refus sec, comme partout où personne ne peut approuver. Une tâche détachée meurt avec le processus qui la porte : fermer le terminal (ou arrêter le serveur) interrompt les tâches en cours, sans annonce, et leur trace s’arrête dans la session fille persistée. - Mention
@dans le terminal :@general <consigne>lance vous-même un sous-agent délégable, en tâche détachée, sous les mêmes filets globaux que les délégations du modèle. Tout autre@garde son sens de mention de fichier. - Interrompre le parent interrompt ses délégations : l’interruption d’un tour se propage aux sous-agents synchrones en cours, et leur rapport revient marqué « interrompu ». Une tâche détachée survit au tour et reste bornée par sa durée, sa détection de boucle et les filets globaux.
- La session fille est persistée comme une session ordinaire : ce que le sous-agent a fait se relit après coup.