# Rule guide
All rules can be configured under `rules` with `off`, `info`, `warning`, or `error`.
For example, disable a rule with `rules: { AGL301: off }`. `agentlint explain AGLxxx`
prints the same core guidance in the terminal.
## Structure (AGL0xx and AGL1xx)
### AGL001 — invalid syntax
Detects JSON, YAML, and TOML that cannot be parsed. Broken syntax prevents agents
from loading configuration. Bad: `{ "servers":`. Good: `{ "servers": {} }`.
### AGL002 — invalid frontmatter
Detects unclosed delimiters, invalid YAML, non-mapping metadata, invalid field types,
and unsupported fields in Markdown/MDC frontmatter. Bad: `description: [`.
Good: `description: Backend rules` between complete `---` delimiters.
### AGL003 — duplicate key
Detects a repeated JSON key in the same object. Different parsers may choose different
values. Bad: two `command` keys in one server. Good: one authoritative `command`.
### AGL101 — invalid MCP
Detects non-object roots/servers, empty servers, absent `command`/`url`, and malformed
`args`, `env`, or `cwd`. Bad: `{ "mcpServers": { "fs": {} } }`. Good: provide a
non-empty command and string argument list.
### AGL102 — unknown field
Detects fields outside conservative known sets for MCP servers and frontmatter. This
often catches spelling errors. Bad: `commandd`. Good: `command`. Vendor extensions
can be allowed by setting this rule to `off` for repositories that need them.
### AGL103 — invalid URL
Detects malformed MCP endpoints and schemes other than HTTP(S). Bad: `ht!tp://host`.
Good: `https://mcp.example.com`.
### AGL104 — missing executable
Checks MCP commands against explicit paths or local `PATH` without executing them.
Bad: `command: npxx`. Good: an installed `npx` or a valid repository-relative binary.
### AGL105 — undocumented environment
Detects `${NAME}`/`$NAME` MCP environment references absent from `.env.example`,
`.env.sample`, or `.env.template`. Bad: require `API_TOKEN` without setup guidance.
Good: add an empty `API_TOKEN=` entry to `.env.example`—never the real value.
## References (AGL2xx)
### AGL201 — invalid glob
Compiles instruction frontmatter globs and reports invalid patterns. Bad: `[src/**`.
Good: `src/**`. agentlint does not guess the intended scope.
### AGL202 — missing path
Uses Markdown links, inline code, extensions, known repository prefixes, MCP args, and
MCP working directories to find plausible paths without treating arbitrary slash words
as paths. Bad: reference removed `src/api/auth.ts`. Good: update it to the current path.
### AGL203 — missing script
Reports missing `scripts/*.sh`, `.fish`, or `.py` references at error severity because
required workflows cannot run. Bad: `Run scripts/check.sh` after it was deleted. Good:
reference the existing validation script.
## Context (AGL3xx)
### AGL301 — large context
Warns at 6,000 approximate local tokens. Large durable prompts crowd out working
context. Bad: embed a complete handbook. Good: keep actionable policy and link to
on-demand documentation.
### AGL302 — duplicate instruction
Compares instructional sentences across files using normalized Jaccard and edit
similarity with a conservative threshold. Bad: repeat the same test rule in AGENTS.md
and CLAUDE.md. Good: keep one canonical rule. It does not use embeddings or cloud AI.
### AGL303 — verbose block
Reports non-code instruction blocks over 1,200 characters as informational. Bad: one
unbroken policy paragraph. Good: short sections with one action each.
## Security (AGL4xx)
### AGL401 — hardcoded secret
Detects credential assignments, bearer tokens, and high-confidence provider prefixes;
placeholders and environment expressions are excluded. Diagnostics reveal only a
masked prefix/suffix. Bad: a live-looking `sk-proj-…` value. Good: `${OPENAI_API_KEY}`.
If triggered, remove and rotate the credential even after deleting it from the file.
## Commands (AGL5xx)
### AGL501 — destructive command
Detects high-risk forms of recursive forced deletion, `git reset --hard`,
`git clean -fdx`, and downloaded scripts piped to a shell. Bad: instruct an agent to
run `git clean -fdx`. Good: inspect and remove explicit paths. Commands are never run.
### AGL502 — unknown command
Checks executables from explicit shell instructions against local `PATH` and suggests
close common-tool spellings. Bad: `nmp test`. Good: `npm test`. Disable or lower this
rule when a repository intentionally documents commands available only in CI.
### AGL503 — missing package script
Checks `npm`, `pnpm`, `yarn`, and `bun` run targets against `package.json`. Bad:
`npm run chek` when only `check` exists. Good: invoke a defined script.
## Consistency (AGL6xx)
### AGL601 — package-manager conflict
Infers npm, pnpm, Yarn, or Bun from lockfiles and `packageManager`, then checks clear
commands and “use …” instructions. Bad: require npm in a pnpm repository. Good: use
pnpm consistently. Ambiguous prose is ignored.
### AGL602 — contradictory instruction
Matches opposite polarity for normalized subjects in imperative forms such as always,
never, must, do not, avoid, forbidden, required, skip, and may freely edit. Bad:
“Always use npm” plus “Never use npm.” Good: retain one scoped policy. This rule is
deliberately not a general-purpose natural-language inference engine.
### AGL603 — tooling mismatch
Detects pytest without Python metadata, Cargo commands without `Cargo.toml`, and Go
tests without `go.mod`. Bad: stale `pytest` guidance in a non-Python repository. Good:
remove it or restore the relevant project metadata.