コーディング助手は、補完やエラー修正のためにコードを読む。リポジトリを開いたとき、渡しているつもりなのは今の作業領域のうち、今回の作業に必要な数ファイルだ。ルートの .env を .gitignore に書いてあれば、「助手は見ない、クラウドはなお見ない」と読む人は多い。2026年9月18日、開発者 ferstar は別の層を書いた。Zhipu 公式のデスクトップアプリ ZCode は、ログイン後に手元で作業領域のスナップショットを作る。一覧で体積の大半を占めるのは src/ ではなく、完全な .git だ。
前稿はChatGPTやGeminiにパスワードを貼る前、先に伏せるべき文字列を書いた。あれは、自分で選んで貼った一段落だ。本稿は問いを替える。.env を入力欄へ貼っていないときでも、作業領域スナップショットの Git オブジェクトストア、LFS キャッシュ、reflog は、すでに消した鍵を一緒に持っていくか。鍵を動かすなら、形は s.html?id=…#… のワンタイムにする。作成も閲覧も登録は要らない。MyPassGen のツールは開いてすぐ使える。以下は、クライアントを分解する方法でも、他人のアップロードを止める手順でもない。ferstar の2026年9月18日の検証と、同日の日本語報道が転じた公式説明がすでに書いた数字と、自分のパソコンで開ける checkpoints を並べる。
先に仕事を分ける
「もう上がらない版へ上げた」が止めるのは、次の梱包だ。すでに作られ、すでに手元を離れ、公式が「Wiki 生成後に直ちに破棄する」と書いたスナップショットは、外からサーバー側の控えや秘密鍵の所在を照合できない。先に手元へ未送信の .enc が無いかを見る。次に、かつて Git へ入ったパスワードを差し替えるかを決める。クライアントの版を変えることを、「この端末にスナップショットが残るか」「履歴からテスト用の鍵がまだ読めるか」の代わりにしない。
リポジトリを開くことと、今のファイルだけを渡すことは違う
会話へ関数を貼れば、モデルが食べるのは選んだ文脈だ。作業領域のスナップショットは別の道だ。クライアントは開いたリポジトリを梱包する。範囲は「今回の質問に必要なファイル」より大きくなり得る。ferstar が書いた一覧を体積で分けると、.git/lfs/、.git/objects/、.git/logs/ を合わせて約 86.6%、残りのソースと文書は約 13.4% だ。今のディレクトリから .env を消していても、オブジェクトストアの古いコミットの blob は一緒に動き得る。
これは「このサイトが、今作っているパスワードを業務データとして出したか」とは別の経路だ。MyPassGen の生成ページは、ブラウザの Network で平文が業務データとして出ていないことを確かめられる。デスクトップ助手のスナップショットは、そのアプリ自身の手元ディレクトリと、そのアプリ自身の外向き接続を通る。作業領域で git rm したファイルは、Git にとって「今の作業ツリーに無い」ことが多い。「履歴に一度も無い」ではない。マスキングしていない鍵をコミットへ書いたことと、パスワードをメール本文へ書いたことは、同じ種類の残りだ。受け手が読むのは、かつて自分で残した控えだ。対照はメール本文に一時パスワードを書くと、送信済み、転送、スマホプレビューに何が残るか。
もう一層、混ざりやすい。.gitignore が止めるのは「これからこの経路を追跡しない」だ。「この経路がかつてコミットされた」は止まらない。助手が今の作業領域のファイルだけを読むなら、無視規則はまだ効く。スナップショットが .git ディレクトリごと入るなら、無視規則は助けにならない。まだ遠隔へ push していないローカルブランチ、reflog の操作記録、.git/config の社内リポジトリURLは、「今のエディタのタブには無い、オブジェクトストアにはある」側だ。
9月18日の検証と公式説明に書かれた数字
ferstar は、起点を手元の ~/.zcode が 700 MB 超を占めていたことだと書く。うち v2/checkpoints/ は約 303 MB。中に約 313 MB の .enc があり、状態ファイルは梱包前の作業領域を約 345 MB、暗号化後を 313070842 バイト、kind を baseline、failureCount を 564 と記す。この商用プロジェクトのスナップショットは手元の pending で止まり、検証は「送信に成功していない」と書く。別のごく小さい公開リポジトリは、538 ファイル、圧縮・暗号化後は約 15 KB、状態はサーバー側が受信済みだ。だから「本当に出たか」——少なくともこの回、小さいリポジトリは出た。
同じ商用プロジェクトのファイル一覧:合計 42411。.git/lfs/ は約 196.1 MB(56.8%)、.git/objects/ は約 102.2 MB(29.6%)、.git/logs/ は約 0.6 MB(0.2%)。コミュニティの別の再現は、ZCode 3.12.3 で一つのプロジェクトスナップショットが約 748 MiB、うち .git が約 98.91% と書く。捕捉の起点として、検証は質問前の captureBeforePrompt と、作業終了時の repo-wiki-update を名指す。一つの活発なセッションログでは、スナップショット捕捉が最大 62 回出た。
公式説明は 9月18日 17:44 に出た。日本語報道は同夜に転じている。要点はこうだ。問題は「コードリポジトリインデックス」にあり、手元の索引、セッションのチェックポイント巻き戻し、Repo Wiki のためだ。Repo Wiki がクラウドでページを作るとき、リポジトリデータが「上がり得る」。Wiki 生成後、関連のアップロードデータは直ちに破棄し、保存しない。公開初期は既定でオン、一部の利用者が影響を受け、問題は「すでに修正した」。近く ZCode をオープンソース化し、第三者の審査を入れる。全利用者へ週次枠の追加リセットを一回。公式は「アップロードがあった」を否定していない。疑いは範囲、当時オフにできたか、「直ちに破棄」を外からどう照合するかだ。9月20日、InfoQ の転載は、太原承明科技が北京智谱华章へ書面を送り、削除、データの行き先、ログ、責任主体の説明を求めたと書く。企業側の問いであり、手元で開ける破棄証明ではない。
.gitが大半:消した鍵はオブジェクトストアに残る
今の作業領域に .env が無いことは、今チェックアウトした木にその経路が無いことだけを証明する。Git のオブジェクトストアは内容で blob を置く。あるコミットが DATABASE_URL= や AWS_SECRET_ACCESS_KEY= を書き、あとでファイルを直し、再コミットし、今のブランチから消しても、古い blob は .git/objects に残りやすい。gc が本当に捨てるまでだ。LFS キャッシュは、過去の大きなファイルを残し得る。reflog は、この端末でどのブランチを動かしたかを記す。この三つをスナップショットへ入れると、クラウドが取るのは「今のエディタの一画面」ではなく、このリポジトリがこの端末に積んだ履歴だ。
検証はもう一つ書く。作業領域のフィルタは一部の鍵ファイルを外すが、.git は梱包へ入る。この文は一度止めて読む価値がある。今日 .env をリポジトリから外し、.env.example だけ残しても、今の作業ツリーはきれいに見える。オブジェクトストアの去年の誤コミットは、フィルタが作業領域の経路だけを見るなら、外されない。社内 GitLab のドメインは .git/config にあり、まだ push していない機能ブランチ名は refs と reflog にある。「もう gitignore した」では回収できない。
これは「パスワードのハッシュが漏れても、相手がすでに平文を読んだことにはならない」と並べられる。代わりにはならない。ハッシュは一方向の置き方でも、パスワードは差し替える。Git 履歴の鍵は、しばしば平文そのものだ。手元でよくある弱いパスワード名簿と照合しても、公開名簿に当たったことだけが分かる。あるスナップショットが古いコミットを持っていったかは証明できない。対照は端末の漏洩名簿と Have I Been Pwned では、証明できることが違う。差し替えるべきは、かつてコミットへ書いた一式だ。「今の作業領域はきれいだ」の一眼ではない。
暗号文にしたことと、自分だけが解けることは違う
検証が復元した外向きの形はこうだ。クライアントは zcode.z.ai へスナップショット用のアップロード認証情報を求め、オブジェクトキー、サイズ上限、RSA 公開鍵を受け取る。手元は作業領域を tar.gz にし、AES-256-CTR で暗号化し、この公開鍵で対称鍵を包み、tar.gz.enc を Alibaba Cloud OSS へ直送する。秘密鍵は最初から最後までクラウド側だけにある。手元の数百 MB の .enc は、自分もクライアントも開けない。アルゴリズム名に AES-256 と書いてあるのは、「路上とバケットの中が平文のファイルではない」を解く。復号権を自分へ渡してはいない。
これは「クラウドのページに暗号化と書いてある」と同じ境界だ。事業者が鍵を預かるなら、保管側はまだ開ける。手元で自分が持つパスフレーズで先に暗号化すれば、先方が見るのは暗号文だけだ。差は「AES の四文字が出たか」ではなく、秘密鍵やパスフレーズが誰の手にあるかだ。MyPassGen のファイル暗号は、ブラウザで AES-256-GCM のストリーム暗号化をする。単一ファイルは 5 GB 以下、出力は .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 へ上げたあとも、同じディレクトリを見る。新しい未送信のアーカイブはまだ増えるか。認証情報を申請するアドレスはまだ成功を返すか。クライアントは自動更新する。版番号とディレクトリは、繰り返し見られる二点だ。ニュースの見出しではない。
9月18日当日に残った公式プライバシーポリシーのスナップショットは、更新日を 2026年6月15日のまま記す。ポリシーは、会話で提出したテキスト、ファイル、コードを集めると書く。助手がモデルを呼ぶときの通常範囲だ。検証は、当時の全文にリポジトリ全体のスナップショットや、完全な 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はまだ増えるか。手元のファイルは、繰り返し見られる証拠だ。他人のクライアントを分解する必要は無く、してはならない。 - 実在のリポジトリへかつて書いたパスワード、トークン、社内URLは、「すでにこの端末を出た」として扱う。元のサービスで差し替え、新しいランダムパスワードへ替える。MyPassGen のパスワード生成は、ランダムモード 6–128 文字、初期値 16、8 未満は弱いと表示する。開いてすぐ使え、生成結果は業務データとして上げない。使い回したパスワードは、強度チェックで手元のよくある弱いパスワード名簿と照合する。当たれば公開名簿だと分かる。あるスナップショットの範囲は証明しない。
- MyPassGen のワンタイムを別に一本作り、同じテスト用パスワードを書く。期限は 24 時間、閲覧回数は 1 のまま。チャットやチケットへ貼るのは、
#の前のs.html?id=…だけ。鍵は電話か対面で言う。開いてすぐ使え、登録は要らない。受け手が番号だけなら、リンクは不完全だと見えるはずだ。半分が揃って初めて復号できる。読んだらクリップボードを上書きする。#の付いたアドレスをリポジトリへ書かない。結果ページの全文を、どの助手の入力欄へも貼らない。
会社のリポジトリなら、もう一つ聞く。助手が既定でどのルートを開くか、鍵のディレクトリを作業領域の外へ出せるか、過去のスナップショットに企業側の削除確認があるかだ。MyPassGen は、あるクラウドが控えを別に残したかを代行して判断しない。照合の結果は、今開いた窓と Git のログを先にする。
鍵を渡さねばならないとき、経路を分ける
一対一で、相手がすぐ開けるなら、パスワードを Git へ入り、助手の作業領域へ入り、オブジェクトストアへ残るファイルへ書かない。手元でパスワードを作り、ワンタイムにする。作成時、ブラウザは AES-256-GCM で暗号化する。平文は 32 KB まで。閲覧回数は既定 1、上限 10。期限は 1 時間、24 時間、7 日、または回数だけ、TTL 無し。サーバーは暗号文だけを一時置きする。鍵は URL の # の後ろにあり、アクセスログと Referer にはこの一段は見えない。リポジトリと助手の入力欄には見える。だから完全なリンクをコミットへ書かない。
リポジトリやチケットへ入口を残さねばならないときは、経路を分ける。ファイルは担当と番号、および「鍵は電話」の一文だけを送る。電話、対面、別の即時メッセージ口座は、# の後ろだけを送る。半分が無ければ解けない。これは使い方であり、製品が既定で分けるわけではない。作成ページが出すのは、一対一の受け渡し向けの完全なリンクだ。プレビューカードを作る経路は、先にテスト用リンクでプレビューが回数を数えるかを見る。対照はSlackやLINEにワンタイムリンクを貼ると、プレビューで先に消費されるか。エラーと設定の抜粋は、先にUTM削除で伏せてから、助手へ貼るかを決める。
32 KB を超える鍵の束や書き出し表は、ワンタイムへ無理に入れない。ファイル暗号へ行く。ブラウザで AES-256-GCM のストリーム暗号化、単一ファイルは 5 GB 以下、出力は .lock / .enc、パスフレーズは別経路。手元で先に暗号化してから同期すれば、先方が見るのは暗号文だけだ。マスキングしていない .env を Git へ push することと、暗号化していない証明書の束をクラウドへ上げることは、同じ種類の残りだ。「これは鍵だ」と証明するそのファイルが、消したつもりだった作業領域を出る。ブラウザで暗号化するとき、平文が業務データとして上がっていないことをその場で確かめる手順は、ブラウザで暗号化したとき、平文が送られていないことをその場で確かめるに書いた。
「checkpoints にその経路の .enc があるか」「git log はまだテスト用パスワードを読めるか」「クライアントを上げただけでは古いスナップショットは消えないか」の三回を終えれば、本稿の問いに答えられる。今の作業ツリーから .env を消しても、オブジェクトストアと、かつて作ったスナップショットは一緒には空にならない。公式が直すのは、彼らが変えられるクライアント経路だ。すでに受信して入ったアーカイブと、リポジトリの古いコミットの平文は、版を一つ上げても空にならない。手元のディレクトリと Git のログは、照合の入口には向く。「鍵を入力欄へ貼っていないから終わった」と仮定する入口には向かない。
よくある質問
もう版を上げた。古いスナップショットも消えたか。
同じ仕事ではない。新しい版が止めるのは、次の認証情報申請と直送だ。手元の古い .enc、状態ファイル、公式が「生成後に直ちに破棄する」と書いたクラウド側の控えは、「上げる」という動作の中に無い。いま checkpoints が残るか、実在の鍵を差し替えたかを先にする。
作業領域では .env をすでに gitignore した。まだ差し替えるか。
履歴を見る。今の作業ツリーは見ない。無視規則が止めるのは、これからの追跡だ。古いコミットに平文が出ていれば、すでに写ったとして扱う。テスト用リポジトリで git log を一度照合するほうが、フィルタを信じるより直接だ。
スナップショットは暗号化されている。漏れていないと考えてよいか。
よくない。検証は、秘密鍵がクラウド側だけにあり、手元の暗号文は自分では解けないと書く。暗号化が止めるのは「バケットに平文の tar が寝ている」ことだ。「リポジトリの持ち主だけが読める」ではない。破棄を外から証明できないなら、かつて Git へ入った鍵は、差し替える材料として扱う。
作成と閲覧に登録は要るか。消し間違えたら、問い合わせで戻るか。
登録は要らない。作成も閲覧も、訪問者へ公開する。暗号文が回数または期限で消えたあと、サーバー側の平文控えは無く、取り戻す窓口も無い。経路を間違えたら、パスワードを作り直し、リンクを別に作る。同じ一本を何度も更新して運を見ない。結果ページをリポジトリへ書いて再送しない。