Formatting
The formatting engine enforces consistent code style using the best-in-class formatter for each language. Formatting findings are weighted at0.3 (the lowest engine weight) because style differences don’t indicate broken logic — but they still appear in your report so nothing stays hidden.
| Language | Tool |
|---|---|
| TypeScript / JavaScript | Biome |
| Python | ruff format |
| Go | gofmt |
| Rust | cargo fmt |
| Ruby | rubocop |
| PHP | php-cs-fixer |
Linting
The linting engine catches bugs and bad practices using the fastest available linter for each language. For JS/TS projects, oxlint ships bundled so you don’t need to install anything separately.| Language | Tool |
|---|---|
| TypeScript / JavaScript | oxlint (bundled, with React/Next.js awareness) |
| Expo / React Native | expo-doctor (project health, dependency checks) |
| Python | ruff |
| Go | golangci-lint |
| Rust | clippy |
| Ruby | rubocop |
Code Quality
The code quality engine measures structural complexity, surfaces dead code, and identifies unused dependencies.knip/* rules apply to JS/TS projects only and require a package.json to be present.
| Rule ID | What it checks |
|---|---|
complexity/function-too-long | Functions exceeding the configurable line limit (default: 80). For Python, only logical body lines count — signatures, docstrings, comments, and blank lines are excluded. async def and multi-line wrapped signatures are detected. |
complexity/file-too-large | Files exceeding the configurable line limit (default: 400) |
complexity/deep-nesting | Control-flow nesting beyond the configurable threshold (default: 5) |
complexity/too-many-params | Functions with too many parameters (default: 6). For Python, only required parameters count — self/cls, *args/**kwargs, *// separators, and defaulted parameters are excluded. |
code-quality/duplicate-block | Repeated blocks of implementation code that should be extracted or shared |
code-quality/repeated-chained-call | Repeated long call chains on the same receiver that should be cached or factored out |
code-quality/unused-declaration | Unused top-level declarations that are safe to remove |
knip/files | Unused files not imported anywhere (JS/TS; fixable with fix -f) |
knip/exports | Unused exports (JS/TS) |
knip/types | Unused exported types (JS/TS) |
knip/dependencies | Unused dependencies listed in package.json (fixable with fix) |
knip/devDependencies | Unused devDependencies in package.json (fixable with fix) |
knip/unlisted | Packages imported in code but missing from package.json |
knip/unresolved | Imports that cannot be resolved |
knip/binaries | Binaries used in scripts but not declared in package.json |
knip/duplicates | Duplicate exports reported by knip |
AI Slop
These are the rules that make aislop unique. They specifically target the patterns that AI coding assistants tend to leave behind — from narrative comments that restate the code to swallowed exceptions that hide runtime failures. The AI slop engine carries the highest default weight (2.5) in your score.
Style and maintainability rules (
trivial-comment, narrative-comment, file-too-large, function-too-long) contribute half their normal score weight. They still appear in your report so nothing is hidden, but genuine slop — swallowed errors, dead code, hallucinated imports — drives your score more than house style.| Rule ID | Severity | What it catches |
|---|---|---|
ai-slop/trivial-comment | warning | Comments that restate the code (// Import React, // Return the value) |
ai-slop/narrative-comment | warning | Decorative separators, phase/section headers, JSDoc preambles without meaningful tags, cross-reference commentary, and prose blocks with an AI-narration signal (restatement openers or step-by-step narration). Length alone is not flagged. |
ai-slop/swallowed-exception | error | Empty catch blocks and catch blocks that only log (JS/TS/Python/Go/Ruby/Java) |
ai-slop/silent-recovery | warning | Catch blocks that log without including the caught error and then continue execution |
ai-slop/meta-comment | warning | Comments about implementation phases, agent behavior, or generated-code process rather than the code itself |
ai-slop/redundant-try-catch | warning | JS/TS catch blocks that only rethrow the same error without adding context, cleanup, or recovery |
ai-slop/redundant-type-coercion | warning | TypeScript primitive parameters re-coerced with String(...), Number(...), or Boolean(...) |
ai-slop/duplicate-type-declaration | warning | Exported TypeScript type/interface declarations repeated with the same name and shape across files |
ai-slop/thin-wrapper | warning | Functions that only forward their own parameters unchanged to another function (call sites that transform arguments are not flagged) |
ai-slop/generic-naming | info | AI-generated placeholder names such as helper_1, data2, or temp1 |
ai-slop/unused-import | warning | Unused imports (JS/TS and Python) |
ai-slop/console-leftover | warning | console.log / console.debug / console.info calls left in production code |
ai-slop/todo-stub | info | Unresolved, untracked TODO/FIXME/HACK comments (TODOs that link a tracking issue are spared) |
ai-slop/unreachable-code | warning | Code after return or throw statements |
ai-slop/constant-condition | warning | Always-true or always-false conditions such as if (true), if (false), or if (0) |
ai-slop/empty-function | info | Empty function bodies |
ai-slop/unsafe-type-assertion | warning | as any casts in TypeScript |
ai-slop/double-type-assertion | warning | The as unknown as X double-cast pattern in TypeScript |
ai-slop/ts-directive | info | @ts-ignore and @ts-expect-error suppression comments |
ai-slop/duplicate-import | warning | Multiple import statements from the same module that should be merged |
ai-slop/hardcoded-url | warning | Environment-specific URLs hardcoded in production code instead of environment variables or config |
ai-slop/hardcoded-id | warning | Provider or project IDs hardcoded in production code instead of environment variables or config |
ai-slop/python-bare-except | warning | Python except: blocks that catch everything without naming an exception type |
ai-slop/python-broad-except | warning | Python broad exception handlers with silent or pass-style bodies |
ai-slop/python-mutable-default | warning | Python function defaults such as [], {}, or set() that are shared across calls |
ai-slop/python-print-debug | warning | Python print(...) debug output left in production modules |
ai-slop/python-range-len-loop | info | Python for i in range(len(items)) loops that should use direct iteration or enumerate() |
ai-slop/python-chained-dict-get | warning | Python .get(..., {}).get(...) fallback chains that hide missing-data cases |
ai-slop/python-repetitive-dispatch | warning | Repeated Python equality branch ladders that should become a table, set, or handler map |
ai-slop/python-isinstance-ladder | warning | Repeated Python isinstance(...) ladders that should become a handler map or normalized representation |
ai-slop/go-library-panic | warning | Go panic(...) calls in non-main library code unless clearly intentional |
ai-slop/rust-non-test-unwrap | warning | Rust .unwrap() calls in production code where errors should be handled or documented |
ai-slop/rust-todo-stub | warning | Rust todo!() stubs in production code |
ai-slop/hallucinated-import | error | Imports of JS/TS packages not declared in the project manifest |
Security
The security engine finds secrets, risky constructs, and vulnerable dependencies. Security findings carry a default engine weight of1.5 in your score.
| Rule ID | What it catches |
|---|---|
security/hardcoded-secret | API keys, AWS credentials, JWT tokens, database URLs, and passwords |
security/eval | eval() usage in JS/TS, Python, Ruby, and PHP |
security/innerhtml | Direct .innerHTML assignment |
security/dangerously-set-innerhtml | React dangerouslySetInnerHTML usage that requires sanitization |
security/sql-injection | String concatenation used to build SQL queries |
security/shell-injection | User input passed to command execution APIs |
security/vulnerable-dependency | Known-vulnerable packages in npm, pip, cargo, and Go dependency audits |
security/dependency-audit-skipped | Dependency audit could not run because tooling or a lockfile was missing |
Architecture (opt-in)
The architecture engine enforces custom import and path rules you define in.aislop/rules.yml. It is disabled by default — enable it by adding engines.architecture: true to your config.
How to enable architecture rules
How to enable architecture rules
Add the following to Then create
.aislop/config.yml:.aislop/rules.yml with your custom rules. See the architecture rules guide for a complete sample file.| Rule type | What it enforces | Example |
|---|---|---|
forbid_import | Bans a package anywhere in the project | Forbid axios project-wide |
forbid_import_from_path | Prevents one path pattern from importing another | Controllers cannot import database modules |
require_pattern | Asserts that files matching a glob contain a required construct | Require error handling in all API route files |
Supported Languages Matrix
The table below shows which engines and rule sets are active for each language aislop supports.| Language | Format | Lint | Code quality | AI slop | Security |
|---|---|---|---|---|---|
| TypeScript | Biome | oxlint | knip, complexity | All rules | All rules |
| JavaScript | Biome | oxlint | knip, complexity | All rules | All rules |
| Expo / React Native | Biome | oxlint + expo-doctor | knip, complexity | All rules | All rules |
| Python | ruff | ruff | complexity | Imports, exceptions, comments | Secrets, audit |
| Go | gofmt | golangci-lint | complexity | Exceptions, comments | Secrets, audit |
| Rust | cargo fmt | clippy | complexity | Comments | Secrets, audit |
| Ruby | rubocop | rubocop | complexity | Exceptions, comments | Secrets |
| PHP | php-cs-fixer | — | complexity | Comments | Secrets |