ANTIGRAVITY LABEN
記事一覧/アプリ開発
アプリ開発/2026-08-24上級

消えたのは中身ではなく作業ディレクトリでした — 無人で走る破壊操作を fail-closed に組み直す

無人で走らせていた掃除処理が、掃除対象の中身ではなく作業ディレクトリそのものを消しました。mkdir -p が安全弁にならなかった理由と、取得失敗を既定値で埋める書き方が破壊側の分岐を選んでいた経緯を、実際の検証出力とともに整理します。

antigravity443agents94automation53shell3reliability6

プレミアム記事

朝、ログを開いたら、あるはずのディレクトリが無くなっていました。

正確に言えば、無くなったのは「掃除対象の中身」ではなく「掃除対象そのもの」です。夜のうちに一度だけ走る保守処理で、私自身が書いた一行が、親ディレクトリごと持っていっていました。

原因はすぐに分かりました。find-mindepth 1 を書き忘れていただけです。ただ、そこから先が長くなりました。「なぜ気づかなかったのか」と「なぜ後段の mkdir -p が助けにならなかったのか」を追っていくうちに、同じ形の穴が、個人開発で回している他の自動化にもいくつも残っていることが見えてきたためです。

突き詰めると、問われていたのは一点でした。無人で走る処理が「わからない状態」に落ちたとき、どちら側へ倒れるか。 私のスクリプトは、そろって破壊側へ倒れる作りになっていました。

消えたのは中身ではなく、ディレクトリそのものでした

まず、事故そのものを再現しておきます。以下は実際に手元の環境(GNU bash 5.1.16 / GNU findutils 4.8.0)で走らせた検証です。

B=/tmp/probe1; rm -rf $B; mkdir -p $B
mkdir -p $B/a/work/sub1 $B/b/work/sub1
touch $B/a/work/f1 $B/a/work/sub1/f2
touch $B/b/work/f1 $B/b/work/sub1/f2
 
# 事故った側: -mindepth 1 なし
find $B/a/work -delete
echo "a/work exists? $([ -d $B/a/work ] && echo yes || echo NO)"
 
# 正しい側: -mindepth 1 あり
find $B/b/work -mindepth 1 -delete
echo "b/work exists? $([ -d $B/b/work ] && echo yes || echo NO) / 中身=$(ls -A $B/b/work | wc -l)件"

実行結果です。

a/work exists? NO
b/work exists? yes / 中身=0件

find の起点パスは、それ自体が探索結果の一件目です。-delete はその一件目も対象にします。つまり -mindepth 1 は「省略しても同じ」ではなく、「起点を守るか、起点ごと渡すか」を決める指定です。

ここまでは、知っていれば防げる話です。私が本当に困ったのは次でした。

mkdir -p は安全弁になりませんでした

私のスクリプトには、掃除の直後に mkdir -p "$WORK" が書いてありました。「万一消えても作り直すから大丈夫」という意図です。実際にはこう振る舞います。

mkdir -p $B/a/work
echo "a/work exists? $([ -d $B/a/work ] && echo yes) / 中身=$(ls -A $B/a/work | wc -l)件"
a/work exists? yes / 中身=0件

ディレクトリは戻りますが、中身は戻りません。そして厄介なのは、後段の処理が「ディレクトリはある」という前提で正常に進んでしまうことです。存在チェックは通り、書き込みも通り、終了コードは 0 です。

事故が起きたのに、事故として観測されません。この日の異常に私が気づいたのは、翌朝ログを目で追ったときでした。mkdir -p は復旧処理のつもりで置いたのに、実際には事故を隠す装置として働いていたわけです。

同じ形の書き方は、ほかにもあります。「無ければ作る」「壊れていれば初期化する」「読めなければ既定に戻す」。どれも復旧の顔をしていますが、壊れた事実を消してから先へ進むという点では同じです。

Antigravity CLI 1.1.16 に「解析できない settings.json を既定値で上書きしてしまう問題」の修正が入りました。従来は、設定ファイルが読めない状態で次に何かを保存した時点で、全設定が黙って初期化されていたそうです。修正後は保存を拒否し、ファイルはバイト単位で保たれ、ステータスラインが該当ファイルを名指しします。

読めない設定を既定値で上書きする、というのは私の mkdir -p と同じ構図です。復旧の意図で書いた分岐が、いちばん情報を失う経路になっていました。手元のスクリプトを見直すきっかけとしては、これ以上ないタイミングでした。

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

この記事の続きを読む

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

この記事で得られること
無人で走らせている掃除・初期化処理のうち、どれが「消える側」に倒れる作りになっているかを、事故が起きる前に洗い出せるようになる
取得に失敗した値を既定値で埋める書き方が、なぜ破壊的な分岐を選んでしまうのかを、自分のスクリプトの中で見分けられるようになる
許可ディレクトリの外へ手を伸ばさせないガードを、シンボリックリンク越しの経路まで塞いだ形で移植できるようになる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

アプリ開発2026-07-02
依存パッケージの更新を月イチの苦行にしない — エージェントに任せる週次アップデートのリスク分類と検証ゲート
未更新47件を前に固まった経験から、依存パッケージ更新をエージェントに任せる週次運用へ移行しました。更新を3つのリスク帯に分ける機械化スクリプト、やらないことを先に書くプレイブック、lockfile 差分を範囲で見る検証ゲートを紹介します。
アプリ開発2026-08-15
壁紙アプリの30カテゴリ分類で、エージェントに選ばせる範囲をどこまで狭めるか
画像を見せて30個のカテゴリから選ばせる分類バッチは、定義を1つ足すだけで全件やり直しになります。エージェントには閉じた語彙のタグだけを出させ、カテゴリは決定的な規則で写像する設計へ切り替えた判断と実装を共有します。
アプリ開発2026-07-18
「Compose ファースト」の後で、View の画面をどの順に移すか — 画面数ではなく変更頻度で決める
Google が Android 開発を Compose ファーストと表明しました。View ベースの画面をどの順で移すかを、画面数ではなく git の変更履歴から決める判断軸と、実際に動かしたスコアリングスクリプトをまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →