7月1日、antigravity.google のリリースページに 2.1.4・2.0.11・2.0.10・2.0.6・2.0.1・2.0.0 と、複数のビルドが一斉に並びました。更新ダイアログを前にして手が止まった方は少なくないはずです。2.1系に上げれば新機能が使える。2.0系に留まれば挙動が安定する。では、夜中に走っているスケジュール実行はどちらに乗せるべきでしょうか。
この「どれに乗るか」を毎回その場の気分で決めていると、いつか無人ランが静かに壊れます。2.0系と2.1系が並行して提供されるようになった今の Antigravity を前提に、ワークロードごとに系列を分けて宣言的に管理する方法を、私が実際に使っている設定ファイルとスクリプトごと共有します。
全部を最新に揃えない、という選択
まず前提の整理から入ります。7月1日の一斉公開は「2.0系の安定化」と「2.1系の新機能」が並行して保守されるという意思表示です。つまり利用者側には、系列を選ぶ自由と、選んだ結果を管理する責任が同時に渡されました。
私自身、個人開発で複数サイトの記事更新やアプリのビルド検証をエージェントの無人ランに任せていますが、この種の運用で一番怖いのは機能の不足ではなく、更新のたびに出力や挙動が微妙に変わることでした。対話しながら使う分には「おや、挙動が変わったな」で済みます。無人ランでは誰も気づかないまま、変わった挙動の上に次の処理が積み重なっていきます。
要求をワークロード別に並べると、選ぶべき系列は自然に分かれます。
観点 対話開発(IDE・チャット) 無人運用(CLI・スケジュール実行)
最優先の性質 新機能・速度 再現性・挙動の不変
挙動変化への耐性 高い(人間がその場で吸収) 低い(検知が遅れて連鎖する)
更新の頻度 早めに追従してよい 意図した時だけ動かす
向いている系列 2.1系 2.0系
結論はシンプルです。手を動かす環境は 2.1系で新機能を吸収し、無人で回る環境は 2.0系に固定する。そして両者の間に「観察してから昇格する」手順を挟む。以降はこの方針を仕組みに落としていきます。
version-policy.json — 系列の宣言を一箇所に集める
系列の使い分けを頭の中や README の注意書きで管理すると、マシンが2台を超えた時点で破綻します。私はワークロードとサーフェスの組ごとに、乗るべき系列を JSON で宣言しています。
このファイルが解決するのは「どの環境が何に乗っているべきかを、誰が見ても機械でも判定できる形にする」という課題です。
{
"$comment" : "version-policy.json — 系列ポリシーの単一ソース" ,
"updated" : "2026-07-02" ,
"policies" : [
{
"surface" : "desktop" ,
"workload" : "interactive" ,
"line" : "2.1" ,
"range" : ">=2.1.4 <2.2.0" ,
"note" : "対話開発。新機能を早めに吸収する"
},
{
"surface" : "cli" ,
"workload" : "unattended" ,
"line" : "2.0" ,
"range" : ">=2.0.11 <2.1.0" ,
"note" : "スケジュール実行。意図した更新以外で動かさない"
},
{
"surface" : "cli" ,
"workload" : "interactive" ,
"line" : "2.1" ,
"range" : ">=2.1.4 <2.2.0" ,
"note" : "手元での検証用。無人系列より常に先を行く"
}
]
}
注意点は range を必ず系列の上限つきで書くことです。>=2.0.11 <2.1.0 としておけば、2.0系のポイントリリースは受け入れつつ、2.1系への意図しない移行だけを弾けます。系列内の更新と系列間の移行は、リスクの桁が違う操作なので、宣言の段階で区別しておきます。
なお、スケジュール実行そのものの再現性(実行のたびに同じバージョンで走らせる固定方法)については、Antigravity CLI のバージョン固定でスケジュール実行の再現性を守る で別途扱っています。ここで扱うポリシーはその一段上、「そもそもどの系列に固定するか」を決める層です。
ドリフト検知 — 宣言と実態のずれを毎朝突合する
宣言ファイルを作っただけでは、実態がずれていても気づけません。各サーフェスの実バージョンを集めてポリシーと突合する小さなスクリプトを、朝の定期ランに1本挟んでいます。
// check-version-policy.mjs — 実バージョンとポリシーの突合
// 使い方: node check-version-policy.mjs <version-policy.json> <report.json>
import { readFileSync } from "node:fs" ;
const [ policyPath , reportPath ] = process.argv. slice ( 2 );
const policy = JSON . parse ( readFileSync (policyPath, "utf8" ));
// report.json は各マシンが `agy --version` 等の結果を書き出したもの
// 形式: [{ "host": "mac-studio", "surface": "cli", "workload": "unattended", "version": "2.0.11" }]
const report = JSON . parse ( readFileSync (reportPath, "utf8" ));
const parse = ( v ) => v. split ( "." ). map (Number);
const cmp = ( a , b ) => {
const [ a1 , a2 , a3 ] = parse (a); const [ b1 , b2 , b3 ] = parse (b);
return a1 - b1 || a2 - b2 || a3 - b3;
};
const inRange = ( version , range ) =>
range. split ( " " ). every (( cond ) => {
const m = cond. match ( / ^ (>= | <= | < | >) ? ( [\d.] + ) $ / );
if ( ! m) return true ;
const [, op = ">=" , bound ] = m;
const c = cmp (version, bound);
return op === ">=" ? c >= 0 : op === "<=" ? c <= 0 : op === "<" ? c < 0 : c > 0 ;
});
let violations = 0 ;
for ( const entry of report) {
const rule = policy.policies. find (
( p ) => p.surface === entry.surface && p.workload === entry.workload
);
if ( ! rule) {
console. log ( `⚠️ ${ entry . host }/${ entry . surface }: ポリシー未定義` );
violations ++ ;
continue ;
}
if ( ! inRange (entry.version, rule.range)) {
console. log (
`❌ ${ entry . host }/${ entry . surface }(${ entry . workload }): ` +
`${ entry . version } は ${ rule . range } の外(系列 ${ rule . line } 指定)`
);
violations ++ ;
}
}
console. log (violations === 0 ? "✅ 全サーフェスがポリシー内" : `違反 ${ violations } 件` );
process. exit (violations === 0 ? 0 : 1 );
report.json 側は各マシンの cron なりスケジュールタスクなりで agy --version の出力を1行書き出すだけなので、収集部分は数行で済みます。依存パッケージなしで動くよう、範囲照合も自前の簡易実装にしてあります。本格的な semver 演算が必要になったら乗り換えればよく、まずは「ずれたら翌朝に分かる」状態を作ることが先だと考えています。
exit code を返しているのは、この突合をそのまま無人ランの前段ゲートにも差し込めるようにするためです。ポリシー違反の環境では走らせない、という消極的な防御で事故を未然に回避するのが一番効きます。
昇格の手順 — 2.1系の観察を2.0系の運用に反映する
系列を分けると、次は「いつ・どうやって無人系列を更新するか」が問題になります。私が使っている手順は次の通りです。
2.1系の新ビルドを対話環境にだけ入れる 。更新ダイアログに従うのはこの環境だけです
1週間、普段の対話開発で観察する 。気づいた挙動差は日付つきで1行メモに残します(後で changelog と突き合わせるため)
2.0系に修正が降りるのを待つ 。並行公開の利点はここで、2.1系で先に踏んだ問題の修正が 2.0系のポイントリリースとして降りてくることがあります
降りてきた 2.0系ポイントリリースを、スモークテストを通してから無人環境に適用する 。この段の具体的な検証手順はポイントリリースをスモークテストとロールバック前提で受け入れる に書いた方法をそのまま使っています
version-policy.json の range 下限を上げて、変更をコミットする 。ポリシーの更新履歴がそのまま版管理の意思決定ログになります
例外は、無人運用で現に踏んでいる不具合の修正が 2.1系にしか入っていない場合です。この時だけ系列をまたぐ昇格を検討しますが、「観察期間を3日以上」「対象の無人タスクを1本だけ先行移行」「1週間の並走後に残りを移す」という三段構えにしています。私はこの慎重すぎるくらいの運びを好みます。個人開発では、系列移行の失敗を巻き戻す時間が一番高くつくからです。全タスクを一斉に系列移行したことは、これまで一度もありません。
6月末、この仕組みが拾った一件
この体制は Mac 2台と無人実行環境1つ、合計3サーフェスで6月上旬から運用しています。6月中に受け入れた 2.0系のポイントリリースは2回、系列をまたぐ移行は0回、毎朝の突合にかかる確認時間はログを1行見るだけなので30秒ほどです。実際に運用して分かったのは、手間のほとんどが最初の宣言ファイル作りに集中していて、以降はほぼ放置で回るということでした。
その上で、具体的な効果を一つ記録しておきます。6月下旬、対話環境を 2.1系のポイントリリースに上げた際、私はメモに「長い出力の途中で部分文字列検索の応答が以前より速いが、結果の並び順が変わった気がする」と残していました。数日後、無人ランの一つ(生成物のログから特定の行を拾って次の処理に渡すタスク)を見直したところ、同じ更新が無人環境に入っていたら並び順への暗黙の依存が壊れていたことが分かりました。
実際には無人環境は 2.0系に固定されていたため何も起きていません。ドリフト検知の報告も「✅ 全サーフェスがポリシー内」のままでした。事故が起きなかった話は地味ですが、系列分離の価値はまさにこの「何も起きない」を設計で作れる点にあります。並び順への依存はその週のうちに明示的なソートに書き換え、2.0系側の更新を安心して受け入れられる状態にしました。
changelog の読み方が変わる
系列を分けて運用し始めると、changelog の読み方も変わります。見るべきは「2.1系に何が入ったか」だけではなく、「2.1系に入った修正のうち、どれが 2.0系にも降りたか」です。7月1日の一斉公開のように複数ビルドが同時に並ぶ日は、系列間の対応関係を確認する絶好の機会です。
私は毎朝の定期ランで releases ページの差分を取り、新しいビルドが検出された日は、上の昇格手順のどの段に影響するかだけを判断しています。全文を毎日読み込む必要はありません。「無人系列に関係するか」を最初のフィルタにすると、確認は数分で終わります。
まとめ — まず宣言ファイルを1枚書く
2.0系と2.1系の並行提供は、裏を返せば「系列選びの責任は利用者にある」という体制です。次のアクションとしては、上に載せた version-policy.json を自分の環境のサーフェス構成に合わせて1枚書き、手元の実バージョンと見比べてみることをお勧めします。ずれていた環境が一つでも見つかれば、それがドリフト検知を定期化する十分な理由になるはずです。
同じように無人運用を抱えている方の参考になれば幸いです。