Skip to content
cccskills
FreePublished on GitHub

codex-drive

Codex が設計・実装を担い、Claude が要件確定・成果物の検証・反復・commit/push を管理する。「codex に書かせて」「codex メインで実装」「codex-drive」で発火。大きめの機能・移植・プロトコル実装向け。

余剰トークンを厚く使う運用も選べる。

The English summary is being prepared. Showing the original description.

See how to install

Files included (3)

  • SKILL.md140.9 KB
  • templates/merger.md2.0 KB
  • templates/review-lens-header.md2.4 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Codex Drive(Claude が操縦、codex がメイン実装)

起動したら最初に codex の枠を見る (ratelimit -source codex -check。rc=1 のときの扱いは subagent-model-tiering.md の「枠の残量」)。

設計の壁打ちから実装まで codex を主役にし (設計 read-only / 実装 write 権限)、Claude は「指示・検証・観測・反復・commit」に徹するワークフロー。 codex-lead が「codex に設計をリードさせ Claude が実装」なのに対し、本 skill は設計壁打ちも実装も codex が担い、 Claude は orchestrator/verifier。新規ライブラリ・大きめ機能・プロトコル実装・大量移植など、コード量が多く codex トークンを積極消費したいタスク向け。

本文中の「実測根拠 (日付 / repo / issue / トークン数)」は意図的に残している。どのフェーズを削れて どれを削れないかの判断は実測が根拠で、数字を落とすと「削減した」という無根拠な主張だけが残る (perf-claims-need-measurement.md)。読み飛ばしてよいが、フェーズ構成を変えるときは必ず参照する。

トークン経済 (v3.0.0): codex は厚く・Claude は薄く。codex トークンは「独立した視点を増やす」方向に 積極消費する — spec 独立読解 2 本 + 相互照合 ([S])、設計案は独立 2 本 (厚い運用は 4 本、[D1]) + クロス批評 ([D1.5])、 方針が割れうる実装は競作 ([2p])、発見型レビュー 1〜3 観点 ([3.5])、敵対的レビューは攻め口別に並列で 未解決の不変条件を確認するまで ([3.6])、壊せなかった不変条件はテストで固定 ([3.7]) し、その検知力をミューテーションで 機械検証 ([3.8])。一方 Claude トークンは以下の 3 手で節約する:

  1. 生出力を読まない — digest 経由の検閲: 並列フェーズ (3 本以上) の出力は必ず codex 集約 (merger) を 挟んで 1 枚の digest にしてから Claude が読む。原文 (保存ログ全文) へ跳ぶのは「採用判定する指摘・ digest が曖昧/矛盾する箇所」だけ。merger の追加起動は codex 消費であり方針と整合する (作法は「並列起動の作法」の集約規約)。起動〜merger は driver (codex-fanout) で 1 往復に畳む (per-run の起動・tail の Bash 往復自体が Claude の消費源。同節参照)。
  2. 貼らずに参照させる: codex は repo 内のファイルを自分で読める (read-only sandbox も読み取りは可)。 -o は CLI が最終応答を保存する機能で、モデルのファイル編集とは別。設計本文・digest は 「本文全体を最終応答で返す。ファイル編集はしない」と指示し、read-only + -o で保存する。 -o の親ディレクトリは起動前に mkdir する。obaket 674 では本文が最終応答に載らず、 ファイル編集が拒否された。この 2 操作を区別して扱う。長文であることを理由に workspace-write へ上げない。 複数のファイルを実際に作る作業だけ、必要な書き込み権限を別途選ぶ。 設計スライス・spec・要件はプロンプトに長文で貼らず、<D>/design.<タスク名>.md 等の ファイルパス + セクション名を指示して読ませる (Claude の出力トークンを長文 heredoc に使わない)。 定型部分は templates/ のテンプレートとのファイル連結で組み、Claude が書くのは brief 数行だけ。
  3. 機械ループは codex に回させる: ミューテーション適用×テスト実行 ([3.8]) のような機械実行は codex に worktree 内で回させ、Claude は結果表 + 抜き取り 1 件の追試で監査する。

節約しないもの (硬い下限): commit ゲートの build/test/diff 精読 ([3]/[4])・採用した指摘の裏取り なぞり ([3.55])・設計承認の Claude 視点 ([D3])。ここを digest で済ませると「無検閲 commit 禁止」 (subagent-model-tiering.md) が破れる。節約するのは検閲の入力の形 (生出力 → digest) であって、 検閲そのものではない。

既定は run の種類で 2 組 (下のモデル表が正本): 読む・判断する run (read-only / review。集約役を除く) は gpt-6.1-sol + effort high (= sol-high)、書く run (danger-full-access) と集約役は gpt-6-luna + effort max (= luna-max)。 フェーズ・難易度でこの 2 組から外さず、品質の上積みは本数と観点の数で作る (ユーザー決定 2026-10-02、読む run の effort は 2026-10-03 に medium から high へ。それまでは全フェーズ luna-max)。 ユーザーが「品質全開で」と明示したときだけ v2 運用 (merger を挟まず Claude が生出力を全文精読) に切り替える。

役割分担(崩さない)

主体担当
codex (設計: codex exec -s read-only / 実装: codex exec -s danger-full-access。外せない環境は workspace-write)設計アウトライン・詳細設計のドラフト (壁打ち)、実ファイルの作成/編集、自分でプロジェクト標準の build/test を回して反復、spec 準拠の実装
Claude (main agent)タスクのスコープ分割 / codex への指示作文 / 設計・成果物の検閲 (設計レビューの 1 視点・build・test・diff 精読) / 観測駆動デバッグ (実行・ログ・CI で事実を集め、次の指示に翻訳) / commit & push / 次の一手の判断

Claude は重い実装を自分で書かない。ただし trivial な 1-2 行の確定的修正 (観測で原因が確定した typo・定数・オフセット) は codex 往復より速いので Claude が直接やってよい (subagent-model-tiering.md の例外と同じ判断)。

大原則

  • codex の出力を無検閲で commit しない (subagent-model-tiering.md)。Claude が必ず build/test/diff を見てから commit。

  • レビューは「探す」ではなく「壊す」、壊せなかったものは「テストで固定し、テストの検知力まで機械検証する」: 実装者が codex なら、レビューも codex に任せた時点で同一モデルの相関盲点が残る。各マイルストーンは 発見型レビュー [3.5] → 裏取り [3.55] → 敵対的レビュー [3.6] (red team・未解決の不変条件に合う攻め口) → テスト強化 [3.7] → ミューテーション検証 [3.8] の 5 段で commit ゲートを組む。 「指摘なし」は「正しい」ではなく「その攻め手では壊せなかった」、「テスト green」は「検知力がある」の 証明ではない、として扱う (作法の正本は codex-review スキル)。

  • トークンは「視点を増やす」ことに使う: 本 skill は codex トークンの積極消費が前提だが、効くのは 独立した視点が増える使い方 ([D1] の独立案・[2p] の競作・[3.6] の lens 別並列・[3.7] のテスト) であって、 同じ観点で本数や effort を増やすことではない (逓減する)。そして律速は Claude が読む digest の量で、 最終判断は委譲できない。本数を増やす前に「merger で 1 枚の digest に集約でき、その digest + spot check を 自分は精読できるか」を見る。集約を挟まず生出力を並べて読むのは、Claude トークンの浪費 (v3 の経済違反)。

  • 主張は偽と仮定して裏を取る: codex の「実装済み」「検証済み」「テスト green」は主張であって証拠ではない。 diff・実行・外部基準 (spec の test vector / 実サーバ / CI) で反証を試みてから受け入れる。

  • codex に git commit させない。commit/push は Claude が行う (検閲後)。codex には「commit しない」と毎回明示。

  • 要件は最初に固定する: 丸投げの依頼は [R] で「要件 + 受け入れ条件」のリストに言語化し、曖昧点は着手前に まとめて質問する。完了判定は [7] でこのリストと照合する (暗黙解釈のまま走らない・黙って完了にしない)。

    • test 専用の同期機構 (waiter / barrier / 到達通知) を足すなら、[R] の受け入れ条件に 「①待った事象が来なければ timeout して red ②cancel で解放 ③reset で drain」の 3 点を書く。 これは安全機構と同じ扱いで、後から敵対レビューに出させるものではない (実測 obaket 725: F1〜F9 → G1〜G8 の 2 ラウンドで「waiter が hang して red にならない」「reset が waiter を drop する」が どちらのラウンドにも出た)。書いていないと、緑は「壊れていない」ではなく「待ちが刺さって何も検査していない」になる。
    • 既存または個別に追加を許可した production の試験用 hook は、未設定のときに追加の suspension・Task・lock を作らない形にする。 呼び出し側も確かめ、この条件を [R] と実装の指示に書く (nil を判定する async の helper を無条件に await しない。 actor の claim と accept の間に置かれた await token.runHook(...) は、未設定でも actor を離れて割り込みを許した。swift-smbee retro 111)
  • 構造投資の水準は「寿命と拡張予定」で決め、[R] で確定して全フェーズに伝搬する:

    • 長期運用・拡張前提 (既定): 症状でなく前提を直す構造的な作りにする (CLAUDE.md「不具合対応の原則」)。 ただし**「拡張しやすい」は先回りの抽象で買わない** — 今使わない generality・プラグイン機構・設定可能化を 足すのは speculative refactor と同罪 (verify-design-intent-before-refactor.md)。買うのは 境界の明確さ・不変条件の明文化・変更の局所性 (次の変更が 1 箇所で済む形) であって、予測実装ではない。
    • 地味な機能・使い捨て・拡張予定なし: 最小 diff と既存構造への追従を優先し、構造改修を持ち込まない (その場しのぎで OK と明示的に判断した場合に限る。判断せずに小手先へ流れるのとは別物)。
    • どちらか不明なら [R] の質問に含める。判定は要件ファイルに書き、D1 の出発点制約・D2 コントラクト・ [2] の実装プロンプト・[3] の diff 精読基準まで一貫させる (フェーズごとに水準がブレるのが最悪 — 構造で設計して小手先で実装する、の逆転が起きる)。
  • 設計は承認ゲートを通す: 設計自由度のあるタスクは [D1]〜[D3] の壁打ちを経て、ユーザー承認後に実装へ入る。 設計自由度が低いタスク (spec 固定のプロトコル実装・大量移植等) は軽量パスに短縮してよいが、 D3 の敵対観点 1 本は軽量パスでも省略しない (D1 の軽量パス項が正本)。判断は一言明示する。

  • 1 タスク = 1 検証可能なマイルストーンにスコープする。codex に「全部」を投げない (15 分制約・精度低下)。

  • 観測駆動 (instrument-before-second-fix.md): 修正が外れたら次の blind fix を投げず、まず観測 (ログ/実行/CI) を増やして 事実を取り、それを codex への次の指示に翻訳する。CI でしか出ない移植/プロトコルバグはこの往復で 1 段ずつ潰す。

  • モデルはスキル側で明示する: -m <model> -c model_reasoning_effort=...。省略すると ~/.codex/config.toml の既定 (対話 TUI 側の都合で変わる) を拾い、実行ごとにモデルが変わってしまう。 effort も省かない (モデルだけ指定すると effort は config.toml の値になる。config.toml は対話用に sol + medium にしてあるので、書く run で effort を省くと luna が medium で走る)。

  • モデルと effort は run の種類で 2 組に分ける (ユーザー決定 2026-10-02):

    runモデル + effortフェーズ
    読む・判断する (-s read-only / codex exec review)gpt-6.1-sol + high[S] の 3 本・[D1]/[D1.5]/[D2]/[D3]・敗者剖検・[3.5]/[3.55]/[3.6]・[7] の敵対照合
    書く (-s danger-full-access) と集約gpt-6-luna + max[2]/[2p]・[3.7]・[3.8]・merger・変更マップ
    • 読む側を sol にするのは、設計の反証と敵対レビューの見落としは後工程で拾えず、1 本あたりの質が効くため。 書く側は run が長く codex の 5h 枠を食うので luna に残す (subagent-model-tiering.md の「重いモデルは短い高価値な run へ」)。 2026-08-26 に裁定役の 3 フェーズだけ sol-mid にして消費が重く同日中に廃止した経緯があるので、 sol の run を並べる前に codex の 5h 枠を見る (ratelimit -source codex -check)。
    • sol の effort の既定は high (ユーザー決定 2026-10-03)。特定のベンチマーク結果を 個別タスクの精度や ChatGPT の 5h 枠の消費に一般化しない。以前の DeepSWE の数値には この文書でたどれる出典・測定条件が無いので、effort の禁止や残量見積もりの根拠から外す。 xhigh / max の優劣は対象タスクで比較して判断する。切り替えるならモデルが対応する値を確認し、 同じ受け入れ条件で採用指摘・差し戻し・所要時間・usage を記録する。印象だけで上げない。
    • luna の effort は max だけ。low / medium / high / xhigh は使わない (sol の組と混ぜない) (難易度の自己判定がブレて難所を低い effort で踏む事故を、固定で構造的に潰す)。
    • モデル別の所要時間と既定の timeout (1200 秒) の適否は、この運用では 未実測。読む run が 時間切れ (rc=124) で落ちたら、その行に timeout 列を付ける ([3.6] の 2400 と同じ扱い)。
    • モデルの例外は書く run の上振れ ([2] の「モデルはマイルストーンの性質で振らない」)。 effort の比較は上の手順で行う。同じ失敗を繰り返す場合は、設定変更だけで解こうとせず forge / cross-review へ escalate する (escalate-to-forge-after-failed-tries.md)。
    • 詰まったときは未解決の原因・観点を先に特定する。観点を増やせば質が 上がる種類の仕事 (案出し・批評・発見型レビュー・要件照合) は本数が効く。
      • 敵対レビュー [3.6] が 1 ラウンド回して新規反証ゼロだが枯れたと思えないときは、lens を足す (既存 lens の言い換えを増やさない)。
      • 同じ指摘・同じ失敗で 2 往復したら 3 往復目を投げ直さず forge / cross-review へ escalate する (escalate-to-forge-after-failed-tries.md)。
    • 実測根拠 (obaket issue 541、2026-08-24): 全フェーズ low で 1 機能を完走したところ、 発散系 (独立 4 案・敵対レビュー) は low でも実害を掘れたが、 実装とテスト強化は low だと「動くが筋が通っていない」ものを繰り返し出した — 常時 1 秒ポーリング / Task を止めない / listing 不在を確認せずに「不在」と警告 / 実機で踏んだ警告コメントの削除 / 落ちないテスト。 その後 effort を上げた回は、計画レビューで「2 ラウンドの定義が緩い」等の誤運用経路を 具体的に構築してきており、low の回では出ていなかった質の指摘だった (= effort を落とすと実装系の質が落ちる。上限固定はこの実測の延長にある)。 → effort を上げても検閲は省略しない ([3] の build/test/diff 精読、 [3.8] のミューテーション検証は必須)。上げるのは codex 側の思考量だけで、 Claude 側の検証は減らさない。

工程の厚さと完了条件

[R] で工程の厚さと予算 (本数・所要時間・レビュー上限) を記録する。

  • 既定: 設計案は独立 2 本から、発見型レビューは主要リスクに合う 1〜3 観点、敵対レビューは 1〜2 lens から始める。 未解決の不変条件、異なる設計案、実際の失敗が増えたときだけ本数を増やす。
  • 厚い運用を明示された場合: 独立 4 案 + クロス批評、発見型 3 観点、敵対 2〜4 lens を使う。 余剰 Codex トークンを厚く使う意図はこのモードで保持する。台帳に追加の採用指摘・差し戻し・壁時計・usage を残す。
  • build/test・diff 検閲・採用指摘の裏取りはどちらでも省略しない。実通信などの oracle が必要なタスクでは本数より先に確保する。
  • 完了条件は 受け入れ条件を満たす / 採用した重要指摘を解消する / 重要な不変条件をテスト・型・設計・外部 oracle で確認する / 未確認範囲を明示する。 「新規ゼロが何周続いたか」は探索の記録であって、完了条件でも安全性の証明でもない。

出力の置き場 (<D>。全フェーズ共通)

本 skill が書くもの (要件・設計ファイル、プロンプト部品、manifest、codex の -o / stdout / rc、patch・status のスナップショット) は すべて 1 つの dir <D> に置く。<D> は着手時に 1 回 skill-tmpdir codex-drive を打って得た絶対パス (<本体 checkout>/tmp/codex-drive/<session-id>/。dotfiles の bin/skill-tmpdir) で、以降はリテラルで書く (Bash の変数は次の呼び出しに残らない)。

  • scratchpad に置かない: 再起動で消え、遅れて完了した run の証拠 (obaket 581。下の [2]) が残らない。repo の外なので codex にも渡しにくい
  • tmp/ 直下に置かない: 置き場が散ると後から run を突き合わせられず、掃除もできない (dotfiles issue 774)
  • worktree の中から打っても本体 checkout を返すので、worktree を消しても出力は残る
  • 同じ session の中では名前を <literal-stamp>. や <タスク名> で一意にする (サブエージェントと共有される)

並列起動の作法([S] / [D1] / [D1.5] / [2p] / [3.5] / [3.55] / [3.6] 共通)

本 skill の並列フェーズはすべてこの作法に従う。各フェーズで再定義しない。

既定: driver (codex-fanout) で 1 往復に畳む

dotfiles の bin/codex-fanout (PATH に載っている)。read-only / review の並列 fan-out + merger を driver 内で完結させ、Claude の Bash 往復を「起動 1 回 + digest 読み 1 回」にする。

1 本だけ起動するときは bin/codex-run (codex-fanout の薄い前面。manifest を書かずに済む):

codex-run -J -C <worktree> -l adv-behavior review <prompt-file>

作業ディレクトリは -C オプション (codex-run が cd する) で渡す。codex exec review 自体は -C を受け付けないが、その差分は codex-run が吸収するので呼び出し側から見えない。 command codex / </dev/null / --ephemeral -o / stdout の保存 / rc の保存 / モデルと effort の固定も codex-run 側で満たす。rc が 0 でも本文が空なら警告を出すので、成果物での判定がそのまま乗る。 -o を省くと ./tmp/codex-run/<stamp>-<label>/ に出る (cwd 基準。-C の影響を受けない)。本 skill では -o <D>/<literal-stamp>.<label> を渡す。

Go repo では codex の sandbox が go build / go test を走らせられないことがある (work dir / build cache を $HOME 配下に作れず operation not permitted、goenv の version 不在。SnapTrim #251 で read-only lens が ほぼ全本「テスト未実行・静的確認のみ」で返った)。Go を触るタスクでは 起動側で GOCACHE=<worktree>/tmp/gocache GOTMPDIR=$(mktemp -d) GOFLAGS=-mod=mod を export してから codex / codex-fanout を起動し、prompt にも同じ env を書く (GOTMPDIR は repo 外にする。repo 内にすると Go 1.26 の t.TempDir() の親が repo になり、codex が TestMain に隔離コードを足して環境の都合が production テストに残る: obaket 719) (workspace-write なら worktree 内へ書ける。 read-only は依然走らないので、その lens の「未実行」は Claude が自分で実行して埋める)。 codex の「テストは sandbox で実行不可」は未検証の印であって、静的確認を実行結果と読まない。

Bash ツールの上限 (15 分) を超えうる起動は detach する: run_in_background の Bash は 15 分で プロセスごと kill される (CODEX_FANOUT_TIMEOUT=2400 や長い workspace-write 実装と矛盾。2026-08-27 に 敵対 fanout と mutation 単発が同時に全滅した = obaket issues/620)。その場合は (nohup codex-fanout … > log 2>&1; echo "rc=$?" > <outdir>.rc) > /dev/null 2>&1 & で起動し、 Monitor ツールで完了を待つ。待つのは driver が必ず書く runs.tsv (全 run の rc が揃うこと) であって、外側の <outdir>.rc ではない (run 単位の成果物は全部揃ったのに外側 rc だけ書かれず永遠に待った例: obaket 696 項目 10)。 待機ループには deadline を置き、超えたら「判定不能」として報告する。プロセス不在かつ成果物無し = 死亡として扱う。 15 分以内に収まる起動は従来どおり run_in_background でよい。 自分の run を止めるときは PID か -o の出力パスで特定する (kill <pid> / pkill -f '<自分の -o パス>')。 pkill -f 'codex exec -s danger-full-access' のような pattern kill は同じマシンの別セッションの codex を巻き込む (2026-09-05 obaket: 別セッションの pattern kill で実装 run が途中で死んだ。編集は残っていたので突き合わせで復旧したが、 kill された側からは「codex が壊れた」に見える)。 outdir / log / manifest は repo root からの絶対パスをリテラルで書く ($PWD 禁止。Bash の cwd は呼び出し間で primary cwd に戻り、別 repo の tmp に出る: obaket 696 項目 1 / 715 項目 5)。

Claude がやるのは:

  1. プロンプト部品を <D> に書く — 定型は ~/.claude/skills/codex-drive/templates/ (review-lens-header.md = lens 共通ヘッダ、merger.md = merger の既定指示) を使い、 Claude が書くのは lens の攻め口 + タスク固有の的の brief 数行だけ (トークン経済 2)
  2. manifest (TSV: label \t mode \t model \t effort \t 部品1,部品2,... [\t timeout_s]。部品は順に連結) を書く。 mode は ro | review の 2 値 (それぞれ codex exec -s read-only / codex exec review)。 下の例はコマンド形で書いてあるので、manifest には略号の方を書くこと。 末尾の timeout_s は任意で、その行だけ timeout を上書きする (省略時は CODEX_FANOUT_TIMEOUT)。 敵対レビュー系 lens は反証の構築に時間がかかり既定値で時間切れ (rc=124) になりやすい (dotfiles issue 150) ので 2400 を付ける ([3.6] が正本)
  3. manifest・prompt 部品・merger prompt (-m)・outdir はすべて cwd 依存なので、各 Bash 呼び出しで 値を再計算するか、前回出力のリテラル絶対パスを使う。prompt part のパスにはカンマを入れない (manifest は単純なカンマ分割)。codex-fanout -J <絶対パスの manifest> <絶対パスの outdir> を、 同じ呼び出しで必要なファイルを生成してから 1 回だけ run_in_background で起動 (2 本以下で merger 不要なら -M。 1 本だけの manifest は -m 明示が無い限り driver が merger を自動スキップする — 1 出力の digest は言い換えでしかない) 生成した manifest はその呼び出しで即実行する。manifest を残しておいて後で再実行すると、repo 移動・ 別 worktree・別マシンで stale path になる (出典: 573-retro-codex-drive-541-2026-08-24.md)。
  4. 完了通知後に <outdir>/digest.md を読む (原文へは digest の出典パスで跳ぶ)

起動と同時に「待機中に自分がやる作業」を決める。 read-only フェーズは実測で 20〜40 分かかることがあり、その間 main agent が「待機中です」のターンを重ねるのは丸損 (1 ターンごとに会話全体を再送する)。起動した直後に、その codex の結果に依存しない作業を 1 つ選んで着手する — issue / commit message のドラフトを <D> に書く、自分でできる裏取り (grep・件数の計測・ログの取得) を済ませる、次のフェーズのプロンプト部品を組む。 待ち自体は成果物ファイルの存在で張る (until [ -f <outdir>/runs.tsv ]。プロセスの存在で 待たない — verify-execution-not-just-exit-code.md)。 実測 2026-09-08 (swift-smbee 087): 待機中に自分で数えた「重複 25 行」が、 後から届いたレビュワーの計数 (別範囲) の誤りを弾く根拠になった。

  • exit code を成功判定に使う: 0 = 全本 + merger 成功 / 2 = 一部失敗 (digest はあるが観点が欠けている — 成功扱いしない。欠けた観点を再実行するか「未実施」を Claude が明示的に引き継ぐ) / 1 = 全滅・merger 失敗
    • codex の利用上限で落ちた run は rc を変えずに、runs.tsv の cause 列が usage_limit・要約が label:rc=N(利用上限) になる (ratelimit -check が見ない枠。prompt や観点を直しても通らないので、再開の時刻を待って回し直す。検出の範囲は bin/codex-fanout の usage_limit_line)
  • 🚨 codex-fanout に -C は無く、各 run は driver を起動した cwd の木を読む。レビュー対象が worktree なら、同じ Bash 呼び出しで cd <worktree の絶対パス> && codex-fanout … として起動し、prompt に書く対象のファイルも絶対パスにする (tmp/… や git show HEAD の 相対の指定は、起動した場所の木を指す。obaket retro 1112: 共有 checkout から起動し、codex が自分で worktree を探したので結果は使えたが、 探し当てる保証は無い)。1 本だけなら codex-run -C で足りる
  • driver は read-only / review 専用。workspace-write の並列 ([2p]) は対象外 (worktree 分離が必要。[2p] の手順に従う)
  • -J で JSONL を保存し、<label>.meta.json の完了状態・thread ID・usage・command_execution を確認する。 機械集約が必要なら -S <schema.json> を ro run に付ける (全行に同じ schema を使える manifest のみ)。 詳細は codex-review「自動化向けの出力」。merger は指摘 ID の対応を保持し、元 run の未確認状態を格上げしない。
  • manifest 形式・タイムアウト (CODEX_FANOUT_TIMEOUT)・出力レイアウトの正本は bin/codex-fanout 冒頭の usage

fallback: per-call 方式 (driver が使えない環境のみ)

「2 本だから driver は大げさ」で素の codex exec を手で組まない。 2 本以下でも codex-fanout -M か codex-run を使う (集約規約が言う「2 本以下は merger 不要」は digest を挟むかどうかの話であって、起動を手組みしてよいという意味ではない)。 手組みに逃げると下の作法を毎回自分で再現することになり、その一つでも落とすと空振りする。

  • 1 本 = 1 つの Bash 呼び出し (run_in_background: true)。1 つのシェルに複数行並べると直列実行になる。
  • シェル変数は Bash 呼び出しをまたいで保持されない。stamp="$(date ...)" を先の呼び出しで作って後続で $stamp を参照すると空文字に化ける (worktree のパスに使っていると存在しないディレクトリを掴んで即死する)。 最初の呼び出しでパスを確定したら、以降の呼び出しにはリテラルの絶対パスを書く (値を会話に控えてから使う)。 driver に渡すパス (manifest / prompt 部品 / merger prompt / outdir) の扱いは 上の「既定: driver」の手順 3 が正本。ここでは繰り返さない。 この罠は [2p] の worktree 準備 (driver 対象外) でも踏むので、driver 有無に関わらず覚えておく。
  • 起動前にレビュー対象の commit/base を SHA に解決して固定する。git log --grep は 候補を探すためだけに使い、複数一致を勝手に選ばない。実行中に rebase・編集が入ったら、 対象が変わったレビューを現行コードの合格根拠にせず、旧 SHA の指摘として扱って差分を再確認する。
  • 出力は 1 本ごとに一意パス。並列で同じパスに書かせない。
  • stdout/stderr も一意ファイルに保存してから末尾を見る。codex exec review はレビュー本文を -o に書かず stdout にだけ出すことがある (正本: codex-review スキル「手順 4」)。| tail -40 だけで受けると本文前半を捨てるため、 重要な反証を読み落としたまま「指摘なし」と誤判定する。形は ... > "$log" 2>&1; tail -40 "$log" にし、 判断の入力は必ず保存したファイル (下記 merger 経由なら merger がその全文) にする。
  • 集約 (merger) 規約 — 並列 3 本以上のフェーズは digest 化してから Claude が読む: 全本の完了後、merger codex (codex exec -s read-only・gpt-6-luna・max) に保存ログのファイルパス群を 渡して読ませ、1 枚の digest を作らせる — 指摘/案ごとに「出典ログパス・file:line・根本原因・発火条件・ 重複マージの結果・severity」を構造化し、全数勘定を必須にする (「run X: N 件中 M 件採用、落とした分は 各 1 行の理由」+ 指摘ゼロの run の明記。merger の黙った取りこぼしを構造的に見えるようにする)。 merger に tail や抜粋を渡さない (本文が -o に出ない罠は、merger が保存ファイル全文を読むことで塞ぐ)。 Claude は digest を読んで採否し、採用する指摘・digest が曖昧/矛盾する項目だけ出典ログの原文へ跳ぶ。 merger 自体の起動は codex 消費 (経済 1)。driver 経由ならこの規約は templates/merger.md が実装済み。 2 本以下のフェーズは merger を挟まず Claude が直接読んでよい (集約のオーバーヘッドが逆転する)。
  • 本数の上限は「merger digest + spot check を Claude が精読できるか」で決める。最終判断は委譲できず律速になる。

Phase 0: codex 適性評価(着手前に必ず・最初にやる)

codex-drive を回す前に、そのタスクが codex 実装に向いているかを Claude が評価する。向いていない領域を 無評価で codex に投げると、もっともらしく動かない/見た目が破綻したコードを量産し検証で空回りする。

codex に向く(そのまま codex-drive で進めてよい)

  • プロトコル/wire 実装・codec・パーサ (バイト構造・spec 準拠・エンディアン)
  • アルゴリズム/暗号プリミティブ (test vector で正誤が機械判定できる)
  • 大量の同型変換・移植・rename・boilerplate
  • CLI / ライブラリ境界の純ロジック (入出力が決定的で unit/CI で検証できる)
  • 仕様書 (RFC/MS-* 等) と test vector があり、正解が客観的に確定できるもの

codex が苦手(一度ユーザーに確認を入れてから進める)

  • UI / UX / 視覚レイアウト (SwiftUI/AppKit/CSS の見た目・余白・色・アニメーション)。 「動く」と「見た目/操作感が正しい」が乖離しやすく、スクショ/実機/人間の目視確認を受け入れ条件に入れる必要がある領域。 今回ユーザー明言: UI は苦手
  • AppKit/SwiftUI のランタイム挙動 (focus/responder/AttributeGraph 等、実行時にしか分からない振る舞い) 実測 (obaket 859, 2026-09-19): 一覧 Table の first responder 修正で、作り直し設計の D3 が P1 を 5 件出した (前提が実機でしか確定しない箇所ばかり)。実機で効いている実装があるなら、作り直しより仕上げ (不要な機構の削除 + 変異 + 敵対レビュー) に留める選択肢をユーザーに提示する
  • デバイス/実機/GUI 操作に依存する検証 (権限・GUI・ネットワーク・実機アクセスに制約されやすく、自走確認を信用しにくい)
  • 主観的・美的判断、プロダクトの方向性、曖昧仕様 (正解が客観確定できない)
  • 大きなアーキテクチャ設計判断を単独で確定させること (ドラフト作成と壁打ちは [D1]〜[D3] で codex にやらせるが、 前提・制約・受け入れ条件・最終承認は人間/Claude が握る。実装を Claude に任せたい場合は codex-lead、多視点実装は forge)

その他の既知の弱点(向く領域でも検証で必ず潰す。SMBee セッション等で実観測)

これらは「codex に任せない」ほどではないが、codex の自己申告/自己テストを信用せず Claude が外部基準で検証する。 以下はそのまま [3.6] 敵対的レビューで最初に攻める的になる (循環テスト・捏造 API・overclaim は「反証しにいけば落ちる」類の弱点)。

  • 循環テストになりがち: codex は自分のエンコードを自分でデコードして通る round-trip テストを書きやすい。 実サーバ/spec の公式 test vector で照合しないと「テスト green なのに実機で wire 拒否」が起きる (実例: NEGOTIATE round-trip は green だが Samba が INVALID_PARAMETER)。外部 vector / 実通信で必ず裏取り。
  • バージョン差・実在しない API/設定キーの捏造: 学習時点と環境のズレで、存在しない設定オプションや 古い API をもっともらしく書く (実例: Samba の smb3 signing algorithms は当該版に存在せず無視された)。 設定キー/API は実環境・実ドキュメントで存在確認。
  • クロスプラットフォーム/別 toolchain のコンパイル不能を見落とす: codex は自分が動く環境 (例 macOS) で しか確かめられず、他ターゲット (Linux/別 Swift 版) の差異を踏む (実例: glibc の addrinfo メンバ順 / SOCK_STREAM 型 / IPPROTO_TCP 型)。ターゲット環境 (CI 等) で必ずビルド。
  • 実環境の観測が環境制約に左右される: Docker/実機/実サーバ/CI は、権限・ネットワーク・GUI・認証の制約で codex の自己完結確認が失敗/不完全になりやすい。実行依存の正否は Claude が CI/実機/実サーバで確認し、 結果を codex に渡す (本 skill の観測駆動ループ [6])。
  • 過大申告 (overclaim): 「確認済み」「対応済み」と未検証で書くことがある。サマリの主張は diff/実行で裏取り。
  • 自分のサンドボックス制約への場当たり回避: --disable-sandbox 等で「通った」と報告しがち。 Claude は素の環境でビルド/テストし直す。
  • 広域の一貫性 (多数ファイル横断): 大きな sweep で命名/規約の一貫性を崩すことがある。範囲を区切り diff を精読。

判定と分岐

  1. タスクを上記で分類する。向く → そのまま [1] へ。
  2. 苦手領域に該当 / 判断に迷う場合は、実装に入る前に一度ユーザーに確認する:
    • 「このタスクは codex が苦手な〈UI/実機/主観判断〉を含むので、(a) それでも codex-drive で進める / (b) Claude が 直接やる / (c) forge 等別アプローチ、のどれにしますか?」と選択肢を添えて聞く。
    • UI を含む複合タスクなら、苦手部分を切り出して「ロジック/wire は codex-drive、UI は Claude/別途」と分割提案する。
  3. ユーザーが「それでも codex で」と言えば進める。確認なしに苦手タスクを codex に丸投げしない。

ワークフロー

[0]   適性評価         … 上記。苦手領域なら一度ユーザーに確認 (UI 等)
[R]   要件確定         … 依頼を「要件 + 受け入れ条件」リストに言語化し <D> へ保存。曖昧点はここでまとめて質問
[S]   spec ダイジェスト … spec/プロトコル系のみ。codex 独立 2 本が spec を読解 → 第 3 の codex が相互照合 →
                        相違点と重要要件を Claude が原典で確認。digest は原典への索引になる
[D1]  設計アウトライン  … codex 独立 2 本 (厚い運用は 4 本・read-only) が各々 1 案を作る。設計自由度が低ければ軽量パス (+ 敵対 1 本)
[D1.5] 設計クロス批評   … 各案を「書いていない」codex が批評 (破綻シナリオ・隠れコスト・要件乖離) → Claude が批評込みで統合
[D2]  設計詳細化       … 採用方針を codex が詳細設計に落とす (境界・データ構造・異常系・マイルストーン分割案)
[D3]  設計多角レビュー  … codex 2並列 (1本は必ず敵対観点・read-only) + Claude 視点 → Claude 統合 → ユーザー承認ゲート
[1]   スコープ確定     … 承認済み設計を基に Claude が「1 マイルストーン」を切り、受け入れ条件 (検証方法) を決める
[2]   codex 実装       … codex exec -s danger-full-access に指示 (外せない環境は workspace-write)。codex がファイルを書きプロジェクト標準の build/test まで回す
                        方針が割れうるマイルストーンは既定で [2p] 競作 (別 worktree・勝者採用・敗者剖検は codex)
[3]   検証 (検閲)      … Claude が build/test を自分で実行 + diff 精読。根拠なき断定・spec 取り違え・指示逸脱を弾く
[3.5] codex レビュー … マイルストーン green 直後。主要リスクに合う 1〜3 観点 (read-only・複数なら並列)
[3.55] 指摘の裏取り     … 3.5/3.6 の指摘ごとに裏取り codex が再現手順を構築 (or「再現不能」判定)。
                        Claude は再現手順を 1 回なぞって採否を確定する (検閲の前処理)
[3.6] 敵対的レビュー    … 「壊れている」前提の red team を攻め口別に並列。重要な指摘・不変条件・未確認範囲を照合して打ち止め
[3.7] テスト強化       … codex に「実装は触らず、この実装を落とすテスト」だけ書かせる
[3.8] ミューテーション検証 … 使い捨て worktree で codex が実装に現実的なバグを注入 → テストが検知するか機械確認。
                        検知漏れ = テストの穴として [3.7] に差し戻す。commit 直前の最終ゲート。
                        **ハーネスは手で組まず `bin/mutate-verify` を使う** (worktree の作成・未コミットの
                        持ち込み・baseline green・当たったか・誤ファイル・構文 (第 3 の結果)・zero execution・
                        red の帰属を強制。issue 408)
[4]   commit & push    … 自分の差分のみ commit (commit-policy)。push は必要時。**マイルストーンごとに issue の「進捗チェックポイント」節を更新して同時に commit する**
                        (採用設計の要点 / マイルストーン表と commit hash / 手順 / 再開方法。context 圧縮や別セッションからの再開はこの節が入口。
                        設計ファイルは `<D>` (gitignore。clean-tmp で消え、別マシンには無い) なので、再開に要る判断はここに残す。obaket 617 で圧縮 2 回を跨いで有効だった)
[5]   実地検証 (任意)   … 実行 / 実機 / CI で動かす。失敗したら [6]
[6]   観測 → 次の指示   … blind fix しない。観測を増やし事実を取り、次の指示にする → [2] (設計前提の誤りなら D2/D3 へ)
[7]   要件照合         … [R] のリストと成果物を突き合わせ。codex 敵対照合 1 本を必須で先行させ、Claude が確定

各マイルストーンが green になったら次のマイルストーンへ。マイルストーン間で Claude が状況を要約し、必要なら人間に判断を仰ぐ。

手順詳細

R. 要件確定(Claude・丸投げの入口)

  • 依頼 (丸投げの一言・issue・会話の文脈) を 「要件リスト + 受け入れ条件」に言語化し、 <D>/design.<タスク名>.md の冒頭に書き出す (このファイルに D3 の確定設計も追記していく)。
  • 曖昧点・選択肢はここでまとめてユーザーに質問する。以降のフェーズを自走させるための前倒しであり、 途中で 1 個ずつ聞き直すのを避ける (丸投げ運用ではユーザーは途中判断を待たない前提で組む)。
  • 寿命・拡張予定を判定して明記する (大原則「構造投資の水準」): 長期運用/拡張前提か、地味な機能で 最小変更が正か。依頼文から読めなければここで質問に含める。既定は長期運用側に倒す。
  • ここでの受け入れ条件はタスク全体のもの。マイルストーン単位の検証方法は従来どおり [1] で決める。
  • テストの待ち方を要件に固定する: 「unit test は時間・スケジューリングを注入し、pollUntil(timeout:) / Task.sleep / 固定 deadline の実時間待ちを新規に書かない (事象待ち + hang guard の awaitOrFail)。実時間そのものを 検証する integration test は別に分けて明示する」を受け入れ条件の 1 行として書く。書かないと codex は repo で最も 多い形 (実時間 polling) を真似る — 実測 2026-09-12 obaket 781: 3 epic を並行させた 13 日で pollUntil が 315 → 402 に増え、増えた 81 箇所は別 epic が lint で「新規には使わない」と書いた形そのものだった (~/dotfiles/_claude/rules/avoid-wall-clock-assertions.md)
  • このリストが D1 の「要件 / 制約」の入力になり、[7] の検収基準になる。要件が途中で変わったらこのファイルを更新する。

S. spec ダイジェスト抽出(spec/プロトコル系のみ・独立 2 本 + 相互照合)

RFC / MS-* / API 仕様が正解を決めるタスクでは、設計より前に spec の読解自体を多重化する。 spec の読み違いは最も高くつく失敗 (実装・テスト・レビューが全部同じ誤読の上に建つ) で、読解を 1 本に しておくと [3.6] の循環テスト lens でも捕まらないことがある。独立読解 2 本の相違 = 読み違いの検出器。

  • 独立 2 本 (codex exec -s read-only・gpt-6.1-sol・high・並列作法どおり) に、実装の存在を前提にせず spec 該当節から抽出させる: 要件 (MUST/SHOULD の別)・不変条件・バイトレイアウト/状態機械・公式 test vector・ spec が曖昧な箇所 (解釈が割れる文)。2 本には互いの存在を伝えない。
  • 各要件に 要件 ID・原典の URL/パスと版・節番号・根拠となる短い引用・MUST/SHOULD・解釈・外部 vector を付ける。 出典の無い項目は合意済みにせず「未確認」とする。
  • 第 3 の codex (read-only・sol-high) に 2 本の digest を突き合わせさせ、相違点・出典欠落・ 原典との食い違いの候補を出させる。同じモデルの一致は独立した正しさの証明として数えない。
  • Claude は相違点に加え、重要な不変条件・wire layout・異常系・破壊的操作の要件を、一致していても原典で確認する。 裁定済み digest を要件ファイル (<D>/design.<タスク名>.md) に保存する。 digest は原典を引くための索引であり、正解の根拠は 原典・外部 vector・実サーバの契約 のままにする。 D1/実装/[3.7] には要件 ID と原典参照も渡す。新しい疑義が出たら digest と原典を再照合する。
  • spec が無い/薄いタスクではこのフェーズを飛ばし、「[S] は対象外 (spec 非依存)」と一言明示する。

D1. 設計アウトライン(codex 壁打ち・read-only)

まず 設計自由度 を判定する:

  • 低い (spec/RFC が設計をほぼ決める・既存設計 doc がある・大量移植で構造が既定) → 軽量パス: D1 を「設計方針の確認 1 回」に短縮し、Claude が検閲してユーザーに一言確認したら D2 を省略して [1] へ。 ただし D3 の敵対観点 1 本 (read-only・gpt-6.1-sol・high) だけは省略せず回す (「設計をほぼ決める spec」の読み違い・前提崩れは軽量パスでこそ実装後に高くつく)。 「設計自由度が低いので軽量パス (+ 敵対 1 本) で進める」と明示する。
  • ある (新規ライブラリ・API 境界の新設・複数の実現方式がある) → D1→D2→D3 をフルで回す。

小タスク軽量パス (CI / スクリプト / 設定 / 単一関数の修正)

上の「設計自由度が低い」軽量パスとは別に、タスク自体が小さいときは設計フェーズの codex を丸ごと省く。 判定は次の全部を満たすこと (1 つでも外れたら通常パス):

  • production の差分が目安 50 行以下で 1 マイルストーンに収まる
  • 受け入れ条件が機械判定できる (スクリプトテスト / lint / CI job の green・red)
  • bug 修正なら真因が観測で確定済み (ログ・再現実験。仮説の段階では通常パス)
  • protocol の wire 挙動・暗号・状態機械を触らない (触るなら通常パス。[S] と D1 の多重化はそこで効く)
フェーズ小タスク軽量パス
[R]通常どおり要件ファイルを作る (観測事実と外部事実もここに書く。新規 run は前の履歴を持たず、継続 run も現行ファイルを読む)
[S] / D1 / D1.5 / D2codex を回さない。Claude が D2 コントラクト形式 (採用アプローチ / 不変条件 / 失敗モード表 / テスト) の最小版を要件ファイルに書く
D3敵対 1 本は省略しない (Claude の設計を Claude だけで閉じない)。指摘は採否表で仕分け
[2]通常どおり codex 実装。テストも同じプロンプトで書かせる ([3.7] を分けない)
[3] / [3.6]通常どおり。[3.6] は 1 ラウンド・lens 2 本まで (「指摘なし」で閉じない条件は同じ)
[3.5] / [3.55]省略 ([3.6] に畳む。指摘 3 件以上なら裏取りは Claude が直接なぞる)
[3.8]Claude が直接変異を当てる (数本なら codex に回すより速い。worktree でなく cp 1 世代のバックアップで可)
[7]Claude 単独で照合してよい (codex 敵対照合を省略できる例外。下の [7] 節参照)

実測根拠 (2026-08-28 swift-smbee、CI job の cache 修正 = production 40 行): D1 263k / D3 359k / 実装 158k / [7] 193k tokens。設計と照合の codex だけで 80 万超を使ったが、D1 の設計は Claude の観測結果と同じ結論で、 [7] は cold/warm cache の文脈を持たず「未充足」と誤判定して Claude が CI ログで判定し直した。 一方 D3 敵対 (9 件中 4 件採用) と実装後の敵対 (6 件中 2 件採用) は実害を拾っており、削るのは案出しと照合、 残すのは反証。「小タスク軽量パスで進める (判定: 差分 N 行 / 受け入れ条件 = X)」と一言明示してから始める。 2 例目 (2026-08-31 obaket 661、UI 配線のバグ修正 = production 80 行): Claude 起草の D2 (Optional 意図 state 1 個) に対し D3 敵対 1 本が「sheet 経由の対象を Delete 押下時に共有 selection から取ると reload で drift する」実経路を file:line で示し、 設計を 2 段 enum + Edit 時 snapshot の受け渡しへ変えた (実装後に見つけていたら signature 変更で 2 往復)。 実装後の敵対 2 lens も 9 件中 3 件採用。小タスクでも D3 敵対 1 本は削らないの実績。

案出しは「1 本に N 案出させる」のではなく「独立 N 本に 1 案ずつ出させる」。同一コンテキスト内で並べた複数案は 互いに相関し、最初に書いた案の周辺に寄る ([3.5] で警戒している同一モデルの相関盲点の設計版)。既定は 独立 2 本。厚い運用を明示されたときは 4 本。 各本に異なる出発点 (制約の優先順位) を与えると多様性が出る。分け方の例:

  • 案 A: 最短で動く実装を優先 (既存構造への追従・追加依存なし)
  • 案 B: 変更容易性 / テスト容易性を優先 (境界を切る・差し替え可能にする)
  • 案 C: 失敗モードの吸収を優先 (異常系・部分失敗・再実行を設計で潰す)
  • 案 D: 既存コードの再利用・削除の最大化を優先 (新規コード最小・重複の統合・むしろ減らす方向)

起動は「並列起動の作法」に従う (別 Bash 呼び出し・run_in_background・出力は一意パス・後続呼び出しに $stamp を 残さずリテラルで書く・stdout もファイルに保存)。

# 起動は codex-fanout driver が既定 (プロンプト部品を 4 案分書き、manifest で 1 回起動)。
# 以下は fallback の per-call 形。プロンプト内容の見本としてはどちらでも同じ。
# --- 案A (Bash 呼び出し 1・run_in_background)。案B〜案D も同形で別呼び出し・別パス ---
out="<D>/<literal-stamp>.designA.md"; log="$out.log"
command codex exec -s read-only -m gpt-6.1-sol -c model_reasoning_effort="high" \
  --ephemeral -o "$out" </dev/null "$(cat <<'EOF'
<タスク>の設計壁打ち。コードは書かない (設計検討のみ)。

## 要件 / 制約
- <D>/design.<タスク名>.md の要件セクションを読むこと (貼らずに読ませる — トークン経済 2)
- <ファイルに無い補足だけ短く書く: 触ってよい範囲・依存方針 等>

## この案で最優先する軸
- <案 A なら「最短で動く」。他案の存在は伝えない (独立に考えさせる)>

## 出してほしいもの
- この軸で最良と考える設計 1 案 (構成・trade-off・リスク)
- この軸を優先したことで捨てたもの (何を犠牲にしたか)
- 確証が持てない前提は「未確認」と明示する (決め打ちしない)
EOF
)" > "$log" 2>&1; tail -40 "$log"
  • 他案の存在を各本に伝えない。「他案と差別化して」と書くと、独立性を保つためにやっている分割が 「相手を意識した案」に崩れる。
  • 案が揃ったら [D1.5] クロス批評を挟む: 各案に批評者 codex 1 本 (read-only・sol・high・並列作法どおり) に、 各々「自分が書いていない 1 案 + [R] の要件」だけを渡し、その案の破綻シナリオ・隠れコスト・要件との乖離を 批評させる (案 A の批評者には案 B〜D を見せない — 相互汚染で独立性が崩れるのを防ぐ)。 作者へ返して改訂させる往復はしない (重い割に、改訂は統合時に Claude が判断できる)。 各案が実質同じ内容に収束していたら D1.5 を省略してよい (「設計自由度が低かった」証拠。一言明示)。
  • 統合ドラフトも codex に作らせる (集約規約): merger に 各案 + 批評の保存ファイルパス群を渡し、 「軸ごとの trade-off 比較表・各案への批評の要点・推奨案ドラフト (+ 他案から取り込む部分)」を 1 枚に まとめさせる。Claude はその 1 枚を検閲して統合を確定する — 推奨案の原文と、批評が「破綻」と 言った案の該当箇所だけ spot check する (8 ファイル全文は読まない)。批評で initial 案が全滅したら、 その批評内容を出発点制約に足して D1 をもう 1 巡する (最大 2 巡)。 🚨 driver の既定の merger (templates/merger.md) は指摘を集める形で、そのまま使うと digest が「各案のリスクの列挙」になり、 案の比較にならない (obaket retro 1040: 4 案の原文を全部読み直した)。D1 / D1.5 では上の構造を書いた merger prompt を -m で渡す。
  • 設計フェーズは読む run なので gpt-6.1-sol + high (モデル表)。
  • Claude が検閲し、ユーザーと方針を選ぶ。壁打ちの相手は codex だけでなく人間も含む (方針候補と推奨理由を 要約して提示し、採用方針の合意を取ってから D2 へ)。
  • 丸投げ運用ではタッチポイントを集約してよい: [R] で曖昧点を潰してあることを前提に、Claude が推奨案を 仮採用して D2/D3 まで自走し、D3 の承認ゲートで「方針 + 設計 + 残リスク」をまとめて 1 回で提示する (方針選択と設計承認を 1 タッチポイントに集約する。ユーザーが方針から関与したい場合は従来どおり D1 で止まる)。

D2. 設計詳細化(codex)

  • D1 で採用した方針を渡し、詳細設計に落とさせる: モジュール/型の境界・データ構造・エラー/異常系の扱い・ テスト戦略・マイルストーン分割案。
  • 出力は 設計コントラクト形式 (codex-lead 1-5 と同形) で構造化させる: 採用アプローチ / 守るべき不変条件 / 失敗モードと吸収方法の表 / 責務分担 (+ データ構造・テスト戦略・マイルストーン分割案)。不変条件と失敗モードは 必須項目 (CLAUDE.md「不具合対応の原則」を設計フェーズに接続する)。自由記述にせず、[3] の乖離チェックが 「コントラクト項目ごとの検証」として機械的に回る形にする。
  • コマンドは D1 と同形 (-s read-only・sol・high)。出力先は別の一意パスに。
  • Claude が検閲する。設計段階でも「実在しない API/設定キーの捏造」は起きる (既知の弱点表)。設計が参照する API・設定キー・ライブラリ機能は実環境・実ドキュメントで存在確認してから採用する。

D3. 設計多角レビュー(codex 2並列 + Claude 視点 → 承認ゲート)

  • [3.5] と同じ並列作法 (別 Bash 呼び出しで run_in_background・出力は別パス) で、直交する 2 観点の codex レビューを並列起動する。ただしこの段階は diff が存在しないので codex exec review ではなく codex exec -s read-only を使い、D2 の設計ドキュメントをプロンプトに含めて渡す。
  • 2 本のうち 1 本は必ず敵対観点 (設計版 red team) に固定する。設計の穴は実装後に見つけるほど高くつくため、 承認ゲートの前に「この設計が破綻するシナリオ」を作らせる。もう 1 本を発見型の観点に充てる。分け方の例:
    • A (発見型): 要件充足・spec 整合・見落とし要件 / 複雑性・変更容易性・テスト容易性
    • B (敵対): この設計を破綻させる前提・入力・運用シナリオを構築する
  • 敵対側 (B) のプロンプトに入れる問い (codex-review「敵対的レビューの作法」の設計版):
    • この設計が前提にしている「当然そうなっているはず」は何か。それが崩れる条件を挙げよ
    • 不変条件を破れる経路はあるか (順序・並行・再送・部分失敗・再起動・権限/ネットワーク断)
    • 列挙された失敗モードのうち、吸収方法が実際には吸収できていないものはどれか
    • この設計で書けないテストは何か (=検証不能なまま残る領域はどこか)
    • 2 年後に機能追加するとき、最初に壊れる/破られる境界はどこか
    • 反証できなかった項目は「反証できなかった」と明記する (「問題なし」と書かせない)
  • Claude 自身も 1 視点として設計をレビューする。codex の設計を codex だけでレビューすると同一モデルの 相関盲点が残る (「循環テスト」問題の設計版)。実装レビューと違い設計は正解が客観確定しにくいため、 別モデル視点を必ず 1 本混ぜる。
  • 発見型 (A)・敵対 (B) ともに sol-high。 B は「設計を破綻させるシナリオ」を 1 本だけで構築する役で、冗長性が誤りを吸収しない。
  • 敵対側の指摘は 発火条件 (どんな前提・入力・運用で破綻するか) が具体的なものだけ設計変更に反映する。 「起こりえないが念のため」の防御を設計に足すと over-engineering になる。示せないものは 残リスクとして承認ゲートの提示物に含め、観測ポイントの候補にする ([6] で拾う)。
  • Claude が統合検閲し、設計サマリ (採用案 / 却下した代替案とその理由 / 残リスク) をユーザーに提示して承認を得る。 承認ゲートを飛ばして実装に入らない。
  • 承認後、確定設計 (コントラクト) を [R] の要件ファイルに追記してから [1] に進む。 独立したレビューは新規セッション、同じ実装担当への修正は session ID で継続する ([2])。 設計・受け入れ条件はセッション履歴だけに依存せずファイルにも残し、各 run が現行版を確認する。

1. スコープ確定(Claude)

  • 承認済み設計 (軽量パスなら確認済みアウトライン) を基に、今回の 1 マイルストーンを決める (例: 「probe が NEGOTIATE して交渉結果を出す」)。大機能は複数マイルストーンに割る。
  • 受け入れ条件 = どう検証するかを先に決める (プロジェクト標準 build/test green / CLI 出力 / CI E2E green / 実機ログ。 Swift プロジェクトなら swift build / swift test)。
  • 挙動保存リファクタで「移行前後の differential 比較」を受け入れ条件に持つなら、移行前の characterization (transcript / 期待値の固定) を最初の実装 commit より前に採取する。 移行 commit 後には「移行前」を動かす手段が消え、原理的に作れない (実測: obaket 651 — M2a 後に気づき characterization + 変異検証の代替で確定させた)。
  • (sandbox を外せない環境向け) そのうち codex 内で完結する検証を、codex が自分の sandbox で回せるか確認する。 既定の -s danger-full-access (下の節) では素のコマンドがそのまま回るので、この確認は要らない。 着手前に確かめるのは本流だけでよい。[2p] の worktree と [3.8] の mutation worktree は cwd・cache path・依存取得先・fixture 位置が変わるので、そのフェーズを実際に使うときに、 そのフェーズの開始時点で確認する (競作しないマイルストーンのために worktree を先に作らない)。
  • 実行できた場合も、確定したコマンドを [2] のプロンプトに必ず貼る。「失敗したときだけ書く」にすると codex が素の swift test に戻って再び未検証コードを返す。codex が「実行できない」と報告したら 受け流さず、着手前の課題として扱う。
  • 初回の確立は blind fix ではなく環境診断とする。実行 root・権限・cache の書き込み先・実際の exit code を観測してから コマンドを確定する (instrument-before-second-fix.md)。macOS/SwiftPM なら、例えば CLANG_MODULE_CACHE_PATH="$PWD/.build/mcache" swift test --disable-sandbox --cache-path .build/spm-cache。 GUI・実機・実サーバ・CI 認証など codex 内で完結しない検証は Phase 0/[5] に委譲し、代替経路と未検証範囲を着手前に固定する。 (出典: 573-retro-codex-drive-541-2026-08-24.md)
  • 🚨 実装 run の sandbox は既定で外す: -s danger-full-access (ユーザー決定 2026-09-13、dotfiles issue 369 案 0-b)。 -s workspace-write では make lint / make build / make test (xcodebuild) が SwiftPM / clang cache の書込拒否で Error 74 になり走らず (obaket 598, 2026-08-27)、型エラー往復 2〜3 回 / マイルストーン (763)、走らない変異ループ (650 M1)、sandbox 由来の偽赤 (613)、「xcodebuild を試みさせない」の縛り (617 M3) がすべてここから派生していた。 外すと codex が自分でプロジェクト標準の build/test を回して反復できる。 プロンプト・事後検閲・git worktree は sandbox と同等の隔離を提供しない。作業根外への 書き込み、認証情報へのアクセス、他プロセスへの操作を事後検閲で取り消せるとは考えない。 この既定は許可済みの信頼できるローカル repo での運用に限る。外部から持ち込まれたコード・ 未信頼の build/test を扱うときは workspace-write または外側の隔離環境を選び、ビルド上の不足を先に診断する。 full access を選んだ場合も、次は編集事故の検出・軽減策として行う:
    • worktree ごとに DerivedData を分ける。codex が worktree で xcodebuild を回している間に Claude が本体で xcodebuild / swift build を回すと、DerivedData と package graph が共有されてエラーではなく無限待ちになる (no-concurrent-spm-build-during-xcodebuild.md、 7.5 時間停止の実例)。[2] のプロンプトに「xcodebuild は -derivedDataPath ./.derived を付ける」を書く (雛形は <<'EOF' で クォートされているので $ROOT は展開されない。相対で書く)。.derived/ は .gitignore か .git/info/exclude に 入れる (入れないと untracked が [3] のスナップショット比較に混ざる)。 Makefile が固定パスで付けられない repo では、codex の run 中は Claude が本体で xcodebuild / swift build を回さない
    • 作業根の外へ書かないをプロンプトに明記する (-C で渡した worktree / repo root の外は読むだけ)。 採用判定 [3] の前に 本体 checkout の git status --short が起動前スナップショットと同じこと、 worktree の git log -1 が起動前と同じ hash であることを確認する (sandbox が無いので、はみ出しは検閲でしか見えない)
      • make target やラッパー経由の build を許すなら、中で走る道具の既定の出力先 (DerivedData・cache・$HOME 配下) まで確かめる。 作業根の外へ書く target は、作業根の中の出力先を指定できない限り使わせず、プロンプトで名指しして禁止する (「外に書かない」の一般則だけではラッパーの既定値を止められない。obaket 1016: make -C macOS build が既定の DerivedData に書いた)
    • git 操作全般の禁止は従来どおりプロンプトで (「git commit はしない」だけでは codex が git pull --ff-only を 試みる。ThumbnailThumb 542)。sandbox があった頃は失敗していたが、いまは成功するので検閲の項目に格上げ
    • 依頼していない破壊的操作 (rm -rf / 他 checkout の編集 / プロセス・tmux 操作) が要約と log に無いかを [3] で読む (bin/tmux shim は非 TTY からの本番 kill を拒否するが、それ以外は無防備)
    • 効いたかは計測で言う (issue 369 案 1)。obaket の次マイルストーンで Error 74 の有無・型エラー往復数・危険操作の有無を checkpoint に残す
  • sandbox を外せない環境 (danger-full-access を許可していないマシン / repo) では、旧規律で分担を最初に切る: codex に任せるのは shared の swift build / swift test (上の cache フラグつき) まで、xcodebuild 系は Claude が 素の環境で回すと [2] のプロンプトに書く。codex の全体 swift test が赤を報告しても sandbox 由来の偽赤が ありうる (613 で同日 2 回観測。素の環境では 0 failure) ので、赤も緑と同じく Claude の再実行で判定する。 codex に xcodebuild を試みさせないとプロンプトに書く (試みると Error 74 の往復で時間を溶かす。617 M3)。 codex に渡せる構文確認は swiftc -parse まで (型検査は依存モジュールが要り sandbox で組めない)。型 error は Claude の make test で 1 往復として織り込む (542: memberwise init の引数順 1 件で passed 0 の往復)。 shared SPM を触るマイルストーンでは、実装プロンプトに**「返す前に cd shared && swift build --build-tests を通す」を 固定文で入れる** (sandbox で走るかは repo ごとに最初のマイルストーンで確かめてから固定する。issue 369 1-2)。 この環境では未実行の理由が sandbox 由来なので、[3.8] の実行ループも最初から Claude のハーネスで当てる (変異 patch の生成だけ codex read-only に作らせる。codex に回しても typecheck だけで「成功」と書く: 650 M1)
  • sandbox の有無に関係なく [2] のプロンプトに書くこと / [3] で見ること: project.pbxproj は触らない (xcodegen が project.yml から生成する) — 書かないと codex が新規テストファイルを pbxproj に手で登録する (obaket 686, 2026-09-01。再生成で上書きされるので実害は無いが diff がノイズになる)。 codex が書いた macOS target のテストは Claude が baseline 緑 + 変異 red を xcodebuild で確認するまで未検証扱い (617 M5: codex 版の macOS テスト 2 本が baseline red / 変異検知が vacuous だった。macOS 側の変異は Claude が worktree で xcodebuild -only-testing:<suite> を当てる)。 codex が Package.swift (依存の追加) を触ったら要約に明示させる (617 M5: test target の依存追加が要約に無く diff で気づいた)。 codex の要約に「未実行」「実行できなかった」がある成果物は、採用判定 ([3]) より先に Claude がその検証を回す (645 M6c, 2026-09-03: 「macOS 側 xcodebuild は未実行」と明記された IA cancel test を、同ラウンドの shared 緑に 引っ張られて後回しにし、hang の発見が 1 ラウンド遅れた)
  • 触ってよい範囲・触らない範囲・既存方針 (設計 doc 等) を明示する。

2. codex に実装させる(write 権限)

# 最終応答・stdout・rc は **run 固有のパス** (<D>/<タスク>/。「出力の置き場」) に保存する。
# 後から「空振りだったのか遅れて完了したのか」を診断するため (2026-08-25 obaket 581 で証拠が残らなかった)。`</dev/null` 必須 (codex-review ルール)。
# 実装は書く run なので luna + effort **max** (モデル表)。
# ROOT は repo root の絶対パス。cwd はサブディレクトリに残っていることがあるので `-C "$ROOT"` を必ず付ける
# (Storage/ を cwd に起動され macOS/bin を書けず「対応できませんでした」で 30 分ロス: obaket 696 項目 1)。
ROOT="$(git rev-parse --show-toplevel)"
last_message="<D>/<タスク>/impl.out.md"; log="<D>/<タスク>/impl.log"; mkdir -p "<D>/<タスク>"
command codex exec -s danger-full-access -C "$ROOT" -m gpt-6-luna -c model_reasoning_effort="max" \
  --json -o "$last_message" </dev/null "$(cat <<'EOF'
<タスク>。git 操作 (commit / pull / checkout / stash 等) はしない (人間が検証して commit する)。作業根 (この repo root) の外には書かない。
ファイルを書き、プロジェクト標準の build/test が green になるまで自分で反復すること。Swift プロジェクトなら swift build / swift test を使う。
最後の確認はテスト全体で行う (関係しそうな suite だけを選んで代用しない。応答の形や request の列は contract / golden の stub が別の suite で作っている)。
xcodebuild を回すときは -derivedDataPath ./.derived (repo root 直下) を付ける。
issue は起票しない。範囲外の発見は要約に書く (採番から push までは人間側が 1 手で行う)。

## ゴール / 受け入れ条件
- <1 マイルストーンの完了条件と検証方法>

## 承認済み設計 (このマイルストーンに関係するスライス)
- <D>/design.<タスク名>.md の「<セクション名>」を読んでから着手すること
  (新規の実装 run は前フェーズの設計を知らない。継続 run も現行版を再確認する。貼らずにパス + セクション名で読ませる — トークン経済 2。
  軽量パス (設計フェーズ省略) のときはこのセクションごと省略可)

## やること
- <具体的な実装項目。spec があれば節番号で参照>

## 制約
- <触らない領域 / 既存方針 / 依存方針 / Linux ビルド維持 等>
- 構造方針: <[R] の判定を貼る。長期運用なら「症状パッチ・特例分岐で凌がず前提を直す。ただし今使わない
  抽象・設定可能化は足さない」/ 最小変更なら「既存構造に追従し、構造改修を持ち込まない」>
- production 型に **test 専用の状態・観測 API・barrier を足さない** (counter / waiter / 到達通知 /
  停止用 seam)。interleaving を固定したいときはテスト側だけで観測できる形 (bounded yield + flag、
  fake の注入、既存の internal 診断 counter) に留め、それでも固定できないなら「pin なし」として
  要約に書く。判断基準は `_claude/rules/refuse-low-value-coverage.md` の「テスト困難 × 価値」表。
- テストに実時間待ちを新規に書かない (`pollUntil(timeout:)` / `Task.sleep` / `.sleep(for:)` / 固定 deadline)。
  待つなら事象待ち (fake の waiter / `waitUntil*ForTesting`) + hang guard の `awaitOrFail`。実時間が検証対象そのもの
  なら integration test として分け、理由コメントを直前行に置く。
- 確証が持てない点は決め打ちせず ⓥ コメントを残し保守的に実装する。
- (挙動を変えない作業のとき) 旧実装の不具合を見つけても直さず、要約の別項目に書く。「挙動を変えない」とだけ書くと直す方へ寄る (obaket retro 1062)。
- 他の AI / CLI (claude / codex 等) を呼ばない。指示にない長時間の検証 (test-load 等) を回さない。
終わったら、変更点・検証結果・未完部分を要約。
EOF
)" > "$log.events.jsonl" 2>"$log"; rc=$?; echo "rc=$rc" | tee "$log.rc"; tail -40 "$log"

同じ実装担当への継続

  • 実装 run は --ephemeral を外して --json を付け、thread.started.thread_id をその run の checkpoint に保存する。 独立レビュー・競作の各候補・テスト強化は引き続き別セッションにする。

  • 同じ実装への修正は 明示 ID で codex exec resume <SESSION_ID> '<修正指示>' --json -o <新しい出力パス> を使う。 --last は並行セッションを誤って選ぶので使わない。resume も </dev/null、モデル・effort・一意なログ・timeout を付ける。 resume の実行ディレクトリは元の worktree にし、記録した sandbox 設定を明示して再指定する。 CLI 0.160.1 の resume は -s を持たないため -c sandbox_mode=read-only 等を使う。 対象 CLI の resume --help で受け付ける設定方法を確認する。継続時の設定を暗黙の継承に任せない。

  • 継続前に元 run の終了を確認し、git diff と現行要件・設計ファイルを読むよう指示する。 rebase・他者の編集・設計変更があればその事実も渡す。session ID が失われた場合や前提が大きく変わった場合は、 checkpoint + 現行差分から新規 run を起こす。停止した run の編集を全ロスと決めつけない。

  • --json の command_execution / turn.completed / turn.failed / error と usage を保存する。 完了イベント・応答があっても実装の正しさは [3] の build/test/diff で検証する。

  • モデルはマイルストーンの性質で振らない (大原則のモデル振り分け): 機械的移植・boilerplate でも、 判断を含む実装・非自明な wire/protocol でも、一律 gpt-6-luna + max (モデル表の書く run)。

    • 唯一の例外は上振れ: luna max の出力の質が低いと [3] の検閲で判定したマイルストーン (「動くが筋が通っていない」/ 捏造 API / 同じ型エラーを 2 往復しても直らない、等) は、 そのマイルストーンだけ -m gpt-6.1-sol (effort は sol の high。モデル表) へ切り替えてよい (ユーザー指示 2026-09-13、dotfiles issue 369 1-3。2026-09-30 に上振れ先を astra から gpt-6.1-sol へ変更 (ユーザー指示: コストが安いため)。probe 実測: codex-cli 0.159.1 で rc 0、応答 "GPT-6")。 切り替えはマイルストーン単位で、checkpoint に「M<n> は sol へ。理由: …」を 1 行残す (前後比較の材料)。 下げる方向 (541 の low) は依然禁止。capacity 死は luna と共通 (openai/codex #43398) なので回避策にはならない。 駄目だった質の判定材料は「[3] で差し戻した回数と種類」であって印象ではない
    • 上振れ先は luna より 1 run の消費が重い。長い実装の run を上振れで起こす前に codex の 5h 枠の残量を見る (subagent-model-tiering.md の「1 本の重さも見る」。obaket 1003 で astra の run が 2 回とも実装の途中で枠切れになった)
  • command codex プレフィックス / </dev/null / -o の作法は codex-review が正本。独立レビューの --ephemeral は [2] の継続実装には付けない。 -o は実行ログ全体ではなく最終応答 (--output-last-message) の保存先。標準出力/標準エラーは必要に応じて呼び出し側で保存する。

  • --full-auto は使わない。実装は -s danger-full-access を明示 (ユーザー決定 2026-09-13、issue 369。理由と セットで守る項目は「1. スコープ確定」の sandbox 節)。外せない環境では -s workspace-write。review の -s read-only とは別。

  • 大きいタスクは codex が時間内に終わらないことがある。プロンプトに「時間内に終わらなければ最小で動く形を優先し、 残りは TODO で残す」と書く。

  • codex の exit 0 を「実装した」の証拠にしない (空振りの検出)。実装フェーズの codex は、方針を述べただけで exit 0・差分ゼロ・-o の出力ファイルも未作成のまま終了することがある (実測 2026-08-24)。成功終了なので 通知だけ見て次へ進むと「テストを足したつもり」で先へ進んでしまう。期待した成果物 (git status --short の 差分、または -o のファイル) が無い exit 0 は空振りとして扱い、再投げか Claude 直筆に切り替える。 🚨 判定は「差分ゼロ = 空振り」ではない (調査タスクや「変更不要」の結論では差分ゼロが正常)。 workspace-write の実装フェーズで、期待した成果物のパスに差分が無いときに限る。並行セッションの 差分と区別する必要があるなら [3.7] の pre/post スナップショットと同じ形を使う。 🚨 空振りと判定する前に、その run が終了していることを確認する。rc が確定する前に成果物の有無だけ見ると、 まだ走っている run を「空振り」と誤判定する。fanout なら runs.tsv の rc、単発なら $? を保存してから成果物を見る。 実害 (2026-08-25 obaket 581): 4 本を空振りと報告したが少なくとも 2 本は遅れて完了していた。 さらに、空振り判定後に Claude が書き直したテストを、遅れて完了した codex の出力が同じパスに 上書きし、commit されたのは codex 版だった (テスト名が同じで取り違えた)。誤判定のコストは 待ち直しではなく「codex が壊れている」という誤った因果を作ること。 🚨 判定できるように、出力先は run 固有のパス (<D>/<タスク>/) にする。-o と JSONL/stdout を scratchpad に出すと 再起動で消え、「空振りだったのか」を後から検証できない (581 で実際に残らなかった)。一般則は verify-execution-not-just-exit-code.md の 「非同期・background の完了も『成果物』で判定する」節。

  • 異常終了 (capacity 死・timeout・中断) も「全ロス」と決めつけない。書き込み権限の run (danger-full-access / workspace-write) は 死ぬ前に編集が途中まで、ときには全部残っている。実例 (2026-08-25 obaket 571): 632k tokens 消費後に 「Selected model is at capacity」で死んだ run は、突き合わせたら要求項目が全部完了していた。 再投げの前に git status --short と要求項目を突き合わせる (全ロス前提の再投げは二重編集を作る)。 起動し直すプロンプトには「再開の注意: まず git diff を読み、どこまで当たっているかを確かめてから続きを行う」を足す (obaket retro 1076: クレジット切れで途中で死んだ run を 3 回この形で起動し直し、3 回とも二重に当てずに続きから終わった)。 上の空振り判定と同じ形で、違うのは向きだけ — あちらは「まだ走っている」を「壊れた」と読む誤り、 こちらは「異常終了した」を「何もしなかった」と読む誤り。 なお capacity で codex が使えない状態が続くなら、独立視点の agent で代替してよい (2026-08-25 の実績: 敵対 round と [7] 検収を agent で代替し、どちらも実害を検出した)。

  • コマンド実行ツールの timeout は 900000ms。

2p. 実装の競作(N-of-M・方針が割れるマイルストーンのみ)

同じマイルストーンを独立 2 本に実装させ、Claude が比較して勝者を採用する。1 本しか走らせないと「その 1 案が 最良か」を比較対象なしに判断することになる (レビューは「書かれたコードの粗探し」しかできず、「別の書き方なら そもそもこの問題が存在しない」には届かない)。競作は codex トークンを倍払って比較対象を買う手段。

適用条件 (満たすなら既定で競作する。満たさないなら通常の [2] 1 本):

  • 実装方針が割れる、または割れる可能性がある (データ構造・分割の粒度・同期/非同期・エラー伝播の設計に 選択肢がありうる)。「確実に割れる」まで待たない — 割れるか不明なら競作して確かめる (2 本が同じものを 書いたら「自由度が低かった」ことの証拠で、無駄撃ちではない。D1 の収束判定と同じ扱い)
  • 受け入れ条件が機械判定できる (build/test/CLI 出力)。判定が主観なら勝者を選べないので競作の意味がない
  • 機械的移植・rename・spec が実装を完全に決めるマイルストーンではやらない (2 本が同じものを書くだけと事前に分かる)

起点は HEAD。開始時点の未コミット変更が今回の実装の前提になっているなら、競作を使わない (または前提を先に commit してから競作する)。両候補は前提を見ずに実装するので、勝者を戻す段で初めて衝突する。

必ず別の git worktree で走らせる。同一 working tree に 2 本の書き込み run を当てると互いの編集を 上書きし合う。codex には -C <worktree> で作業根を渡す。 その repo に worktree を作るコマンドがあれば (例: my-products の bin/wt create。毎回新しい path + repo 直下の .wt-setup による 下準備)、detached で足りる用途 (実装 1 本・変異検証) ではそれを使う。下の例は branch を付ける競作用の手組み。

# --- 準備 (Bash 呼び出し 1)。パスは repo root からの絶対パスで確定し、出力された値を控える ---
root="$(git rev-parse --show-toplevel)"; stamp="$(date +%Y%m%d-%H%M%S).$$"
git worktree add -b "codex-drive/$stamp-a" "$root/../wt-$stamp-a" HEAD
git worktree add -b "codex-drive/$stamp-b" "$root/../wt-$stamp-b" HEAD
echo "A=$root/../wt-$stamp-a"; echo "B=$root/../wt-$stamp-b"   # ← この 2 行を控える

$stamp は次の Bash 呼び出しに残らない。控えた絶対パスをリテラルで書くこと (「並列起動の作法」)。 ../wt-* を cwd 基準で書くと、cwd が repo のサブディレクトリのとき repo 内部に worktree ができて 本流の untracked を汚す。上記のように repo root 基準の絶対パスにする。

# --- 案a (Bash 呼び出し 2・run_in_background)。案b も同形で別呼び出し・別 worktree ---
wt="/<控えた A の絶対パス>"; out="<D>/<literal-stamp>.implA.md"; log="$out.log"
command codex exec -s danger-full-access -C "$wt" -m gpt-6-luna \
  -c model_reasoning_effort="max" --ephemeral -o "$out" </dev/null \
  "<[2] と同じプロンプト>" > "$log" 2>&1; tail -40 "$log"
  • 2 本には同じプロンプト (同じゴール・同じ受け入れ条件) を渡す。案出し ([D1]) と違い、ここで軸を分けると 「違う仕様のものが 2 つ」になり比較できない。振れ幅は codex 側の非決定性に任せる。
  • 勝者の選び方 (Claude が判定する): ① 受け入れ条件を機械判定で満たすか (満たさない方は即脱落) → ② 承認済み設計のコントラクト (不変条件 / 失敗モード吸収 / 責務分担) に忠実か → ③ diff が小さく既存構造に 馴染むか → ④ テストが循環していないか。「codex のサマリがよく書けている方」で選ばない (overclaim は既知の弱点)。
  • 敗者剖検は codex にやらせる (検閲の前処理): 勝者と敗者の diff を渡し、「敗者にだけある良い判断 (見落としていた異常系・簡潔な書き方・追加テスト・片方だけが踏んだ落とし穴) を列挙して、勝者へ移植する 最小 patch 案を出せ」と read-only (sol・high) で 1 本回す。Claude は剖検結果を検閲して移植を判断する (2 本の diff 全文を並べて読む作業を digest 化する — 競作の主目的である「比較で見える落とし穴」を 取りこぼさずに検閲単価を下げる)。移植の実施は [2] (codex) か trivial なら Claude 直接。
  • 勝者を本流に持ち込む (patch 経由・codex には commit させない): 勝者 worktree には commit が無く、 新規ファイルは untracked なので、merge / cherry-pick / 素の git diff はどれも取りこぼす。 git add -A で untracked を index に載せてから --cached --binary で patch 化し、本流に apply する。 適用前に必ず --check を通し、落ちたら強制適用しない。原因を git apply --check -v で切り分けて分岐する:
    • 適用位置のズレだけ (本流が別の場所で進んだ) → git apply -3 (3way) を試す。競合が残ったら手動で解消する
    • 本流の差分と同じ箇所が重なっている → その本流側の差分が自分の作業由来なら手動で統合する。 見覚えのない差分 (並行セッションの可能性) なら触らず、状況をユーザーに報告して指示を仰ぐ (commit-with-pathspec)
    • どちらでも解けない → 競作を中止し、勝者の設計メモだけを引き継いで通常の [2] (単発・本流の作業ツリー) で 実装し直す。worktree は下記の手順で必ず片付ける
wt="/<控えた勝者の絶対パス>"; patch="<D>/<literal-stamp>.winner.patch"
git -C "$wt" add -A
git -C "$wt" diff --cached --binary > "$patch"
git apply --check "$patch" && git apply "$patch"   # --check が落ちたら適用しない
  • worktree とブランチは勝敗が決まった時点で必ず消す。両 worktree は dirty なので通常の remove は拒否される。 git worktree remove --force を使い、-b で作ったブランチは別途 git branch -D する (worktree remove はブランチを消さない)。放置しない (CLAUDE.md「並行作業者がいるときの worktree 退避」)。 削除は patch の適用と内容確認が済んでから行う (--force は未移送の成果物ごと消す)。
git worktree remove --force "/<A の絶対パス>"; git worktree remove --force "/<B の絶対パス>"
git branch -D "codex-drive/<literal-stamp>-a" "codex-drive/<literal-stamp>-b"
git worktree list   # 消えたことを確認する
  • 本流に載せたら [3] に入る。以降の検証・レビュー・commit は通常フローと同じで、commit は Claude が 自分が触ったパスを pathspec で明示して行う (commit-with-pathspec)。競作したことは commit message に一言残す。
  • 3 本以上に増やしてよいのは、方針が 3 つ以上に割れていて Claude が全部を精読できるときだけ。 律速は Claude の比較検閲なので、読み切れない本数を走らせると質は下がる。

3. 検証(Claude が必ず検閲)

  • 🚨 順序: codex が返した直後にまず型検査 (make build 相当) を回し、通ってから [3.5] / [3.6] を起動する。 レビュー fanout と並走させると型エラーを後から知り、「型エラーを抱えたままレビューに出した」往復が 1 回増える (obaket 763 項目 4: マイルストーンごとに 2〜3 往復。issue 369 1-2)。型エラーはどの往復でも最終的に直るので、 先に潰しても質は変わらない — 減るのは往復だけ。macOS target を触るマイルストーンは薄く切り、この型検査を短くする
  • 自分の環境でプロジェクト標準の build/test を実行して green を確認 (Swift プロジェクトなら swift build / swift test。 codex 環境の sandbox 差で codex 報告が --disable-sandbox 等になっていても、Claude は素の環境で確認する)。
  • codex のサマリは「主張」として読む。「実装済み」「動作確認済み」と書かれた項目こそ最初に裏を取る対象にする (overclaim は既知の弱点)。裏が取れない主張は「未検証」として扱い、green の根拠に数えない。 🚨 「変異 N ケース全成功」「手動ランナー成功」も同じ。sandbox で swift test が走らない環境では、codex の 変異検証は typecheck だけで「成功」と書かれる (実測 2026-09-05 obaket 650 M1: fix ×4 すべてで swift test は 一度も実行されておらず、Claude が当て直したら 1 本 hang・2 本 green だった)。変異検証は codex の報告を 数に入れず、Claude が [3.8] で必ず自分で当て直す。プロンプトには「実行できなかった検証は成功と書かない」を 入れてはあるが、報告の書き方は変わらないので、読む側で「実行ログの無い成功」を落とす
  • diff を精読: 根拠なき断定 (「実装済み」「動作確認済み」)・spec 取り違え・承認済み設計との乖離 (D3 で確定したコントラクトの項目 = 不変条件 / 失敗モード吸収 / 責務分担 ごとに実装が守っているか検証する)・ 指示外ファイルへの変更・半端な編集を弾く。構造方針との乖離も弾く: 長期運用判定のタスクに 症状パッチ・特例 if 分岐・「このケースだけ救う」ワークアラウンドが入っていないか / 逆に最小変更判定の タスクに頼んでいない抽象化・機構の新設が入っていないか (どちらの方向の逸脱も差し戻す)。 🚨 production に test 専用の状態が入っていないかを毎回見る (名前に ForTests / Diagnostics / waitFor… が付く stored property・actor・public/internal API、到達通知の counter、停止用 barrier)。 codex は「レビューで指摘された不変条件をテストで固定する」を最優先に解くので、production の 複雑性を上げる seam を躊躇なく足す。実測 (obaket 650 M1 fix3, 2026-09-05): 敵対レビューの 「テストが interleaving を強制していない」に対して production actor へ duplicateEndCleanupCount / duplicateEndWaiters / waitForDuplicateEndCleanup() を追加してきた。次ラウンドで 「production に入った test 専用状態」として指摘され、fix4 でテスト側の bounded yield + flag へ置き換えた。 _claude/rules/refuse-low-value-coverage.md の「テストのために production へ seam を足して本番側の 複雑性を上げるなら、それはテスト困難の判定材料」と正面から衝突するので、差し戻す。 🚨 テストの失敗経路に、後始末を飛ばす early return が足されていないかも同じ位置で見る (「待ちが失敗したら return」の guard が、Task の join・lease の終了・runtime の破棄を飛ばす)。 プロンプトで禁じても繰り返し足される (実測 obaket 806: 4 件。うち 3 件は diff 精読でしか見つからなかった) 🚨 既存ファイルを書き換えさせたら、削除されたコメント行を数え、理由 (なぜ / なぜしない) の消失を見る (git diff -- <file> | grep -cE '^-\s*//' と ^\+\s*// を並べ、大きく減っていたら削除行を読む)。codex は書き換えのついでに 理由のコメントを要約・削除し、要約にはそれを書かない (実測 obaket 807: engine で削除 52 行に対し追加 29 行。issue 323 / 334 の理由が 消えていて差し戻した)。消えたものは list-masked-failure-modes-before-removing-guard.md の「統合・移設で comment を書き換えるとき」の扱いで戻させる 🚨 既存の分岐が投げるエラーの種類と、再試行の扱い (再試行する / しない) が変わっていないかを先に読む。codex は寄せる・整える ついでにエラーの分類を変え、要約に書かない。テストがエラーの型しか見ていなければ素通りする (実測 obaket 1033: 再試行しない capabilityLimit を再試行する transport に変え、ファイル全体の取得を最大 5 回繰り返す退行。diff 精読でだけ見つかった。 一般則は survey-receiver-guards-before-passing-new-values.md の「逆向きも同じ」)
  • 大きい diff (目安 200 行超) は「変更マップ」をナビに 1 回で精読する: codex (read-only・luna・max) に 「ファイル × 変更意図 × リスク順の hunk ランキング + 各 hunk の機械的/判断の分類 (根拠つき)」を 作らせ、Claude はマップの順に diff を 1 回だけ読む (行き来と再読を消す — 精読を安くするのであって 減らすのではない: 全 hunk に目は通す)。斜め読みしてよいのは「機械的」と分類された hunk だけで、 そのうち最低 1 割は精読して分類を監査する。分類誤りを 1 件でも見つけたらマップを信用せず 全 hunk 精読に戻す。小さい diff はマップを作らず直接読む (前処理のオーバーヘッドが逆転する)。
  • 軽微な確定的問題 (typo・命名) は Claude が直接直してよい。設計に関わる修正は codex に戻す。

3.5. codex レビュー(主要リスクに合う1〜3観点・発見型)

[3] の build/test が green になったマイルストーンごとに自動で実行する (green の前に起動しない — [3] の順序の項)。実装した codex とは別プロセスの レビュアーとして、主要リスクに合う 1〜3 観点を選ぶ。複数なら重複を避けて並列で回す。 厚い運用は 3 観点。1 本で扱えない独立したリスクがあるときに観点を増やす。 ここは「問題を探す」発見型パスで、この後に [3.55] (裏取り) → [3.6] (壊す) → [3.7] (固定) → [3.8] (テストの検知力検証) が続く 5 段構え。

  • 観点はタスクごとに Claude が決める。複数本は観点を分ける (同じ観点で複数流さない)。選んだ観点を 一言明示してから起動する。分け方の例:
    • 汎用: A=バグ/リグレッション/データ破壊/並行不整合、B=仕様逸脱/spec 取り違え/境界条件、 C=テスト不足/検証可能性/その場しのぎ (症状パッチ・特例分岐・構造方針との乖離)
    • プロトコル/wire 実装: A=wire/spec 準拠 (バイト構造・エンディアン・節番号照合)、B=エラー処理/境界/異常系、 C=状態機械の遷移漏れ/順序依存
    • 大量移植/sweep: A=行レベルの取りこぼし・誤変換、B=命名/規約の一貫性・横断整合、C=移植元と挙動が変わった箇所
  • D2/D3 でモジュール/型の境界・責務分担を定義したタスクでは、選んだ観点のうち 1 本を「境界違反」に充てる (依存方向の逆転・レイヤー越境・D2 コントラクトで別モジュールに割った責務の漏れ出し・境界を跨いだ内部表現の 露出・触らない範囲と宣言した領域への波及)。[3] の Claude 精読もコントラクト照合をするが、 多数ファイル横断の依存方向・広域一貫性は codex の既知の弱点 ([0] の表) かつ diff 精読で追いにくいので、 レビュー側にも観点として明示的に持たせる。境界を定義していないタスク (機械的置換等) では充てなくてよい
  • 選んだ本数を background で起動する (複数なら並列)。出力は各々ユニークな別パスにし、ぶつけない。
# 起動は codex-fanout driver が既定 (mode=review の 3 行 manifest で 1 回起動 → digest を読む)。
# 以下は fallback の per-call 形。パスはリテラルで書く ($stamp は次の呼び出しに残らない)。
# stdout も保存する ($log 群は merger に全文読ませる)。詳細は「並列起動の作法」。
# --- 観点A (Bash 呼び出し 1・run_in_background)。観点B・C も同形で別呼び出し・別パス ---
out="<D>/<literal-stamp>.reviewA.md"; log="$out.log"
command codex exec review -m gpt-6.1-sol -c model_reasoning_effort="high" \
  --ephemeral -o "$out" </dev/null \
  "<観点A の指示。file:line・理由・最小修正案を。要約/称賛不要>" > "$log" 2>&1; tail -40 "$log"
  • command codex / </dev/null / --ephemeral -o / --full-auto 禁止は codex-review スキルが正本。
  • 全出力が揃ったら merger に digest 化させ (集約規約)、その digest を [3.55] の裏取りへ渡す。 Claude は digest + 裏取り結果で統合・検閲する (subagent-model-tiering.md)。生ログの原文へ跳ぶのは 採用する指摘と digest が曖昧な項目だけ。レビュー出力を無検閲で採用しない。
  • 採用した指摘の修正は blind fix にせず [2] に戻す (既存の反復ループに合流)。green を維持したまま [3.6] へ。

3.55. 指摘の裏取り(codex による検閲の前処理)

[3.5] / [3.6] が出した指摘リストを、採否判断の前に裏取り codex に前処理させる。従来は指摘の真偽確認が 丸ごと Claude の精読に乗っており、ここが本数を増やせない律速だった。裏取りを前置することで、Claude の検閲は 「指摘を一から検証する」から「構築済みの再現手順をなぞって確定する」に軽量化される。

  • 裏取り codex (read-only・gpt-6.1-sol・high) に指摘リストを渡し、各指摘について:
    • 再現手順を構築させる (どの入力・順序・環境で発火するか。可能なら最小の再現コード/コマンド)
    • 構築できなければ 「再現手順を構築できず未確認」と明記させる (「たぶん正しい」と書かせない)
    • 指摘同士の重複 (同一根本原因) をマージさせる
  • 採否の最終判断は Claude: 「再現手順つき」を優先精読し、手順を自分の環境で 1 回なぞって確定する (裏取り codex の「再現した」も主張であり証拠ではない — 大原則)。「手順未構築」判定は [3.6] の採否表の 「未確認」に残す。到達経路・契約違反をコードから確認できる場合は、その根拠も添えて採否する。
  • 指摘が 2 件以下なら裏取りを省略して Claude が直接検証してよい (前処理のオーバーヘッドが逆転する)。一言明示する。

3.6. 敵対的レビュー(red team・攻め口別に並列)

[3.5] の指摘対応が終わり build/test が green に戻った状態で回す。 [3.5] が「問題を探す」レビューなのに対し、ここは 「壊す」ことを目的とした反証パス。 実装者が codex である以上、発見型レビューだけでは「codex が自分の書いたコードを自分の基準で見る」構図が残るため、 明示的に敵対側に立たせるフェーズを分けて置く。

  • プロンプトは codex-review スキルの「敵対的モード」テンプレートが正本。ここでは再定義せず、そのまま使う (差分対象の選び方・実行作法も codex-review に従う。command codex / </dev/null / --ephemeral -o / --full-auto 禁止。 ただし出力先は本 skill の「出力の置き場」 (<D> の一意パス) に従う)。 1 本に全部の攻め口を投げず、攻め口 (lens) ごとに分けて並列で回す。「壊す条件を構築する」作業は攻め口ごとに 必要な思考が別物で、1 本に束ねると最初に見つけた 1 種類の周辺を掘って残りが浅くなる。[0] の「既知の弱点」表が そのまま lens になる。タスクに合うものを 既定 1〜2 本、厚い運用は 2〜4 本選び、選んだ lens を一言明示してから起動する:

  • 循環テスト: 追加されたテストは自作実装を自作テストで追認しているだけでないか。外部 test vector / 実サーバ / 別実装と照合されているか。落とせば「green だが実機で拒否される」を commit 前に捕まえられる

  • 捏造 API / 設定キー: 参照している API・設定キー・オプションが対象バージョンに実在するか

  • overclaim: サマリ・コメント・コミットメッセージの「対応済み」「保証される」を 1 件ずつ反証する

  • 別ターゲット: codex が動いた環境以外 (Linux / 別 toolchain / 別 OS バージョン) で壊れないか

  • 境界 / 並行 / 順序: 境界値・空・巨大入力・再送・二重実行・部分失敗・再起動で不変条件を破れるか

  • マイルストーン境界: 前マイルストーンとの結合部・移行中の中途半端な状態で壊れないか

  • 新規ファイルの欠落: 変更が新しいファイルを追加しているなら、「そのファイルが commit / checkout / patch に含まれなかったら何が起きるか」を攻めさせる。git diff には出ないので diff 精読では構造的に見えず、抜けると新規ファイルに依存する全経路が同時に死ぬ (実測 2026-09-08 swift-smbee 076: 共有 init を 1 ファイルへ抽出した変更で、 それが untracked のままだと 5 workflow + ローカル smoke の全 launcher が停止する、を lens が P1 で拾った)

  • 境界違反: D2 コントラクトの境界を破る経路を構築できるか — 依存方向を逆転させずにこの機能を拡張できない 箇所はないか / 別モジュールに割った責務がこの実装で漏れ出していて、次の変更が 2 箇所同時修正を強制されないか / 境界を跨いで内部表現 (型・生データ・状態) が露出していて、片側の変更が他方を黙って壊せないか

  • 目的達成の反証 (リファクタ・改善系で特に効く): その変更が守ると称する目的を、変更後もなお silent に破れる残り経路を列挙させる (例: 「将来 case 追加で壊れない」が目的なら、実際に case を 足す開発者を演じて素通りする箇所を挙げる。実測: obaket 635 round 3 で最多の実害を出した lens)

  • モデルと effort の既定は読む run の gpt-6.1-sol + high (モデル表)。 未確認の重要な不変条件が残れば、それを攻める lens・実験・外部 oracle を追加する。 「新規指摘ゼロ」だけで閉じず、下の完了条件で判断する。effort の比較はモデル表の手順による。

  • 各 lens は 別々の Bash 呼び出しで run_in_background: true・出力は別パス ([3.5] と同じ並列作法)。

  • [3.5] と同時に走らせない (3.5 の指摘を直した後のコードを攻めるため)。

  • manifest の各 lens 行に timeout 列 2400 を付ける (発見型レビューと違い、反証の構築は思考時間が 長く既定の 1200 秒で 時間切れ (当時の rc=143。今は 124) が頻発した — dotfiles issue 150 の実測。3〜4 回落ちて単発再実行では毎回完走)。 900 秒超なので起動は detach 形 (「並列起動の作法」の nohup + Monitor) にする。 🚨 codex-run で 1 本だけ起動するときも -t 2400 を明示する。codex-run は timeout を CODEX_FANOUT_TIMEOUT の既定 (1200 秒) から取るので、付け忘れると 20 分待ってから 時間切れ (rc=124) で 本文ゼロになる (実測 2026-09-15 obaket 820 の D3: 32,062 行のログだけが残り、-t 2400 で 再実行して 1,426 秒で完走した)。上の manifest の記述は codex-fanout の列の話なので、 1 本だけのときに落としやすい。

# 起動は codex-fanout driver が既定 (lens ごとの brief + review-lens-header.md を連結する manifest)。
# --- fallback の per-call 形: lens ごとに別 Bash 呼び出し・run_in_background。パスは round と lens で一意にする ---
out="<D>/<literal-stamp>.r<N>-adv-<lens>.md"; log="$out.log"
command codex exec review -m gpt-6.1-sol -c model_reasoning_effort="high" \
  --ephemeral -o "$out" </dev/null \
  "<codex-review「敵対的モード」テンプレート全文 + この lens の攻め口だけを指定>" > "$log" 2>&1; tail -40 "$log"

打ち止めは「工程の厚さと完了条件」で決める: 1 ラウンド後に重要な指摘・不変条件・未確認範囲を照合する。 採用指摘を修正した場合は、その修正と回帰を再レビューする。未解決の重要項目があるときは、 そこに合う別 lens・実験を選ぶ。「新規ゼロが 2 周」は探索の記録に残してよいが、閉じるための必須回数にはしない。

  • ラウンドごとに lens を入れ替える。同じ lens を繰り返すと同じ場所を掘り直すだけで枯れの判定にならない。
  • 「既出」の判定単位は文面ではなく「根本原因 + 発火条件 + 破れる不変条件」の組。 ラウンド台帳 (根本原因 / 発火条件 / 破れる不変条件 / 判定 / 解消したラウンド) と照合する。 台帳の更新ドラフトはラウンドの merger に作らせる (各指摘の新規/既出/格上げ判定つき。台帳ファイルの パスを渡して現行台帳と突き合わせさせる) — Claude は判定を検閲して確定・追記する (トークン経済 1)。 台帳は要件ファイル (<D>/design.<タスク名>.md) に追記して各ラウンドの統合検閲の直後に更新する (<D> の外に台帳を置かない)。解消した項目は行を消さず「解消 (round N)」と記す — 消すと次ラウンドで 同じものが「新規」に見える。行番号では同定しない (修正のたびにズレる)。 file:line や言い回しが変わっただけの同一原因は既出、 前ラウンドで「未確認リスク」だったものに具体的な発火条件が付いたら新規として数える (格上げは発見であり、 既出扱いで捨てると最も価値のある反証を落とす)。
  • 上限は 3 ラウンド。ここに達したら未解決項目があっても探索を打ち切る (完了とは扱わない)。残った反証・未確認リスクを 整理し、① マイルストーンの切り方か設計前提を疑って [6] / D2・D3 に戻す、② 残リスクを明示して ユーザーに判断を仰ぐ、のどちらかを選ぶ。4 ラウンド目は回さない (モグラ叩きにしない)。
  • 修正して [2] に戻ったときの再開地点: [3] (build/test + diff 精読) は毎回必ず通す。 [3.5] の発見型レビューは再実行しない (同じ観点を毎ラウンド流すのはトークンを使うだけで視点が増えない)。 例外は修正がマイルストーンの構造を変えたとき (新規ファイル・境界の引き直し) で、そのときだけ [3.5] に戻る。

採否の前に [3.55] の裏取りを通す (指摘 3 件以上のとき)。その上で codex-review「敵対的レビューの作法」の 仕分けに従う(敵対レビューほど無検閲採用が危険):

出力扱い
発火条件が具体的 → 再現またはコード・契約で裏取りできた修正対象。[2] に戻して構造的に直す (直したら次ラウンドで攻め直す)
発火条件が具体的 → 再現できない到達経路・契約違反をコードでも確認する。確定できなければ未確認、到達不能などの反証があれば根拠つきで却下
未確認リスク (発火条件を示せない)修正しない。残リスクとして報告 / issue 化し、[6] の観測ポイント候補にする
「起こりえないが念のため」提案原則採らない。その入力の出所を示せた時だけ採る
「壊せなかった」green の根拠にしない。重要な不変条件はテストで固定して初めて閉じる
  • 省略できるケース: 純粋に機械的な置換・rename だけで、判断ロジックも境界も動いていないマイルストーン。 省略したら「今回のマイルストーンは機械的置換のみのため 3.6 を省略した」と一言明示する (黙って飛ばさない)。

3.7. テスト強化(codex に「落とすテスト」を書かせる)

[3.6] の採用指摘を解消し、重要な不変条件の確認対象を整理した状態で、実装ではなくテストだけを書かせるフェーズを 1 本回す (この後 [3.8] で テストの検知力を機械検証してから commit する)。

[3.6] の採否表は「壊せなかった = green の根拠にしない。重要な不変条件はテストで固定して初めて閉じる」と している。その固定作業をやるのがここ。敵対的レビューは指摘を出して消えるが、テストはリポジトリに残って 次の変更でも同じ攻撃を自動で再実行する — 消費したトークンが恒久資産になる唯一のフェーズなので、 [3.6] を削ってでもここは通す価値がある。

  • 実装ファイルを触らせない。プロンプトで「テストファイル以外は変更禁止」と明示する。実装を直したくなる 発見があれば「テストを落とす形で示せ」と指示する (直すのは [2] の仕事)。 ただし sandbox mode は prompt の禁止を強制しない (danger-full-access なら何も止めない) ので、内容スナップショットで検出する。 [2] の実装差分は未コミットのまま (M path) なので、パス一覧の比較では実装への追加編集を検出できない (前後とも M path のまま)。前後の差分の中身を比べる:
# 起動前 (上の起動コマンドと同じ Bash 呼び出しで)
git diff > "<D>/<literal-stamp>.pre.patch"
git status --porcelain --untracked-files=all > "<D>/<literal-stamp>.pre.status"
# 終了後
git diff > "<D>/<literal-stamp>.post.patch"
git status --porcelain --untracked-files=all > "<D>/<literal-stamp>.post.status"
diff -u "<...>.pre.patch" "<...>.post.patch" | head -200   # ← [3.7] が実際に足した変更
diff -u "<...>.pre.status" "<...>.post.status"             # ← 新規ファイルの検出
  • テスト扱いの範囲を先に決めて宣言する (テストディレクトリ・命名規約・fixture・snapshot・golden・ テストヘルパー)。判断がつかないファイルは非テスト扱いにする (保守側に倒す)。
  • 非テストパスへの変更を見つけたら、まずそれが codex のものかを pre/post の中身で確認する。 [3.7] 実行中に並行セッションが触った可能性もあり、中身を見ずに checkout すると他人の作業を消す。
  • codex のものと確認できたら復元する: tracked なら git checkout -- <path> で HEAD に戻し、 pre.patch の当該パス分を git apply で再適用して起動前の状態に戻す (単に checkout すると [2] の実装まで消える)。untracked の新規実装ファイルは checkout では消せないので、内容を確認して 削除する。
  • 由来が判定できない変更は消さずに残し、ユーザーに報告する。指示違反のテストは採用しない。
  • 同じテスト要求で 2 ラウンド失敗したら Claude がテスト本体だけを書く。1 ラウンドは、同一要求を同一プロンプトで 1 回投げ、結果を検査するまで。これは [3.6] の探索ラウンドとは別のカウンタ (あちらは敵対レビューのラウンド、こちらはテスト生成のラウンド)。混ぜて数えない。失敗は「要求した観点が揃わない」「テスト自体がコンパイルできない」「偽 green (ミューテーションで落ちない)」だけを数える。追加テストが妥当で実装バグを見つけたため [2] に戻った回は、 テスト生成の成功なので数えない。テスト側の誤りを直させた回もカウントを進めない。これは、仕様・oracle・入力・ 対象ファイル範囲が事前に確定していて量が限られる場合に限る「重い実装を Claude が書かない」の例外であり、 fixture / helper / mock / production コードは Claude が書かない。条件が未確定、外部 vector が無い、または未確認リスクが 多い場合はテストを書かせず [6] か設計へ戻す。
  • 書かせる的: [3.6] で「反証できなかった」と報告された不変条件 / [D3] の失敗モード表で「吸収する」と 宣言した経路 / 境界値・異常系・再実行。 「未確認リスク」は的に含めない。発火条件が示せない項目にはテストの入力も oracle も無く、codex が 契約を創作した mock テストになる (そしてそれが落ちて「実装のバグ」と誤判定される)。未確認リスクは [6] の観測で契約が確定してから、改めてテストに昇格させる。
  • 循環テストを禁じる (codex の既知の弱点そのもの)。「自作実装を自作テストで追認するだけのテストは書くな。 外部 test vector・spec の例・別実装・実サーバの応答と照合できるものを優先しろ」と明示する。 照合先が無い領域は 性質 (property) で書かせるが、自作 encode を自作 decode で往復させる形は循環テスト そのものなので禁止する (正本の典型例)。往復を書いてよいのは片側が外部実装 / 外部 vector のときだけ。 自作同士で書けるのは、片側の実装に依存しない性質 — 冪等性・順序不変・境界での単調性・不変条件の保存など。
  • 成果物を機械判定可能に要求する。要約には grep -c '@Test' の実測値とテスト総数を貼らせる (実測ではこれを書いた回だけ本数が揃った)。ただしこれは要求本数の取りこぼし検出であって、検知力の証明ではない — parameterized test / 1 宣言に複数ケース / コメント内の文字列も数に入る。実装を落とせるかは [3.8] の ミューテーションで別に確認する。本数と検知力を同じ指標として扱わない。
  • effort は max (モデル表の書く run)。「実装を落とす入力」を組み立てるのは構築作業で、 effort を落とすと常に真になる assert や壊せないヘルパーが出やすい (実測)。 モデルは gpt-6-luna。テストを自分で回させるので実装と同じ -s danger-full-access (外せない環境は workspace-write)。
# 起動前スナップショット (上の pre.patch / pre.status) をこの呼び出しの冒頭で採る
out="<D>/<literal-stamp>.harden.md"; log="$out.log"
command codex exec -s danger-full-access -m gpt-6-luna -c model_reasoning_effort="max" \
  --ephemeral -o "$out" </dev/null "$(cat <<'EOF'
このマイルストーンの実装を「落とす」テストを書く。git 操作 (commit / pull / checkout / stash 等) はしない。

## 絶対の制約
- **テストファイル以外は変更しない**。実装のバグを見つけても直さず、それを落とすテストとして書く
- 自作実装を自作テストで追認するだけの循環テストを書かない (自作 encode を自作 decode で往復させる形を含む)。
  外部 test vector / spec の例 / 別実装 / 実サーバ応答との照合を優先し、照合先が無ければ片側の実装に
  依存しない性質 (冪等・順序不変・境界での単調性・不変条件の保存) で書く

## 狙う的
- <[3.6] で「反証できなかった」不変条件・失敗モード表の吸収経路・境界/異常系。
  発火条件を示せなかった「未確認リスク」は的に含めない>

## 出力
- 追加したテストと、それぞれが「何を破ろうとしているか」
- 実装のバグを示せた (= 落ちた) テストがあれば、それを最初に列挙する
EOF
)" > "$log" 2>&1; tail -40 "$log"
  • Claude が全テストを自分で実行する。落ちたテストが出たら、まずそのテストが正しいかを検閲する (期待値の根拠は spec / 外部 vector か codex の解釈か / 時刻・順序・環境に依存していないか / mock は本物の 契約と一致しているか)。テストが妥当で実装だけが落ちているときに限り実装のバグとして [2] に戻す。 テスト側が誤っていたら、そのテストを直すか捨てる — 正しい実装を誤ったテストに合わせない (「テストを緩めて通さない」は、妥当なテストを甘くするなという意味であって、誤ったテストを守れではない)。
  • 追加テストも検閲対象。「常に真になる assert」「実装をコピーしただけの期待値」「モックが本物の契約と ずれている」テストは、green を増やすだけで何も守らないので落とす (refuse-low-value-coverage.md の判断軸)。 加えて ハング (無限待ち・タイムアウト無しのネットワーク待ち)・破壊的 teardown (共有リソースの削除)・ 環境依存 (実機/GUI/時刻/ロケール) を持ち込んでいないか見る。CI を壊すのはたいていこの 3 つ。
  • [3.7] がテスト差分を新たに足した以上、その差分は敵対レビューを通っていない。テストを追加したら [3.6] を 1 ラウンドだけ、追加テスト差分に絞って回す (lens はテスト品質 = 循環テスト・偽 green・環境依存)。追加テストがゼロなら追い撃ちも不要。
  • 追い撃ちの対象差分は「pre.patch と post.patch の差」。codex exec review は差分の選び方を自分で決めるため 「追加テストだけ」を渡せない ([2] で既に触ったテストファイルは以前の hunk が混ざる)。追い撃ちは codex exec -s read-only にし、上で保存した pre/post の差 (= [3.7] が足した hunk) を プロンプトに貼って対象を固定する。
  • 追い撃ちで実装のバグが出たら [2] に戻る。戻った後は [3] → [3.7] 再実行 → 追い撃ち、と巡回するが、 この巡回は最大 2 巡。2 巡しても新しい実装バグが出続けるなら、マイルストーンの切り方か設計前提を疑って [6] / D2・D3 に戻す (通常 [3.6] の 3 ラウンド上限とは別枠で数える)。
  • 省略できるケース: [3.6] を省略できるマイルストーン (機械的置換・rename のみ) と、 既存テストが受け入れ条件を完全に機械判定していて追加の的が無いとき。省略したら一言明示する。

3.8. ミューテーション検証(テストの検知力を機械確認・commit 直前の最終ゲート)

[3.7] で足したテスト (と既存テスト) が本当に実装の破壊を検知できるかを機械検証してから commit する。 「テストが green」は「テストに検知力がある」の証明にならない — 陽性対照なしの assert・空振りの検証は 書いた直後の自分でも見逃す (起源: 2026-07-30 の bench/fzf テストで「除外 assert が元データ不足で空振り」を セルフレビューで検出した実例。人手のセルフレビューを機械化したのがこのフェーズ)。

  • 使い捨て worktree で行う (git worktree add <path> HEAD + 未コミット実装を patch で持ち込む)。 本流でミューテーションしない: 変異の復元に git checkout を使うと未コミットの実装/修正ごと巻き戻す (2026-07-29 に実際に起きた事故。worktree なら丸ごと捨てられるので復元事故が構造的に消える)。 worktree に patch を持ち込んだら baseline commit を作ってから注入させる。持ち込んだ直後の worktree でも patch は未コミットなので、codex の git checkout -- . 復元が seam ごと消してテストがコンパイル不能になる (obaket 696 項目 4)。
  • codex に注入から実行ループまで回させる (-s danger-full-access・-C <worktree>・gpt-6-luna・max — 機械作業。トークン経済 3)。🚨 例外: sandbox を外せない環境で、その repo の swift test が sandbox で走らないと 1 度分かったら、以降のマイルストーンでは実行ループを codex に回さない。変異 patch の生成だけ codex read-only に 作らせ、適用 → テスト実行 → 復元は最初から Claude のハーネスで当てる (obaket 650 M1: max effort で 15〜40 分の ループが typecheck だけで「全成功」を返し、Claude が全部当て直した。回させた分は丸ごと無駄。issue 369 1-1。 Claude 側の作業は増えるが、判定はどちらでも Claude の実行結果なので質は変わらない)。プロンプト: 「このマイルストーンの実装に、現実的なバグを 3〜5 個、1 個ずつ独立の patch として作れ (境界の off-by-one・条件の反転・エラー処理の握りつぶし・early return の欠落など、 レビューで見逃しやすい類)。各 patch は git diff 形式で別ファイルに保存し、1 個ずつ適用 → テスト実行 → git checkout -- . で復元を繰り返せ。テストファイルは触らない。出力は変異ごとの結果表: patch ファイルパス / 変異の内容 1 行 / テストの生の終了コード / 落ちたテスト名 (検知漏れなら「検知されず」)」
    • 🚨 patch は既定の context 付き (git diff、-U3) で保存させる。-U0 / context 無しを使わせない。 context の無いハンクは git apply が照合できず、再適用すると意図しない位置に落ちる (実測 2026-09-15 obaket 809: @@ -1080,0 +1080,5 @@ の挿入がファイル末尾の top level に入り statements are not allowed at the top level でビルド不能になった)。codex 自身は context 照合の apply_patch で当てるのでその run では正しい位置に入り、保存された成果物からだけ再現できない。 抜き取り追試が空振りするだけでなく、後から「codex が何を検証したのか」を誰も確認できなくなる
  • Claude は結果表を監査する (codex の自己申告は主張であって証拠ではない — 大原則):
    • 変異の質を patch ファイルで一瞥する: コンパイルが通らない変異・実装と無関係な変異は検知できて当然なので数に入れない
    • 抜き取り 1 件を自分で追試する: 表から 1 変異 (「検知された」と報告されたもの) を選び、worktree で 適用 → テスト実行し、表と結果が一致するか照合する。不一致なら表全体を信用せず Claude が全変異を回し直す
    • 全変異が検知された (+ 抜き取り一致) → 検知力が確認できた。worktree を削除して [4] へ
    • 検知漏れがあった → その変異は「テストの穴」の実物。[3.7] に的として差し戻し (「この patch を落とすテストを書け」— 的が具体的なので循環テストになりにくい)。テスト追加後に漏れた変異だけ再検証
  • 省略できるケース: [3.7] を省略したマイルストーン (追加テストなし + 既存テストで受け入れ条件を完全機械判定)。 省略したら一言明示する。worktree は成否に関わらず必ず削除する。 後始末に stale な swiftpm-testing-helper の確認を含める: codex の swift test --disable-sandbox や worktree での mutation 実行が helper プロセスを残す (obaket 674 項目 6: 5 個以上残留。無害だがリソースを食う)。pgrep -fl swiftpm-testing-helper で確認し、 自分が起動した scratch / worktree の path を持つものだけ kill する (他セッションの実行中 helper を巻き込まない)。 🚨 timeout N swift test で打ち切った run は、子の helper が必ず孤児になる (timeout は親しか殺さない)。変異ループの 各 run の直後に helper を刈る (実測 2026-09-05: 5 時間超の孤児 3 本が残った)
  • 変異の結果は red / green / hang の 3 値。hang (timeout で rc=124) は「検知できなかった」ではなく 「テストが停止を失敗にできない」という別の穴。原因は大抵 2 つ: suite に .timeLimit が無い / await task.value が 外側の cancel に反応しない (unstructured Task の値待ちは time limit でも中断されない → cancel を転送する helper を通す)。 fake clock の「条件が来るまで待つ」observer も cancellation-aware にしておく。実測 2026-09-05 M1: 最初の hang は time limit を付けても抜けず、この 2 点を直してから初めて red になった
  • 🚨 swift build が「Another instance of SwiftPM is already running ... waiting」を出したら待たない。lock を握って いるのは大抵 read-only codex が sandbox で試した swift test --skip-build (hang する) か、前の変異 run の孤児。 ps -axo pid,etime,command | grep swift で見て kill する。実測 2026-09-05: 気づくまで 2 時間 53 分待った

4. commit & push(Claude)

  • 自分が触った差分のみ git add <path> (commit-policy)。並行する他作業/WIP を巻き込まない。
  • 1 マイルストーン = 1 commit を基本に。commit message に「codex 実装 + main agent 検証」と何をやったかを書く。
  • 🚨 [S] / [D1]〜[D3] で受け入れ条件が変わったら、設計ファイルだけでなく issue 本文にも移す。 設計ファイルは <D> にあり gitignore されるのでcommit されず、make clean-tmp で消え、別マシンには無い。issue に移し忘れると、 完了時のチェックリストが起票時の (古い) 条件だけになり、敵対レビューが足した条件が 誰にも検証されないまま done になる (実測 2026-09-07 obaket 740: D3 が足した 5 条件を設計ファイルに だけ書き、done へ移す直前に気づいて移した)。移すのは条件そのものと、それが足された理由 1 行 (move-report-conclusions-to-issues.md)。
  • 🚨 codex に issue へ記録させたら、commit 前に grep -n 'tmp/' <issue> で gitignore 配下への参照が無いか見る。codex は生出力のパスをそのまま markdown リンクで書く。手元には実体があるのでリンク検査は通り、新品チェックアウトと CI でだけ落ちる (実測 2026-09-15 obaket 809: tmp/809/mutations.md へのリンクが check-doc-links を素通りしていた)。見つけたら中身を issue 本文へ転記してリンクを外す (パスを tracked へ移すのではない — 同じものが 2 箇所になる)。 地の文での言及 (「原文は tmp/… にある」) はリンクではないので残してよい。
  • push は必要時のみ (CI で実地検証したい時など)。push 可否ルールは各リポジトリに従う。
  • submodule なら commit 後に即 push し親参照を bump (submodule-workflow)。

5. 実地検証(任意・該当時)

  • ユニットで担保できない部分 (実通信・実機・統合) は、実行 / CI / 実機で動かす。
  • 例: CI E2E を push でトリガし gh run watch <id> --exit-status で結果を待つ。GUI/実機など自走確認が難しい検証は スクショ・ログ・人間確認を受け入れ条件に含める。

6. 観測 → 次の指示(blind fix 禁止)

  • 失敗したら 2 発目の blind fix を打たない (instrument-before-second-fix.md)。
  • まず 観測を増やす: ログ/hex dump/実 status/成功経路との差分。「何が見えていないか」を可視化する診断を (Claude が小さく入れるか codex に入れさせて) 仕込み、実行/CI で事実を取る。
  • 取れた事実 (実 status・実バイト・差分) を codex への次の的確な指示に翻訳して [2] に戻る。
  • 観測が「設計前提の誤り」を示したら [2] に戻らず D2/D3 へ戻る: 実装の直しで吸収せず、設計を修正して 多角レビュー + ユーザー再承認を取り直し、保存済み設計ファイル (<D>/design.<タスク名>.md) を更新してから 実装に戻る。承認ゲートは初回限りではなく、設計が変わるたびに通す (黙って設計を変質させない)。
  • これにより、CI/実機でしか再現しない移植・プロトコル・wire バグを 1 往復 1 バグで確実に収束させる。

7. 要件照合(Claude・丸投げの出口)

  • 全マイルストーン完了後、[R] の要件リストを 1 件ずつ成果物 (コード・テスト・実地検証結果) と突き合わせる。 マイルストーン green の総和 ≠ 全要件充足 ([1] の分割時に落ちた要件はここでしか捕まらない)。
  • 照合も敵対的にやる: 各要件について「充足した」と言い切る前に、その主張を崩す問いを 1 つ当てる ——「この要件が満たされていないとしたら、どのケースか?」「充足の証拠は実行結果か、それとも codex の申告か?」。 受け入れ条件を満たす証拠 (テスト・実行ログ・CI・実機) を示せない要件は **充足ではなく「未検証」**に落とす。
  • 未充足・部分充足・未検証・意図的にスコープ外にした項目を明示して報告する (黙って「完了」にしない)。 未充足が残るなら [1] に戻して追加マイルストーンを切るか、ユーザーに判断を仰ぐ。
  • codex 敵対照合 1 本を必須で先行させる (read-only・sol-high)。「充足を確認して」ではなく **「未充足の要件を探して。充足の主張を反証して。証拠 (テスト・実行ログ・CI) の無い『充足』を列挙して」**と 敵対側で投げる (肯定形で聞くと追認が返ってくる)。その出力を材料に Claude が要件ごとの最終判定を行う (v2.0.0 で任意→必須化。照合は本 skill の出口ゲートで、ここの見落としだけは後工程が無い)。 例外は D1 節の「小タスク軽量パス」だけ: 要件が数個で証拠が CI ログ / テスト結果に機械的に現れるときは Claude 単独の照合でよい (codex は run の文脈 (cold/warm 等) を持たず、証拠の読み違いを Claude が 再判定する往復が増えるだけだった。2026-08-28 実測)。それ以外の通常パスでは必須のまま。
  • 照合が済んで報告したら要件ファイル (<D>/design.<タスク名>.md) を削除してよい (ユーザーが「残して」と明示したら残す)。

codex-lead / forge との使い分け

skill主役使う場面
codex-drive (本 skill)codex が設計壁打ち + 実装、Claude が検閲/観測/反復と承認ゲート運営コード量が多い実装・移植・プロトコル実装。codex トークンを積極消費し、Claude トークンは digest 検閲 + ファイル参照で節約
codex-leadcodex が設計リード、Claude が実装設計は codex に任せつつ実装の主役は Claude にしたい時
forge専門家エージェント並行 + クロスレビュー高品質・多視点が要る実装/レビュー。バグ修正の自前試行が 1-2 回失敗した escalation 先
codex-review / cross-reviewレビューのみコードは変えない

やること / やらないこと

  • ✓ 並列起動は codex-fanout -J driver (manifest + 1 回の background 起動) に畳み、Claude は digest 1 枚 + 出典 spot check で検閲する (driver の exit 2 = 観点が欠けた digest。成功扱いしない)
  • ✓ 並列フェーズ (3 本以上) の出力は merger codex で 1 枚の digest に集約する (merger には保存ログのファイルパス群を渡して全文を読ませ、全数勘定 — 落とした件数と理由 — を必須にする)
  • ✓ 設計・spec・要件は貼らずにファイルパス + セクション名で codex に読ませ、定型は templates/ との連結で組む (Claude の出力を長文 heredoc に使わない)
  • ✓ 大きい diff は codex の変更マップをナビに全 hunk を 1 回で精読し、機械的分類の hunk も最低 1 割は精読して分類を監査する (分類誤り 1 件で全 hunk 精読に戻す)
  • ✓ [3.8] の変異適用×テスト実行ループは codex に回させ、Claude は結果表 + 抜き取り 1 件の追試で監査する
  • ✓ 変異 patch は既定の context 付き (git diff、-U3) で保存させる (-U0 は再適用すると別の位置に落ちる)
  • ✓ codex-run で敵対レビューを 1 本だけ回すときも -t 2400 を明示する (既定は 1200 秒で 時間切れ (rc=124) になる)
  • ✓ codex に issue へ記録させたら、commit 前に grep -n 'tmp/' <issue> で gitignore 配下へのリンクを潰す
  • ✓ 着手前に codex 適性を評価し、苦手領域 (UI/実機/主観判断) なら一度ユーザーに確認する
  • ✓ 丸投げ依頼は [R] で「要件 + 受け入れ条件」に言語化してから着手し、[7] でそのリストと照合して締める
  • ✓ [R] で「長期運用か最小変更か」の構造投資水準を確定し、D1〜[3] まで同じ水準で通す (拡張性は境界と不変条件で買い、先回りの抽象では買わない)
  • ✓ 設計自由度のあるタスクは D1〜D3 の壁打ちから始め、ユーザー承認ゲートを経てから実装に入る (自由度が低ければ軽量パス + 敵対 1 本を明示)
  • ✓ 差分 50 行以下・受け入れ条件が機械判定・真因確定済みの小タスクは「小タスク軽量パス」を明示して、設計と [7] の codex を省き、D3 と [3.6] の敵対だけ残す
  • ✓ spec/プロトコル系は [S] で読解を多重化し、要件ごとに原典を付ける。相違点と重要要件は一致していても原典で確認する
  • ✓ 設計案出し [D1] は独立 2 本 (厚い運用は 4 本) に 1 案ずつ作らせ (他案の存在を伝えない)、[D1.5] のクロス批評を経て Claude が統合する
  • ✓ 方針が割れうる + 受け入れ条件を機械判定できるマイルストーンは既定で [2p] 競作する (別 worktree・同一プロンプト・勝敗後に worktree 削除)
  • ✓ 設計多角レビューには Claude 視点を必ず 1 本混ぜ、codex 2 本のうち 1 本は敵対観点 (設計を破綻させるシナリオ) に固定する
  • ✓ [3.6] は攻め口 (lens) 別に並列で回し、重要な指摘・不変条件・未確認範囲を照合して打ち止める (ラウンドごとに lens を入れ替える)
  • ✓ 指摘が 3 件以上なら [3.55] で裏取り codex に再現手順を構築させ、Claude は手順をなぞって採否を確定する
  • ✓ commit 直前に [3.8] で使い捨て worktree にバグを注入し、テストが検知するかを機械確認する (検知漏れは [3.7] の的)
  • ✓ commit 直前に [3.7] で「実装を触らずに落とすテスト」を書かせる。落ちたテストはまずテスト自体を検閲し、 テストが妥当で実装だけが落ちているときに [2] に戻す (テスト側の誤りなら直すか捨てる)
  • ✓ codex に実装の主役を任せ、Claude は検証・観測・commit・反復に徹する
  • ✓ 1 マイルストーンに絞り、受け入れ条件 (検証方法) を先に決める
  • ✓ codex 出力は必ず build/test/diff で検閲してから commit
  • ✓ マイルストーン green 直後に codex に主要リスクに合う 1〜3 観点でレビューさせ、Claude が統合検閲してから commit
  • ✓ D2/D3 で境界・責務分担を定義したタスクは、[3.5] の 1 観点 (と必要なら [3.6] の lens) を「境界違反」に充てる
  • ✓ 失敗時は観測を増やしてから次の指示を出す (blind fix しない)
  • ✗ codex に git commit させる / 無検閲で commit する
  • ✗ 承認ゲートを飛ばして実装に入る / 設計レビューを codex だけで閉じる / 再承認なしに設計を変質させる
  • ✗ 観点を直交させず同じ観点で複数本流す / 1 つのシェルに並べて直列実行する / レビュー出力を無検閲で採用する
  • ✗ 敵対レビューの「指摘なし」を安全の証明として扱う / 発火条件を示せない反証に防御コードを足す (未確認リスクとして残す)
  • ✗ [3.6] / [3.7] / [3.8] を黙って省略する / [3.6] を [3.5] と同時に走らせる (3.5 の修正後のコードを攻める)
  • ✗ 本流の working tree でミューテーションする ([3.8] は worktree。checkout 復元が未コミット修正を巻き戻した実事故あり)
  • ✗ 裏取り codex の「再現した」を自分でなぞらずに採用する (裏取りも主張であり証拠ではない)
  • ✗ commit ゲートの build/test/diff 精読・採用指摘の裏取りなぞり・設計承認の Claude 視点を digest で代替する (節約は検閲の入力の形まで。検閲そのものを削らない)
  • ✗ 集約を挟まず 3 本以上の生出力を全文精読する (Claude トークンの浪費。ユーザーが「品質全開で」と明示したときだけ v2 運用に戻す)
  • ✗ 敵対レビューを 1 ラウンドで打ち止める / 既出の指摘を「新規反証」に数える / 4 ラウンド以上モグラ叩きを続ける
  • ✗ [3.7] でテストを緩めて通す / 循環テスト (自作実装を自作テストで追認) を採用する / 実装ファイルの変更をそのまま採用する
  • ✗ 落ちたテストを、テスト自体 (期待値の根拠・環境依存・mock 契約) を検閲せずに「実装のバグ」と確定する
  • ✗ 競作を同一 working tree で走らせる / 2 本に別々の仕様を渡す / 勝敗後に worktree とブランチを残す
  • ✗ 並列フェーズで $stamp 等のシェル変数を後続の Bash 呼び出しに持ち越す (空文字に化ける。リテラルで書く)
  • ✗ codex exec review の stdout を保存せず tail の表示だけで「指摘なし」を判断する (本文が -o に出ないことがある。merger に tail や抜粋だけ渡すのも同罪)
  • ✗ digest + spot check でも精読しきれない本数の codex を並列で走らせる (律速は digest 精読。本数を増やして検閲を薄めない)
  • ✗ codex の「実装済み」「検証済み」を裏取りなしに green の根拠に数える
  • ✗ 重い実装を Claude が自分で書く (trivial な確定修正は例外)
  • ✗ 「全部まとめて」を 1 回の codex 実行に投げる
  • ✗ 要件を暗黙解釈のまま D1 に入る / マイルストーン green の総和を全要件充足と見なして [7] を飛ばす
  • ✗ 判断なしに小手先の症状パッチで凌ぐ / 逆に、最小変更でよいタスクに今使わない抽象・機構を足す

関連

  • ~/dotfiles/bin/codex-fanout — 並列起動 driver の実体 (manifest 形式・exit code・出力レイアウトの正本は冒頭 usage)。テンプレートは本 skill の templates/ (merger.md / review-lens-header.md)
  • ~/.claude/skills/codex-review/SKILL.md — command codex / </dev/null / --full-auto 禁止などコマンド作法の正本。敵対的レビュー ([3.6] / D3 の敵対観点) のテンプレートと指摘採否ルールもここが正本。検証フェーズのレビュー委譲先
  • ~/.claude/skills/codex-lead/SKILL.md — 設計は codex・実装は Claude の分担 (本 skill は設計も実装も codex)。D2 の設計コントラクト形式の正本 (1-5)
  • ~/dotfiles/_claude/rules/subagent-model-tiering.md — 下位主体の出力は main が必ず検閲
  • ~/dotfiles/_claude/rules/instrument-before-second-fix.md — 観測駆動デバッグ (本 skill の [6] の正本)
  • ~/dotfiles/_claude/rules/escalate-to-forge-after-failed-tries.md — 収束しない時の escalation

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

audit

Free

プロジェクト監査。「監査して」「audit」「/audit」で発火。設計/UX/品質/テストなどの観点でコードベース全体を監査し、課題をissuesディレクトリに書き出す。実行ログで重複実行を防止。特定の差分・コミットのレビューには使わない(codex-review / cross-review を使う)。

The English summary is being prepared. Showing the original description.

jiikko/dotfiles2Updated Oct 19, 2026

AVFoundation (AVPlayer / AVPlayerLayer / AVPlayerItemVideoOutput / AVAsset) の落とし穴・文書化されていない実装挙動・debugging チェックリストを集約した reference skill。Swift / Objective-C で AVPlayer を使った動画再生 / seek / scrub / frame stepping を実装・debug するときに発火。VLCKit ではなく **AVFoundation 系** の問題に特化。

The English summary is being prepared. Showing the original description.

jiikko/dotfiles2Updated Oct 19, 2026

c

Free

このセッションで行った変更をコミットする。「コミットして」「commit」「/c」で発火。push はしない/クレデンシャルは混入させない。

The English summary is being prepared. Showing the original description.

jiikko/dotfiles2Updated Oct 19, 2026

ディレクトリ・レイヤーごとに置いた CLAUDE.md と README.md が実体 (コード・コマンド・構成) とずれていないかを点検し、裏の取れた乖離だけを直す。引数で対象のディレクトリを任意に指定できる (省略時は repo 全体)。「CLAUDE.md を refresh して」「README が古くないか見て」「claude-md-refresh」「/claude-md-refresh」で発火。issues/ の更新漏れは issue-writeback / issue-sync の担当で、この skill は扱わない。

The English summary is being prepared. Showing the original description.

jiikko/dotfiles2Updated Oct 19, 2026

タスク着手時に codex にリードしてもらうワークフロー。codex に設計/方針を主導(リード)させ、その方針に沿って Claude が実装し、実装後は codex で設計適合・実装正当性・敵対的(red team)の 3 観点でレビューする。余っている codex トークンを積極的に消費したい時に使う。「codexにリードしてもらって」「設計から codex に任せて」「タスクを codex 主導で」「codex-lead」「/codex-lead」で発火。

The English summary is being prepared. Showing the original description.

jiikko/dotfiles2Updated Oct 19, 2026

codex exec review を基本に、必要なら codex exec を使ってコード変更のレビューを依頼し、指摘事項を報告する。通常 / 厳しめ (--strict) / 敵対的 (--adversarial、実装を壊しにいく red team) の 3 モードを持つ。「codexでレビューして」「codex-review」「/codex-review」「敵対的にレビューして」で発火。Codex 単体での単独レビュー用途。複数エージェント並行レビューは cross-review、差分ではなくコードベース全体の監査は audit を使う。

The English summary is being prepared. Showing the original description.

jiikko/dotfiles2Updated Oct 19, 2026

See all skills by jiikko

Report a problem with this skill