An AI usage policy engineers will follow
An AI usage policy for coding agents is an acceptable-use document covering data classes, approved routes, disclosure, review duties and prohibited actions, in which every clause is tagged with how it is enforced: by managed settings, by a hook or repository rule, by detection after the fact, or by trust alone. Clauses that rest on trust need a named check.
Your legal team circulated a four-page “Generative AI Acceptable Use” PDF in spring. Since then two developers have logged in to Claude Code with personal accounts, someone added an unvetted MCP server that reads the whole Jira instance, and nobody can say which merged pull requests an agent wrote. The PDF was never wrong; it was unenforceable and unverifiable.
This page is for the CTO who signs the policy and the tech lead who makes it true in eight repositories. It reuses the data tiers from data privacy and enterprise policies and leaves distribution and audit to enforcing one policy across every coding agent.
What this AI usage policy template gives you
Section titled “What this AI usage policy template gives you”- A policy of 28 numbered clauses for your handbook, each tagged with its enforcement type.
- An enforcement map naming the Claude Code, Codex, Cursor or repository setting behind each clause.
- A managed-settings file for Claude Code and a
requirements.tomlfor Codex. - A prompt-screening hook and a pull-request disclosure check.
- A verification routine, plus the failure modes that quietly switch clauses off.
Why do engineers ignore most AI usage policies?
Section titled “Why do engineers ignore most AI usage policies?”Most AI policies state values (“use AI responsibly”), not behavior a reviewer could check. Engineers follow the letter and lose the tools, or follow judgment and hope. Neither produces the “clear and communicated AI stance” that DORA lists as the first of its seven AI capabilities (Google Cloud blog, Storer and DeBellis, 2025-09-23). DORA’s rationale: “Ambiguity creates risk. A clear policy provides the psychological safety developers need to experiment effectively” (Google Cloud blog, Harvey and Park, 2025-12-10).
A policy engineers follow is short and specific: every clause names an action, a data class or a tool setting, and a clause no concrete act can break belongs in the preamble. It is enforced where the tool allows it and honest about the rest: clauses no setting can enforce (“do not paste customer data into a browser chatbot on your phone”) are labeled trust clauses with a named check.
How is each clause tagged?
Section titled “How is each clause tagged?”| Tag | Meaning | Evidence that it holds |
|---|---|---|
[MANAGED] | Enforced by the tool’s managed configuration, which users and repositories cannot override | /status in Claude Code names the managed source; /debug-config in Codex shows the requirement source |
[HOOK] | Enforced by an organization-deployed hook that blocks the action at run time | Hook denial events in telemetry; a drill that triggers the block |
[REPO] | Enforced by repository rules or a required CI check, independent of which tool wrote the code | Ruleset and required-check configuration; a failing test PR |
[DETECT] | Not prevented, but detected after the fact through telemetry, audit logs or scanning | A named dashboard or report and its owner |
[TRUST] | Rests on the engineer’s judgment; no tool can see the act | A named periodic check (sampling, attestation, training record) |
Aim for mostly [MANAGED], [HOOK] and [REPO]; a mostly-[TRUST] policy is the legal team’s PDF with better formatting.
The AI usage policy template
Section titled “The AI usage policy template”Copy this into your handbook and replace the owners and tool list. Keep clause numbers stable, because hooks, CI messages and exception tickets cite them.
# AI usage policy for software engineering (v1.0, owner: CTO, reviewed quarterly)
Purpose: let every engineer use coding agents daily, on real work, inside guardrailsthe tools enforce. Where a guardrail cannot be enforced, this policy says so.
## 1. Scope1.1 Applies to every employee and contractor who uses an AI coding tool (IDE agent, CLI agent, cloud agent, chat assistant) on company code, data or systems. [TRUST]1.2 Applies to unattended agents (CI jobs, scheduled loops, review bots) through their owners, recorded in the agent identity register. [DETECT]
## 2. Data classes (tiers from the data privacy policy)2.1 Public and Internal code may be used with any approved route (section 3). [MANAGED]2.2 Confidential material (unreleased features, pricing logic, security design) may be used only through approved routes whose terms exclude training on company data. [MANAGED]2.3 Credentials never appear in a prompt. [HOOK]2.4 Customer PII, payment and health data never enter an agent's context: not in prompts, files the agent can read, logs or test fixtures. [TRUST]2.5 Agents may not read secret files (.env*, cloud credential files, SSH keys). [MANAGED]2.6 Production data reaches an agent only as an anonymized or synthetic copy. [TRUST]
## 3. Approved routes3.1 Use only the approved tools listed in the tool register, signed in to the company tenant. Personal accounts on company work are not allowed. [MANAGED]3.2 Use only the models on the approved list; new models are added through the model change process. [MANAGED]3.3 MCP servers, plugins and plugin marketplaces must be on the allowlist. [MANAGED]3.4 Browser chat assistants outside the tool register may be used for Public material only. [TRUST]3.5 A tool not on the register can be trialed through an exception (section 7), never by installing it and asking later. [DETECT]
## 4. Disclosure4.1 Commits an agent authored or co-authored carry the tool's attribution trailer; do not strip it. [MANAGED] [DETECT]4.2 Every pull request states its AI assistance level: none, assisted or agent-authored. [REPO]4.3 Customer-facing deliverables produced with agents follow the client contract's disclosure clause. [TRUST]
## 5. Review duties5.1 A human with merge rights approves every change before it reaches the default branch; an agent approval never counts as the required review. [REPO]5.2 The approver is accountable for the change as if they wrote it, and approves on evidence (tests, checks, acceptance criteria), not on the agent's summary. [TRUST]5.3 Changes to paths owned by security, payments or infrastructure require a review from the owning team. [REPO]5.4 CI gates (type check, lint, tests, secret scanning, dependency checks) must pass; no agent may disable or skip them. [REPO]
## 6. Prohibited actions6.1 Pasting credentials into a prompt, a file or an agent configuration. [HOOK]6.2 Running an agent with approvals and sandbox fully bypassed, outside a disposable, network-restricted sandbox. [MANAGED]6.3 Letting an agent force-push, rewrite shared history or push to protected branches. [MANAGED] [REPO]6.4 Letting an agent deploy to production, run migrations against production or change production secrets without the human gate in the governance policy. [REPO]6.5 Adding hooks, MCP servers or plugins to a repository to widen what an agent may do without platform-team review. [MANAGED]6.6 Using agent output to make decisions about people (hiring, performance). [TRUST]
## 7. Exceptions and review7.1 Exceptions are requested by ticket, name the clause, the scope and an end date, and are approved by the platform owner and security. [DETECT]7.2 This policy is reviewed quarterly and after every AI-related incident; each change names the clause, the reason and the enforcement change. [TRUST]The template counts 28 clauses: 17 are enforced by managed settings, hooks or repository rules (6.3 by both; 4.1 is also detected in CI), 3 are detected only, and 8 rest on trust.
Which clauses can Claude Code, Codex and Cursor enforce?
Section titled “Which clauses can Claude Code, Codex and Cursor enforce?”The enforcement map is the platform team’s working document; each row names the setting or rule that makes the clause true. Cursor cells are thinner because its admin controls could not be re-verified on 2026-09-26; treat a Cursor clause as [REPO] plus [TRUST] until your Cursor admin confirms the control.
| Clause | Claude Code (managed settings) | Codex (requirements.toml) | Cursor | Repository |
|---|---|---|---|---|
| 2.2 Confidential only on no-training routes | Company tenant login (3.1) plus the retention terms of that plan | Company workspace login (3.1) plus its data terms | Privacy settings: confirm in admin dashboard | — |
| 2.3 Credentials out of prompts | UserPromptSubmit hook that exits 2 | [hooks] UserPromptSubmit in requirements.toml | Hooks (JSON over stdio) | Secret scanning with push protection |
| 2.5 No secret-file reads | permissions.deny plus sandbox.filesystem.denyRead | [permissions.filesystem] deny_read (absolute paths or globs) | Confirm in agent security settings | — |
| 3.1 Company tenant only | forceLoginMethod, forceLoginOrgUUID | allowed_login_methods, allowed_chatgpt_workspaces | SSO on the team plan: confirm | — |
| 3.2 Approved models | availableModels, enforceAvailableModels; deniedModels needs v2.1.283 (latest channel on 2026-09-26) | No model allowlist key in requirements.toml (checked 0.157.1); model_provider pins the provider and [models.new_thread] sets defaults only | Model controls: confirm | — |
| 3.3 MCP, plugin, marketplace allowlist | allowedMcpServers + allowManagedMcpServersOnly, strictKnownMarketplaces | [mcp_servers.<name>.identity], plugins, marketplaces | Confirm in admin dashboard | — |
| 4.1 Attribution trailer | attribution in managed settings | A built-in instruction to add Co-authored-by: Codex <noreply@openai.com>, switched by the user’s account setting | — | Trailer detection in CI |
| 4.2, 5.1, 5.3, 5.4, 6.4 | — | — | — | Rulesets, CODEOWNERS, required checks, environment approvals |
| 6.2 No full bypass | permissions.disableBypassPermissionsMode: "disable" | allowed_sandbox_modes without danger-full-access; allowed_approval_policies | Confirm run-mode controls | — |
| 6.3 No force-push | permissions.deny on Bash(git push --force *) | [rules] prefix_rules with decision = "forbidden" | Hooks | Branch rulesets block force-push |
| 6.5 No repository-added hooks | allowManagedHooksOnly, allowManagedPermissionRulesOnly | allow_managed_hooks_only = true | — | CODEOWNERS on .claude/, .codex/, .cursor/ |
The repository column judges the change rather than the tool, so it covers every agent, including shadow tools; that is why clauses 5.1 to 5.4 and 6.4 live there. Both tools add attribution by instructing the model, not by rewriting the commit. Codex reads the switch from the user’s account setting (commit_attribution_enabled in openai/codex at rust-v0.157.1, checked 2026-09-26) and requirements.toml has no key for it, so for Codex clause 4.1 is detection only. A human can amend any commit, so the CI trailer check is the evidence for both tools.
How do you enforce the data and route clauses?
Section titled “How do you enforce the data and route clauses?”Deliver these files through device management, not the repository (see the first failure mode below).
Claude Code reads managed settings from /Library/Application Support/ClaudeCode/managed-settings.json on macOS, /etc/claude-code/managed-settings.json on Linux and WSL, and C:\Program Files\ClaudeCode\managed-settings.json on Windows, or from server-managed settings in the claude.ai admin console on Team and Enterprise plans. Managed settings take precedence over command-line arguments, project and user settings.
{ "forceLoginMethod": "claudeai", "forceLoginOrgUUID": "ORG_UUID", "availableModels": ["opus", "sonnet"], "enforceAvailableModels": true, "permissions": { "deny": [ "Read(./.env)", "Read(./.env.*)", "Read(~/.aws/**)", "Read(~/.ssh/**)", "Bash(git push --force *)", "Bash(git push -f *)" ], "disableBypassPermissionsMode": "disable" }, "allowManagedPermissionRulesOnly": true, "sandbox": { "enabled": true, "filesystem": { "denyRead": ["~/.aws/credentials", "~/.ssh"] } }, "allowedMcpServers": [ { "serverUrl": "https://api.githubcopilot.com/mcp/*" }, { "serverUrl": "https://mcp.internal.example.com/*" } ], "allowManagedMcpServersOnly": true, "strictKnownMarketplaces": [ { "source": "github", "repo": "anthropics/claude-plugins-official" }, { "source": "github", "repo": "acme-corp/approved-plugins" } ], "allowManagedHooksOnly": true, "attribution": { "commit": "Co-Authored-By: Claude <noreply@anthropic.com>\nAI-Policy: v1.0" }, "companyAnnouncements": [ "AI usage policy v1.0 applies: handbook/ai-usage-policy. Restricted data never goes in a prompt." ]}ORG_UUID is your Anthropic organization ID. The Read deny rules cover Claude’s file tools and the Bash file commands Claude Code recognizes, such as cat and sed. With the sandbox on, Claude Code also copies every Read(...) deny path into the sandbox’s denyRead list, which the operating system enforces for every sandboxed command; the explicit denyRead entries add home-directory credential files the default sandbox read policy would expose. List the marketplaces you actually approve: an empty strictKnownMarketplaces array blocks every source, including Anthropic’s official one.
Codex reads admin constraints from /etc/codex/requirements.toml on macOS and Linux and %ProgramData%\OpenAI\Codex\requirements.toml on Windows (paths from the openai/codex source, checked 2026-09-26). Keep config.toml for defaults and requirements.toml for constraints.
allowed_login_methods = ["chatgpt"]allowed_chatgpt_workspaces = ["WORKSPACE_ID"]allowed_approval_policies = ["on-request", "untrusted"]allowed_sandbox_modes = ["read-only", "workspace-write"]allowed_web_search_modes = ["disabled", "cached"]allow_managed_hooks_only = true
[mcp_servers.github.identity]url = "https://api.githubcopilot.com/mcp/"
[mcp_servers.jira.identity]url = "https://mcp.internal.example.com/jira"
[rules]prefix_rules = [ { pattern = [{ token = "git" }, { token = "push" }, { any_of = ["--force", "-f"] }], decision = "forbidden", justification = "AI usage policy 6.3: no force-push" },]WORKSPACE_ID is your ChatGPT workspace ID. Listing MCP servers under [mcp_servers.<name>.identity] turns the section into an allowlist: a server whose name and URL or command do not match is filtered out. A prefix rule matches tokens in order, so git push origin main --force slips past it, as it slips past the Claude Code Bash(git push --force *) pattern. That is why clause 6.3 is also [REPO]: the branch ruleset blocks the force-push whatever the spelling. allowed_web_search_modes keeps Confidential context out of live search queries (clause 2.2); drop it if your policy allows live search.
Cursor documents Rules, Hooks (JSON over stdio), Plugins and MCP configuration (checked 2026-08-28). Its admin controls could not be re-verified on 2026-09-26, so this page does not name them.
- Ask your Cursor admin to confirm, in the admin dashboard, a control for each of clauses 2.2, 3.1, 3.2 and 3.3. Record each one you find in the enforcement map as
[MANAGED]. - Deploy the same prompt screening as a Cursor hook, after checking its input and blocking contract on Cursor’s hooks page.
How do you enforce prohibited actions with a hook?
Section titled “How do you enforce prohibited actions with a hook?”Clauses 2.3 and 6.1 need a check that runs before the model sees the prompt. The script below rejects a prompt that contains a private key or a common credential format; it cannot recognize customer PII, which is why clause 2.4 stays [TRUST]. Save it where developers cannot edit it and register it in managed settings.
#!/usr/bin/env bash# /etc/claude-code/hooks/block-credentials.sh (AI usage policy 2.3, 6.1)command -v jq >/dev/null || { echo 'AI usage policy: jq missing, prompt blocked' >&2; exit 2; }prompt=$(jq -r '.prompt // empty') || { echo 'AI usage policy: unreadable hook input, prompt blocked' >&2; exit 2; }if printf '%s' "$prompt" | grep -Eq -- '-----BEGIN [A-Z ]*PRIVATE KEY-----|AKIA[0-9A-Z]{16}|gh[pousr]_[A-Za-z0-9]{36}|sk-ant-[A-Za-z0-9_-]{20,}'; then echo "Blocked by AI usage policy 2.3/6.1: the prompt contains a credential. Remove it and reference the secret by name." >&2 exit 2fiexit 0{ "hooks": { "UserPromptSubmit": [ { "hooks": [{ "type": "command", "command": "/etc/claude-code/hooks/block-credentials.sh" }] } ] }}In Claude Code, exit code 2 from a UserPromptSubmit hook rejects the prompt and shows the message; exit code 1 is a non-blocking error that lets the prompt through. With allowManagedHooksOnly set, only managed hooks and hooks from force-enabled plugins run. The two jq guards make the hook fail closed when jq is missing or the input cannot be parsed.
Codex has the same UserPromptSubmit event among its 12 hook events. Register the script in the [hooks] table of requirements.toml (shape from hook_config.rs and config_requirements.rs in openai/codex at rust-v0.157.1, checked 2026-09-26):
[hooks]managed_dir = "/etc/codex/hooks"windows_managed_dir = 'C:\ProgramData\OpenAI\Codex\hooks'
[[hooks.UserPromptSubmit]]
[[hooks.UserPromptSubmit.hooks]]type = "command"command = "/etc/codex/hooks/block-credentials.sh"timeout = 10A user or project layer cannot replace these managed hooks. The source does not settle whether Codex reads exit code 2 as Claude Code does, so confirm the block with /hooks and a test prompt. The pattern list is a floor: pair it with your secret scanner’s rules.
How do you enforce disclosure and review in the repository?
Section titled “How do you enforce disclosure and review in the repository?”Three controls carry clauses 4.2 and 5.1 to 5.4:
- A branch ruleset on the default branch requiring a pull request, one approving review, passing required checks and no force-pushes. Only approvals from accounts with write access count, so keep agent identities without it.
- CODEOWNERS for security-owned paths and the agent configuration directories (
.claude/,.codex/,.cursor/,.mcp.json), so widening an agent’s permissions needs the platform team. - A required disclosure check, below, on every pull request.
name: ai-disclosureon: pull_request: types: [opened, edited, synchronize]permissions: contents: readjobs: disclosure: runs-on: ubuntu-latest steps: - name: Require an AI assistance declaration (policy 4.2) env: PR_BODY: ${{ github.event.pull_request.body }} run: | if ! printf '%s' "$PR_BODY" | grep -Eq '^AI assistance: (none|assisted|agent-authored)[[:space:]]*$'; then echo "::error::Add 'AI assistance: none|assisted|agent-authored' to the PR description (AI usage policy 4.2)." exit 1 fiThe workflow passes the untrusted PR body through env:, not interpolation. It proves a declaration exists, not that it is true: add a second step that flags a PR whose commits carry a Co-Authored-By: Claude or Co-authored-by: Codex trailer while the body says none. The change provenance answer key shows how to route the declared level into review depth.
How do you make trust clauses checkable?
Section titled “How do you make trust clauses checkable?”Eight clauses stay [TRUST]. For each, name a check and an owner, so “trust” means “trusted and sampled”, not “unexamined”:
| Clause | Check | Owner | Cadence |
|---|---|---|---|
| 1.1, 3.4 Scope and browser chat | Annual attestation plus the AI-literacy training record | Engineering managers | Yearly, at onboarding |
| 2.4 No PII, payment or health data | Sample 10 agent-session transcripts and the fixtures and logs they touched; check for real customer data | Data protection lead | Quarterly |
| 2.6 Anonymized production data | Sample 10 test fixtures added in agent-authored PRs; check for real identifiers | Data protection lead | Quarterly |
| 4.3 Client disclosure | Contract checklist at kickoff for each client engagement | Delivery lead | Per engagement |
| 5.2 Approve on evidence | Sample 20 merged agent-authored PRs; can the approver name the evidence? | Tech leads | Monthly |
| 6.6 No decisions about people | HR process review | HR and CTO | Yearly |
| 7.2 Policy review | Change log with clause, reason and enforcement change | CTO | Quarterly |
The AI-literacy record can also serve as evidence of the staff AI-literacy measures that Article 4 of the EU AI Act still requires (softened, not removed, by the Digital Omnibus according to Gibson Dunn’s summary, checked 2026-09-26); see the EU AI Act for companies building software with agents.
The three [DETECT] clauses each need a source and owner:
| Clause | Detection source | Owner | Cadence |
|---|---|---|---|
| 1.2 Unattended agents registered | Agent identity register reconciled against CI service accounts and bot tokens | Platform team | Monthly |
| 3.5 No unregistered tools | Device-management software inventory, plus claude_code.managed_settings_resolved coverage | IT and security | Monthly |
| 7.1 Exceptions expire | Exception tickets past their end date | Security | Weekly |
How do you verify the policy is actually in force?
Section titled “How do you verify the policy is actually in force?”A clause marked [MANAGED] that is not deployed is worse than a [TRUST] clause, because everyone believes it holds. Run this routine at rollout and every quarter.
- Confirm the managed source on a sample of machines. In Claude Code,
/statusshowsEnterprise managed settingsin theSetting sourcesline, andclaude doctorlists entries dropped as invalid. In Codex,/debug-configshows config layers and requirement sources. - Drill each enforced clause in a disposable scratch repository with no real secrets: first confirm
claude --dangerously-skip-permissions,codex -s danger-full-accessandcodex --dangerously-bypass-approvals-and-sandboxare rejected (6.2), then, in a normal session, paste a dummy key that matches the hook pattern, add an unlisted MCP server and force-push from the agent. Each attempt must fail with a message that cites the clause. - Check the repository controls with a test PR. Open a PR with no disclosure line and one that edits
.claude/settings.json. The first must fail the required check; the second must request the platform team’s review. - Watch the detection signals. With Claude Code’s OpenTelemetry export (
CLAUDE_CODE_ENABLE_TELEMETRY=1and an OTLP endpoint set in managed settings), theclaude_code.managed_settings_resolvedevent shows which managed source each session loaded, andclaude_code.hook_execution_completecounts blocking decisions (num_blocking) per hook. Coverage below 100% means machines outside the rollout, and rising denials on one clause mean it is blocking real work (see below). The agent observability guide covers the pipeline. - Record the results. Keep the drill log with the policy version: it is the auditor’s evidence and the input to the quarterly review (clause 7.2).
Sign-off: the platform owner signs the drill log, security countersigns the map, and the CTO approves each version. The operating model places these roles in its RACI.
Prompts to tailor and audit the policy
Section titled “Prompts to tailor and audit the policy”Run both prompts in Claude Code or Codex from the root of your handbook repository.
Drill 6.1 separately, because the hook would reject the combined prompt at submission: submit a one-line prompt containing AKIAABCDEFGHIJKLMNOP and expect the 2.3/6.1 message. Drill 6.2 from the shell, as in step 2 of the verification routine.
A “no” in the blocked column is a finding, not an agent failure.
Why do AI usage policies fail in practice?
Section titled “Why do AI usage policies fail in practice?”A policy lives in project settings. A repository’s .claude/settings.json or .codex/config.toml can be changed on any branch. Recovery: move every enforcement key to managed settings or requirements.toml, keep project files for defaults, and put CODEOWNERS on the agent directories.
Login pinning with the wrong key. In Claude Code, forceLoginMethod pre-selects but does not enforce the method on the interactive /login screen; forceLoginOrgUUID from a managed source is what restricts claude.ai logins to your organization. Recovery: set both, and test by logging in with a personal account.
Deny rules that look complete. Read deny rules miss commands that read files without naming them, such as grep -r, and arbitrary subprocesses. Recovery: turn on the sandbox with sandbox.filesystem.denyRead, and keep secrets out of the workspace, per agent identity, credentials and secrets.
A managed file that breaks startup or disables a feature. Claude Code refuses to start when a managed settings file is not valid JSON, allowManagedHooksOnly stops /goal from running because it depends on hooks, allowManagedPermissionRulesOnly ignores every user and project allow rule, and sandbox.enabled needs bubblewrap on Linux and WSL2 and is not supported on native Windows. Recovery: validate the file in CI, put shared allow rules in managed settings, special-case native Windows and pilot first.
A hook that fails open. Without guards, a missing dependency or unparsable input yields an empty prompt and exit 0, so everything goes through while the clause is still tagged [HOOK]. Recovery: fail closed, as the jq guards above do, and include the hook in the drill.
Codex keys in the wrong file or the wrong system. allow_managed_hooks_only in config.toml does nothing, and a [rules] entry with decision = "allow" fails to parse. On permission profiles (beta), allowed_sandbox_modes is the wrong constraint: use allowed_permission_profiles, because OpenAI states the profile and legacy sandbox systems do not compose. Recovery: keep a linted requirements.toml in the platform repository and check /debug-config on a sample machine after every change.
CI runners caught by the developer file. Leaving never out of allowed_approval_policies also blocks codex -a never on any machine that carries the file, including a CI runner. Recovery: exclude runners from the device rollout and give them their own requirements.toml.
The policy blocks the work. Engineers route around an approved route that is slower than the forbidden one. Watch the exception queue (clause 7.1) and hook-denial counts; a clause that generates weekly exceptions needs a better approved route, not a sterner memo.
Shadow tools the map never covered. A new IDE agent or browser extension carries none of your managed settings. Add the tool to the register or block it at the device layer, per the tooling policy answer key.
Treat any policy breach that reaches production as an incident: revoke the identity, then fix the control that failed; see when an agent causes an incident.
Where to go next with your AI usage policy
Section titled “Where to go next with your AI usage policy”- Enforcing one policy across every coding agent covers distribution, versioning and audit of these files, including for GitHub Copilot.
- Governance and autonomy: put humans at the gates defines the production gate that clause 6.4 points to.
- The agent threat model explains which attacks clauses 2.3, 3.3 and 6.5 close.
- Where the model runs settles the retention and residency questions behind clause 2.2.
- Legal and IP questions about agent-written code covers client disclosure and ownership behind clause 4.3.
- Shared hooks governance shows how to review, test and version the hooks that carry clauses 2.3 and 6.1.