Ассистенту нужен код, чтобы дописать функцию или починить ошибку. Вы открываете репозиторий и мысленно отдаёте те несколько файлов текущего дерева, которые нужны этой задаче. Если .env уже лежит в .gitignore, многие читают это как «ассистент не видит, облако тем более не видит». 18 сентября 2026 разработчик ferstar описал следующий слой: официальный десктопный клиент Zhipu — ZCode — после входа собирает на этой машине снимок рабочей области. Основной объём списка — не src/. Это полный каталог .git.
В русской практике чаще спорят о другом: «не давайте ИИ читать .env». Это про текущие файлы в дереве и про то, что Cursor, Claude Code или Copilot могут подтянуть открытый конфиг в контекст. Здесь другой вопрос. Вы .env в чат не вставляли. Унесут ли объектное хранилище Git, кэш LFS и reflog внутри снимка рабочей области ключи, которые вы уже удалили. Если ключ всё же нужно отдать, берите одноразовую ссылку вида s.html?id=…#…. Создать и прочитать можно без аккаунта. Инструменты MyPassGen открываются сразу. Дальше клиент не разбираем и чужую загрузку не учим глушить. Сверяем цифры из разбора ferstar от 18 сентября 2026 и вечернего пересказа официального пояснения на ITHome плюс каталог checkpoints, который можно открыть на этом компьютере. Предыдущая заметка закрывала другой путь: какие поля закрыть маской, прежде чем вставить пароль в ChatGPT или Gemini.
Сначала разведите две задачи
«Я уже обновился до сборки, которая больше не загружает» закрывает следующий архив. Снимки, которые уже собрали, уже ушли с этой машины и которые компания называет «уничтоженными сразу после генерации Wiki», снаружи не проверить. Сервер вы не откроете: ни что бэкап исчез, ни у кого ещё лежит закрытый ключ. Сначала посмотрите, нет ли ожидающего .enc, потом решите, какие пароли, однажды попавшие в Git, нужно сменить. Версию клиента не подставляйте вместо «на этой машине ещё лежит снимок, и git log всё ещё печатает тестовый ключ».
Открыть репозиторий — не значит отдать только это дерево
Функция, которую вы сами вставили в чат, — это контекст, который вы выбрали. Снимок рабочей области — другая дорога: клиент упаковывает открытый репозиторий, и охват может быть шире, чем «файлы, нужные этому запросу». Когда ferstar разложил список по размеру, .git/lfs/, .git/objects/ и .git/logs/ вместе дали около 86,6%. Исходники и документы — около 13,4%. Значит, даже если в текущем каталоге .env уже нет, старый blob из объектного хранилища может уехать вместе со снимком.
Это не тот же путь, что «отправил ли сайт пароль, который я сейчас генерирую, как деловые данные». На странице генератора MyPassGen во вкладке «Сеть» можно увидеть, что открытый текст как деловые данные не уходит. Десктопный ассистент, который собирает снимок, пользуется своим локальным каталогом и своим исходящим соединением. Файл после git rm чаще значит «нет в этом дереве», а не «никогда не было в истории». Открытый ключ в коммите — тот же класс задачи, что пароль в теле письма: вторая сторона смотрит копию, которую вы когда-то сами оставили. Этот путь — в Одноразовый пароль или ключ в теле письма: что останется в «Отправленных», резервных копиях и у администратора.
Ещё один слой легко смешать. .gitignore закрывает «этот путь больше не отслеживать». Он не закрывает «этот путь однажды уже закоммитили». Документация GitHub на русском прямо пишет: если в истории лежит секрет, первым шагом его отзывают и меняют; правка текущего файла сама по себе его не обезвреживает. Если ассистент читает только файлы текущего дерева, правила игнора ещё помогают. Если снимок забирает весь каталог .git, эти правила уже ни при чём. Локальная ветка, которую вы не пушили, операции в reflog и внутренний адрес репозитория в .git/config относятся к набору «эта вкладка редактора не видит, объектное хранилище всё ещё держит».
Цифры, которые 18 сентября уже записали
ferstar пишет, что отправной точкой стал каталог ~/.zcode больше 700 МБ. v2/checkpoints/ занял около 303 МБ. Внутри лежал .enc примерно на 313 МБ. Файл состояния записал около 345 МБ до упаковки, 313070842 байт после шифрования, kind — baseline, failureCount — 564. Этот снимок коммерческого проекта остался локально в pending; в разборе сказано, что он не ушёл. Маленький публичный репозиторий — другая история: 538 файлов, около 15 КБ после сжатия и шифрования, статус — сервер принял. Значит, «ушло ли хоть что-то» — хотя бы в тот раз маленький репозиторий ушёл.
Тот же список коммерческого проекта: 42 411 файлов; .git/lfs/ около 196,1 МБ (56,8%), .git/objects/ около 102,2 МБ (29,6%), .git/logs/ около 0,6 МБ (0,2%). Отдельное воспроизведение в сообществе писало: на ZCode 3.12.3 один снимок проекта занял около 748 МиБ, из них .git — около 98,91%. По триггерам захвата разбор называет captureBeforePrompt перед вопросом и repo-wiki-update по окончании задачи. В логе одной активной сессии захват снимка встречался до 62 раз.
Официальное пояснение вышло 18 сентября в 17:44. ITHome пересказала его в тот же вечер. Суть: проблема сидела в «индексации репозитория» — локальный индекс, откат по контрольным точкам сессии и Repo Wiki; генерация страницы Wiki в облаке «может» запустить загрузку данных репозитория; после генерации Wiki эти данные сразу уничтожают и не хранят; на старте функция была включена по умолчанию, часть пользователей затронута, проблема «уже исправлена»; ZCode скоро откроют и пригласят сторонний аудит; всем пользователям — ещё один недельный сброс квоты. Что загрузка была, компания не отрицала. Под вопросом остаются охват, можно ли было тогда это выключить и как «сразу уничтожили» проверить снаружи. 20 сентября InfoQ пересказала письмо тайюаньской Chengming Technology в Beijing Zhipu Huazhang: просят объяснить удаление, маршруты, логи и кто отвечает. Это корпоративный запрос. Это не акт уничтожения, который вы откроете на этой машине.
Большая часть — .git: удалённые ключи остаются в объектах
Отсутствие .env в текущем дереве доказывает только одно: в этой рабочей копии такого пути нет. Git хранит blob по содержимому. Если какой-то коммит однажды записал DATABASE_URL= или AWS_SECRET_ACCESS_KEY=, а вы потом правили файл, коммитили снова или даже удалили его из этой ветки, старый blob часто живёт в .git/objects, пока сборщик мусора его действительно не выбросит. Кэш LFS может держать старые крупные файлы. Reflog помнит, какие ветки вы двигали на этой машине. Упакуйте эти три вещи в снимок — и в облаке окажется не «этот экран в редакторе», а история, которую репозиторий накопил здесь.
В разборе также сказано: фильтры рабочей области отсекают часть файлов с секретами, но .git в архив всё равно входит. На этой фразе стоит остановиться. Сегодня вы вынесли .env из репозитория и оставили только .env.example. Дерево выглядит чистым. Прошлогодний ошибочный коммит всё ещё лежит в объектном хранилище. Фильтр, который смотрит только пути текущего дерева, его не снимет. Внутреннее имя GitLab в .git/config и название фича-ветки, которая с ноутбука не уходила, живут в refs и в reflog. «Я уже прописал gitignore» их не возвращает.
Это можно сравнивать с «утечка хеша пароля — не то же самое, что открытый текст уже прочитали». Хеш хранят в одну сторону, и пароль всё равно меняют. Ключ в истории Git часто и есть открытый текст. Локальная сверка с открытым списком слабых паролей доказывает только попадание в этот список. Она не доказывает, унёс ли конкретный снимок ваш старый коммит. Разница — в Локальный список утечек и Have I Been Pwned: что доказывает каждая проверка. Меняйте набор, который однажды попал в коммит, а не взгляд «сейчас дерево чистое».
Зашифровано — не значит, что расшифруете только вы
Исходящую схему разбор восстановил так: клиент просит у zcode.z.ai учётные данные для загрузки снимка и получает ключ объекта, лимит размера и открытый ключ RSA. Эта машина упаковывает рабочую область в tar.gz, шифрует AES-256-CTR, оборачивает симметричный ключ тем открытым ключом и отправляет tar.gz.enc напрямую в Alibaba Cloud OSS. Закрытый ключ всё время остаётся в облаке. Сотни мегабайт .enc на диске вам не откроются — и клиенту тоже. В названии алгоритма есть AES-256. Это закрывает «по пути и в бакете лежит не открытый tar». Это не передаёт право расшифровки вам.
Та же граница, что у страницы диска со словом «зашифровано». Когда ключ держит поставщик, сторона хранения файл всё ещё откроет. Когда вы сначала шифруете паролем, который держите сами, с той стороны должен быть только шифротекст. Разница не в том, мелькнули ли четыре буквы AES. Разница в том, у кого закрытый ключ или парольная фраза. Шифрование файлов MyPassGen делает потоковый AES-256-GCM в браузере, один файл до 5 ГБ, выход .lock / .enc, открывается сразу. Пароль вы отправляете другим каналом. Файл как деловые данные не загружается. Конвертный ключ того снимка ZCode брал открытый ключ с сервера и закрытый ключ оставлял на сервере. Цель противоположная: чтобы сервер смог расшифровать. См. Перед тем как бросить файл в облако: кто получит открытый текст и каким каналом передавать пароль.
В официальном пояснении написано: после генерации Wiki загрузку сразу уничтожают и не хранят. Если уничтожение происходит на сервере, с этого компьютера вы не проверите бэкапы, версии объектного хранилища и копии закрытого ключа. ferstar по 3.14.0 написал: код пути загрузки из клиента убрали, upload-credential отвечает 404, локально остаётся только checkpoint. Это доказывает «этот новый клиент больше не просит те учётные данные». Это не доказывает «снимок маленького репозитория, который сервер уже принял, физически стёрт из всех копий». Прочитать «было зашифровано» как «вижу только я» — пропустить ротацию, которую всё равно нужно сделать.
Выключить настройку — не значит остановить упаковку
Разбор сопоставил два переключателя с путём в коде. optimizeAgentExperienceEnabled (оптимизация опыта) отвечает, можно ли использовать данные для обучения. После выключения снимок всё равно собирается. repoSnapshotIndexingEnabled (индексация снимка репозитория) отвечает, строит ли сервер индекс, когда снимок уже у него. После выключения локальная упаковка всё равно идёт. На 3.12.3 логика захвата и загрузки поднималась после того, как вход отдавал JWT. Отдельного пункта «не упаковывать и не отправлять» в интерфейсе не было. Официальное пояснение не назвало галочку, которую пользователь снимает и сразу проверяет, что исходящий трафик остановился. Оно сказало: на старте функция была включена по умолчанию, проблему уже закрыли.
Поэтому «я не включал Repo Wiki» и «я выключил обучение» — не индульгенция для 3.12.3. Смотрите, появлялся ли тогда в каталоге checkpoints новый .enc и стоял ли статус pending или «принято». После обновления до 3.14.0, которую называет разбор, откройте тот же каталог снова: вырастает ли новый ожидающий архив и отвечает ли адрес учётных данных успехом. Клиент умеет обновляться на лету. Номер версии и этот каталог можно смотреть сколько угодно раз. Заголовок новости — нет.
Снимок официальной политики конфиденциальности, сохранённый 18 сентября, всё ещё показывал дату обновления 15 июня 2026. Политика писала: продукт собирает текст, файлы и код, отправленные в разговоре — обычный контур ассистента, который вызывает модель. Разбор указывает: на той странице тогда не было сказано, что в облако уйдёт снимок всего репозитория или полная история Git. Когда фраза политики и локальный список файлов расходятся, верьте списку и файлу состояния. Не выводите из «я согласился с политикой» заключение «значит, ушёл только абзац из окна чата».
Рядом: текущее дерево, история Git и чат
Один и тот же тестовый ключ, который однажды попал в репозиторий, распадается минимум на четыре пути «кто ещё может прочитать». Разница не в бренде ассистента. Разница в том, куда скопировали, и у кого право расшифровки.
| Что вы сделали | Что эта машина ещё держит | Остаток, который уже назвали официально или в разборе |
|---|---|---|
| Только открыли репозиторий, в ассистент не входили | Рабочее дерево и .git |
Нет (у пути снимка ещё не было сессии входа) |
Вошли в 3.12.3; в текущем дереве .env уже нет |
Старые blob всё ещё в объектном хранилище | Список снимка всё ещё может нести полный .git; у маленького репозитория была запись «сервер принял» |
| Выключили обучение / индексацию снимка | К объектному хранилищу не относится | Разбор 3.12.3: машина всё равно упаковывает; переключатели загрузку не покрывают |
| Обновились до сборки без загрузки, checkpoints не смотрели | Старые .enc и файлы состояния могут остаться |
Следующий исходящий путь остановили; уничтожили ли уже принятый снимок, снаружи не проверить |
| Ключ в Git не попадал; передача — одноразовая ссылка с разнесённым каналом | Тестовые файлы можно удалить | Поиск по снимку не найдёт полную учётную запись; для расшифровки нужны обе половины |
Пятую строку с первыми четырьмя не смешивайте. Если полную s.html?id=…#… записать в репозиторий и потом открыть ассистент, история и снимок всё ещё могут подобрать всю учётную запись. Хост, который только хранит шифротекст, ключ по-прежнему не видит. Разнесите номер и ключ — полнотекстовый поиск не найдёт ссылку, которая открывается. Полная ссылка всё равно пароль. «Сначала шифр, потом синхронизация» — про файл. Когда объектное хранилище Git уже видело открытый текст, поздний .lock старый blob не стирает.
Проверка на месте
Эти шаги не опираются на обещание бренда. Берите тестовый пароль и одноразовый репозиторий, которые не входят в рабочий аккаунт и не указывают на корпоративный репозиторий. В пустом каталоге закоммитьте одну строку вроде orange-lake-7, затем удалите её. На текущем мастер-пароле, боевом ключе API и живой одноразовой ссылке не тренируйтесь.
- Посмотрите номер версии на странице «О программе» ZCode или на установщике. Разбор называет 3.12.3 проблемной сборкой, 3.14.0 — сборкой, с которой путь загрузки сняли. Верьте цифре, которую читаете сейчас. Объявление в чате вместо этого взгляда не подставляйте.
- Откройте
v2/checkpointsв корне локальных данных (на macOS и Linux часто~/.zcode/v2/checkpoints; на Windows — пользовательский каталог после установки). Есть ли.encи рядом JSON состояния. Из полей, которые открываются, смотрите: не указывает лиworkspacePathна проект, который вы «никогда не открывали»,encryptedSizeBytes,failureCount,kind. Совпадающий путь значит: эта машина этот репозиторий упаковывала. БольшойfailureCountзначит только, что этот архив не ушёл. Он не доказывает, что другой репозиторий никогда не уходил успешно. - Создайте пустой тестовый репозиторий, закоммитьте один тестовый пароль, затем удалите его из этого дерева. Командами
git log -pилиgit log --all --full-history -- имя-файлапосмотрите, жив ли старый коммит. Если жив, «я уже удалил» объектное хранилище не спасает. Так ведёт себя сам Git, с ассистентом или без. Если снимок забирает.git, он читает именно этот слой. - Если 3.12.3 когда-либо открывал этот тестовый репозиторий: вернитесь в checkpoints и посмотрите, появился ли новый архив с тем же путём. После обновления понаблюдайте: вырастает ли новый ожидающий
.enc. Локальные файлы — доказательство, которое можно смотреть снова. Чужой клиент разбирать не нужно и не стоит. - Каждый пароль, токен и внутренний адрес, которые когда-либо попадали в настоящий репозиторий, считайте «уже покинувшими эту машину»: смените их в исходном сервисе и выпустите новый случайный пароль. Генератор MyPassGen в случайном режиме даёт 6–128 символов, по умолчанию 16, ниже 8 предупреждает, что слабее. Открывается сразу. Результат как деловые данные не загружается. Повторённую строку прогоните через проверку — локальное сравнение с открытым списком слабых паролей. Это доказывает попадание в список. Это не доказывает охват конкретного снимка.
- Соберите одноразовую ссылку MyPassGen на странице одноразовой ссылки с той же тестовой фразой, срок 24 часа, число чтений оставьте 1. В чат или тикет вставьте только часть до решётки,
s.html?id=…. Ключ скажите по телефону или лично. Открывается сразу, без регистрации. С одним номером получатель должен увидеть неполную ссылку; для расшифровки нужны обе половины. После чтения перезапишите буфер. Адрес с#в репозиторий не пишите и страницу результата в чат любого ассистента не вставляйте.
Для корпоративного репозитория добавьте полшага: спросите, какие корни ассистент открывает по умолчанию, можно ли держать каталог секретов вне рабочей области и есть ли у исторических снимков корпоративный акт удаления. MyPassGen не решит за вас, оставило ли чужое облако ещё одну копию. Верьте окнам, которые только что открыли, и журналу Git.
Если ключ нужно передать — разделите канал
Когда передача один на один и человек откроет ссылку сразу, не пишите пароль в файл, который попадёт в Git, в рабочую область ассистента и останется в объектном хранилище. Сгенерируйте его на этом устройстве, затем оберните одноразовой ссылкой. При создании браузер шифрует AES-256-GCM. Одна заметка — до 32 КБ. Число чтений по умолчанию 1, максимум 10. Срок — 1 час, 24 часа, 7 дней или только по числу, без TTL. Сервер хранит только шифротекст. Ключ стоит после # в адресе, поэтому журналы доступа и Referer этот кусок не видят. Репозиторий и окно чата ассистента его видят. Полную ссылку в коммит не пишите.
Если в репозитории или в тикете всё же нужен вход, разделите канал. В файле — только ответственный, номер и фраза «ключ по телефону». Звонок, личная передача или другой мессенджер несут только кусок после #. Одна половина не расшифровывает. Это приём использования, не заводская настройка: страница создания по-прежнему выдаёт одну полную ссылку — так удобнее отдать один на один. На канале, который рисует карточку превью, сначала прогоните тестовую ссылку и посмотрите, считает ли превью чтение. Это в Если вставить одноразовую ссылку в Slack или Telegram, сожжёт ли превью её раньше вас. Выдержки ошибок и конфигов сначала закройте маской на «Убрать UTM», потом решайте, вставлять ли их в ассистент.
Пакет ключей или выгрузка больше 32 КБ в текстовую одноразовую ссылку не лезут. Берите шифрование файлов: потоковый AES-256-GCM в браузере, один файл до 5 ГБ, выход .lock / .enc, пароль — другим каналом. Сначала зашифруйте на этом устройстве, потом синхронизируйте; с той стороны должен быть только шифротекст. Незамаскированный .env в Git — тот же класс задачи, что незашифрованный пакет сертификатов в облако: копия, которая доказывает «это ключ», ушла из дерева, которое вы уже считали чистым. Как на месте проверить, что шифрование в браузере не отправило открытый текст как деловые данные, — в Как на месте проверить, что шифрование в браузере не отправило открытый текст.
Когда сверили «есть ли в checkpoints .enc на этот путь», «печатает ли git log тестовый пароль» и «чистит ли одно обновление клиента старый снимок», на вопрос статьи уже можно ответить: удалить .env из текущего дерева — не значит опустошить объектное хранилище и уже собранный снимок. Официальное исправление закрывает клиентский путь, который они могут поменять. Архив, который сервер уже принял, и открытый текст в старых коммитах от одной смены версии не пустеют. Локальный каталог и журнал Git годятся для сверки. Они плохо годятся для мысли «я ключ в чат не вставлял — значит, кончено».
Частые вопросы
Я уже обновился. Старые снимки тоже исчезли?
Это разные задачи. Новая сборка закрывает следующий запрос учётных данных и прямую загрузку. Старый .enc на этой машине, файл состояния и облачная копия, которую компания называет «уничтоженной после генерации», в этот клик «Обновить» не входят. Верьте тому, лежат ли ещё checkpoints, и сменили ли вы живой ключ.
В дереве .env уже в .gitignore. Всё равно менять ключи?
Читайте историю, не это дерево. Правило игнора закрывает только будущий учёт. Если старый коммит держал открытый текст, считайте его уже скопированным. Один прогон git log на тестовом репозитории прямее, чем вера в фильтр.
Снимок зашифрован. Можно считать, что утечки не было?
Нет. В разборе сказано: закрытый ключ остаётся в облаке. Локальный шифротекст вы сами не откроете. Шифрование мешает «в бакете лежит открытый tar». Оно не значит «читает только владелец репозитория». Если уничтожение снаружи не доказать, ключи, которые когда-либо попадали в Git, считайте материалом для ротации.
Нужен ли аккаунт, чтобы создать и прочитать? Если отправил не туда, поддержка вернёт?
Регистрация не нужна. Создание и чтение открыты посетителю. После сжигания шифротекста по числу чтений или по сроку серверной копии открытого текста нет, и ящика поддержки, который её вернёт, тоже нет. Сгенерируйте новый пароль и новую ссылку. Ту же ссылку не обновляйте в надежде, что она вернётся, и страницу результата в репозиторий «на всякий случай» не пишите.