🛡️ plan-linter
"Fail your agent's flight-plan in CI—before it fails production."
plan-linter is an open-source static analysis toolkit for LLM agent plans.
It parses the machine-readable plan emitted by a planner/brain, validates it against schemas, policy rules, and heuristics, and returns Pass / Fail with an annotated risk-score JSON.
📦 Installation
Using pip
pip install plan-lint
From source
git clone https://github.com/cirbuk/plan-lint.git
cd plan-lint
pip install -e .
🚀 Quick Start
The simplest way to use plan-linter is to run it on a plan JSON file:
plan-lint path/to/plan.json
For a more advanced usage, you can provide a policy file:
plan-lint path/to/plan.json --policy path/to/policy.yaml
📝 Example Plan Format
{
"goal": "Update product prices with a discount",
"context": {
"user_id": "admin-012",
"department": "sales"
},
"steps": [
{
"id": "step-001",
"tool": "sql.query_ro",
"args": {
"query": "SELECT product_id, current_price FROM products"
},
"on_fail": "abort"
},
{
"id": "step-002",
"tool": "priceAPI.bulkUpdate",
"args": {
"product_ids": ["${step-001.result.product_id}"],
"discount_pct": -20
}
}
],
"meta": {
"planner": "gpt-4o",
"created_at": "2025-05-15T14:30:00Z"
}
}
📋 Example Policy Format
# policy.yaml
allow_tools:
- sql.query_ro
- priceAPI.bulkUpdate
bounds:
priceAPI.bulkUpdate.discount_pct: [-40, 0]
deny_tokens_regex:
- "AWS_SECRET"
- "API_KEY"
max_steps: 50
risk_weights:
tool_write: 0.4
raw_secret: 0.5
loop: 0.3
fail_risk_threshold: 0.8
For detailed information on creating policies, including advanced YAML policies and Rego policies with Open Policy Agent integration, see our Policy Authoring Guide.
🔍 Command Line Options
Usage: plan-lint [OPTIONS] PLAN_FILE
Options:
--policy, -p TEXT Path to the policy YAML file
--schema, -s TEXT Path to the JSON schema file
--format, -f TEXT Output format (cli or json) [default: cli]
--output, -o TEXT Path to write output [default: stdout]
--fail-risk, -r FLOAT Risk score threshold for failure (0-1) [default: 0.8]
--help Show this message and exit
🧩 Adding Custom Rules
You can create custom rules by adding Python files to the plan_lint/rules directory. Each rule file should contain a check_plan function that takes a Plan and a Policy object and returns a list of PlanError objects.
Here's an example of a custom rule that checks for SQL write operations:
from typing import List
from plan_lint.types import ErrorCode, Plan, PlanError, Policy
def check_plan(plan: Plan, policy: Policy) -> List[PlanError]:
errors = []
for i, step in enumerate(plan.steps):
if step.tool.startswith("sql.") and "query" in step.args:
query = step.args["query"].upper()
write_keywords = ["INSERT", "UPDATE", "DELETE"]
for keyword in write_keywords:
if keyword in query:
errors.append(
PlanError(
step=i,
code=ErrorCode.TOOL_DENY,
msg=f"SQL query contains write operation '{keyword}'",
)
)
return errors
🤝 Contributing
We welcome contributions from the community! To get started:
- Check the open issues or create a new one to discuss your ideas
- Fork the repository
- Make your changes following our contribution guidelines
- Submit a pull request
Please read our Code of Conduct to keep our community approachable and respectable.
🏗️ Development
To set up a development environment:
# Clone the repository
git clone https://github.com/cirbuk/plan-lint.git
cd plan-lint
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install development dependencies
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install
📚 Documentation
For comprehensive documentation, visit our documentation site or build it locally:
# Clone the repository
git clone https://github.com/cirbuk/plan-lint.git
cd plan-lint
# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install the package with documentation dependencies
pip install -e ".[docs]"
# Build and serve the documentation locally
mkdocs serve
The documentation includes:
- Detailed guides on policy authoring
- Examples of integrating with MCP servers
- API reference
- Advanced usage scenarios
You can also build a static version of the documentation:
mkdocs build
This will create a site directory with the static HTML documentation.
📄 License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Metadata
Release files for plan-lint 0.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| plan_lint-0.0.3.tar.gz | 50.6 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| plan_lint-0.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.6 MB
Release files / plan_lint-0.0.3.tar.gz
| Download URL | plan_lint-0.0.3.tar.gz |
|---|---|
| Size | 50.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6c2c49dcd43cbbba43409dfbd3efae51766b5ce401e5f42ce191f11939a7b98a
|
|
BLAKE2b-256 checksum How to use checksums |
26a44946590fe11238ebf7689e08d9c3fcbd0e735098838c250dfc4126fd2ff9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.5.24
|
Release files / plan_lint-0.0.3-py3-none-any.whl
| Download URL | plan_lint-0.0.3-py3-none-any.whl |
|---|---|
| Size | 21.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ea83abf412338e007110eb511b5716cda61c752c6733539dc1ce470b2887b002
|
|
BLAKE2b-256 checksum How to use checksums |
7c05f5ff8c98bff1dedeeb568f31fcaee6317720fb83da9a9be75c1421bc632f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.5.24
|