CLAUDE LABEN
APPLY — ant CLI v1.30.0 に ant apply が入りました。エージェント・環境・スキル・メモリストア・デプロイメントを、リポジトリのファイルから作成・更新できますLOCKFILE — 書き出される claude-lock.json は必ずコミットしてください。忘れると、実行のたびに同じリソースが新しく作られていきますPLAN — ant apply は適用の前に計画を表示し、承認を挟みます。CI で無人実行するなら、この承認をどう扱うかを先に決めておくことですPRICING — Claude Sonnet 5 の 3 ドル / 15 ドルへの値上げは実施されていません。導入価格の 2 ドル / 10 ドルがそのまま標準価格になりましたSOURCE — 価格と版番号は二次ニュースに誤りが混じります。platform.claude.com のリリースノートで裏を取ってから書くようにしていますBETA — Agent Skills と Skills API はベータを抜け、skills-2025-10-02 ヘッダが不要になりました。Files API はヘッダの有無でレスポンス形式が変わる点に注意ですAPPLY — ant CLI v1.30.0 に ant apply が入りました。エージェント・環境・スキル・メモリストア・デプロイメントを、リポジトリのファイルから作成・更新できますLOCKFILE — 書き出される claude-lock.json は必ずコミットしてください。忘れると、実行のたびに同じリソースが新しく作られていきますPLAN — ant apply は適用の前に計画を表示し、承認を挟みます。CI で無人実行するなら、この承認をどう扱うかを先に決めておくことですPRICING — Claude Sonnet 5 の 3 ドル / 15 ドルへの値上げは実施されていません。導入価格の 2 ドル / 10 ドルがそのまま標準価格になりましたSOURCE — 価格と版番号は二次ニュースに誤りが混じります。platform.claude.com のリリースノートで裏を取ってから書くようにしていますBETA — Agent Skills と Skills API はベータを抜け、skills-2025-10-02 ヘッダが不要になりました。Files API はヘッダの有無でレスポンス形式が変わる点に注意です
記事一覧/Claude Code
Claude Code/2026-08-10上級

同じ rm -rf が、10箇所では戻せて5箇所では戻せませんでした — auto モード既定化の前に可逆性を測る

8月14日から auto モードが Pro / Max / Team の既定になります。止まる境界は「取り消せない・破壊的・環境の外」ですが、可逆性は操作の名前ではなく実行時点の状態で決まりました。復旧不能バイトを数えるプローブと、15対象の実測をまとめます。

Claude Code250auto mode3権限設計4git17個人開発126

プレミアム記事

8月14日という日付をカレンダーに書き込んでから、自分の手元で何が変わるのかを確かめる作業に半日を使いました。

Claude Code の auto モードが、Pro・Max・Team の既定として有効になります。auto モードは各ステップごとに承認を求めず、「取り消せない・破壊的・自分の環境の外へ向かう」と判定された操作でだけ止まります。

言葉としては、迷いようがないほど明快です。

けれど自分の環境に当てはめようとした瞬間に、手が止まりました。個人開発でアプリのビルド成果物やスクリーンショットの整理を夜間に走らせていると、削除も上書きも日常的に混ざります。そのうちのどれが「取り消せない」のか、私は即答できませんでした。

答えを出すために、リポジトリを一本まるごと使って測ってみました。結果として得られたのは、「危険なコマンドの一覧」を作ろうとしていた自分の前提そのものが間違っていた、という気づきでした。

「取り消せない」を操作の名前で決めようとして詰まった

最初にやったのは、多くの人がやるのと同じことです。手元のシェル履歴を眺めて、危なそうなコマンドを書き出しました。

rm -rfgit push --forcegit clean -fdxnpm publish、外部 API への POST

書き出したところで、リストが役に立たないことに気づきます。同じ rm -rf でも、git が追跡しているディレクトリを消したときと、.gitignore に入っているディレクトリを消したときでは、被害の性質がまったく違います。前者は数百ミリ秒で完全に戻ります。後者は永久に戻りません。

つまり「取り消せるかどうか」は、コマンドの属性ではありませんでした。そのコマンドが、その瞬間に、どんな状態のファイルへ向けられているかという、状態の属性です。

コマンド名の列挙で表現できないものを、コマンド名の列挙で表現しようとしていた。これが半日の最初の1時間で分かったことです。

私はこの気づきを、deny ルールを書き始める前に得られてよかったと感じています。列挙型のルールは、増やすほど自分の首を絞めます。ルールセットが膨らんだ後の棚卸しについては 許可ルールを積み上げたセッションが毎ターン重くなる — ルールセットの棚卸しと、安全性を保ったまま数を減らす設計 に別途まとめています。

可逆性を測るプローブを書く

状態の属性であるなら、実行前に状態を測ればよいことになります。

測る対象は、対象パス配下のファイルのうち git から戻せないもののバイト数 です。追跡されていてクリーンなファイルは戻ります。追跡されていない、あるいは無視されているファイルは戻りません。

以下が実際に使ったプローブです。標準ライブラリだけで動きます。

#!/usr/bin/env python3
"""指定パス配下のファイルを「git から戻せるか」で分類し、復旧不能なバイト数を出す。"""
import os, subprocess, sys, collections
 
def git(*args):
    r = subprocess.run(["git", *args], capture_output=True, text=True)
    return [p for p in r.stdout.split("\0") if p]
 
def classify(root="."):
    tracked   = set(git("ls-files", "-z"))
    ignored   = set(git("ls-files", "-z", "--others", "--ignored", "--exclude-standard"))
    untracked = set(git("ls-files", "-z", "--others", "--exclude-standard"))
    dirty     = set(git("diff", "-z", "--name-only"))
    staged    = set(git("diff", "-z", "--name-only", "--cached"))
 
    buckets = collections.defaultdict(lambda: [0, 0])   # [ファイル数, バイト数]
    for dirpath, dirnames, filenames in os.walk(root):
        if ".git" in dirpath.split(os.sep):
            continue
        for name in filenames:
            path = os.path.relpath(os.path.join(dirpath, name), root)
            if   path in ignored:   kind = "ignored"           # 復旧不能
            elif path in untracked: kind = "untracked"         # 復旧不能
            elif path in staged:    kind = "tracked-staged"    # index からのみ
            elif path in dirty:     kind = "tracked-modified"  # 変更分は失う
            elif path in tracked:   kind = "tracked-clean"     # 完全復旧
            else:                   kind = "unknown"
            try:
                size = os.path.getsize(os.path.join(root, path))
            except OSError:
                continue
            buckets[kind][0] += 1
            buckets[kind][1] += size
    return buckets
 
RECOVERABLE = {"tracked-clean"}
 
if __name__ == "__main__":
    b = classify(sys.argv[1] if len(sys.argv) > 1 else ".")
    lost_f = lost_b = tot_f = tot_b = 0
    for kind, (n, size) in sorted(b.items()):
        tot_f += n; tot_b += size
        if kind not in RECOVERABLE:
            lost_f += n; lost_b += size
        print(f"{kind:18} files={n:6d} bytes={size:12,d}")
    print("-" * 46)
    print(f"復旧不能 files={lost_f}/{tot_f} ({lost_f/tot_f*100:.1f}%) "
          f"bytes={lost_b:,}/{tot_b:,} ({lost_b/tot_b*100:.1f}%)")

分類を6つに分けたのには理由があります。tracked-clean だけが無条件に戻ります。tracked-modified は「ファイルは戻るが、まだコミットしていない編集内容は失う」という中間状態で、これを「戻せる」に数えると判断を誤ります。私は RECOVERABLE を意図的に1種類だけにしました。

計測はサンドボックス(Linux 6.8.0 / Python 3.10.12 / git 2.34.1 / 4 vCPU / メモリ 3.9GB)で実際に走らせています。以下の数値はすべてその実行結果です。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
auto モードの既定化を前に何を deny すべきか決めかねていた人が、自分のリポジトリで復旧不能なバイト数を数えてから線を引けるようになる
同じ rm -rf が対象によって可逆にも不可逆にもなることを15対象の実測で確かめ、コマンド名ベースの列挙から状態ベースの事前判定へ移せる
force push を戻せるかが「誰が SHA を持っているか」で決まる仕組みを理解し、リモート任せにしない復旧経路を用意できる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

関連記事

Claude Code2026-09-04
Claude Code に project.pbxproj だけは直接触らせていません
Xcode のプロジェクトファイルは、開けなくなる壊れ方より開けてしまう壊れ方のほうが高くつきました。直接編集をやめてスクリプト経由に寄せるまでに測ったことと、いま引いている線を書き残します。
Claude Code2026-07-19
auto モードの設定が、いつの間にか自分でも思い出せなくなっていた — 既定へ戻す claude auto-mode reset の使いどころ
夜間の自動運用を続けるうちに、auto モードの設定を少しずつ触り足していました。ある朝の違和感で、自分が何を変えたのか思い出せないことに気づきます。既定へ戻す claude auto-mode reset を基点にして設定を組み直した、個人開発の片付けの記録です。
Claude Code2026-07-14
空の変数と rm -rf の夜 — Claude Code auto モードの事前確認に助けられた片付けの記録
空になった変数のせいで rm -rf が広範囲に化けかけた夜の記録です。set -u が空文字を素通りさせる理由を手元のシェルで検証し、ドライランを既定にした掃除スクリプトの実行結果まで残しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます