◉ANTIGRAVITY LABEN
記事一覧/連携・プラグイン
⬡ 連携・プラグイン/2026-07-15上級

無人ランで作業フォルダが突然『別の人の持ち物』になる — 所有者ドリフトを検知して書ける場所へ逃がす

数週間緑だった無人スケジュールが、ある朝 git config を書けずに止まりました。原因は永続作業フォルダの所有者ドリフト。存在チェックでは通り書き込みだけが弾かれる罠を切り分け、書込可否を実測して別の場所へ逃がすプリフライトを実装まで残します。

antigravity464antigravity-cli14unattendedautomation54troubleshooting89

✦ プレミアム記事

ある朝、無人スケジュールの記録を上から順に見ていて、指が止まりました。前夜まで何週間も緑だったはずのランが、いちばん最初のステップで赤くなっています。ログにはこう残っていました。

error: could not lock config file .git/config: Permission denied
fatal: not in a git directory
error: cannot open .git/FETCH_HEAD: Permission denied

不思議なのは、その少し下の行で find content/articles/ja -name '*.mdx' | wc -l が普通に数を返していたことです。読めている。一覧も取れている。それなのに git は「書けない」と言い張る。ファイルが消えたわけでも、認証が切れたわけでもありませんでした。

犯人は、毎回使い回していた永続作業フォルダの所有者でした。個人開発で複数のサイトを無人のスケジュールで回していると、作業フォルダを毎回 clone し直すのはもったいないので、/tmp/repos/site.net のような場所に置いて git pull --rebase で差分だけ取りたくなります。ところが実行基盤のサンドボックスが世代交代すると、その永続フォルダが別のUID(多くは nobody)の持ち物として残ることがあります。読み取りは誰でもできるので ls も find も通る。けれど .git/config へのロック、つまり書き込みだけが Permission denied で弾かれる。この非対称性が、朝の切り分けを一段ややこしくしていました。

この記事は、その「読めるのに書けない作業フォルダ」を無人ランの前に見抜き、書ける場所へ静かに逃がすためのプリフライトを設計した記録です。エラーメッセージへの後追いではなく、走り出す前に足場を確かめてしまう作りに寄せています。

存在チェックが嘘をつく理由

多くのパイプラインは、作業フォルダの再利用可否をこう判定していると思います。

if [ -d "$WORK/.git" ]; then
  cd "$WORK" && git pull --rebase origin main
else
  git clone --depth 1 "$REPO_URL" "$WORK"
fi

-d "$WORK/.git" は「ディレクトリが存在するか」しか見ていません。所有者が誰であっても、パーミッションがどうであっても、存在さえしていれば真を返します。所有者ドリフトが起きたフォルダは、まさにここで「再利用できる」と誤判定されます。そして git pull --rebase の内部で初めて .git/config や .git/FETCH_HEAD へ書きに行き、そこで初めて崩れる。

つまり失敗が遅いのです。プリフライトで弾けず、実処理の途中まで進んでから転ぶので、ログは「pullの途中で謎の権限エラー」という見え方になります。私は最初、GitHub の認証まわりを疑って小一時間を溶かしました。実際には認証は無関係で、ローカルの .git に触れなかっただけでした。この取り違えは、本番運用で無人ランを止めないためにこそ、先に潰しておきたい落とし穴です。

一次情報として一点補足します。読み取りが通るのは、退避先や親ディレクトリのパーミッションが 755 相当で「その他ユーザーに読み取り+実行」を許していることが多いからです。所有者が nobody でも、他人の私たちはディレクトリを辿って中を読める。書き込みビットだけが自分に無い。この一行の非対称が、症状の全てを説明します。

書けるかどうかは、実際に書いて確かめる

存在チェックが嘘をつくなら、判定を「実際に書けたか」に置き換えます。所有者UIDの比較(stat で取れます)も補助にはなりますが、最終的な真実は「今の自分がそのディレクトリ配下に一時ファイルを作れたか」です。マウント形態やACL次第で、UID一致でも書けない・UID不一致でも書ける、という食い違いが起きうるからです。私は所有者UIDを警戒のシグナルとして使い、可否は実書き込みで決める、という二段構えを推奨します。

次の関数が、この記事の核です。候補ディレクトリを受け取り、実際に一時ファイルを作って消し、書けたら真を返します。

# 実書き込みで「今の自分が書けるか」を確かめる。存在や所有者UIDだけに頼らない。
is_writable_dir() {
  local dir="$1"
  [ -d "$dir" ] || return 1
  # ディレクトリ直下に一意名の probe を作り、成否で判定する
  local probe="${dir}/.wtest.$$.$RANDOM"
  if ( set -C; : > "$probe" ) 2>/dev/null; then
    rm -f "$probe" 2>/dev/null
    return 0
  fi
  return 1
}
 
# 所有者UIDが自分と一致するか(警戒シグナル。可否判定そのものには使わない)
owner_is_me() {
  local dir="$1"
  [ -d "$dir" ] || return 1
  local owner_uid
  owner_uid="$(stat -c '%u' "$dir" 2>/dev/null || stat -f '%u' "$dir" 2>/dev/null)"
  [ "$owner_uid" = "$(id -u)" ]
}

set -C(noclobber)を効かせた上でリダイレクトしているのは、万一 probe 名が衝突しても既存ファイルを潰さないためです。$$(PID)と $RANDOM を混ぜて衝突をほぼ起こさないようにしていますが、安全側に倒しておきます。stat は Linux(-c)と macOS/BSD(-f)で書式が違うので両方を試すのが実務的な対処です。無人ランはどちらの基盤に載るか分からないので、こういう小さな差異を先に吸収しておくと、後で「片方の環境だけで落ちる」を防げます。

✦

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

この記事の続きを読む

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

この記事で得られること
✦『ディレクトリは在るのに書けない』を、存在チェックではなく実書き込みテストで判定するプリフライトの完全実装
✦所有者ドリフトを検知したら削除を試し、消せなければユーザー専用の退避先へ落とす3段フォールバックの設計
✦6週間47ランで所有者ドリフト5回を全て自動復旧した実測と、二度と同じ朝を迎えないための冪等化の勘所
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

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

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

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

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

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

関連記事

⬡ 連携・プラグイン2026-03-23
Antigravity × Terraform で実現する AI 駆動インフラ自動化 — IaC をAIがレビュー・生成するワークフロー
独特の構文を持つ Terraform の HCL を、Antigravity の AI がレビュー・生成するワークフローを構築します。IaC エージェントの設定、Project Context やセキュリティ要件の書き方、コード自動生成の実際までを手順を追って解説します。
⬡ 連携・プラグイン2026-09-05
GOOGLE_GEMINI_BASE_URL を差し替えても、鍵の持ち主は変わりません
Antigravity CLI の宛先を自前のゲートウェイへ向けたとき、手元の API キーがどこまで運ばれるかを受け側で記録しました。クロスホストのリダイレクトで Authorization は落ちるのに API キーヘッダーは残る、という挙動差の実測と、鍵を端末から外すゲートウェイの組み方を書き残します。
⬡ 連携・プラグイン2026-05-24
Antigravity サブエージェントの「動いているのに何もしていない」を捕まえる Observability 3層設計
Antigravity サブエージェントを 6 アプリ並行で動かしていると、月に 10 件以上「実行ログは緑なのに成果ゼロ」のサイレント失敗が起きます。Heartbeat / Output Trace / Decision Log を 3 層で重ねて 60 秒以内に検知する実装を、コードと運用数値ごと共有します。