はじめに
対象読者は、Codex CLI を CI・スケジュール実行・シェルスクリプトから非対話で叩いている開発者です。
自動化に組み込んだ CLI のバージョンを上げるとき、多くの人は --help の差分を見ます。オプションが消えていなければ、自分のスクリプトは壊れないと考えるからです。ところが Codex CLI 0.146.1 から 0.147.0 への更新では、--help を全サブコマンド分そろえて比較しても、削除されたフラグは 1 つも出てきません。にもかかわらず codex exec --full-auto は 0.147.0 で起動すらしなくなります。
なぜ --help の差分がこの破壊的変更を素通りさせたのか、そして認証もネットワークも使わずに手元で検出する方法を、両バージョンを実際にインストールして確かめました。
TL;DR
- 0.147.0 で
codex exec --full-autoはerror: unexpected argument '--full-auto' foundとなり exit 2 で即死します。0.146.1 では非推奨警告付きで受理されていました。 - 24 サブコマンドの
--helpから抽出したフラグは 253 個から 262 個へ増加 し、削除は 0 個 でした。--full-autoは 0.146.1 の時点ですでに--helpに載っていない隠しフラグだったためです。 - したがって
--helpの diff を CI ゲートにしても、この種の削除は検出できません。フラグを実際に 1 つずつ渡して終了コードを見るプローブなら、認証なし・API 呼び出しなしで検出できます。 - 0.147.0 で追加された
--approve-for-meは root とexec/resume/forkなど計 7 か所に付き、--dangerously-bypass-approvals-and-sandboxとは排他です。
検証環境
実際に走らせた環境は次のとおりです。OpenAI アカウントの認証情報は与えていません。
| 項目 | 値 |
|---|---|
| OS | Linux(コンテナ実行環境) |
| Node.js | v22 系(npm 同梱) |
| 比較対象 |
@openai/codex@0.146.1 と @openai/codex@0.147.0
|
| 導入方法 | 別ディレクトリへローカル npm i(グローバル導入を汚さない) |
| 認証 | なし(codex login を実行していない) |
npm レジストリ上の最新版は取得時点で 0.147.0 でした。
npm view @openai/codex version
# => 0.147.0
2 つのバージョンを別ディレクトリへ入れておくと、同じシェルで並べて叩けます。
mkdir -p codex-old codex-new
(cd codex-old && npm init -y >/dev/null && npm i @openai/codex@0.146.1)
(cd codex-new && npm init -y >/dev/null && npm i @openai/codex@0.147.0)
./codex-old/node_modules/.bin/codex --version # => codex-cli 0.146.1
./codex-new/node_modules/.bin/codex --version # => codex-cli 0.147.0
公式リリースノートが言っていること
OpenAI の変更履歴には、0.147.0(2026-08-07)の項目として --approve-for-me の追加と並んで、次の一文があります1。
Remove the deprecated
codex exec --full-autoflag; usesandbox workspace-writeinstead.
一方 0.146.1(2026-08-05)は「cyber 能力の高いモデル向けに自動レビューの既定をより安全側にし、権限変更を説明する」というバグ修正の 1 行だけです。つまり削除の予告は 0.146.1 のリリースノートには書かれておらず、0.147.0 の本文で初めて明示されます。
実測 1: --full-auto は 0.147.0 で受理されない
両バージョンで同じコマンドを叩き、終了コードを取りました。認証がないため API 呼び出しは 401 になりますが、フラグの解釈はその手前で終わるため判定には影響しません。
0.146.1 の場合は、非推奨の警告を出したうえで処理が進み、認証で落ちます。
$ ./codex-old/node_modules/.bin/codex exec --full-auto --skip-git-repo-check "x"
warning: `--full-auto` is deprecated; use `--sandbox workspace-write` instead.
... ERROR ... 401 Unauthorized ...
$ echo $?
1
0.147.0 では引数解析の時点で拒否されます。
$ ./codex-new/node_modules/.bin/codex exec --full-auto --skip-git-repo-check "x"
error: unexpected argument '--full-auto' found
tip: to pass '--full-auto' as a value, use '-- --full-auto'
$ echo $?
2
終了コードが 1 から 2 に変わる点は、シェルスクリプト側の分岐にも効きます。exit 1 を「モデル側の失敗」として握りつぶしている実装だと、0.147.0 では引数エラーの 2 が返るため、握りつぶしの条件から外れて別経路に落ちます。逆に || true で全部潰していると、フラグが死んだこと自体に気づけません。
実測 2: --help の差分では削除を検出できない
次に、24 個のサブコマンドすべての --help からフラグ名だけを機械抽出し、バージョン間で比較しました。抽出スクリプトは以下です。説明文の折り返し行を拾わないよう、行頭のインデント付きオプション行だけを対象にしています。
#!/bin/bash
# 全サブコマンドの --help からフラグ名だけを抽出する
BIN="$1"; OUT="$2"; : > "$OUT"
SUBS=$("$BIN" --help 2>/dev/null \
| awk '/^Commands:/{f=1;next} /^Arguments:|^Options:/{f=0} f && /^ [a-z][a-z-]* /{print $1}')
for s in ROOT $SUBS; do
cmd=$s; [ "$s" = "ROOT" ] && cmd=""
"$BIN" $cmd --help 2>/dev/null \
| grep -oE '^[[:space:]]+(-[a-zA-Z], )?--[a-z0-9][a-z0-9-]*' \
| grep -oE '\-\-[a-z0-9][a-z0-9-]*' | sort -u | sed "s|^|$s |" >> "$OUT"
done
sort -u "$OUT" -o "$OUT"
結果は次のとおりでした。
| 項目 | 0.146.1 | 0.147.0 |
|---|---|---|
| 走査したサブコマンド数 | 24 | 24 |
| 抽出できたフラグ数(サブコマンド × フラグ名) | 253 | 262 |
| 相手版に存在しないフラグ | 0 | 9 |
--full-auto の出現 |
0 | 0 |
comm で差分を取ると、増えた 9 件だけが並び、消えた側は空になります。
$ comm -23 flags-old.txt flags-new.txt # 0.146.1 にしかないフラグ
(出力なし)
$ comm -13 flags-old.txt flags-new.txt # 0.147.0 で追加されたフラグ
ROOT --approve-for-me
archive --approve-for-me
delete --approve-for-me
exec --approve-for-me
exec-server --concurrent-requests
exec-server --exit-on-stdin-close
fork --approve-for-me
resume --approve-for-me
unarchive --approve-for-me
--full-auto の出現回数が両版とも 0 という点が答えです。0.146.1 の段階で --full-auto はすでにヘルプ非表示の隠しフラグ扱いになっており、動作はするがドキュメント上は存在しない状態でした。削除されたのは「ヘルプに載っていない実装」なので、ヘルプ同士を比べても差が出ません。
実測 3: 認証なしで使えるフラグ受理プローブ
引数解析はネットワークより前に走るため、--help を後ろに付けて叩けば API も認証も使わずに受理可否だけを判定できます。自分のスクリプトが使っているフラグを列挙して回すだけです。
#!/bin/bash
# 使っているフラグが今の版でまだ受理されるかを、認証もネットワークもなしで確かめる
BIN="$1"; shift
for f in "$@"; do
if "$BIN" exec "$f" --help >/dev/null 2>&1; then
echo "OK $f"
else
echo "REMOVED $f (exit $?)"
fi
done
同じフラグ集合を両版に流した結果です。
$ ./probe-flags.sh ./codex-old/node_modules/.bin/codex \
--full-auto --skip-git-repo-check --json --approve-for-me --sandbox
OK --full-auto
OK --skip-git-repo-check
OK --json
REMOVED --approve-for-me (exit 2)
REMOVED --sandbox (exit 2)
$ ./probe-flags.sh ./codex-new/node_modules/.bin/codex \
--full-auto --skip-git-repo-check --json --approve-for-me --sandbox
REMOVED --full-auto (exit 2)
OK --skip-git-repo-check
OK --json
OK --approve-for-me
REMOVED --sandbox (exit 2)
--full-auto と --approve-for-me はバージョンをまたいで期待どおり反転しました。
ここで --sandbox が両版とも REMOVED と出ている点には注意が必要です。これは削除されたのではなく、--sandbox が値を要求するフラグだからです。値を付けて渡せば両版とも受理されます。
$ ./codex-old/node_modules/.bin/codex exec --sandbox workspace-write --help >/dev/null; echo $?
0
$ ./codex-new/node_modules/.bin/codex exec --sandbox workspace-write --help >/dev/null; echo $?
0
つまりプローブに渡すのはフラグ名だけでなく、値を取るものは値込みの文字列にする必要があります。この一手間を忘れると偽陽性で埋まり、プローブそのものが信用されなくなります。
実測 4: 追加された --approve-for-me の性格
0.147.0 で追加された --approve-for-me のヘルプ文は 1 行です。
--approve-for-me
Route approval requests through automatic review using the workspace-write sandbox
承認要求を人に投げる代わりに、workspace-write サンドボックス上の自動レビューへ流す、という位置づけです。付与先は root コマンドと exec / resume / fork / archive / unarchive / delete の計 7 か所で、review サブコマンドには付いていませんでした。
サンドボックスと承認を丸ごと外す既存フラグとは同時指定できません。
$ ./codex-new/node_modules/.bin/codex exec --approve-for-me \
--dangerously-bypass-approvals-and-sandbox --skip-git-repo-check "x"
error: the argument '--approve-for-me' cannot be used with '--dangerously-bypass-approvals-and-sandbox'
$ echo $?
2
排他になっているのは妥当です。前者は「サンドボックス内で自動レビューに通す」、後者は「サンドボックスも承認も無効化する」なので、同時に成立しません。--full-auto の削除とあわせて読むと、非対話実行の入口を --sandbox の明示指定に寄せ、承認の自動化は専用フラグとして切り出す方向に整理されたことが分かります。
実測 5: codex doctor は失敗時に exit 1 を返す
更新後の健全性確認には codex doctor が使えます。認証なしでも起動し、環境・設定・更新・接続性・バックグラウンドサーバーの各セクションを出したうえで、末尾に集計行を出します。
$ ./codex-new/node_modules/.bin/codex doctor
...
✗ install npm install -g @openai/codex would update a different install ...
✗ updates update would target a different npm install ...
⚠ websocket Responses WebSocket failed; HTTPS fallback may still work ...
─────────────────────────────────────────────
14 ok · 1 idle · 3 notes · 1 warn · 2 fail failed
$ echo $?
1
失敗項目があると終了コードが 1 になるため、そのまま CI のステップにできます。ローカル npm i で入れた環境では、グローバルの @openai/codex と実行中のパッケージルートが食い違うため install と updates が必ず失敗する点は差し引いて読む必要があります。集計の内訳は接続状況によって実行ごとに揺れました(同じ 0.147.0 で 2 fail と 3 fail の両方を観測)。バージョン間の差として読むのは適切ではありません。
筆者が引っかかった点
筆者は最初、--help の全サブコマンド差分を取った時点で「削除ゼロなら移行作業は不要」と判断しかけました。実際に --full-auto を叩いてみたのは、公式リリースノートに削除が明記されているのに差分に現れないという食い違いが気になったからです。この食い違いがなければ、そのまま更新して CI で初めて気づくことになっていました。
ここから引き出せる教訓は、CLI の互換性チェックをヘルプ出力に依存させないことです。ヘルプは「利用を推奨するインターフェースの一覧」であって「受理される引数の一覧」ではありません。非推奨化はまずヘルプからの非表示という形で入り、実際の削除はその後に来ます。ヘルプだけを見ていると、非表示になった瞬間の変化はゼロに見え、削除された瞬間だけが突然の破壊として現れます。
もう 1 点、--full-auto が 0.146.1 で出していた警告は stderr に出ます。非対話実行で stderr を捨てている場合、猶予期間中の唯一のシグナルを自分で消していることになります。移行の予告を受け取れる唯一の場所なので、少なくとも警告行だけは残す価値があります。
更新前にやること
0.146.1 以前から 0.147.0 へ上げる場合、次の順序で確認すると手戻りがありません。
- リポジトリ内の
--full-autoを洗い出す(grep -rn -- '--full-auto' .)。CI 定義・Makefile・シェルスクリプト・ドキュメントが対象です。 -
--sandbox workspace-writeへ置き換える。承認の自動化まで必要なら--approve-for-meの併用を検討します。 - 上記のプローブスクリプトに、自分が使っているフラグを値込みで渡して回す。REMOVED が出たものだけを直します。
- 更新後に
codex doctorを走らせ、終了コードを確認する。ローカル導入時のinstall/updates失敗は想定内として扱います。
隠しフラグの削除はこの 1 件で終わりとは限りません。プローブをリポジトリに置いておけば、次のバージョンでも同じ手順が使い回せます。
関連記事
- Crushのserverモード、認証なしで/v1 APIが素通りした
- Codex CLIの名前付きセッション、ヘッドレスではTUI版が動かなかった
- mcp-cliに時刻取得を頼んだら、Geminiは無視しOpenAIは例外で落ちた
-
OpenAI, "Changelog" https://learn.chatgpt.com/docs/changelog(0.147.0 / 0.146.1 の項目。2026-08-07 参照) ↩