bots-garden/mini-mepublic Fork
⑂ feature/go-1.27.3
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/mini-me.git
git clone ssh://git@rickub.com/bots-garden/mini-me.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
🛟 Updated. 46087c3 · on feature/go-1.27.3 · k33g · 8d ago
yolo-and-permissions.md · 54 lines · 7.7 KBmarkdown
Blame HistoryOpen raw

Le mode yolo et les permissions — explication

De quoi s'agit-il ?

Un agent de code exécute des commandes et écrit des fichiers sur votre machine. Quelqu'un doit décider si chacun de ces appels peut s'exécuter : soit l'utilisateur, appel par appel, soit personne, parce que l'utilisateur a décidé une fois pour toutes de laisser l'agent agir. mini-me appelle ce second choix le mode yolo et en fait un seul réglage, yolo, lu de la même façon par les trois façades — le mode ligne, la fenêtre et l'éditeur (ACP) — et par un agent interrogé par un autre.

Pourquoi yolo est la valeur par défaut

mini-me est conçu pour piloter un petit modèle local à travers de nombreuses étapes courtes. Demander avant chaque ls rend cette boucle inutilisable en pratique, et le mode ligne — la première façade — ne demandait jamais. Avant ce réglage, le comportement dépendait de l'endroit où l'on lançait mm : le mode ligne ne demandait jamais, la fenêtre demandait seulement avec permissions: ask, et l'éditeur demandait toujours, qu'on le veuille ou non. Le même fichier d'agent ne voulait pas dire la même chose à trois endroits.

La valeur par défaut a donc été fixée sur ce que faisaient déjà la plupart des exécutions — agir sans demander — et la protection est devenue un choix délibéré et visible : yolo: false. La bannière dit dans quel sens le réglage est posé (yolo: on / yolo: off (tools ask)), pour que personne ne le découvre par surprise, dans un sens comme dans l'autre. La conséquence à connaître : dans un éditeur, le dialogue de permission n'apparaît qu'avec yolo: false ; avant, il apparaissait toujours.

Exister ou demander

Deux questions différentes sont volontairement séparées :

  • L'outil existe-t-il ? bashTool, editTools, fetchContentTool. Un outil qui n'existe pas n'est pas du tout déclaré au modèle ; il ne peut même pas essayer.
  • Un outil qui existe demande-t-il avant de s'exécuter ? yolo.

Ainsi, yolo: true avec bashTool: false est un agent qui modifie librement les fichiers mais n'a pas de shell, et yolo: false avec bashTool: true est un agent qui a un shell mais a besoin de votre accord pour chaque commande. Fusionner les deux en une valeur à trois états (bashTool: ask) a été envisagé puis écarté : il aurait fallu la répéter pour chaque outil, alors que la vraie décision — « est-ce que je fais confiance à cet agent pour agir seul, maintenant ? » — est unique.

Seuls les appels qui modifient quelque chose demandent : bash, write_file, edit_file, fetch_content quand il enregistre, rename de lsp, et les actions de plan qui modifient un plan. Les lectures (read_file, read_skill, les actions de navigation de lsp, fetch_content sans output) ne demandent jamais : une question à chaque lecture apprend aux gens à cliquer « autoriser » sans lire.

Quatre réponses, une mémoire

Quand un appel demande, la réponse peut valoir une fois ou pour la session, et oui ou non : autoriser une fois, autoriser cet outil pour la session, refuser cet appel, ne jamais autoriser cet outil dans cette session. « Jamais » existe parce qu'un refus qui ne dure qu'un appel oblige à refuser la même nouvelle tentative encore et encore ; « refuser une fois » existe parce que sans lui, la seule façon de dire non serait définitive. Les réponses mémorisées d'une session le sont par nom d'outil, survivent à /new (l'éditeur voit toujours la même session) et disparaissent quand mm s'arrête.

Les règles vivent dans un seul paquet, internal/consent : la vérification de yolo (Gate), les quatre réponses (Answer), ce qu'une session retient (Policy) et le point d'accroche de l'invite du mode ligne. Chaque façade se contente de dessiner la question à sa manière — une ligne 🔐, la zone de la fenêtre, le dialogue de l'éditeur. Auparavant, chaque façade avait sa propre table « autorisé pour la session », et les trois avaient déjà commencé à diverger.

Pourquoi l'agent qui interroge décide

Avec mmConfigs, un agent peut en interroger un autre (/ask-jan, mm --ask jan). Deux fichiers de configuration, deux valeurs de yolo : laquelle l'emporte ? Celle de l'agent que l'utilisateur a lancé. C'est le seul agent qui a un utilisateur en face de lui, et l'utilisateur a choisi sa configuration pour cette session ; le fichier de l'agent interrogé a été écrit pour une autre situation — peut-être pour tourner seul en mode yolo.

Techniquement, l'agent interrogé est lancé avec AGENT_YOLO=false : il soumet donc chaque appel qu'il filtrerait par la requête de permission ACP — le même canal qu'utilise un éditeur. L'agent qui interroge la reçoit et la fait passer par son propre consent.Gate : en mode yolo, il autorise aussitôt ; sinon, il demande à son propre utilisateur, dans sa propre façade, et mémorise la réponse sous jan/bash, pour qu'autoriser le shell de Jan n'autorise pas le vôtre. L'agent interrogé, lui, ne retient rien : on lui redemande à chaque fois, et c'est la mémoire de l'agent qui interroge qui répond.

Un raffinement garde le même principe : le fichier de l'utilisateur peut donner à un agent interrogé son propre yolo, dans l'entrée mmConfigs de cet agent (homer: {path: …, yolo: true}). Il décide alors des appels de cet agent à la place du yolo de l'agent qui interroge : true les exécute — un codeur à qui l'on confie les modifications une fois le passage de main approuvé —, false demande pour chacun même quand l'agent qui interroge s'exécute librement. C'est toujours le fichier lancé par l'utilisateur qui décide ; le propre fichier de l'agent interrogé ne compte toujours pas.

Les modes qui ne peuvent pas demander

mm -p et mm --ask n'ont personne à qui demander : le premier est une exécution unique, le second lit sa question sur stdin. Avec yolo: false, ils refusent les appels qui demanderaient et le disent une fois sur stderr. Les autoriser en silence ferait de yolo: false un réglage qui dépend de la façon dont on a lancé mm, exactement l'incohérence que cette conception supprime ; rester bloqué sur une question invisible bloquerait les scripts pour toujours.

Alternatives écartées

  • Un simple flag --yolo en ligne de commande. Il n'atteindrait pas les kits de sandbox ni les réglages de lancement d'un éditeur, qui posent des variables d'environnement et des fichiers, pas des flags. AGENT_YOLO couvre le cas d'une seule exécution.
  • Garder permissions: ask | auto. Seule la fenêtre la lisait, et elle n'apparaissait dans aucune configuration livrée. Elle fonctionne encore — ask signifie yolo: false — avec un avertissement d'obsolescence, pour que les anciens fichiers gardent leur protection.
  • Laisser yolo passer outre les serveurs MCP marqués ask. Un serveur MCP est du code tiers que l'utilisateur a explicitement marqué comme non fiable ; yolo: true respecte ce choix par serveur. yolo: false, en revanche, fait demander chaque outil MCP : activer la protection ne doit jamais laisser de trou.

Liens avec le reste

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# Le mode yolo et les permissions — explication

## De quoi s'agit-il ?

Un agent de code exécute des commandes et écrit des fichiers sur votre machine. Quelqu'un doit décider si chacun de ces appels peut s'exécuter : soit l'utilisateur, appel par appel, soit personne, parce que l'utilisateur a décidé une fois pour toutes de laisser l'agent agir. mini-me appelle ce second choix le **mode yolo** et en fait un seul réglage, `yolo`, lu de la même façon par les trois façades — le mode ligne, la fenêtre et l'éditeur (ACP) — et par un agent interrogé par un autre.

## Pourquoi yolo est la valeur par défaut

mini-me est conçu pour piloter un petit modèle local à travers de nombreuses étapes courtes. Demander avant chaque `ls` rend cette boucle inutilisable en pratique, et le mode ligne — la première façade — ne demandait jamais. Avant ce réglage, le comportement dépendait de l'endroit où l'on lançait mm : le mode ligne ne demandait jamais, la fenêtre demandait seulement avec `permissions: ask`, et l'éditeur demandait toujours, qu'on le veuille ou non. Le même fichier d'agent ne voulait pas dire la même chose à trois endroits.

La valeur par défaut a donc été fixée sur ce que faisaient déjà la plupart des exécutions — agir sans demander — et la protection est devenue un choix délibéré et visible : `yolo: false`. La bannière dit dans quel sens le réglage est posé (`yolo: on` / `yolo: off (tools ask)`), pour que personne ne le découvre par surprise, dans un sens comme dans l'autre. La conséquence à connaître : dans un éditeur, le dialogue de permission n'apparaît qu'avec `yolo: false` ; avant, il apparaissait toujours.

## Exister ou demander

Deux questions différentes sont volontairement séparées :

- **L'outil existe-t-il ?** `bashTool`, `editTools`, `fetchContentTool`. Un outil qui n'existe pas n'est pas du tout déclaré au modèle ; il ne peut même pas essayer.
- **Un outil qui existe demande-t-il avant de s'exécuter ?** `yolo`.

Ainsi, `yolo: true` avec `bashTool: false` est un agent qui modifie librement les fichiers mais n'a pas de shell, et `yolo: false` avec `bashTool: true` est un agent qui a un shell mais a besoin de votre accord pour chaque commande. Fusionner les deux en une valeur à trois états (`bashTool: ask`) a été envisagé puis écarté : il aurait fallu la répéter pour chaque outil, alors que la vraie décision — « est-ce que je fais confiance à cet agent pour agir seul, maintenant ? » — est unique.

Seuls les appels qui modifient quelque chose demandent : `bash`, `write_file`, `edit_file`, `fetch_content` quand il enregistre, `rename` de `lsp`, et les actions de `plan` qui modifient un plan. Les lectures (`read_file`, `read_skill`, les actions de navigation de `lsp`, `fetch_content` sans `output`) ne demandent jamais : une question à chaque lecture apprend aux gens à cliquer « autoriser » sans lire.

## Quatre réponses, une mémoire

Quand un appel demande, la réponse peut valoir *une fois* ou *pour la session*, et *oui* ou *non* : autoriser une fois, autoriser cet outil pour la session, refuser cet appel, ne jamais autoriser cet outil dans cette session. « Jamais » existe parce qu'un refus qui ne dure qu'un appel oblige à refuser la même nouvelle tentative encore et encore ; « refuser une fois » existe parce que sans lui, la seule façon de dire non serait définitive. Les réponses mémorisées d'une session le sont par nom d'outil, survivent à `/new` (l'éditeur voit toujours la même session) et disparaissent quand mm s'arrête.

Les règles vivent dans un seul paquet, `internal/consent` : la vérification de `yolo` (`Gate`), les quatre réponses (`Answer`), ce qu'une session retient (`Policy`) et le point d'accroche de l'invite du mode ligne. Chaque façade se contente de dessiner la question à sa manière — une ligne `🔐`, la zone de la fenêtre, le dialogue de l'éditeur. Auparavant, chaque façade avait sa propre table « autorisé pour la session », et les trois avaient déjà commencé à diverger.

## Pourquoi l'agent qui interroge décide

Avec `mmConfigs`, un agent peut en interroger un autre (`/ask-jan`, `mm --ask jan`). Deux fichiers de configuration, deux valeurs de `yolo` : laquelle l'emporte ? Celle de l'agent que l'**utilisateur a lancé**. C'est le seul agent qui a un utilisateur en face de lui, et l'utilisateur a choisi sa configuration pour cette session ; le fichier de l'agent interrogé a été écrit pour une autre situation — peut-être pour tourner seul en mode yolo.

Techniquement, l'agent interrogé est lancé avec `AGENT_YOLO=false` : il soumet donc chaque appel qu'il filtrerait par la requête de permission ACP — le même canal qu'utilise un éditeur. L'agent qui interroge la reçoit et la fait passer par son propre `consent.Gate` : en mode yolo, il autorise aussitôt ; sinon, il demande à son propre utilisateur, dans sa propre façade, et mémorise la réponse sous `jan/bash`, pour qu'autoriser le shell de Jan n'autorise pas le vôtre. L'agent interrogé, lui, ne retient rien : on lui redemande à chaque fois, et c'est la mémoire de l'agent qui interroge qui répond.

Un raffinement garde le même principe : le fichier de l'utilisateur peut donner à un agent interrogé son propre `yolo`, dans l'entrée `mmConfigs` de cet agent (`homer: {path: …, yolo: true}`). Il décide alors des appels de cet agent à la place du `yolo` de l'agent qui interroge : `true` les exécute — un codeur à qui l'on confie les modifications une fois le passage de main approuvé —, `false` demande pour chacun même quand l'agent qui interroge s'exécute librement. C'est toujours le fichier lancé par l'utilisateur qui décide ; le propre fichier de l'agent interrogé ne compte toujours pas.

## Les modes qui ne peuvent pas demander

`mm -p` et `mm --ask` n'ont personne à qui demander : le premier est une exécution unique, le second lit sa question sur stdin. Avec `yolo: false`, ils refusent les appels qui demanderaient et le disent une fois sur stderr. Les autoriser en silence ferait de `yolo: false` un réglage qui dépend de la façon dont on a lancé mm, exactement l'incohérence que cette conception supprime ; rester bloqué sur une question invisible bloquerait les scripts pour toujours.

## Alternatives écartées

- **Un simple flag `--yolo` en ligne de commande.** Il n'atteindrait pas les kits de sandbox ni les réglages de lancement d'un éditeur, qui posent des variables d'environnement et des fichiers, pas des flags. `AGENT_YOLO` couvre le cas d'une seule exécution.
- **Garder `permissions: ask | auto`.** Seule la fenêtre la lisait, et elle n'apparaissait dans aucune configuration livrée. Elle fonctionne encore — `ask` signifie `yolo: false` — avec un avertissement d'obsolescence, pour que les anciens fichiers gardent leur protection.
- **Laisser yolo passer outre les serveurs MCP marqués `ask`.** Un serveur MCP est du code tiers que l'utilisateur a explicitement marqué comme non fiable ; `yolo: true` respecte ce choix par serveur. `yolo: false`, en revanche, fait demander chaque outil MCP : activer la protection ne doit jamais laisser de trou.

## Liens avec le reste

- Les clés de configuration : [référence de la configuration](../reference/configuration.md).
- Comment l'activer : [Confirmer les appels d'outils](../how-to/confirm-tool-calls.md).
- Le chemin d'événements que partagent les façades (`ui.Sink`, `Allow`) : [Architecture](architecture.md).
- Interroger un autre agent : [Interroger un autre agent](asking-another-agent.md).
- Décider selon une règle plutôt qu'en demandant : [Les hooks](hooks.md) — un hook `preToolCall` s'exécute avant la demande d'autorisation, si bien qu'un appel qu'il refuse n'est jamais soumis à l'utilisateur.