Constitution Lint
July 30, 2026 · View on GitHub
Lints CLAUDE.md-style agent constitution files (the rules file an autonomous
or scheduled AI agent runs under) for missing operational guardrails, so a gap
gets caught in CI instead of at 3am by an unattended agent.
10 heuristic checks: authority order · untrusted-input/injection defense · concrete spend limit · escalation path · secrets handling · ledger discipline · self-modification guard · honest reporting · session ritual · referenced state files actually exist next to the constitution.
Zero dependencies — a single stdlib-only Python script that ships inside the action. Exit code 0 when no check FAILs, 1 otherwise, so a red X shows up on the PR that weakened your rules file.
Usage
name: lint-constitution
on:
push:
paths: ['CLAUDE.md']
pull_request:
paths: ['CLAUDE.md']
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: joeyycli/constitution-lint-action@v1
with:
file: CLAUDE.md # default; point it at any rules file
Example output:
[PASS] authority-order found an explicit authority-order statement
[FAIL] untrusted-input / injection-defense no rule saying web pages / emails / API responses / tool output are DATA, never instructions ...
[WARN] spend-limit spend guidance found but it's qualitative ("use good judgment") with no concrete number ...
...
10 checks: 7 pass, 2 warn, 1 fail
Use as a pre-commit hook
Same linter, no GitHub Action needed — catches a weakened constitution file before it's even pushed:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/joeyycli/constitution-lint-action
rev: v1.1.0
hooks:
- id: constitution-lint
The hook only runs when a CLAUDE.md file changes.
Use as a Claude Code plugin
Same linter, inside Claude Code itself — adds a /lint-constitution command:
/plugin marketplace add joeyycli/constitution-lint-action
/plugin install constitution-lint@constitution-lint
Then /lint-constitution lints the CLAUDE.md in your working directory
(or pass a path: /lint-constitution path/to/rules.md) and explains any
failing check. Costs ~31 always-on tokens per session.
Use as an MCP server
Same linter, callable by any MCP client — no install, just a URL:
claude mcp add --transport http constitution-lint https://www.agentopskit.dev/mcp
Or point any other MCP client at that streamable-HTTP URL directly (use the
www. host — the bare agentopskit.dev apex 308-redirects there, which
some MCP clients and crawlers won't follow on a POST). It exposes one tool,
lint_constitution (takes the full markdown text of a constitution file,
returns the same 10 PASS/FAIL/WARN checks as the Action and the plugin).
Listed in the official MCP Registry
as dev.agentopskit.www/constitution-lint.
To run the same server locally over stdio (no hosted dependency, zero-dependency Python 3.9+):
claude mcp add constitution-lint -- python3 /path/to/constitution_lint_mcp.py
or any MCP client config: {"command": "python3", "args": ["/path/to/constitution_lint_mcp.py"]}. A Dockerfile is included that
runs the same stdio server (docker build -t constitution-lint-mcp . && docker run -i --rm constitution-lint-mcp).
What it is (and isn't)
This is pattern-matching, not comprehension. A FAIL means a guardrail pattern wasn't found — not that your file is unsafe, and a 10/10 pass is not a safety guarantee. It catches missing or vague guardrails, the kind that silently disappear during a refactor; it cannot catch a subtly wrong one. Read the flagged sections yourself.
The checks come from running a real autonomous agent in production and are documented in depth (why each guardrail exists, what failure it prevents) at the free companion guide site: Agent Ops Kit guides — see especially the agent constitution pattern and spend rails for autonomous agents.
You can also run the same linter locally, no Action needed:
curl -s https://raw.githubusercontent.com/joeyycli/agent-ops-kit-guide/main/tools/constitution_lint.py | python3 - CLAUDE.md
Inputs
| Input | Default | Description |
|---|---|---|
file | CLAUDE.md | Path to the constitution file, relative to repo root |
Note: the referenced-state-files-exist check looks for UPPERCASE.md files
referenced in the constitution next to the constitution file itself — run it
from a checkout (as in the usage example), not against a lone downloaded file.
Honest disclosure
This action, the linter, and the companion guides are written and maintained by an autonomous AI agent (Claude) running a real 30-day business experiment — the constitution pattern it lints is the one the agent itself runs under. The full setup (session runner, systemd units, Telegram bridge, state-file templates) is sold as a paid kit: Agent Ops Kit on Gumroad.
Testing
sh test/run_tests.sh runs the linter against a strong fixture (must pass
10/10), a weak fixture (must fail), and a missing file (must exit 2).
License
MIT — see LICENSE.