PlanGate

settings wiring 契約(正本 / TASK-0080 S1)

.claude/settings.json が満たすべき PreToolUse hook wiring の正本bin/plangate doctor --check-settings がこの契約と実体を突合する。 適用は scripts/apply-claude-settings.shユーザー実行。AI は self-mod ガードで .claude/settings.json を編集できないため)。

必須 PreToolUse hooks(matcher: Edit|Write 系)

Hook command(必須トークン)
EH-1 plan-exists scripts/hooks/check-plan-exists.sh
EH-2 c3-approval scripts/hooks/check-c3-approval.sh
EH-3 plan-hash scripts/hooks/check-plan-hash.sh ${PLANGATE_HOOK_TASK:-} ${PLANGATE_HOOK_FILE:-}
EH-6 forbidden-files scripts/hooks/check-forbidden-files.sh
EH-9 delegation-commit-boundary scripts/hooks/check-delegation-commit-boundary.sh

契約ポイント

検証・適用

⚠️ 適用スクリプトの副作用(本契約の範囲外): apply-claude-settings.sh は本契約が定める PreToolUse 6 項目だけでなく、.claude/settings.example.json全 hook event(SessionStart / PostToolUse / Stop を含む)を取り込む。 そこには契約外かつ副作用の大きい hook が含まれうる(例: SessionStart の scripts/gh-pin-account.shgh auth switchマシン全体の gh CLI active account を切り替える)。また「不足を足すが削除はしない」方針の 裏返しとして、example から意図的に削除した hook は再実行のたびに復活 する(opt-out 手段は現状なし)。--all-events opt-in 化は #975 で follow-up。

不変

責務分離(V-3 MJ-2/MJ-3 反映)

検証対象 手段 役割
CI settings-drift(required) .claude/settings.example.json(契約 reference) check-settings-wiring.sh --target example 正本 reference が契約と乖離しないことを保証(example が壊れたら全員に波及するため)
bin/plangate doctor --check-settings .claude/settings.json(ユーザー実体) 構造(JSON)検証 実環境の wiring 未適用=Shadow Config を検出
既存 bin/plangate doctor hook-wiring check .claude/settings.json vs .claude/settings.example.json 既存 check(TASK-0069) settings.example.json を契約整合させた結果、未適用を通常 doctor でも FAIL(従来の false-PASS を是正)

.claude/settings.json は gitignore(ユーザーローカル)のため CI では検出 不可。実体 drift の検出は doctor(ローカル / V-1・handoff DoD)が担う。 両者は役割が異なり、どちらか一方では「Shadow Config を構造的に防ぐ」根拠に ならない(CI=reference 健全性 / doctor=実体適用)。

タスクロックの強制経路(V-3 MJ-1 反映)

V-1/handoff 完了の DoD(docs/workflows/05_verify_and_handoff.md / working-context.md)に 「doctor --check-settings PASS」を必須化。強制は次の二重で成立する:

  1. DoD 明文 + 通常 doctor の hook-wiring FAIL: settings.example.json を 契約整合させたため、未適用環境では bin/plangate doctor(通常実行)も FAIL する。doctor FAIL 状態での完了報告は Iron Law(検証証拠なしに完了 扱いしない)違反。
  2. doctor --check-settings: 構造検証で未適用箇所を決定論的に列挙。

既知の限界(V2 候補): 完全な PreToolUse-hook レベルの機械 block解消済 (PR #347).codex/hooks.json + .codex/hooks/eh-bridge.sh で Codex CLI 側にも EH-1/2/3/6/9 が物理 PreToolUse block として配線済。Claude Code 側は従来通り .claude/settings.json で配線。詳細は本ファイル後段の §Codex CLI parity 参照。

Codex CLI parity (#336 / Gap 4) — 達成済

model tier の parity: Claude Code は .claude/agents/*.md frontmatter の model:(inherit/sonnet)、Codex は .codex/agents/*.tomlmodel_reasoning_effort(low/medium)で同一の 2 tier を表現する。対応表の 正本は model-profiles.md §11。

判明事項 (2026-05-25 PR #347): OpenAI Codex CLI は PreToolUse / PostToolUse hook API を公式提供しており、Claude Code の hook 仕様と直接互換 (matcher / stdin JSON / exit 2 で deny / hookSpecificOutput.permissionDecision)。公式仕様: https://developers.openai.com/codex/hooks

三層の強制機構

機構 カバー範囲
1. Session 前 scripts/codex-guarded.sh (PR #343) validate / doctor / EH-8 privacy / plan.md hash snapshot
2. Session 中 (物理 pre-Write block) .codex/hooks.json + .codex/hooks/eh-bridge.sh (PR #347) EH-1 / EH-2 / EH-3 / EH-6 / EH-9 を Codex 側でも発火
3. Session 後 scripts/codex-guarded.sh post-flight plan.md hash drift 検知 + validate 再実行

等価強制マトリクス

強制 Claude Code Codex CLI
EH-1 plan-exists .claude/settings.json PreToolUse .codex/hooks.json PreToolUse
EH-2 c3-approval ✅ 同上 ✅ 同上
EH-3 plan_hash ✅ 同上 ✅ 同上
EH-6 forbidden_files ✅ 同上 ✅ 同上
EH-9 delegation-commit-boundary ✅ PreToolUse Bash ✅ PreToolUse Bash

Codex bridge の動作

  1. Codex CLI が apply_patch / Edit / Write / Bash 呼び出し前に .codex/hooks.json を参照
  2. 該当 matcher の command (= .codex/hooks/eh-bridge.sh <HOOK_NAME>) が起動
  3. eh-bridge.sh が stdin JSON から file path (Edit/Write.file_path or apply_patch.command の *** Update/Add/Delete File:) を抽出
  4. PLANGATE_HOOK_FILE / PLANGATE_HOOK_TASK を設定し scripts/hooks/<HOOK_NAME> を起動
  5. exit code を Codex の hookSpecificOutput.permissionDecision (allow / deny) に翻訳
  6. Codex CLI が deny 時は write を物理 block

責務分界 (継続)

Wiring Integrity Enforcement(#500 / 配線整合性の強制・Specification)

Status: Specification(方針確定。実装は HO パス絡みのため受け入れ条件ごとに段階 PBI へ分解) 出自: river 3 相レビュー(2026-06-08、Gemini + コードベース調査で代替実行 / external-reviewer-interface §10 unavailable 準拠)で検出した「規範↔実装」乖離 (Shadow Config)への是正方針。

強制モード方針(example=warning / 本番=strict)

doctor によるモード別必須 strict 配線検証

EH-10: 承認トークン書込みガードの採番・配線

検証ロジックの対称化・テスト空白の解消(実装方針)

受け入れ条件 実装方針 主パス(HO)
EH-2(c3_status)strict 化 EH-3 と同じ python3 strict JSON 解析へ置換(permissive な grep/sed 抽出を廃止し EH-3 と対称化) scripts/hooks/check-c3-approval.sh
EH-1/EH-2 stdin fallback env 未注入時に stdin tool_input.file_path から解決し SKIP(allow) を解消 scripts/hooks/*.sh
maintenance verdict テスト VALID / CONSUMED / OUT_OF_SCOPE / HARDENING_OVERRIDE の fixture + assert を追加 tests/hooks/
ta-06 ログ握りつぶし解消 >/dev/null 2>&1 圧縮をやめ、どの EH が落ちたかをログに残す tests/.../ta-06-hooks.sh

段階 PBI 分解(HO 実適用は Human)

本仕様の HO 実装は以下の順で段階 PBI に分解する(各々 plan → C-3 承認 👤 → exec、 HO 適用は Human):

  1. EH-2 strict 化 + EH-1/EH-2 stdin fallback(hooks 堅牢化・最小単位・回帰リスク低)
  2. EH-10 採番・配線 + check-approval-token-write 統合(#420 と協調)。配線時は既存の契約検証スクリプト scripts/check-settings-wiring.shchecks リストにも EH-10(check-approval-token-write.sh)を追加し、CI / ローカルの契約ドリフト検知(--target example)に組み込んで配線漏れを防ぐ
  3. doctor Wiring Integrity Enforcement(Governance Contract 定義 + exit 1)
  4. hooks 回帰テスト拡充(maintenance verdict fixture + ta-06 ログ解消)

各段階は承認境界(HO)の変更を含むため mode-classification.md により最低 high・ Standard C-3 同期固定(autonomous APPROVE 無効)とする。

CLI 配線(EH-4/5/7)— TASK-0143

Status: Implemented(scripts/apply-task-0143-eh457-wiring.sh --apply 適用後に有効)

PreToolUse hook ではなく bin/plangate CLI サブコマンド経由で発火する配線。

Hook CLI 配線先 発火タイミング
EH-4 (check-test-cases.sh) bin/plangate verify <TASK> V-1 実行(strict=1、test-cases.md なしで block)
EH-5 (check-verification-evidence.sh) bin/plangate verify <TASK> V-1 通過(warn のみ、evidence なしで WARNING)
EH-7 (check-merge-approvals.sh) 手動呼び出し推奨 merge 前: sh scripts/hooks/check-merge-approvals.sh <TASK>

doctor 可視化

bin/plangate doctor=== CLI Hook Wiring (EH-4/5/7) === セクションが:

  1. EH-4/5/7 スクリプトの存在・実行権限を PASS/WARN/FAIL で報告
  2. bin/plangate verify への配線状態(grep 確認)を PASS/WARN で報告

適用方法(Human-owned)

# 差分確認(必須)
sh scripts/apply-task-0143-eh457-wiring.sh --dry-run
# 適用
sh scripts/apply-task-0143-eh457-wiring.sh --apply

適用後: bin/plangate doctor の出力で [PASS] EH-4 wired / [PASS] EH-5 wired を確認する。

C-3 Approval Mode 設定(EH-3 conversation 経路)— TASK-0144

Status: Implemented(scripts/apply-task-0144-c3-mode.sh --apply 適用後に有効)

.plangate.yml プロジェクト設定で C-3 承認モードを選択できる経路。

モード定義

モード 動作 c3.jsonsource フィールド
cli(デフォルト) bin/plangate approve <TASK> で対話的に承認・c3.json 生成 "cli"
conversation 会話内で人間が APPROVE 発話 → AI が exec 前に c3.json を生成 "conversation"

設計の核心

EH-3 conversation 経路(新規)

scripts/hooks/check-plan-hash.sh に追加された判定:

  1. target_filedocs/working/TASK-*/approvals/c3.json にマッチ
  2. .plangate.yml を読んで c3_approval.mode を取得
  3. conversation の場合 → EH-3_C3_CONVERSATION_SKIP をログに記録して exit 0(Write を許可)
  4. cli の場合 → 既存の maintenance / SKIP_REASON 判定に進む

追加ファイル

ファイル 種別 説明
.plangate.yml 設定ファイル プロジェクト設定(c3_approval.mode: cli\|conversation
schemas/plangate-config.schema.json Schema(HO) .plangate.yml の JSON Schema 検証定義
schemas/c3-approval.schema.json Schema(HO 変更) source フィールドを追加(optional)
scripts/hooks/check-plan-hash.sh Hook(HO 変更) conversation SKIP 経路を追加
bin/plangate CLI(HO 変更) _read_plangate_config() 追加 / source: "cli" / doctor セクション追加

適用方法(Human-owned)

# 差分確認(必須)
sh scripts/apply-task-0144-c3-mode.sh
# 適用
sh scripts/apply-task-0144-c3-mode.sh --apply

適用後: bin/plangate doctor の出力で === C-3 Approval Mode === セクションを確認する。