From cfcf840d8e6316d4ebbb82f1028927cfd24ffa23 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 8 Aug 2026 02:53:11 +0000 Subject: [PATCH 1/4] =?UTF-8?q?chore:=20feature/inventory-codex-conformanc?= =?UTF-8?q?e=20=E3=81=AE=20Draft=20PR=20=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From f775568be15762d00d410b1e6060dfdfc7ccbc0d Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 8 Aug 2026 04:17:00 +0000 Subject: [PATCH 2/4] =?UTF-8?q?Feat:=20Codex=20=E9=85=8D=E5=B8=83=E7=89=A9?= =?UTF-8?q?=E3=81=B8=E6=9A=97=E9=BB=99=E8=B5=B7=E5=8B=95=E3=82=92=E6=8A=91?= =?UTF-8?q?=E6=AD=A2=E3=81=99=E3=82=8B=20openai.yaml=20=E3=82=92=E7=94=9F?= =?UTF-8?q?=E6=88=90=20(0-8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex は Skill ごとの `/agents/openai.yaml` の `policy.allow_implicit_invocation` で暗黙起動を制御する。配布物に このファイルがなく、`deploy` を含む全 Skill が暗黙起動できる状態だった。 `scripts/build-runtime-plugins.sh` に `write_codex_skill_policies` を追加し、 共有 Skill の frontmatter に `disable-model-invocation: true` を持つものだけへ `agents/openai.yaml` を生成する。`argument-hint` を持つ場合は `interface.default_prompt` へ対応付ける。 生成は Codex 配布物の同期処理内(`sync_skills` の codex-runtime 分岐)で 一時ディレクトリに対して行うため、対象から外れた Skill の生成物は 配布ディレクトリごと差し替えられて残らない。`--check` でも差異を検出できる。 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01AGejnYyYFuSkQjBhW2KQNy --- .../skills/cherry-pick-pr/agents/openai.yaml | 4 ++ .../ndf-codex/skills/clean/agents/openai.yaml | 2 + .../skills/deploy/agents/openai.yaml | 4 ++ .../skills/merged/agents/openai.yaml | 4 ++ .../skills/pr-tests/agents/openai.yaml | 4 ++ .../ndf-codex/skills/pr/agents/openai.yaml | 4 ++ .../skills/review/agents/openai.yaml | 4 ++ .../skills/sync-main/agents/openai.yaml | 2 + scripts/build-runtime-plugins.sh | 62 +++++++++++++++++++ 9 files changed, 90 insertions(+) create mode 100644 plugins/ndf-codex/skills/cherry-pick-pr/agents/openai.yaml create mode 100644 plugins/ndf-codex/skills/clean/agents/openai.yaml create mode 100644 plugins/ndf-codex/skills/deploy/agents/openai.yaml create mode 100644 plugins/ndf-codex/skills/merged/agents/openai.yaml create mode 100644 plugins/ndf-codex/skills/pr-tests/agents/openai.yaml create mode 100644 plugins/ndf-codex/skills/pr/agents/openai.yaml create mode 100644 plugins/ndf-codex/skills/review/agents/openai.yaml create mode 100644 plugins/ndf-codex/skills/sync-main/agents/openai.yaml diff --git a/plugins/ndf-codex/skills/cherry-pick-pr/agents/openai.yaml b/plugins/ndf-codex/skills/cherry-pick-pr/agents/openai.yaml new file mode 100644 index 00000000..31590300 --- /dev/null +++ b/plugins/ndf-codex/skills/cherry-pick-pr/agents/openai.yaml @@ -0,0 +1,4 @@ +policy: + allow_implicit_invocation: false +interface: + default_prompt: " (例: qa/staging, release/v2)" diff --git a/plugins/ndf-codex/skills/clean/agents/openai.yaml b/plugins/ndf-codex/skills/clean/agents/openai.yaml new file mode 100644 index 00000000..5b1f887a --- /dev/null +++ b/plugins/ndf-codex/skills/clean/agents/openai.yaml @@ -0,0 +1,2 @@ +policy: + allow_implicit_invocation: false diff --git a/plugins/ndf-codex/skills/deploy/agents/openai.yaml b/plugins/ndf-codex/skills/deploy/agents/openai.yaml new file mode 100644 index 00000000..68c5828d --- /dev/null +++ b/plugins/ndf-codex/skills/deploy/agents/openai.yaml @@ -0,0 +1,4 @@ +policy: + allow_implicit_invocation: false +interface: + default_prompt: " (例: qa/staging, release/v2)" diff --git a/plugins/ndf-codex/skills/merged/agents/openai.yaml b/plugins/ndf-codex/skills/merged/agents/openai.yaml new file mode 100644 index 00000000..35f2e747 --- /dev/null +++ b/plugins/ndf-codex/skills/merged/agents/openai.yaml @@ -0,0 +1,4 @@ +policy: + allow_implicit_invocation: false +interface: + default_prompt: "[PR番号]" diff --git a/plugins/ndf-codex/skills/pr-tests/agents/openai.yaml b/plugins/ndf-codex/skills/pr-tests/agents/openai.yaml new file mode 100644 index 00000000..35f2e747 --- /dev/null +++ b/plugins/ndf-codex/skills/pr-tests/agents/openai.yaml @@ -0,0 +1,4 @@ +policy: + allow_implicit_invocation: false +interface: + default_prompt: "[PR番号]" diff --git a/plugins/ndf-codex/skills/pr/agents/openai.yaml b/plugins/ndf-codex/skills/pr/agents/openai.yaml new file mode 100644 index 00000000..ce8499a5 --- /dev/null +++ b/plugins/ndf-codex/skills/pr/agents/openai.yaml @@ -0,0 +1,4 @@ +policy: + allow_implicit_invocation: false +interface: + default_prompt: "[--draft] [base-branch] or [commit-message]" diff --git a/plugins/ndf-codex/skills/review/agents/openai.yaml b/plugins/ndf-codex/skills/review/agents/openai.yaml new file mode 100644 index 00000000..22e2c991 --- /dev/null +++ b/plugins/ndf-codex/skills/review/agents/openai.yaml @@ -0,0 +1,4 @@ +policy: + allow_implicit_invocation: false +interface: + default_prompt: "[PR番号 | --branch] [AIエージェント(codex|gemini)] [--focus AREA]" diff --git a/plugins/ndf-codex/skills/sync-main/agents/openai.yaml b/plugins/ndf-codex/skills/sync-main/agents/openai.yaml new file mode 100644 index 00000000..5b1f887a --- /dev/null +++ b/plugins/ndf-codex/skills/sync-main/agents/openai.yaml @@ -0,0 +1,2 @@ +policy: + allow_implicit_invocation: false diff --git a/scripts/build-runtime-plugins.sh b/scripts/build-runtime-plugins.sh index b3c895eb..f4c7ff8b 100755 --- a/scripts/build-runtime-plugins.sh +++ b/scripts/build-runtime-plugins.sh @@ -99,6 +99,67 @@ rewrite_codex_skill_paths() { done } +# Codex は Skill ごとの `/agents/openai.yaml` で暗黙起動を制御する。 +# SKILL.md の frontmatter を読み、`disable-model-invocation: true` を持つ Skill だけへ生成する。 +write_codex_skill_policies() { + local skills_dir="$1" + + python3 - "$skills_dir" <<'PY' +import sys +from pathlib import Path + +skills_dir = Path(sys.argv[1]) + + +def parse_frontmatter(text: str) -> dict[str, str]: + lines = text.splitlines() + if not lines or lines[0].strip() != "---": + return {} + fields: dict[str, str] = {} + for line in lines[1:]: + if line.strip() == "---": + break + # ネストした値(allowed-tools のリストなど)はここでは扱わない + if not line or line[0].isspace() or ":" not in line: + continue + key, _, value = line.partition(":") + value = value.strip() + if len(value) >= 2 and value[0] == value[-1] and value[0] in "\"'": + value = value[1:-1] + fields[key.strip()] = value + return fields + + +def yaml_double_quoted(value: str) -> str: + return '"' + value.replace("\\", "\\\\").replace('"', '\\"') + '"' + + +for skill_dir in sorted(p for p in skills_dir.iterdir() if p.is_dir()): + skill_md = skill_dir / "SKILL.md" + if not skill_md.is_file(): + continue + + agents_dir = skill_dir / "agents" + policy_path = agents_dir / "openai.yaml" + # 前回の生成物を必ず捨ててから作り直す(対象から外れた Skill に残さない) + policy_path.unlink(missing_ok=True) + + fields = parse_frontmatter(skill_md.read_text(encoding="utf-8")) + if fields.get("disable-model-invocation") != "true": + if agents_dir.is_dir() and not any(agents_dir.iterdir()): + agents_dir.rmdir() + continue + + lines = ["policy:", " allow_implicit_invocation: false"] + argument_hint = fields.get("argument-hint") + if argument_hint: + lines += ["interface:", f" default_prompt: {yaml_double_quoted(argument_hint)}"] + + agents_dir.mkdir(parents=True, exist_ok=True) + policy_path.write_text("\n".join(lines) + "\n", encoding="utf-8") +PY +} + rewrite_kiro_skill_paths() { local skills_dir="$1" local file @@ -175,6 +236,7 @@ sync_skills() { if [ "$variant" = codex-runtime ]; then rewrite_codex_skill_paths "$tmp_dir" skills + write_codex_skill_policies "$tmp_dir" elif [ "$variant" = kiro-runtime ]; then rewrite_kiro_skill_paths "$tmp_dir" fi From a7d4dd15be69d4ca34ebc24d5102cd6994e9eead Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 8 Aug 2026 04:49:31 +0000 Subject: [PATCH 3/4] =?UTF-8?q?Docs:=20Codex=20=E3=81=AE=E6=9A=97=E9=BB=99?= =?UTF-8?q?=E8=B5=B7=E5=8B=95=E6=8A=91=E6=AD=A2=E3=81=AB=E3=82=88=E3=82=8B?= =?UTF-8?q?=E5=88=A9=E7=94=A8=E8=80=85=E3=81=B8=E3=81=AE=E5=BD=B1=E9=9F=BF?= =?UTF-8?q?=E3=81=A8=E8=B5=B7=E5=8B=95=E6=96=B9=E6=B3=95=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `disable-model-invocation: true` の Skill 8 個は Codex の skill 一覧に 載らなくなるが、Codex には Claude Code の slash command に相当する 明示起動口がないため、起動方法が利用者に伝わらない状態だった。 `plugins/ndf-codex/README.md` に以下を追記する。 - 抑止対象の Skill 一覧 - 暗黙起動されなくなること - 起動するには SKILL.md のパスまたは Skill 名を示して読ませること - codex-cli 0.146.1 での実機検証結果 (抑止 / 対照 / 名前起動 / パス起動) Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01AGejnYyYFuSkQjBhW2KQNy --- plugins/ndf-codex/README.md | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/plugins/ndf-codex/README.md b/plugins/ndf-codex/README.md index ff0e11e3..395cc5a6 100644 --- a/plugins/ndf-codex/README.md +++ b/plugins/ndf-codex/README.md @@ -20,6 +20,48 @@ codex plugin add ndf@ai-plugins Claude Code 専用の agents、statusline 自動設定、transcript retention 自動設定は含めません。Codex runtime が読むファイルはこの `plugins/ndf-codex` 配下だけで完結します。 +## 暗黙起動を抑止する Skill + +破壊的操作を伴う以下 8 個の Skill は、`skills//agents/openai.yaml` の `policy.allow_implicit_invocation: false` によって **Codex の暗黙起動 (モデルが自分で選んで起動する経路) を抑止**しています。共有 Skill の frontmatter が `disable-model-invocation: true` のものが対象で、`scripts/build-runtime-plugins.sh` が自動生成します。 + +| Skill | 内容 | +|-------|------| +| `cherry-pick-pr` | 環境ブランチへの cherry-pick PR 作成 | +| `clean` | マージ済みローカル/リモートブランチの削除 | +| `deploy` | 環境ブランチ (qa/staging, release/v2 等) への deploy PR 作成 | +| `merged` | PR マージ後のクリーンアップ | +| `pr` | commit / push / PR 作成・更新 | +| `pr-tests` | PR テストプランの実行と結果コメント | +| `review` | PR / ブランチ差分のレビューと approve・request-changes 投稿 | +| `sync-main` | main / master の取り込み | + +### 利用者への影響と起動方法 + +これらの Skill は Codex のセッションに読み込まれる **skill 一覧に載らなくなります**。Codex には Claude Code の `/ndf:deploy` のような明示起動用の slash command 口がないため、**起動するにはファイルパスまたは Skill 名を示して Codex に読ませてください**。 + +```text +# 動く: パスを示して読ませる +.agents/skills/deploy/SKILL.md を読んで、その手順どおりに qa/staging へ deploy PR を作成してください。 + +# 動かない: 名前だけで起動を依頼する +deploy skill を実行してください。 +``` + +Codex plugin としてインストールした場合の実体パスは Codex のプラグインキャッシュ配下になります。パスが不明なときは「`deploy` の SKILL.md を探して読み、その手順どおりに実行してください」のようにファイル探索を許可する形で依頼してください。 + +### 実機検証結果 (codex-cli 0.146.1 / gpt-5.5) + +`.agents/skills/` 配下に検証用 Skill を置いて確認した結果です。 + +| 検証 | 設定 | 結果 | +|------|------|------| +| 抑止 | 本プラグインの生成物と同一の `openai.yaml` を配置 | skill 一覧に **載らない**。エラー・警告は出ない | +| 対照 | 同一構造で `allow_implicit_invocation: true` のみ変更 | skill 一覧に **載る** | +| 名前で起動依頼 | 抑止済み Skill を名前だけで指定 | 「利用可能なスキル一覧に無い」として拒否。別 Skill で代替されることがある | +| パスで起動依頼 | `SKILL.md` のパスを指定 | Codex が自分で読み込み、本文どおり実行する | + +対照検証により、抑止は yaml のパース失敗による Skill の取りこぼしではなく `policy` が意図どおり効いた結果であることを確認しています。 + ## Slack 通知 Codex 版の Stop hook は `NDF_CODEX_SLACK_NOTIFY=true` が設定されている場合だけ Slack 通知を送ります。通知を使う場合は、利用プロジェクト側で以下の環境変数を設定します。 From 7acc4bc56f51024d0569430f6301609fe2252700 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 8 Aug 2026 05:12:32 +0000 Subject: [PATCH 4/4] =?UTF-8?q?Docs:=20Codex=20=E3=81=AE=E6=98=8E=E7=A4=BA?= =?UTF-8?q?=E8=B5=B7=E5=8B=95=20($skill)=20=E3=81=AE=E6=8C=99=E5=8B=95?= =?UTF-8?q?=E3=82=92=E5=AE=9F=E6=A9=9F=E6=A4=9C=E8=A8=BC=E7=B5=90=E6=9E=9C?= =?UTF-8?q?=E3=81=AB=E5=9F=BA=E3=81=A5=E3=81=8D=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `allow_implicit_invocation: false` でも `$` の明示起動は動作することを 実機検証 (codex-cli 0.146.1) で確認し、README を「暗黙起動のみ抑止」へ修正 - 起動経路ごとの挙動を表で整理し、推奨を `$` に変更 - プラグイン Skill はワークスペース外のキャッシュに置かれるため、曖昧な ファイル探索依頼は失敗しうる点を注意喚起として追記し、実体パスの形式を明記 - base ブランチ取り込みで削除された clean / sync-main の openai.yaml を再生成で除去 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01AGejnYyYFuSkQjBhW2KQNy --- plugins/ndf-codex/README.md | 49 +++++++++++++------ .../ndf-codex/skills/clean/agents/openai.yaml | 2 - .../skills/sync-main/agents/openai.yaml | 2 - 3 files changed, 35 insertions(+), 18 deletions(-) delete mode 100644 plugins/ndf-codex/skills/clean/agents/openai.yaml delete mode 100644 plugins/ndf-codex/skills/sync-main/agents/openai.yaml diff --git a/plugins/ndf-codex/README.md b/plugins/ndf-codex/README.md index 395cc5a6..85dd2324 100644 --- a/plugins/ndf-codex/README.md +++ b/plugins/ndf-codex/README.md @@ -22,45 +22,66 @@ Claude Code 専用の agents、statusline 自動設定、transcript retention ## 暗黙起動を抑止する Skill -破壊的操作を伴う以下 8 個の Skill は、`skills//agents/openai.yaml` の `policy.allow_implicit_invocation: false` によって **Codex の暗黙起動 (モデルが自分で選んで起動する経路) を抑止**しています。共有 Skill の frontmatter が `disable-model-invocation: true` のものが対象で、`scripts/build-runtime-plugins.sh` が自動生成します。 +破壊的操作を伴う以下 6 個の Skill は、`skills//agents/openai.yaml` の `policy.allow_implicit_invocation: false` によって **Codex の暗黙起動 (モデルが自分で選んで起動する経路) を抑止**しています。共有 Skill の frontmatter が `disable-model-invocation: true` のものが対象で、`scripts/build-runtime-plugins.sh` が自動生成します。 | Skill | 内容 | |-------|------| | `cherry-pick-pr` | 環境ブランチへの cherry-pick PR 作成 | -| `clean` | マージ済みローカル/リモートブランチの削除 | | `deploy` | 環境ブランチ (qa/staging, release/v2 等) への deploy PR 作成 | | `merged` | PR マージ後のクリーンアップ | | `pr` | commit / push / PR 作成・更新 | | `pr-tests` | PR テストプランの実行と結果コメント | | `review` | PR / ブランチ差分のレビューと approve・request-changes 投稿 | -| `sync-main` | main / master の取り込み | ### 利用者への影響と起動方法 -これらの Skill は Codex のセッションに読み込まれる **skill 一覧に載らなくなります**。Codex には Claude Code の `/ndf:deploy` のような明示起動用の slash command 口がないため、**起動するにはファイルパスまたは Skill 名を示して Codex に読ませてください**。 +抑止されるのは **暗黙起動だけ**です。`$` による明示起動は抑止後も従来どおり動きます。 + +| 起動経路 | 抑止後の挙動 | +|----------|-------------| +| 暗黙起動 (モデルが自分で選ぶ) | **起動しない**。セッションの skill 一覧 (`## Skills` の `### Available skills`) に載らない | +| 明示起動 `$deploy` | **起動する**。Codex CLI が `$<名前>` を展開し、SKILL.md 本文を `` ブロックとして注入する | +| 名前だけの自然文依頼 (`deploy skill を実行して`) | **起動しない**。一覧に無いため拒否され、別の Skill で代替されることがある | +| SKILL.md の絶対パスを示す | 通常のファイル読み取りとして読み込まれ、本文どおり実行される | + +推奨は `$` です。対話モード / 非対話モード (`codex exec`) のどちらでも同じ展開が行われます。 ```text -# 動く: パスを示して読ませる -.agents/skills/deploy/SKILL.md を読んで、その手順どおりに qa/staging へ deploy PR を作成してください。 +# 動く: 明示起動 (推奨) +$deploy qa/staging + +# 動く: 実体パスを示して読ませる +~/.codex/plugins/cache/ai-plugins/ndf/4.20.1/skills/deploy/SKILL.md を読んで、その手順どおりに qa/staging へ deploy PR を作成してください。 # 動かない: 名前だけで起動を依頼する deploy skill を実行してください。 ``` -Codex plugin としてインストールした場合の実体パスは Codex のプラグインキャッシュ配下になります。パスが不明なときは「`deploy` の SKILL.md を探して読み、その手順どおりに実行してください」のようにファイル探索を許可する形で依頼してください。 +対話モード (`codex` を引数なしで起動) では `/skills` で Skill 一覧と有効・無効を確認できます。 + +### プラグイン Skill のファイル探索に関する注意 + +marketplace 経由でインストールした場合、Skill の実体は **ワークスペース外**の Codex プラグインキャッシュに置かれます。 + +```text +$CODEX_HOME/plugins/cache////skills//SKILL.md +# 既定 ($CODEX_HOME=~/.codex) の例: +# ~/.codex/plugins/cache/ai-plugins/ndf/4.20.1/skills/deploy/SKILL.md +``` + +そのため「`deploy` の SKILL.md を探して読んで」のような曖昧な依頼は、Codex のファイル探索がワークスペース内に限られる状況では失敗しえます。`$` はキャッシュ配下の Skill も skill roots から解決するため、まず `$` 起動を使ってください。パスで指示したい場合は `codex plugin list` で実体パスを確認し、絶対パスを渡します。 ### 実機検証結果 (codex-cli 0.146.1 / gpt-5.5) -`.agents/skills/` 配下に検証用 Skill を置いて確認した結果です。 +`.agents/skills/` 配下に検証用 Skill (`probe-explicit` = 本プラグインと同じ `openai.yaml` を配置 / `probe-open` = 抑止なし) を置き、`codex exec` で確認した結果です。 -| 検証 | 設定 | 結果 | +| 検証 | 内容 | 結果 | |------|------|------| -| 抑止 | 本プラグインの生成物と同一の `openai.yaml` を配置 | skill 一覧に **載らない**。エラー・警告は出ない | -| 対照 | 同一構造で `allow_implicit_invocation: true` のみ変更 | skill 一覧に **載る** | -| 名前で起動依頼 | 抑止済み Skill を名前だけで指定 | 「利用可能なスキル一覧に無い」として拒否。別 Skill で代替されることがある | -| パスで起動依頼 | `SKILL.md` のパスを指定 | Codex が自分で読み込み、本文どおり実行する | +| 暗黙起動の抑止 | 「Available skills のうち probe で始まるものを列挙」と依頼 | `probe-open` のみ。`probe-explicit` は **載らない**。エラー・警告は出ない | +| 明示起動 | `codex exec '$probe-explicit'` | **起動した**。セッションログに `probe-explicit` + SKILL.md 本文が注入される | +| プラグイン Skill の明示起動 | ワークスペース外にインストール済みの `ndf` に対し、無関係な作業ディレクトリで `codex exec '$deploy'` | **解決した**。`~/.codex/plugins/cache/ai-plugins/ndf/4.20.1/skills/deploy/SKILL.md` を読み込んで実行 | -対照検証により、抑止は yaml のパース失敗による Skill の取りこぼしではなく `policy` が意図どおり効いた結果であることを確認しています。 +暗黙起動の抑止と明示起動の可否は独立しており、抑止した Skill も `$` で起動できることを確認しています。 ## Slack 通知 diff --git a/plugins/ndf-codex/skills/clean/agents/openai.yaml b/plugins/ndf-codex/skills/clean/agents/openai.yaml deleted file mode 100644 index 5b1f887a..00000000 --- a/plugins/ndf-codex/skills/clean/agents/openai.yaml +++ /dev/null @@ -1,2 +0,0 @@ -policy: - allow_implicit_invocation: false diff --git a/plugins/ndf-codex/skills/sync-main/agents/openai.yaml b/plugins/ndf-codex/skills/sync-main/agents/openai.yaml deleted file mode 100644 index 5b1f887a..00000000 --- a/plugins/ndf-codex/skills/sync-main/agents/openai.yaml +++ /dev/null @@ -1,2 +0,0 @@ -policy: - allow_implicit_invocation: false