Custom Policies
Anvil evaluates custom rules written in OPA/Rego. This tutorial walks through creating, testing, and running a policy that limits file length.
Prerequisites
- Anvil initialised in your project (
anvil init) - OPA binary installed (install guide)
Verify OPA is available:
opa version
1. Create the Policies Directory
mkdir -p .anvil/policies
Anvil loads every .rego file in this directory automatically.
2. Write the Policy
Create .anvil/policies/max_file_length.rego:
package anvil.policies.max_file_length
import future.keywords.if
default max_lines := 300
max_lines := input.config.max_lines if {
input.config.max_lines
}
violation[msg] {
count(input.file.lines) > max_lines
msg := sprintf("%s exceeds %d lines (%d)",
[input.file.path, max_lines,
count(input.file.lines)])
}
How it works:
max_linesdefaults to 300 but can be overridden viainput.config- The
violationrule fires when a file exceeds the threshold - Anvil treats every string in the
violationset as a warning
3. Test the Policy
Run the built-in policy test harness:
anvil policy test
Testing policies...
.anvil/policies/max_file_length.rego
PASS violation fires when file exceeds max_lines
PASS no violation when file is within limit
PASS respects config override
All policy tests passed.
Add your own test cases in
.anvil/policies/max_file_length_test.regousing standard OPA test conventions. :::
4. Run the Policy
anvil check --all
Checking architecture... done
Checking anti-patterns... done
Checking policies...
[POLICY] max_file_length
src/services/legacy-handler.ts exceeds 300 lines (487)
1 policy warning found.
5. Customise the Threshold
Override the default in anvil.config.json:
{
"gates": {
"policies": {
"enabled": true,
"config": {
"max_file_length": {
"max_lines": 500
}
}
}
}
}
You can also set per-directory thresholds using gate-config.json files placed alongside the code they govern.
Ideas for More Policies
| Policy | What it enforces |
|---|---|
| Naming conventions | Require files in src/services/ to end with .service.ts |
| Import depth | Flag import chains deeper than N levels |
| Test ratio | Require at least one test file per source file |
| Export count | Warn when a module exports more than a threshold |
Each policy is a standalone .rego file. Drop it into .anvil/policies/ and
Anvil picks it up on the next run.
Next: Architecture Boundaries