ガバナンス強制層 — ルールがルールになる方法
第3章の権限モデルは「何をしてはいけないか」を語る。この文書はその次の問い — 「違反をどう確実に防ぐか」 — を扱う。ワークスペースは同じルールをフック・プロンプト・スキルの三層に掛けて、一つの層が欠けても別の層が持ちこたえる構造にしている。
出典: ai-workspace-standards CONSTITUTION.md §11 · ECCガバナンス Phase 1–3設計(docs/designs/ecc-phase*.md) · scripts/hooks/gateguard-fact-force.ts v1.3.0 · scripts/audit.ts v2.46.0
- フック・プロンプト・スキル3層強制モデルと各層の強度・カバレッジ
- GateGuardの「編集前ファクト強制」 — 何を調査させるのか
- ガバナンスインフラが3段階で成熟した過程
- 検証スクリプト群とfail-closed vs warnの区別
- プラットフォームごとに強制力が違う理由と、ブロック時の対処法
概要 — 防御は一度ではなく三度
「エージェントがファイルを勝手に編集できないようにする」というルールを一つ考えてみよう。このルールをシステムプロンプトにだけ書いておくとどうなるか — エージェントが指示を見落とすか無視したら終わりだ。ワークスペースはこの問題を 3層強制モデル で解いた。
| 層 | 手段 | 強度 | カバレッジ |
|---|---|---|---|
| 1. フック(Hook) | 決定論的スクリプト(Claude PreToolUse、Gemini BeforeTool) | 最強 — ゲートを通過するまで進行不可 | Claude Code CLI・Gemini CLIは完全対応、Desktop Appは条件付き、Antigravity・Codexは未対応 |
| 2. プロンプト(Prompt) | CLAUDE.md/GEMINI.md/CODEX.md/HERMES.mdに組み込まれたシステム指示 | 中 — エージェントの自己遵守に依存 | 5プラットフォームすべて |
| 3. スキル(Skill) | /gateguard などのオンデマンド手動呼び出し | 最弱(任意) — 人が実行 | 5プラットフォームすべて |
設計意図は明確だ。最も強いフックはプラットフォームごとの対応差が大きいため、フックのない環境ではプロンプト層が最低限の防御を担い、スキル層が人主導の点検手段を残す。一つの層の失敗が全体の失敗ではない。
GateGuard — 編集前ファクト強制
GateGuardは 事前編集品質ゲート だ。セッション内で最初にファイル編集を試みた瞬間に発火し、編集前に三つのことを調査するようエージェントに 強制 する。
- このファイルを 利用している(importer/参照)箇所 はどこか
- このファイルが公開する スキーマ・インターフェース・型 は何か
- ユーザーの指示はこの作業に スコープ制約 を課しているか
調査が終わると [GATEGUARD] Pre-edit investigation complete ブロックにリスク度と推奨を構造化して出力する。動作モードは二つ — askモード(Claudeのデフォルト)はエージェントが調査結果を提示するまで進行を保留し、denyモード(Geminiのデフォルト、Claudeは --mode deny で選択)は終了コード2で編集自体をハードブロックする。セッション状態は .gateguard-state/ にPIDキーのJSONで残り、フックプロセスの再起動にも耐える。memory/、CHANGELOG.md などの安全パスは免除だ。
ガバナンス成熟の3段階
このインフラは一日にして成らずだ。ECCガバナンスロードマップの三段階で積み上がった。
- Phase 1 — コアインフラ(P0): 3層モデルの確立、GateGuardのフック+プロンプト+スキル実装、エージェント/スキルフロントマターのJSONスキーマ、プロンプト防御の基準線(エンコーディング警戒・濫用パターン検知)、CONSTITUTION §11の新設
- Phase 2 — 強化(P1): コマンドフロントマタースキーマ、GateGuard
--mode ask|denyの設定化、GeminiAfterTool連携(post-write-lifecycle-check.ts)、フック信頼性のサブプロセス単体テスト - Phase 3 — 成熟(P2): PIDキー状態の永続化(
.gateguard-state/)、audit.tsの自動エンコーディング警戒(CRLF・ホモグリフ・ゼロ幅文字)、GOVERNED_CONFIG_PATHSによるCLAUDE.md・CONSTITUTION.md・package.jsonなど高価値設定ファイルの編集ゲーティング
教訓はシンプルだ — ガバナンスもソフトウェアだ。初版で完成を目指さず、コア→強化→成熟の反復で実際のブロック事例を吸収しながら育てる。
検証スクリプト群
フックが「編集の瞬間」のゲートなら、検証スクリプト群は「コミット・同期の時点」のゲートだ。
scripts/audit.ts— ワークスペース標準の総合監査スクリプト。構造検査、リンク切れ、エンコーディング警戒、フロントマタースキーマ検証、スペックレジストリ検査などを実行し、FAILが一つでもあれば exit 1scripts/qa-gate.ts— Phase 6品質ゲート。audit.tsを第1段階としてハード実行し、プロジェクトテスト・ドキュメント整合性・ガバナンスレコードのデプロイ確認を続ける。一つでも失敗すればパイプライン停止scripts/validate-agents.ts/validate-skills.ts/validate-templates.ts— それぞれエージェント・スキル・テンプレートのフロントマターとガバナンスレコード(docs/lifecycle/)を検証scripts/verify-adr-governance.ts— ガバナンス文書に参照されないまま承認されたADRと、憲法原文とのマーカーハッシュのドリフトを検出(参照Bで詳述)
fail-closedとwarn — どこで止まり、どこで見過ごすか
audit.tsの検査結果は三段階だ。
- Pass — 通過
- Fail — エラーカウンターを増やし、最終的に
process.exit(1)。パイプライン全体が止まる(fail-closed) - Warn — 黄色の警告を出力するだけで通過させる
何をWarnのままにするかは政策的選択だ。variantスクリプトのドリフト、コンテキスト共通化、CRLF(Windows移行期の暫定)などはWarn — 自動失敗にするには偽陽性のリスクがあるが、必ず目に見えるべきものだ。一方、必須フィールド欠落などのスキーマエラーはFailだ。スキーマ検証の内部でも error(必須欠落)と warning(推奨欠落)が区別され、Failにつながるのはerrorだけだ。
プラットフォーム別の強制力の違い
同じルールでもプラットフォームによって体感が違うことを正直に認めるのが、この設計の成熟した部分だ。
- Claude Code CLI / Gemini CLI — フック完全対応。機械的ブロックが機能する。
- Claude Desktop App — フックは条件付きで発火。プロンプト層が主防御線。
- Antigravity — フック未対応。プロンプトの指示だけが残る。ここでルールを無視しても機械的ブロックはないが、それは ガバナンス違反 として記録される。
- Codex (CLI・Desktop App) — フック未対応。代わりに
CODEX.mdがシステムプロンプトとして直接注入されるため、プロンプト層が基本防御線になる。ここでルールを無視しても機械的ブロックはないが、同様に ガバナンス違反 として記録される。
したがって「フックのないプラットフォームではルールが任意」というより「強制層が弱くなるだけで、違反の性質は同じ」と解釈するのが正確だ。
ブロックされたときの対処法
- ゲートメッセージを読む — GateGuardのaskモードなら、調査すべき方向(参照元・スキーマ・スコープ)が理由に書かれている。
- 調査して結果を提示する — importer、スキーマ、スコープ制約を確認し、その根拠を答えれば進行が許可される。
- denyモードなら — 編集はハードブロックされる。調査後に同じ編集を再試行すればよい。迂回(
--no-verifyなど)は禁止だ。シークレットスキャンとすべての品質ゲートをスキップすることになる。 - qa-gateで止まったら — FAILメッセージの最初の項目から直す。2回繰り返しても通過できなければPMへのエスカレーションが規定の手順だ(最大2回の反復)。