$git clone https://github.com/hermes-labs-ai/lintlanglintlang is a deterministic static linter for AI agent configs, tool descriptions, and system prompts. It combines 7 structural detectors (H1–H7) with 6 HERM v1.1 scoring dimensions and runs without model or network calls.
| 1 | # lintlang |
| 2 | |
| 3 | **lintlang is a deterministic static linter for AI agent configs, tool descriptions, and system prompts. It combines 7 structural detectors (H1–H7) with 6 HERM v1.1 scoring dimensions and runs without model or network calls.** |
| 4 | |
| 5 | > Release status: `0.3.1` is the latest public release, on PyPI and GitHub. |
| 6 | |
| 7 | This release also includes a separate provider-neutral `preflight` surface for |
| 8 | one present instruction plus explicit context. See [Provider-neutral preflight](docs/preflight.md). |
| 9 | |
| 10 | Run `bash evals/sample-detection-rate.sh` to check the bundled regression fixtures: four deliberately broken samples must be flagged and one designated clean sample must pass. This is a repository regression check, not an accuracy estimate or validation corpus. |
| 11 | |
| 12 | AI agent configs can be syntactically valid while their language remains vague, unbounded, or structurally inconsistent. |
| 13 | |
| 14 | `lintlang` flags a bounded set of those static patterns before runtime review — without calling a model. |
| 15 | |
| 16 | - "My agent picks the wrong tool because the tool descriptions all sound the same." |
| 17 | - "We only catch prompt and config drift after the agent starts looping." |
| 18 | - "I want a prompt linter or agent-config linter that runs in CI with no model calls." |
| 19 | - "Our YAML is valid, but the instructions inside it are still bad." |
| 20 | |
| 21 | ```bash |
| 22 | pip install lintlang |
| 23 | ``` |
| 24 | |
| 25 | ```bash |
| 26 | lintlang scan samples/bad_tool_descriptions.yaml |
| 27 | ``` |
| 28 | |
| 29 | ```text |
| 30 | LINTLANG v0.3.1 |
| 31 | samples/bad_tool_descriptions.yaml |
| 32 | |
| 33 | FAIL — 1 CRITICAL, 2 HIGH, 6 MEDIUM, 3 LOW |
| 34 | H1: Tool Description Ambiguity |
| 35 | [CRITICAL] tool:process_ticket |
| 36 | Tool 'process_ticket' has no description. |
| 37 | ``` |
| 38 | |
| 39 | ## How it differs from LLM-based config review |
| 40 | |
| 41 | Model-based agent-config review depends on a model runtime and may add API cost, latency, or output variability. lintlang skips the model and applies local static rules. |
| 42 | |
| 43 | | | LLM-based config review | lintlang | |
| 44 | |---|---|---| |
| 45 | | Model or API cost per scan | Provider-dependent | **None** | |
| 46 | | Model or API latency | Provider-dependent | **None** | |
| 47 | | Same input → same output | Model/configuration-dependent | **Yes (regex + AST)** | |
| 48 | | Runs without a model or API key | No | **Yes** | |
| 49 | | Catches *vague* tool descriptions | Model-dependent | **Static H1 heuristic** | |
| 50 | | Detects *missing* termination conditions | Model-dependent | **Static H2 heuristic** | |
| 51 | |
| 52 | Detection rules are static regex + structural heuristics. File discovery and findings are deterministically ordered. |
| 53 | |
| 54 | ## When to use it |
| 55 | |
| 56 | Use `lintlang` when you author or review AI agent tool descriptions, system prompts, or config files and want a static prompt/config quality gate in CI before runtime testing. |
| 57 | |
| 58 | ## When NOT to use it |
| 59 | |
| 60 | - **Semantic correctness** — lintlang is structural. It catches *vague* tool descriptions, not *wrong* ones. ("delete_user" with empty description fails; "delete_user" pointing at the wrong table is invisible to lintlang.) |
| 61 | - **Open-ended creative writing** — H1–H7 are calibrated for agent configs and system prompts, not prose. |
| 62 | - **Silent auto-fix or sending** — repository scans do not rewrite; preflight corrections require an explicit source-bound preview/apply action and never contact a provider. |
| 63 | - **Behavioral safety proofs** — a clean lintlang scan is not evidence that an agent is safe or correct. Use runtime evaluation and domain review for behavioral claims. |
| 64 | - **Input boundaries** — JSON, YAML, plain text, `.prompt`, and Markdown are parsed as language-bearing inputs. Python files use AST extraction only for embedded prompts and agent-pipeline thresholds; lintlang does not lint general Python syntax, style, types, or program correctness. Arbitrary nested templates may not parse. |
| 65 | |
| 66 | [](https://github.com/hermes-labs-ai/lintlang/actions/workflows/ci.yml) |
| 67 | [](https://pypi.org/project/lintlang/) |
| 68 | [](https://pypi.org/project/lintlang/) |