Skip to content

ai-policy: Codex 権限面の正本化 — managed rules baseline + projects trust の doctor 監視 (#139) - #187

Merged
kosako merged 3 commits into
mainfrom
ai-policy-codex-rules-139
Jul 10, 2026
Merged

ai-policy: Codex 権限面の正本化 — managed rules baseline + projects trust の doctor 監視 (#139)#187
kosako merged 3 commits into
mainfrom
ai-policy-codex-rules-139

Conversation

@kosako

@kosako kosako commented Jul 10, 2026

Copy link
Copy Markdown
Owner

概要

#139 の実体化。Claude 側は managed settings.json で権限を設計している一方、Codex 側の権限(承認 rules / projects trust)はどの管理系にも属さず「今後確認しない」の堆積で事実上決まる非対称を解消する。

裏付け(実機): 2026-07-02 に是正した home-root trust([projects."/Users/kosako"])が 2026-07-10 の監査で復活していた + 廃止 path の残骸 2 件。堆積は実際に再発する。

変更

対象 内容
dot_codex/rules/default.rules.tmpl 検証済み read-only baseline を managed 化(read 系 gh + ローカル git のみ)。堆積 grant = drift 可視化 → apply でリセット(棚卸しの仕組み化)。gate=enableAiPolicy の template 自己 gate(#184 教訓)
scripts/doctor.sh AI policy section に Codex 権限面の report-only 監視: live rules の外向き/昇格 auto-allow を rule 行ごと warn + config.toml[projects] trust を section header の path のみ scan(MCP env 等は読まない=#148 規律)し whole-home trust / stale path を warn。exit 0 維持
docs/ai-policy.md 「権限方針の正本と管理点」節を新設(tool 別管理点の表 + 共通原則: read=無確認可 / 外向き・昇格=都度承認(将来 #131 で context-gated 化) / 堆積の定期棚卸し)
tests rules baseline の exact 内容 pin(外向き混入で fail)/ 両方向の gate 独立性 / doctor の warn・非 warn・canary 非 echo・exit 0(AIP/AIP-2)/ render expected set

設計判断

検証(ローカル全 green)

  • test-codex-settings(baseline exact + gate 独立性)/ test-doctor(AIP/AIP-2 含む)/ test-render / validate-policy --all / shellcheck -S warning / preflight
  • 実機 doctor: home-root trust 復活・stale 2 件(~/work/ai-agent-plansrc/sandbox/env)を即検出、exit 0

merge 後の運用(ユーザー操作)

  • chezmoi apply(rules は no-op・managed 化のみ)
  • doctor の warn に従い codex 側で projects trust を手動除去(home root / stale 2 件)

Closes #139

🤖 Generated with Claude Code

…doctor 監視 (#139)

Claude 側は managed settings.json で権限を設計している一方、Codex 側の権限
(承認 rules / projects trust)はどの管理系にも属さず「今後確認しない」の
堆積で事実上決まる非対称があった(#139)。実際に 2026-07-02 に是正した
home-root trust が 2026-07-10 の監査で復活していた(堆積は再発する)。

- dot_codex/rules/default.rules.tmpl: 検証済み read-only baseline を managed 化
  (read 系 gh サブコマンド + ローカル git 操作のみ・外向き/昇格 allow なし)。
  堆積 grant は drift として可視化され、apply が baseline へリセット
  (定期棚卸しの仕組み化)。gate=enableAiPolicy の template 自己 gate
  (#184 教訓: requires だと既存 file が残置)。
- modules.yaml: codex-settings に .codex/rules 系 paths 追加(hooks.json とは
  独立 gate)。
- doctor.sh: AI policy section に Codex 権限面の report-only 監視を追加
  (codex-settings active な profile のみ):
  - live rules の外向き/昇格 auto-allow(push/create/merge/comment/release/
    sudo 等)を rule 行ごと warn(行は command 語のみで echo 安全)
  - config.toml [projects] trust は section header の path のみ scan
    (MCP env 等は読まない=#148 のキー名限定規律)。home root への trust と
    実在しない path の残骸を warn。exit 0 維持。
- docs/ai-policy.md: 「権限方針の正本と管理点」節を新設 — tool 別の管理点
  (Claude=settings.json / Codex rules=managed baseline / projects trust=
  管理不可・doctor 監視)と共通原則(read=無確認可 / 外向き・昇格=都度承認、
  将来 #131 で context-gated 化 / 堆積の定期棚卸し)を正本化。
- profiles.yaml / scripts/README.md: enableAiPolicy の駆動内容を追従。
- test-codex-settings.sh: baseline の exact 内容 pin(11 rules・外向き混入で
  fail)+ 両方向の gate 独立性(enableAiPolicy off で rules だけ真に削除・
  hooks 残存 / reader off で rules 残存)。
- test-doctor.sh: AIP/AIP-2 — 外向き allow の rule 名 warn・whole-home trust
  warn・stale path warn・実在 project は非 warn・config.toml の canary
  (MCP env token)非 echo・clean 時の偽 warn なし・exit 0。
- test-render.sh: personal expected set に .codex/rules 系を追加。

実機の live rules は baseline と同一(2026-07-02 の細分化そのまま)なので
apply は rules について no-op。config.toml の是正(home-root trust /
stale path の除去)は codex 所有ファイルのためユーザー操作。

Closes #139

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qw8BkUDu5WdwhYfiFFX5n
@kosako

kosako commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

🔍 レビュー依頼(→ Codex)

  • 観点: production レール + security 配線。特に:
    • baseline の安全性: rules baseline に外向き/昇格を auto-allow する行が混入していないか。exact pin テストがそれを固定できているか。
    • doctor の read 規律: config.toml scan が本当に section header の path しか読まない/echo しないか(MCP env の secret が漏れる経路がないか)。sed パターンの取りこぼし・過剰マッチ。
    • 外向き検出の pattern: push|create|merge|comment|edit|delete|close|release|secret|login|sudo|curl|wget の false negative / false positive(read 系を誤 warn しないか)。
    • gate 独立性: 同一 module 内 2 file の別 capability gate(hooks=reader / rules=aiPolicy)に相互干渉がないか。
    • docs の主張の強度: 「apply でリセット=棚卸し」が過大主張になっていないか(apply は手動実行・自動ではない)。
  • ランク: 🔴 must / 🟡 should / ⚪ nit。各指摘に file:line
  • 結果はこの PR にコメントで返します。

…+ clone 除去

Codex 相互レビュー(must2/should2/nit1)対応:

- must1: 行 grep は blanket prefix(["gh","pr"] が gh pr create を allow する
  2026-07-02 の実堆積形)・複数行 rule・decision 省略(既定 allow — 実機
  execpolicy で確認)を見逃し、read 系(gh release view)を誤検知する。
  → 固定 probe リスト(push/PR・issue・comment 作成/release/repo delete/
  auth login/sudo/clone/curl/wget、15 本)を codex execpolicy check で
  live rules に評価する方式へ全面置換。意味論は codex 自身の engine に委譲。
  codex CLI 不在時は skip を明示(report-only)。
- must2: rule 行の echo は pattern/justification の任意文字列由来 secret を
  漏らしうる。→ probe 方式で doctor は rules file を一切読まない(path を
  codex に渡すだけ)。echo するのは自前の probe 文字列のみ。テストに
  rules 内 secret canary の非 echo を追加。
- should1: [projects] は trust_level を判別せず header だけで trusted 扱い
  していた。→ awk で section + trust_level="trusted" のみ抽出(untrusted
  entry は無視。テストに untrusted stale の非 warn を追加)。
- should2: git clone の auto-allow は任意 remote への network 取得で
  read-only baseline と不整合(URL は injection 下で covert channel)。
  → baseline から除去(10 rules)し、除外理由を template と docs に明記。
- nit: 「定期棚卸しの仕組み化」は過大(apply は手動)。→「棚卸しの
  リセット操作を機械化(定期実行までは仕組み化していない)」に是正。

test-doctor は fake codex shim(#150 の fake-npm と同型・CODEX_FAKE_ALLOWS
で verdict 制御)で doctor の報告契約を hermetic に固定(CI に codex 不要)。
実機 doctor は live rules に残る clone allow を probe が即検知(baseline
との乖離として正しい。apply で解消)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qw8BkUDu5WdwhYfiFFX5n
@kosako

kosako commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

📋 レビュー結果(by Codex)— 初回

判定: ⛔ 要対応(must 2) → 全指摘対応済み(commit aff1673)・増分再レビューは Codex quota 待ち(must0 確認まで merge しない)

🔴 must(いずれも採用)

  1. scripts/doctor.sh — 行 grep の外向き検出は blanket prefix(["gh","pr"]gh pr create を allow する 2026-07-02 の実堆積形)・複数行 rule・decision 省略(既定 allow)を見逃す。実機 codex execpolicy check で全パターン確定(blanket→allow / decision 省略→allow)。→ 固定 15 probe を codex execpolicy check で live rules に評価する方式へ全面置換(意味論を codex engine に委譲・CLI 不在時は skip 明示)。
  2. scripts/doctor.sh — rule 行の echo は pattern/justification の任意文字列由来 secret を漏らしうる。→ probe 方式で doctor は rules file を一切読まない(path を渡すだけ・echo は自前 probe 文字列のみ)。rules 内 secret canary の非 echo をテスト化。

🟡 should(いずれも採用)

  1. [projects] の header だけでは trust_level="untrusted" を trusted と誤報 → awk で trusted のみ抽出(untrusted stale の非 warn をテスト化)。
  2. git clone の auto-allow は任意 remote への network 取得で read-only baseline と不整合(URL は injection 下で covert channel)→ baseline から除去(10 rules)・理由を template/docs に明記。

⚪ nit(採用)

  • 「定期棚卸しの仕組み化」は過大(apply は手動)→「棚卸しのリセット操作を機械化」に是正。

対応の検証

  • 全テスト green(test-doctor は fake codex shim で hermetic 化=CI に codex 不要)・shellcheck clean
  • 実機 doctor: live rules に残る git clone allow を probe が即検知(baseline との乖離として正しい・apply で解消)

残り: 増分再レビュー(must0 確認)を Codex quota 回復後(19:12〜)に実施してから merge。

Codex 増分レビュー(新規 must3)対応:

- must A(fail-open false-clean): execpolicy のエラー(rc1 = rules 破損/不在/
  非互換 codex — 実機で rc 確定)を空 verdict に潰して「clean」と誤報していた。
  → rc で評価失敗を区別し、1 件でも失敗したら「scan INCOMPLETE」warn を出し
  clean ok を抑止。shim に CODEX_FAKE_MODE=fail を追加し経路をテスト固定。
- must B(probe 網羅): gh issue edit/close/delete/transfer・gh release
  edit/delete/upload・gh repo edit/archive/rename・gh api --method POST・
  gh secret set を追加(15→27 probe。docs の Approval Required 由来)。
  shim の probe log で **probe set 全体を exact に pin**(黙った削除・漏れが
  テストで落ちる)。
- must C(TOML 形式差): trust_level の $1/$3 判定は compact 形
  (trust_level="trusted")と single-quote 形を見逃す。→ 空白許容 +
  両 quote 対応の regex に変更。awk/read 失敗は「0 trusted」でなく
  「scan INCOMPLETE」warn(false-clean 排除)。fixture を compact(whole-home
  entry)+ single-quote(stale entry)に変えて形式差をテスト固定。

実機 doctor: 27 probe で計 ~6.8s・exit 0 維持。live rules の clone allow /
whole-home trust / stale 2 件を引き続き検出。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qw8BkUDu5WdwhYfiFFX5n
@kosako

kosako commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

📋 レビュー結果(by Codex)— 増分 2〜3 巡目

判定: ✅ merge 可(must 0)(初回 must2/should2/nit1 → 対応 → 増分で新規 must3 → 対応 → 3 巡目で解消確認)

🔴 must(増分・いずれも採用、commit 3794e89)

  1. fail-open false-clean: execpolicy のエラー(rc1)を空 verdict に潰し「clean」と誤報 → rc で評価失敗を区別し scan INCOMPLETE warn + clean ok 抑止(AIP-3 でテスト固定)。
  2. probe 網羅の穴: gh issue edit/close/delete/transfergh release edit/delete/upload(Approval Required 明記済)・gh repo edit/archive/renamegh api --method POSTgh secret set が未検知 → 15→27 probe に拡充し、shim log で probe set 全体を exact に pin(黙った削除がテストで落ちる)。
  3. TOML 形式差: trust_level="trusted"(compact)・single-quote 形を見逃し 0 trusted と誤報 → 空白許容 + 両 quote 対応 regex、awk 失敗も scan INCOMPLETE(fixture を compact/single-quote に変更しテスト固定)。

3 巡目の解消確認(Codex)

  • rc≠0 集計と INCOMPLETE/抑止、27 probe の exact-set pin 一致(重複・欠落なし)、compact/quote/コメント付き形式の認識と awk 異常終了の INCOMPLETE 扱い — いずれも実装と一致。実 execpolicy の rc 挙動(正常 0 / 読込失敗 1)も独立確認。

実機 doctor: 27 probe で計 ~6.8s・exit 0。live の clone allow / whole-home trust / stale 2 件を検出継続。CI green 確認後 merge します。

@kosako
kosako merged commit e0250b2 into main Jul 10, 2026
2 checks passed
@kosako
kosako deleted the ai-policy-codex-rules-139 branch July 10, 2026 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ai-policy モジュールの実体化: AI エージェント権限方針の正本化(Codex 側との対称性)

1 participant