Un assistant de code doit lire le dépôt avant de compléter une fonction ou de corriger une erreur. Vous ouvrez un projet et vous supposez n’avoir livré que les quelques fichiers de cet arbre de travail dont la tâche a besoin. Si .env est déjà dans .gitignore, beaucoup en concluent que « l’assistant ne le voit pas, le cloud encore moins ». Le 18 septembre 2026, le développeur ferstar a écrit la couche suivante : une fois connecté, le client bureau officiel de Zhipu, ZCode, fabrique sur cette machine un instantané de l’espace de travail. Ce n’est pas src/ qui pèse dans la liste. C’est le répertoire .git entier.
Un texte précédent a vu quels mots masquer avant de coller un mot de passe dans ChatGPT ou Gemini : c’est une chaîne que vous avez choisie de coller. Ici, la question change. Vous n’avez jamais collé .env dans le chat. Est-ce que la base d’objets Git, le cache LFS et le reflog, une fois emballés dans un instantané, emportent encore des clés déjà supprimées. Si une clé doit voyager, passez par un lien à usage unique de la forme s.html?id=…#…. Créer et lire s’ouvrent tous les deux sans compte. Les outils MyPassGen s’ouvrent sans inscription. La suite ne désosse aucun client et n’explique pas comment bloquer l’envoi de quelqu’un d’autre. Elle aligne les chiffres déjà écrits dans la reconstruction de ferstar du 18 septembre 2026 et dans la reprise ITHome de la note officielle du même jour, plus le dossier checkpoints que vous pouvez ouvrir sur cet ordinateur.
Séparez d’abord deux tâches
« J’ai déjà passé sur une version qui n’envoie plus » bloque le prochain emballage. Les instantanés déjà construits, déjà partis de cette machine, et que l’éditeur dit « détruits dès que le Wiki est généré », ne se contrôlent pas depuis l’extérieur. Vous n’ouvrez pas le serveur pour voir si une sauvegarde a disparu, ni qui tient encore la clé privée. Cherchez d’abord une .enc en attente, puis décidez quels mots de passe déjà entrés dans Git doivent tourner. Un numéro de client ne remplace pas la question : « cette machine tient-elle encore un instantané, et git log imprime-t-il encore la clé de test. »
Ouvrir un dépôt, ce n’est pas ne livrer que cet arbre
Une fonction collée dans le chat, c’est le contexte que vous avez sélectionné. Un instantané d’espace de travail est un autre chemin : le client emballe le dépôt ouvert, et le périmètre peut dépasser « les fichiers dont cette invite a besoin ». Après que ferstar a découpé la liste par taille, .git/lfs/, .git/objects/ et .git/logs/ représentaient ensemble environ 86,6 %. Le code source et la documentation pesaient environ 13,4 %. Donc, même si ce dossier a déjà supprimé .env, un ancien blob de la base d’objets peut encore voyager.
Ce n’est pas le même chemin que « ce site a-t-il envoyé comme donnée métier le mot de passe que je suis en train de générer ». Sur la page générateur de MyPassGen, l’onglet Réseau permet de vérifier que le texte clair ne part pas comme donnée métier. Un assistant bureau qui emballe un instantané utilise son propre dossier local et sa propre connexion sortante. Un fichier que vous enlevez avec git rm est souvent « absent de cet arbre », pas « jamais apparu dans l’historique ». Écrire une clé non masquée dans un commit est le même type de problème qu’écrire un mot de passe dans le corps d’un e-mail : l’autre côté lit une copie que vous avez un jour laissée exprès. Ce chemin est dans si vous écrivez un mot de passe temporaire dans un e-mail, ce que Envoyés, le transfert et l’aperçu mobile gardent encore.
Une couche de plus se mélange facilement. .gitignore bloque « ne plus suivre ce chemin ». Il ne bloque pas « ce chemin a déjà été commité une fois ». Si l’assistant ne lit que les fichiers de l’arbre actuel, les règles d’ignore aident encore. Si un instantané emballe tout le répertoire .git, ces règles n’aident plus. Une branche locale jamais poussée, des opérations encore dans le reflog, une URL interne dans .git/config : tout cela appartient à l’ensemble « cet onglet d’éditeur ne le voit pas, la base d’objets le tient encore ». En français, les guides de durcissement le disent depuis longtemps : un secret commité ne disparaît pas avec le commit suivant ; l’historique Git le conserve.
Les chiffres écrits le 18 septembre
ferstar a écrit que le point de départ était ~/.zcode à plus de 700 Mo. v2/checkpoints/ pesait environ 303 Mo. Dedans se trouvait une .enc d’environ 313 Mo. Le fichier d’état notait environ 345 Mo avant l’emballage, 313070842 octets après chiffrement, kind baseline, et un failureCount de 564. Cet instantané d’un projet commercial est resté local, en pending ; la reconstruction dit qu’il n’est pas parti. Un dépôt public beaucoup plus petit raconte autre chose : 538 fichiers, environ 15 Ko après compression et chiffrement, état reçu par le serveur. Donc « quelque chose est-il vraiment sorti » — au moins cette fois-là, le petit dépôt, oui.
La même liste du projet commercial : 42 411 fichiers ; .git/lfs/ environ 196,1 Mo (56,8 %), .git/objects/ environ 102,2 Mo (29,6 %), .git/logs/ environ 0,6 Mo (0,2 %). Une autre reproduction communautaire a écrit que, sur ZCode 3.12.3, un instantané de projet pesait environ 748 Mio, dont .git environ 98,91 %. Sur les déclencheurs de capture, la reconstruction nomme captureBeforePrompt avant une question, et repo-wiki-update à la fin d’une tâche. Dans le journal d’une session active, la capture d’instantané est apparue jusqu’à 62 fois.
La note officielle est sortie à 17 h 44 le 18 septembre. ITHome l’a reprise le soir même. Les points : le problème tenait à « l’indexation du dépôt de code », utilisée pour un index local, un retour arrière de point de contrôle de session, et Repo Wiki ; générer une page Wiki dans le cloud « peut » déclencher un envoi de données de dépôt ; une fois le Wiki généré, ces données envoyées sont détruites tout de suite et ne sont pas conservées ; la fonction était allumée par défaut au lancement, une partie des utilisateurs a été touchée, et le problème « est déjà corrigé » ; ZCode serait bientôt open source, avec un audit tiers ; chaque utilisateur recevrait une remise de quota hebdomadaire supplémentaire. L’éditeur n’a pas nié qu’un envoi a eu lieu. Ce qui reste en doute, c’est le périmètre de l’envoi, si on pouvait l’éteindre à l’époque, et comment « détruit tout de suite » se contrôle depuis l’extérieur. Le 20 septembre, InfoQ a repris un courrier de Taiyuan Chengming Technology à Beijing Zhipu Huazhang demandant la suppression, le parcours des données, les journaux et le responsable. C’est une question d’entreprise. Ce n’est pas un reçu de destruction que vous pouvez ouvrir sur cette machine.
.git pèse le plus : les clés déjà supprimées restent dans les objets
L’absence de .env dans l’arbre de travail actuel prouve seulement que cette extraction n’a plus ce chemin. Git stocke les blobs par contenu. Si un commit a un jour écrit DATABASE_URL= ou AWS_SECRET_ACCESS_KEY=, et que vous avez ensuite modifié le fichier, recommité, ou même l’avez retiré de cette branche, l’ancien blob reste souvent dans .git/objects jusqu’à ce qu’un gc le jette vraiment. Un cache LFS peut garder d’anciens gros fichiers. Le reflog enregistre quelles branches vous avez déplacées sur cette machine. Emballez ces trois éléments dans un instantané, et le cloud ne tient pas « cet écran dans l’éditeur ». Il tient l’historique que ce dépôt a accumulé ici.
La reconstruction a aussi écrit que les filtres d’espace de travail excluent certains fichiers de secrets, mais que .git entrait quand même dans l’emballage. Cette phrase mérite une pause. Aujourd’hui vous sortez .env du dépôt et ne laissez que .env.example. Cet arbre a l’air propre. Le commit raté de l’an dernier est encore dans la base d’objets. Un filtre qui ne regarde que les chemins de l’arbre de travail ne l’enlèvera pas. Un nom d’hôte GitLab interne dans .git/config, et le nom d’une branche de fonctionnalité qui n’a jamais quitté ce portable, vivent dans les refs et le reflog. « Je l’ai déjà mis dans gitignore » ne les rapatrie pas.
On peut comparer avec « une fuite de hash de mot de passe n’est pas la même chose que quelqu’un a déjà lu le texte clair ». Un hash est un stockage à sens unique, et on fait quand même tourner le mot. Une clé dans l’historique Git est souvent le texte clair lui-même. Contrôler cette machine contre une liste de mots faibles courants prouve seulement une correspondance sur une liste publique. Cela ne prouve pas si un instantané donné a emporté votre ancien commit. Cette différence est dans liste locale de fuites et Have I Been Pwned : ce que chaque contrôle prouve. Faites tourner l’ensemble qui est déjà entré dans un commit, pas le coup d’œil qui dit « cet arbre est propre maintenant ».
Chiffré ne veut pas dire que vous seul déchiffrez
La forme sortante que la reconstruction a rétablie est celle-ci : le client demande à zcode.z.ai des identifiants d’envoi d’instantané, et reçoit une clé d’objet, une limite de taille, et une clé publique RSA. Cette machine emballe l’espace de travail en tar.gz, le chiffre en AES-256-CTR, enveloppe la clé symétrique avec cette clé publique, et poste tar.gz.enc directement vers l’OSS d’Alibaba Cloud. La clé privée reste dans le cloud tout le temps. Les centaines de mégaoctets de .enc sur le disque ne s’ouvrent pas pour vous, et ne s’ouvrent pas pour le client. Le nom d’algorithme dit AES-256. Cela règle « le chemin et le seau ne sont pas un fichier en clair ». Cela ne vous donne pas le droit de déchiffrer.
C’est la même frontière qu’une page de disque cloud qui affiche « chiffré ». Quand le prestataire tient la clé, le côté stockage peut encore ouvrir le fichier. Quand vous chiffrez d’abord avec une phrase secrète que vous tenez, l’autre côté ne doit voir que du chiffré. La différence n’est pas l’apparition des quatre lettres AES. C’est qui tient la clé privée ou la phrase secrète. La boîte de chiffrement de fichiers MyPassGen fait de l’AES-256-GCM en flux dans le navigateur, un fichier jusqu’à 5 Go, sortie .lock / .enc, et s’ouvre sans compte. Vous envoyez la phrase secrète par un autre chemin. Le fichier n’est pas envoyé comme donnée métier. La clé d’enveloppe de cet instantané ZCode utilisait une clé publique émise par le serveur et une clé privée tenue par le serveur. Le but est l’inverse : garantir que le serveur puisse déchiffrer. Voir avant de déposer un fichier dans le cloud, qui peut lire le texte clair — et par quel canal envoyer la phrase secrète.
La note officielle dit que l’envoi est détruit tout de suite après la génération du Wiki et n’est pas conservé. Si cette destruction a lieu côté serveur, vous ne pouvez pas contrôler depuis cet ordinateur les sauvegardes, les versions du stockage d’objets, ni les copies de clé privée. ferstar a écrit que, sur 3.14.0, le code du chemin d’envoi avait disparu du client, upload-credential renvoyait 404, et qu’il ne restait qu’un checkpoint local. Cela peut prouver « ce nouveau client ne demande plus ces identifiants ». Cela ne peut pas prouver « l’instantané du petit dépôt déjà reçu par le serveur a physiquement disparu de chaque copie ». Lire « c’était chiffré » comme « moi seul peux le voir » saute la rotation qu’il reste à faire.
Couper une option n’arrête pas l’emballage
La reconstruction a aligné deux interrupteurs sur le chemin de code. optimizeAgentExperienceEnabled (optimiser l’expérience) couvre l’usage des données pour l’entraînement. Une fois coupé, l’instantané s’emballe encore. repoSnapshotIndexingEnabled (indexation d’instantané de dépôt) couvre la construction d’un index côté serveur une fois l’instantané reçu. Une fois coupé, l’emballage local tourne encore. Sur 3.12.3, la logique de capture et d’envoi se levait après que la connexion lui avait donné un JWT. L’interface n’avait pas d’interrupteur séparé « ne pas emballer et envoyer ». La note officielle n’a pas listé une case qu’un utilisateur peut décocher, puis vérifier sur place que le trafic sortant s’est arrêté. Elle a dit que la fonction était allumée par défaut au début, et que le problème était déjà corrigé.
Donc « je n’ai jamais allumé Repo Wiki » et « j’ai coupé l’entraînement » ne sont pas une décharge pour 3.12.3. Fiez-vous à la présence d’une nouvelle .enc dans le dossier checkpoints à ce moment-là, et à l’état pending ou reçu. Après un passage à la 3.14.0 nommée dans la reconstruction, regardez le même dossier : un nouvel emballage en attente apparaît-il, et l’URL d’identifiants renvoie-t-elle encore un succès. Le client peut se mettre à jour à chaud. Le numéro de version et ce dossier sont deux choses que vous pouvez regarder plus d’une fois. Un titre d’actualité, non.
Une copie de la politique de confidentialité officielle, enregistrée le 18 septembre, montrait encore une dernière mise à jour au 15 juin 2026. La politique disait que le produit collecte le texte, les fichiers et le code soumis dans une conversation — le périmètre habituel d’un assistant qui appelle un modèle. La reconstruction souligne qu’à ce moment-là, la page ne disait jamais qu’un instantané de dépôt entier, ou tout l’historique Git, irait dans le cloud. Quand une phrase de politique et une liste de fichiers locale se contredisent, fiez-vous à la liste et au fichier d’état. Ne remontez pas de « j’ai accepté la politique de confidentialité » vers « donc seul le paragraphe de la boîte de chat est parti ».
Côte à côte : cet arbre, l’historique Git, le chat
La même clé de test déjà entrée dans un dépôt se coupe en au moins quatre chemins « qui peut encore la lire ». La différence n’est pas la marque de l’assistant. C’est où une copie a été faite, et qui tient le droit de déchiffrer.
| Ce que vous avez fait | Ce que cette machine garde encore | Résidu déjà nommé par la note officielle ou la reconstruction |
|---|---|---|
| Dépôt seulement ouvert, assistant non connecté | L’arbre de travail et .git |
Aucun (le chemin d’instantané n’avait pas encore de session) |
Connecté à 3.12.3 ; cet arbre a déjà supprimé .env |
Anciens blobs encore dans la base d’objets | La liste d’instantané peut encore tenir un .git complet ; un petit dépôt a eu un enregistrement « reçu par le serveur » |
| Entraînement / index d’instantané coupés | Sans lien avec la base d’objets | Reconstruction 3.12.3 : cette machine emballe encore ; les interrupteurs ne couvrent pas l’envoi |
| Passage à une version qui n’envoie plus, checkpoints jamais ouverts | Anciennes .enc et fichiers d’état peuvent encore être là |
Le prochain envoi s’arrête ; la destruction d’un instantané déjà reçu ne se contrôle pas depuis l’extérieur |
| La clé n’est jamais entrée dans Git ; la remise a utilisé un lien à usage unique, canaux séparés | Les fichiers de test peuvent être supprimés | Une recherche dans l’instantané ne trouve pas un identifiant complet ; les deux moitiés sont nécessaires pour déchiffrer |
Ne mélangez pas la cinquième ligne avec les quatre premières. Si vous écrivez un s.html?id=…#… complet dans le dépôt puis ouvrez l’assistant, l’historique et un instantané peuvent encore ramasser tout l’identifiant. L’hôte qui range le texte chiffré ne voit toujours pas la clé. Séparez l’identifiant et la clé, et une recherche plein texte ne trouve pas un lien qui s’ouvre. Un lien complet reste un mot de passe. Chiffrer puis synchroniser, c’est pour un fichier. Une fois que la base d’objets Git a vu du texte clair, ajouter un .lock plus tard n’efface pas l’ancien blob.
Contrôler sur place
Ces étapes ne dépendent d’aucune promesse de marque. Utilisez un mot de passe de test et un dépôt jetable qui ne se connectera pas à un compte de travail réel et ne pointera pas vers un dépôt d’entreprise. Dans un dossier vide, commitez une ligne du type orange-lake-7, puis supprimez-la. Ne vous entraînez pas avec un mot de passe principal encore en service, une clé API de production, ni un lien à usage unique encore vivant.
- Lisez le numéro sur la page À propos de ZCode ou sur l’installateur. La reconstruction nomme 3.12.3 comme version en cause et 3.14.0 comme version qui a retiré le chemin d’envoi. Fiez-vous au chiffre que vous lisez maintenant. Ne substituez pas une annonce de groupe à ce regard.
- Ouvrez
v2/checkpointssous la racine de données locale (sur macOS et Linux, souvent~/.zcode/v2/checkpoints; sur Windows, le dossier utilisateur après installation). Y a-t-il une.enc, et un JSON d’état à côté. Les champs que vous pouvez ouvrir : siworkspacePathest un projet que vous pensiez n’avoir jamais ouvert,encryptedSizeBytes,failureCount,kind. Un chemin qui correspond signifie que cette machine a emballé ce dépôt. UnfailureCountélevé dit seulement que cet emballage n’est pas parti. Il ne prouve pas qu’aucun autre dépôt n’a jamais réussi. - Créez un dépôt de test vide, commitez un mot de passe de test, puis retirez-le de cet arbre. Utilisez
git log -pougit log --all --full-history -- nom-de-fichieret voyez si l’ancien commit est encore là. S’il l’est, « je l’ai déjà supprimé » ne sauve pas la base d’objets. C’est le comportement de Git, avec ou sans assistant. Si un instantané emballe.git, c’est cette couche qu’il lit. - Si 3.12.3 a un jour ouvert ce dépôt de test : retournez aux checkpoints et voyez si un nouvel emballage correspond à ce chemin. Après une mise à jour, observez un moment : une nouvelle
.encen attente apparaît-elle. Les fichiers locaux sont une preuve que vous pouvez regarder plus d’une fois. Vous n’avez pas besoin, et vous ne devez pas, désosser le client de quelqu’un d’autre. - Traitez chaque mot de passe, jeton et adresse interne déjà entré dans un vrai dépôt comme « déjà parti de cette machine » : faites-le tourner sur le service d’origine, et inventez un nouveau mot de passe aléatoire. Le générateur de mot de passe MyPassGen propose un mode aléatoire de 6 à 128 caractères, 16 par défaut, et prévient sous 8. Il s’ouvre sans compte. Le résultat n’est pas envoyé comme donnée métier. Pour une chaîne réutilisée, utilisez Force pour contrôler cette machine contre une liste de mots faibles courants. Cela peut prouver une correspondance sur une liste publique. Cela ne peut pas prouver le périmètre d’un instantané donné.
- Créez un lien MyPassGen Usage unique avec la même phrase de test, expiration 24 heures, lectures laissées à 1. Dans le chat ou un ticket, collez seulement la partie avant le dièse,
s.html?id=…. Dites la clé au téléphone ou en personne. S’ouvre sans compte. Avec seulement l’identifiant, le destinataire doit voir un lien incomplet ; les deux moitiés sont nécessaires pour déchiffrer. Après lecture, écrasez le presse-papiers. N’écrivez pas une adresse qui tient encore#dans un dépôt, et ne collez pas la page de résultat dans aucun chat d’assistant.
Sur un dépôt d’entreprise, ajoutez une demi-étape : demandez quelles racines l’assistant ouvre par défaut, si un dossier de secrets peut rester hors de l’espace de travail, et si les instantanés historiques ont un reçu de suppression côté entreprise. MyPassGen ne tranchera pas si un cloud donné a gardé une autre copie. Fiez-vous aux fenêtres que vous venez d’ouvrir et au journal Git.
S’il faut transmettre une clé, séparez les canaux
Pour une remise en tête-à-tête que l’autre personne peut ouvrir tout de suite, n’écrivez pas le mot de passe dans un fichier qui va entrer dans Git, entrer dans un espace de travail d’assistant, et rester dans la base d’objets. Générez-le sur cet appareil, puis enveloppez-le dans un lien à usage unique. À la création, le navigateur chiffre avec AES-256-GCM. Une note tient au plus 32 Ko. Les lectures valent 1 par défaut et plafonnent à 10. L’expiration peut être 1 heure, 24 heures, 7 jours, ou seulement au compteur, sans TTL. Le serveur ne range que le texte chiffré. La clé se place après # dans l’URL, donc les journaux d’accès et le Referer ne voient pas cette tranche. Un dépôt et une boîte de chat d’assistant peuvent encore la voir. N’écrivez pas le lien complet dans un commit.
Quand un dépôt ou un ticket a encore besoin d’un point d’entrée, séparez le canal. Le fichier porte seulement le responsable, l’identifiant, et la phrase « clé par téléphone ». Un appel, une remise en personne ou un autre compte de messagerie porte seulement la tranche après #. Aucune moitié ne déchiffre seule. C’est un usage, pas un défaut produit. La page de création émet encore un lien complet, commode pour un envoi en tête-à-tête. Sur un canal qui dessine des cartes d’aperçu, lancez d’abord un lien de test et voyez si l’aperçu compte une lecture, comme dans si vous collez un lien à usage unique dans Slack ou WeChat, l’aperçu le brûle-t-il d’abord. Masquez extraits d’erreur et de configuration dans Nettoyer URL / masquage avant de décider s’ils doivent encore entrer dans un assistant.
Un paquet de clés ou un export de plus de 32 Ko n’a pas sa place sur un lien texte à usage unique. Passez par la boîte de chiffrement de fichiers : AES-256-GCM en flux dans le navigateur, un fichier jusqu’à 5 Go, sortie .lock / .enc, phrase secrète envoyée à part. Chiffrez d’abord sur cet appareil, puis synchronisez ; l’autre côté ne doit voir que du chiffré. Pousser un .env non masqué dans Git est le même type de problème que pousser un paquet de certificats non chiffré vers un disque : la copie qui prouve « c’est bien la clé » a quitté l’arbre de travail que vous pensiez déjà nettoyé. Comment vérifier sur place que le chiffrement dans le navigateur n’a pas envoyé le texte clair comme donnée métier est dans comment vérifier que le chiffrement dans le navigateur n’envoie pas le texte clair.
Une fois contrôlé « les checkpoints tiennent-ils une .enc pour ce chemin », « git log imprime-t-il encore le mot de passe de test » et « une mise à jour du client seule vide-t-elle un ancien instantané », vous pouvez déjà répondre à la question de l’article : supprimer .env de cet arbre ne vide pas la base d’objets, et ne vide pas un instantané déjà emballé. La correction officielle couvre le chemin client qu’ils peuvent changer. Un emballage déjà reçu par le serveur, et le texte clair de vos anciens commits, ne se vident pas parce que vous avez mis à jour une fois. Le dossier local et le journal Git sont un endroit où contrôler. C’est un mauvais endroit pour supposer « je n’ai jamais collé la clé dans le chat, donc c’est fini ».
Questions fréquentes
J’ai déjà mis à jour. Les anciens instantanés ont-ils disparu aussi ?
Ce sont deux tâches différentes. Une nouvelle version bloque la prochaine demande d’identifiants et l’envoi direct. Une ancienne .enc sur cette machine, le fichier d’état, et la copie cloud que l’éditeur dit « détruite après génération » ne sont pas dans ce clic de mise à jour. Fiez-vous à la présence encore ici des checkpoints, et à la rotation d’une clé encore vivante.
Cet arbre a déjà mis .env dans gitignore. Faut-il encore faire tourner les clés ?
Lisez l’historique, pas cet arbre. Une règle d’ignore ne bloque que le suivi futur. Si un ancien commit tenait du texte clair, traitez-le comme déjà copié. Un passage de git log sur un dépôt de test est plus direct que de croire un filtre.
L’instantané est chiffré. Puis-je le traiter comme jamais fuité ?
Non. La reconstruction dit que la clé privée reste dans le cloud. Vous ne pouvez pas ouvrir vous-même le chiffré local. Le chiffrement arrête « un tar en clair qui dort dans le seau ». Il ne veut pas dire « seul le propriétaire du dépôt peut lire ». Si la destruction ne se prouve pas depuis l’extérieur, traitez les clés déjà entrées dans Git comme une matière à faire tourner.
Faut-il un compte pour créer et lire ? Si je me trompe de canal, le support peut-il récupérer ?
Aucune inscription. Créer et lire sont publics pour un visiteur. Une fois le texte chiffré brûlé par le compteur ou l’expiration, il n’y a pas de sauvegarde en clair côté serveur, ni de boîte support qui puisse le récupérer. Générez un nouveau mot de passe et un nouveau lien. N’actualisez pas la même URL pour voir si elle revient, et n’écrivez pas la page de résultat dans un dépôt pour la renvoyer.