Skip to content
Development
Command

/ai-governance

Generate and enforce policy gates for AI coding agents (Copilot, Claude Code) — real-time session hooks that deny protected-path edits and dangerous commands, plus a merge-time backstop for anything that bypasses them. Use when asked to "govern AI agents", "block AI from

From plugin
platform-skills
4244 skills1 agent44 commands
Install
> /plugin marketplace add nitinjain999/platform-skills
> /plugin install platform-skills@platform-skills

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/ai-governance

Context preview

What this command does when you run it.

Generate and enforce policy gates for AI coding agents (Copilot, Claude Code) — real-time session hooks that deny protected-path edits and dangerous commands, plus a merge-time backstop for anything that bypasses them. Use when asked to "govern AI agents", "block AI from

Command definition

ai-governance.md
name: ai-governance
description: Generate and enforce policy gates for AI coding agents (Copilot, Claude Code) — real-time session hooks that deny protected-path edits and dangerous commands, plus a merge-time backstop for anything that bypasses them. Use when asked to "govern AI agents", "block AI from touching secrets", "add an AI policy gate", or "why did the AI agent hook not fire".
argument-hint: "[generate|check|audit|explain] [path]"
title: "AI Governance Command"
sidebar_label: "ai-governance"
custom_edit_url: null

Generate and enforce a policy gate for AI coding agents operating on this repo: real-time session hooks for Copilot and Claude Code, plus a merge-time GitHub Actions check that catches anything the hooks miss.

Read `references/ai-governance.md` before responding.

---

Interactive Wizard (fires when no arguments are provided)

When invoked with no arguments, ask before proceeding:

**Q1 — Mode?**

What do you need?
  1. generate — scaffold policy, evaluator, hooks, and merge-time check
  2. check    — dry-run the evaluator against a path, command, or diff
  3. audit    — scan repos in an org for policy presence, tier, and drift
  4. explain  — plain-English translation of an existing .ai-governance.yaml

Enter 1-4 or mode name:

**Q2 — Context** (after mode selected, one at a time):

  • **generate**: `Which default policy pack? (terraform / kubernetes / generic / blank)`
  • **check**: `Give me a file path, a command string, or a diff range (e.g. main...HEAD) to test:`
  • **audit**: `Which org or repo list should I scan?`
  • **explain**: `Path to the .ai-governance.yaml to explain (default: ./.ai-governance.yaml):`

Then proceed into the relevant mode below.

---

Mode: generate

Scaffold the policy file, evaluator, session hooks, and merge-time check for this repo.

Steps:

1. Detect which AI tools are configured (`.github/copilot/`, `.claude/`, `.cursor/`, `.codex/` if present) and which CI system is in use — reuse the scan approach `setup-agents.md` already implements; do not reimplement it.

2. Write `.ai-governance.yaml` with the chosen default pack. All packs share this shape; only `protected_paths` differs:

**generic:**

   version: 1
   source: local
   enforcement: audit
   protected_paths:
     - ".github/workflows/**"
     - ".github/hooks/**"
     - ".claude/settings.json"
     - ".ai-governance.yaml"
     - ".ai-governance/**"
     - "**/secrets/**"
   denied_commands:
     - "rm -rf"
     - "git push --force"
   max_diff_files: 25
   require_disclosure: true

**terraform** (adds): `"**/*.tfstate"`, `"iam/**"` to `protected_paths`; adds `"terraform apply"` to `denied_commands`.

**kubernetes** (adds): `"**/rbac/**"`, `"**/*secret*.yaml"` to `protected_paths`; adds `"kubectl delete"` to `denied_commands`.

**blank**: same shape, empty `protected_paths`/`denied_commands` — for a team that wants to author its own list from the CODEOWNERS-mandatory paths onward.

3. Copy `examples/ai-governance/evaluate.sh` into `.ai-governance/evaluate.sh` in the target repo, executable bit set (`chmod +x`).

4. Check for `yq` (`command -v yq`); if absent, install it using the OS-detected path (same pattern `checkov.md` uses for its own bootstrap). Pin the version and verify the checksum — `releases/latest` is a moving target, and this binary parses the file that decides what the agent may touch:

   YQ_VERSION=v4.53.6
   YQ_SHA256=c5f056448f973ae7d39b5401949648a78f2dc1947d6a8eb65be60d5c504b9385  # yq_linux_amd64

   case "$(uname -s)" in
     Darwin) brew install yq ;;   # Homebrew verifies its own bottle checksum
     Linux)
       curl -fsSL -o /tmp/yq \
         "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64"
       echo "${YQ_SHA256}  /tmp/yq" | sha256sum -c -
       sudo install -m 0755 /tmp/yq /usr/local/bin/yq
       ;;
   esac

5. Write `.github/hooks/preToolUse.json`:

   {
     "version": 1,
     "hooks": {
       "preToolUse": [
         {"type": "command", "bash": ".ai-governance/evaluate.sh --mode=hook --platform=copilot --event=preToolUse", "timeoutSec": 10}
       ]
     }
   }

And `.github/hooks/postToolUse.json` (same shape, `--event=postToolUse`). This one is not a second gate. `--event=postToolUse` short-circuits before the policy is even loaded: it appends one `completed` line to the audit log, emits no decision, and exits 0. It never re-evaluates `protected_paths` or `denied_commands` — the call has already run by then, and re-deciding would duplicate the audit line `preToolUse` already wrote for the same call under `audit` or `warn`:

   {
     "version": 1,
     "hooks": {
       "postToolUse": [
         {"type": "command", "bash": ".ai-governance/evaluate.sh --mode=hook --platform=copilot --event=postToolUse", "timeoutSec": 10}
       ]
     }
   }

6. **Merge, never overwrite** `.claude/settings.json`.

Claude Code's `settings.json` hook registration is **three levels deep**, not two: each event key holds an array of *matcher-group* objects, and each matcher group holds its own inner `hooks` array of handler objects. `matcher` is optional — omitting it means "match every tool call", which is what this policy wants (every call gets evaluated, not just one tool):

   {
     "hooks": {
       "PreToolUse": [
         {
           "hooks": [
             {"type": "command", "command": ".ai-governance/evaluate.sh --mode=hook --platform=claude --event=PreToolUse"}
           ]
         }
       ]
     }
   }

Merge into that structure with `jq`, appending a new matcher group whether or not the event key already has entries, and skipping the append if this exact command is already registered so re-running `generate` is idempotent:

   PRE_CMD='.ai-governance/evaluate.sh --mode=hook --platform=claude --event=PreToolUse'
   POST_CMD='.ai-governance/evaluate.sh --mode=hook --platform=claude --ev
Read more
Ships withplatform-skills

A production-grade field handbook for platform, DevOps, SRE, and cloud engineers covering Kubernetes, Flux CD, Terraform, GitHub Actions, AWS, OPA/Rego, KEDA, Karpenter, supply chain security, Falco, observability, and more.

Get the whole plugin
Stats
42
Stars
10
Forks
Active
Maintenance
Shell
Language
Apache-2.0
License
3d ago
Last commit
5mo ago
Created

Repo: nitinjain999/platform-skills

Other commands on platform-skills.