Policies that stop your coding agent from doing the thing you would have caught in review.
The policies · See it block · How it works · Contributing · the framework →
Your agent is fast, tireless, and occasionally commits an AWS key. Prompting it not to works until the context fills up. This is the part that does not depend on the model paying attention.
A rule an agent reads is advice. A hook that exits non-zero is a control. Both belong in a repo, and the difference has to be visible, because the failure mode of governance tooling is that everyone believes it is doing more than it is. So every policy here is labelled with what it actually reaches — stated up front rather than in the appendix, because 22 of the 39 are advisory, and that is the number most catalogs would round up:
| What it means | How many | |
|---|---|---|
enforced-at-commit |
the command exits non-zero, the commit does not happen | 9 |
in-agent |
the tool call is refused before it runs, if the hook itself runs | 8 |
advisory |
text an agent reads and may or may not follow | 22 |
The same distribution, in the shared open-coder-ai figure language and readable in either theme:
Advisory evals report as skipped, never as passing, because there is nothing to replay.
Enforced at commit — declarative gates, verified by replaying their own gate against a throwaway repo on every push.
| Policy | Blocks | Evals |
|---|---|---|
protect-main-branch |
commits and pushes to main/master |
4/4 |
scan-secrets |
credentials in staged changes | 20/20 |
verify-dependency-exists |
packages absent from your allowlist | 5/5 |
block-invisible-unicode |
bidi-override and tag-block Unicode in staged changes -- Trojan Source and instructions hidden from reviewers but legible to agents | 8/8 |
block-wildcard-agent-permissions |
committed everything-grants -- bare-wildcard shell grants and allow-everything tool lists -- that hand an agent unlimited tool authority | 11/11 |
pin-github-actions |
a workflow that references a third-party GitHub Action by a movable tag or branch instead of a full commit SHA -- so a re-tagged or compromised release can't change what CI runs; SHA pins and local actions pass | 9/9 |
block-wildcard-iam |
wildcard Action or Resource in an IAM policy document, AdministratorAccess attachment, GCP roles/owner or roles/editor, and Terraform wildcard action or resource lists -- the mechanizable slice of ASI03 |
6/6 |
block-unpinned-agent-components |
agent components pulled at an unpinned version -- npx/uvx/bunx launches at @latest (the standard MCP server idiom), quoted "@latest" in agent config, and :latest image tags -- the mechanizable slice of ASI04 |
6/6 |
block-unsafe-code-execution |
bare eval/exec, shell-mode subprocess calls, os.system, pickle/marshal loads, yaml.load without SafeLoader, execSync and new Function -- a best-effort line scan over the mechanizable slice of ASI05 |
7/7 |
Enforced before the tool runs — guard scripts consulted before the agent executes a command, natively wired in Claude Code, Cursor, Copilot CLI and VS Code (and, via the codex plugin format, Codex after its per-hook trust review).
| Policy | Refuses | Evals |
|---|---|---|
block-destructive-commands |
rm -rf /, force push, hard reset, terraform destroy, dropdb, helm uninstall, docker volume rm, aws s3 rm --recursive, gcloud … delete |
42/42 |
block-no-verify |
--no-verify, which bypasses every gate above |
17/17 |
protect-agent-config |
shell edits to the agent's own instruction, permission and enforcement files (now including the policy guard sources themselves) -- self-modification refused up front | 24/24 |
protect-commit-privacy |
commit messages and gh pr create/edit bodies that narrate the development conversation (or leak a session link) instead of describing the change — a leak class that only exists once an agent authors the commit |
20/20 |
block-curl-pipe-sh |
piping a network download into a shell or script interpreter — curl … | sh, wget … | bash, curl … | python, bash -c "$(curl …)", iwr … | iex — while download-to-file and pipes into non-interpreter tools stay allowed |
27/27 |
protect-ci-workflows |
shell writes to the CI/CD config that gates a change — .github/workflows/, .github/actions/, .github/dependabot.yml — so an agent can't delete or loosen the checks reviewing its own work; reads and chock sync pass |
19/19 |
block-unapproved-egress |
a network client that uploads data — curl -d/-F/--upload-file, -X POST, wget --post-file, Invoke-WebRequest -Method POST — to a host outside the egress allowlist; fetch-only traffic and pip install pass. A tool-time floor, not a network sandbox |
32/32 |
verify-mcp-allowlist |
a shell write to .mcp.json adding an MCP server not on the allowlist, or changing an allowed server's command/args/url to point elsewhere (including one renamed to an allowed name) — the allowlist ships inside the guard script itself, protected the same way as any other policy's guard source; a matching entry passes without a human approval each time |
15/15 |
22 advisory policies — expand
Advisory — rule text compiled into agent context. No mechanism, no executed evals.
agent-discipline · code-safety ·
context-hygiene · chock-mise ·
firecrawl-fallback-only ·
git-safety ·
injection-defense ·
memory-discipline · token-efficiency
3 compliance policies — expand
Compliance — jurisdiction-specific, in compliance/ rather than base/. Everything
above applies to any repo; these only earn their place if the regulation reaches you.
| Policy | Covers | In force |
|---|---|---|
eu-ai-act-transparency |
EU AI Act Art 50 — AI disclosure, machine-readable marking of synthetic output, deepfake labelling | now |
eu-ai-act-prohibited-practices |
Art 5 — social scoring, face scraping, workplace emotion inference, NCII/CSAM | now |
eu-ai-act-high-risk-triage |
Annex III domains, Articles 9–15 | 2027-12-02 |
Advisory, like everything else with no mechanism. Regulatory scoping is judgement, and a
keyword gate here would block on emotion_recognition in a comment.
OWASP ASI01–10 coverage — expand
Agentic security — the OWASP Top 10 for Agentic Applications (2026), in
agentic-security/. One policy per ASI category. These govern the agentic system you are
building; everything above governs the agent doing the building. They only earn their
place if your repo ships agents that plan, call tools, persist memory, or coordinate.
| Policy | Guards against |
|---|---|
owasp-asi01-agent-goal-hijack |
untrusted content redirecting the agent's goal or tool scope |
owasp-asi02-tool-misuse |
excess agency, parameter abuse, unsafe tool chains |
owasp-asi03-identity-privilege-abuse |
borrowed credentials, shared accounts, long-lived broad tokens |
owasp-asi04-agentic-supply-chain |
unverified MCP servers, frameworks, runtime-discovered tools |
owasp-asi05-unexpected-code-execution |
generated code escaping its sandbox; untrusted strings reaching an interpreter |
owasp-asi06-memory-context-poisoning |
poisoned durable memory steering later sessions |
owasp-asi07-insecure-inter-agent-communication |
peer impersonation, tampering, replay, fake discovery |
owasp-asi08-cascading-failures |
one agent's bad output propagating through downstream automation |
owasp-asi09-human-agent-trust |
approval surfaces the agent itself authors |
owasp-asi10-rogue-agents |
drifted, compromised, or uninventoried agents |
Advisory, and for the same reason: whether a tool grant is "least agency" is a judgement
about your architecture, not a pattern a gate can match. Three of these deliberately overlap
injection-defense, code-safety, and memory-discipline — those govern your coding
agent's own session, these govern the product it writes.
Three ASI categories do have a slice a diff can literally show, and those slices get real gates — narrow siblings named for exactly what they block, so the advisory policy never claims an enforcement it does not have:
| Gate | Blocks | Slice of | Evals |
|---|---|---|---|
block-unsafe-code-execution |
bare eval/exec, shell=True, unsafe deserialization |
ASI05 | 7/7 |
block-wildcard-iam |
"Action": "*", AdministratorAccess, roles/owner |
ASI03 | 6/6 |
block-unpinned-agent-components |
npx -y server@latest, :latest images |
ASI04 | 6/6 |
The pattern is the same one base/ uses: code-safety advises broadly while
scan-secrets blocks narrowly. The gate is not the rule promoted — it is the greppable
fraction, enforced honestly, with the judgement half still labelled advisory.
How the 10/10 claim above is re-derived on every build, and what partial versus full
actually means, is in docs/coverage.md.
Every policy has its own page — what it solves, how it works, which primitive it becomes, and what is safe to change.
The whole install is three commands, in a repo of your own:
pip install chock
git init -q demo && cd demo
chock init .
chock add scan-secrets
chock sync --repo .The next commit containing a credential exits non-zero instead of landing:
$ echo 'AWS_KEY=AKIAIOSFODNN7EXAMPLE' > config.py && git add config.py && git commit -m "add config"
Potential secret detected in this change. Remove credentials and rotate any exposed keys. At commit, add '# pragma: allowlist secret' on the same line only for documented test fixtures; the pragma is NOT honored at tool-use, where the scanned text is a live tool argument an appended token could neutralize.
- config.py: content pattern
# exit 1This is the session the GIF above records — real output from a real repository, not written to look like it was. The full seven-step transcript, including the passing commit once the key is removed, is in docs/demo-session.md; here is the shape of it.
Onboard a repo and adopt scan-secrets and protect-main-branch, on a feature branch:
$ chock init .
Initialized Chock in …
Policies: none. This repo enforces nothing yet.
$ chock add scan-secrets
Added scan-secrets to .agents/policies/scan-secrets
from https://github.com/open-coder-ai/chock-catalog at …
Compiled. Run `chock sync --repo .` to activate commit-time enforcement.
$ chock add protect-main-branch
Added protect-main-branch to .agents/policies/protect-main-branch
from https://github.com/open-coder-ai/chock-catalog at …
Compiled. Run `chock sync --repo .` to activate commit-time enforcement.
$ chock sync --repo .
Recompiled 2 policies
$ echo 'AWS_KEY=AKIAIOSFODNN7EXAMPLE' > config.py && git add config.py && git commit -m "add config"
Potential secret detected in this change. Remove credentials and rotate any exposed keys. At commit, add '# pragma: allowlist secret' on the same line only for documented test fixtures; the pragma is NOT honored at tool-use, where the scanned text is a live tool argument an appended token could neutralize.
- config.py: content pattern
# exit 1Remove the key and the same commit passes. Then, on main:
$ git commit --allow-empty -m notes
Direct commits/pushes to a protected branch (main|master) are blocked. Create a feature branch and open a pull request.
- main
# exit 1The protected branches in that message are not hard-coded — they are the ones the gate is
actually enforcing, read from chock.defaults.protected_branches. A block message that names
a different set from the gate is how an adopter learns to distrust the tool.
One folder per policy. manifest.yaml declares identity and either a gate or rule text;
chock sync compiles that into git hooks, native pre-tool hooks, or ambient rule text,
whichever surfaces the agent you use actually supports:
The same policy reaches different levels on different agents, and coverage.json records
every pair — unsupported where a surface can't carry it, rather than a silently missing row.
Gates run in git itself, so they hold no matter which agent, or human, is at the
keyboard — the whole argument for a hook over a prompt an agent can forget once the
instruction scrolls out of context. Thirteen adapters (claude, copilot, cursor,
gemini, codex, aider, windsurf, devin, grok, kimi-code, replit, tabnine,
vscode) are generated from one AGENTS.md, because the rules live in one place and the
adapters exist only to match filenames each agent looks for.
Every policy folder is yours: cp -r base/scan-secrets <your-repo>/.agents/policies/ plus
chock sync --repo . produces output byte-identical to chock add, and nothing upstream
ever overwrites your copy. The full argument for gates over prompts, the complete adapter
list, and what editing your copy looks like are in
docs/how-it-works.md.
The catalog is a Chock adopter: .agents/policies/ holds every base/ policy, so it
protects itself the same way it asks any open-source repo to, and the first commit after
adoption was rejected by protect-main-branch. That is not a flourish — a worked example
that is a repository cannot drift from the instructions the way a README snippet does, and
running it has already found four framework bugs no test caught. CI still keeps two things
apart: what this repo runs (the base/ tier only — the compliance and agentic-security
packs stay uninstalled because, by their own doctrine, they only earn their place where they
apply) and what this repo ships (every published policy, staged into a throwaway repo the
way an adopter installs them). A catalog should publish more than it is bound by — the
full three-paragraph version, including which policy is installed-but-disabled here and
why, and the specific framework bugs this adoption already caught, is in
docs/how-it-works.md.
Every base/<id>/ folder is also a conformant Agent Plugins 1.0.0
package — plugin.json plus skills/<id>/SKILL.md, both generated from manifest.yaml — so
any client implementing the spec can read these policies with no Chock installed at all. That
is a portability claim, not an enforcement one: the standard defines no hook mechanism, so a
policy read as a plugin is advisory regardless of its tier here, and real enforcement still
comes from chock sync or from the per-vendor plugin builds, each witnessed denying a
destructive command on a real install —
claude ·
copilot ·
cursor ·
codex.
A policy here is not inert data: its implementations/*.sh becomes a git hook that runs on
every commit and a guard consulted before your agent executes a command, so chock add
installs executable content over git clone. There is no signing key — pin and verify when
the catalog is not one you control:
chock add scan-secrets --ref v1.0.0 --verify-sha <sha256>Two limits worth knowing before you rely on any of this: git commit --no-verify skips every
git hook, and git hooks are not cloned — a fresh clone enforces nothing until someone runs
chock sync. SECURITY.md has the rest.
Issues and PRs welcome, including "this policy is wrong" — an overstated policy is worse here than a missing one. Every claim here is checked by CI rather than a reviewer's memory: a policy claims only what it can do, and its evals are the argument for what its gate actually blocks. Start with a good first issue, or read the full guide — transcripts, DCO, review criteria — in CONTRIBUTING.md and run the same loop CI does:
chock check && chock check --only evalsLooking for something specific to work on, or a place to ask a question first? The threat ledger and Discussions link are in CONTRIBUTING.md.
| agentseam | the primitives — one handler API and a verified capability matrix across 16 agents |
| chock | the compiler — one policy into git hooks, CI gates and native pre-tool hooks |
| chock-catalog | the policies — 39, each labelled enforced or advisory, with replayed evals |
| context-report | the evidence — a signed report of whether an agent artifact actually works |
| chock-threat-intel | the threat ledger the catalog's policies answer to |
| chock-{claude,cursor,copilot,codex}-plugins | the catalog, packaged for each agent's plugin format (generated) |
| chock-quickstart · chock-example | template repos: what chock init leaves behind, and a full adoption |
Apache-2.0 — see LICENSE. Contributor Covenant Code of Conduct.