Last validated: 2026-04-05 against 8 real-world repos (shallow clones).
Current precision: ~91% across 5 repos with context files.
Current version: 1.1.1 — includes monorepo path resolution, non-JS ecosystem support, SARIF output, watch mode, MCP config validation, .ctxlintrc config, --strict mode, expanded context file format support, mcp-env-syntax rule, and ci-coverage rule.
Was: Paths like src/cli/next-dev.ts were flagged as error even when the file exists at packages/next/src/cli/next-dev.ts.
Now: findFileSuggestion() checks for suffix matches before basename matches. When a path is a suffix of an existing file, ctxlint emits warn (not error) with the message: "src/cli/next-dev.ts needs a monorepo prefix — update to packages/next/src/cli/next-dev.ts".
Affected repos: next.js, codex, langchain
Was: stale-command and init were JS-only. Rust/Go/Python projects got no validation or generated commands.
Now:
src/detector/project.jsdetectsCargo.toml(hasCargo),go.mod(goModule), andpyproject.tomlscripts (pythonScripts)stale-commandflagscargo/go/uv/poetry/pytestcommands when the corresponding project file is absentinitgeneratescargo build/test/clippyfor Rust,go build/test/fmt ./...for Go, anduv run pytest/poetry run pytest/python -m pytestfor Python
Affected repos: ruff, langchain (Python), codex (Rust)
--format sarif emits a valid SARIF 2.1.0 document for GitHub Code Scanning integration. Severity mapping: error → error, warn → warning, info → note.
--watch re-lints on every context file save using Node's built-in fs.watch. 300ms debounce handles rapid editor saves. Terminal format only.
ctxlint mcp validates .mcp.json and other MCP config locations. Rules: mcp-schema, mcp-missing-command, mcp-hardcoded-secret, mcp-localhost-url, mcp-deprecated-transport.
Per-project config via .ctxlintrc or .ctxlintrc.json. Supports checks (rule whitelist), ignore (rule blacklist), strict, contextFiles, and tokenThresholds. CLI flags always override config file.
--strict flag (or "strict": true in .ctxlintrc) causes ctxlint to exit 1 on warnings as well as errors. Useful for CI enforcement.
Added .windsurfrules, .clinerules, .aiderules, and CONVENTIONS.md to CONTEXT_FILES in src/constants.js. ctxlint now lints 8 context file formats out of the box, covering Windsurf, Cline, and Aider users.
Validates that env var references use the correct syntax per MCP client. VS Code (.vscode/mcp.json) requires ${env:VAR} syntax; using ${VAR} there produces a warn. Rule receives the config file path to determine which client to check.
Flags CI workflows in .github/workflows/ that are not mentioned in the context file. Emits info severity to encourage documenting what each workflow does so agents understand the CI pipeline.
Problem: Rules check structural correctness (does the file exist?) but not semantic freshness (is the description of that file still accurate?). A file can exist but have been completely rewritten since the context file was last updated.
Current behavior: No semantic drift detection — only structural checks.
Desired behavior: Flag when a referenced file has changed significantly since the context file was last committed (via git diff).
Where to fix: src/commands/diff.js already has partial git-diff logic — extend it to detect semantic staleness in check as well.
Problem: ruff's "Development Guidelines" section was flagged at ~45% trigram overlap with the README "Rules" section. Manual review needed to confirm whether this is a true positive or the trigram threshold is too low for technical content.
Current behavior: Flagged as warn.
Desired behavior: Investigate whether the 40% threshold (TRIGRAM_OVERLAP_THRESHOLD) should be raised for repos with highly technical/domain-specific vocabulary, where common technical terms inflate overlap scores.
Where to fix: src/constants.js → THRESHOLDS.TRIGRAM_OVERLAP_THRESHOLD; src/rules/redundant-readme.js
Problem: The cost projection is hardcoded for Claude Sonnet pricing at 5 developers, 20 sessions/day. This may not reflect every team's actual usage or model choice.
Desired behavior: Allow configuration via a ctxlint.config.js or CLI flags (e.g. --team-size, --sessions-per-day).
Where to fix: src/rules/token-budget.js → accept config params; src/cli.js → expose flags
| Repo | Diagnostic | Classification | Fix applied |
|---|---|---|---|
| codex | stale-file-ref target/ |
FP | Skip generated dir segments |
| langchain | stale-file-ref ../langchain-google/ |
FP | Skip ../ parent-relative paths |
| langchain | no-inferable-stack docstring convention |
FP | Added docstring to exception patterns |
| next.js | stale-file-ref dist/, node_modules/, .next/ |
FP | Skip generated dir segments |
| next.js | stale-file-ref react-dom/server.edge |
FP | Added npm subpath import guard |
| ruff | no-style-guide naming convention description |
FP | Tightened pattern to require line-start directive verb |
| next.js, codex, langchain | stale-file-ref monorepo-relative paths |
FP→warn | Suffix match detection — downgraded to warn with prefix suggestion |
| Count | |
|---|---|
| Total diagnostics emitted (unique files) | ~33 |
| False positives before fixes | ~12 |
| Precision before fixes | ~68% |
| False positives after fixes | ~2 borderline |
| Precision after fixes | ~91% |
Target was >80% before publishing. ✓