# aislop withholds its score on unsupported languages, and removes suppressions before scoring

> A deterministic static checker with 50 plus rules for ten language targets, shipped to npm, Homebrew and PyPI. The interesting decisions are the ones it refuses to make: no score on code it did not read, and a severity map that can turn rules off entirely.

**scanaislop/aislop** — Catch and fix the code-quality issues AI coding agents leave behind - dead code, unsafe casts, swallowed errors, duplication, security risks, and more. 50+ deterministic rules across 10 language targets, with CLI, CI, and GitHub Actions. No LLM at runtime. MIT.

- Repository: https://github.com/scanaislop/aislop
- Website: https://scanaislop.com
- Stars: 667 · Forks: 36
- Language: TypeScript
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/scanaislop-aislop

## Ruff and golangci-lint are missing until you run one extra command

Package installation deliberately does not run dependency lifecycle scripts, and the documentation says what to do about it: run `aislop-tools` once after installing if you want bundled Ruff and golangci-lint coverage. The core scanner works without it.

That line covers two of the ten language targets. Ruff is the Python linter and golangci-lint is the Go one, so out of the box a Python or Go repository is scanned by aislop's own rules without the deep linter underneath. Since the coverage claim is formatting, linting, complexity, AI-slop detection and security checks together, the difference between a default install and a post-install run is larger than the sentence implies.

The install channels are unusually wide. The quick path needs nothing at all:

```bash
npx aislop@latest scan
```

Then there is npm, Yarn, Bun, Homebrew and PyPI, plus a scoped `@scanaislop/aislop` on GitHub Packages. Two of those channels carry a Node requirement even when you did not ask for Node. Homebrew installs Node.js as a dependency if it is not already present, and `pipx` keeps aislop in its own isolated environment but still needs Node.js on `PATH`. The Python channel is a wrapper, not a native alternative.

The package exposes three binaries: `aislop` from `dist/cli.js`, `aislop-mcp` from `dist/mcp.js`, and `aislop-tools` from `scripts/install-tools.mjs`. Only the first is what the quick start runs.

## Suppressions are removed before scoring, and only a count survives

There are three suppression directives and they work in any comment syntax, so the same directive reads the same in `//`, in `#` and in an HTML comment. `aislop-ignore-next-line` covers the following line, `aislop-ignore-line` covers the line it sits on, and `aislop-ignore-file` covers the whole file wherever you place it. Each takes an optional rule name and an optional reason after a double dash.

The scoring consequence is stated in one sentence: suppressed findings are removed before scoring, and the run reports how many were silenced.

That is honest, and it is also the number that matters. A directive removes a diagnostic before it can cost anything, so the score a project reports can be raised to 100 with a comment on every line, and the artefact that shows it happened is a single count in the run output. Nothing in the schema requires a reason, so a suppression and a justified suppression produce the same trace.

The config file offers the same power at a coarser grain. Under a `rules` map you can rewrite any rule's severity to `error`, `warning` or `off`, by id, with `ai-slop/trivial-comment: "off"` given as the drop-it-entirely case and `ai-slop/narrative-comment: warning` as a rewrite. An absent map keeps default behaviour, so a project that adds a config for one rule inherits nothing else.

Paths can be excluded in bulk as well, through `exclude` in `.aislop/config.yml` or an `.aislopignore` at the project root with the same glob semantics and `#` comments allowed. The defaults are `node_modules`, `.git`, `dist`, `build` and `coverage`.

## An unsupported stack gets score: null instead of a number

Most linters print a score over whatever files they happened to read. aislop takes the opposite position for a repository built on something it does not analyse. If the repo is mostly Swift, Kotlin, Java or another unsupported language, scoring a handful of incidental files would misrepresent it, so the score is withheld and the tool says so.

The JSON output makes the refusal machine-readable: `score: null`, `scoreable: false`, and a `coverage` breakdown alongside them. So a pipeline can branch on it rather than parse prose.

What the documentation does not state is what a CI gate does with a null. The config carries a `ci: failBelow: 80` key, and there is a dedicated `aislop ci` command described as CI mode with JSON and a gate. Whether a null score passes, fails or errors is left to the implementation, and that is the question to answer before you put this in a required check on a polyglot repository.

The ten targets themselves are TypeScript, JavaScript, Expo and React Native, Python, Go, Rust, Ruby, PHP, C#, and C and C++ as one entry. Some checks lean on optional system tools, which is the second reason the withheld score is not the only blind spot.

## The repository's own scan script misspells .gitignore

The package scripts are worth reading as a sample of how the tool is used on itself. There is one for the standard scan, one for JSON, one for includes, one for excludes, and a test script.

The exclude script passes `--exclude .idea --exclude .gitnore --exclude node_modules`. That middle token is `.gitnore`, with the second g missing. It is not a directory anything has, so that flag does nothing, and the intent of excluding the repository's own Git metadata is quietly dropped.

Every one of those scripts rebuilds the bundle first. `scan` is `pnpm build && node dist/cli.js scan .`, and the same prefix is on the include, exclude and JSON variants. `test` is `pnpm build && vitest run`, so running the test suite compiles the package before the tests start. For a local loop that is a cost you pay each time; in CI it means the scanner measures the tree it was just handed rather than a prebuilt artefact.

The include script is also shaped differently from the documented flag. It passes `--include src --include tests` as two separate flags, whereas the usage examples show a single quoted glob covering the source tree. Whether repeated includes union or overwrite is not stated anywhere in the visible documentation.

The published `files` array is short: `dist`, `scripts` and `tools/jb`. The build itself is driven by `tsdown`, typechecking by `tsc --noEmit`, and tests by `vitest`.

## Five framework adapters ship, and six of the ten targets have no example config

The package exports a root entry plus five framework adapters: `./adapters/astro`, `./adapters/expo`, `./adapters/nuxt`, `./adapters/sveltekit` and `./adapters/vite`. Five integrations for a tool whose headline claim is ten language targets.

The example configurations in `examples/` cover a smaller slice again. There are five files: `architecture-rules.yml`, `csharp.yml`, `monorepo-relaxed.yml`, `python-go.yml` and `typescript-strict.yml`. Read as a set they exercise TypeScript, Python, Go and C#, plus two TypeScript-shaped variations for monorepos and architecture rules.

That leaves Ruby, PHP, Rust, C and C++, plain JavaScript and Expo without a worked configuration in the repository. Four of the five JavaScript-family adapters are for Astro, Nuxt, SvelteKit and Vite, which are bundler and framework concerns rather than language targets, so adapter coverage and language coverage are two different axes and the repository is stronger on the first.

For configuration there is a JSON Schema at `schema/aislop.config.schema.json` that editors can point at, and a generation script behind it. Project config can extend a parent with an `extends` key pointing at a relative path, then override individual keys such as the CI threshold underneath.

There is also an `.aislop/` directory committed at the repository root, so the tool runs on its own configuration rather than shipping defaults alone.

## Nine open issues, three agent instruction files, and four distribution channels

The release cadence is steady and the version numbers agree with the tags. `0.15.0` on 2026-08-26, `0.16.0` on 2026-08-31 and `0.16.1` on 2026-09-09, with the manifest sitting at the same `0.16.1`. The last push to the default branch is 2026-09-30, three weeks after the newest tag.

Around 660 stars and 36 forks with nine open issues is a normal shape for a tool at this stage.

The top-level tree has 34 entries and several of them describe how the project expects to be reached. `action.yml` makes it a GitHub Action. `.pre-commit-hooks.yaml` makes it a pre-commit hook provider. The three binaries cover the command line, an MCP server and the tooling installer. And `aislop ci` plus `aislop hook install --claude` cover the two integration points most teams want.

There are three agent instruction files, `AGENTS.md`, `CLAUDE.md` and `GEMINI.md`, which is a considered choice for a tool whose entire premise is that agents write the code it inspects.

One configuration file deserves a second look. `knip.json` configures Knip, a package for finding unused files and dependencies, in a repository whose product is finding unused files and dependencies. Whatever aislop scores its own tree, the dead-code ground truth is delegated to another tool rather than to its own rules.

The scan surface itself is broad: `--changes` from HEAD, `--changes --base origin/main` for pull requests, `--staged`, verbose detail with `-d`, `--json`, `--sarif` for GitHub code scanning, and a separate `--format json` form.

## Conclusion

aislop earns a place in a pipeline for teams whose agents have already shipped the kind of code it looks for, and the SARIF output and the withheld-score behaviour make it usable as a real gate rather than a demo. Two things to check first: run `aislop-tools` once after installing, or you are running without the bundled Python and Go linters and will see fewer findings than the rule count suggests. And read how your team uses suppressions, because findings removed by a directive never reach the score and the only trace is a count on the run.

## FAQ

### what is ai slop code

The patterns aislop is built to catch are narrative comments above self-explanatory code, swallowed exceptions, hidden fallbacks, as-any casts, hallucinated imports, duplicated helpers, dead code, todo stubs and oversized functions. Its premise is that tests and lint can both pass while the code still rots.

### what is ai slop detector

aislop is one, and it is deterministic rather than model-based. It runs 50+ rules across 10 language targets with no LLM in the runtime path, so the same code gives the same 0-100 score, and it outputs SARIF 2.1.0 for GitHub code scanning.

### Why did my aislop scan return no score?

If the repository is mostly an unsupported language such as Swift, Kotlin or Java, aislop withholds the score instead of scoring the few incidental files. The JSON output reports score: null and scoreable: false together with a coverage breakdown so a pipeline can tell the difference.

### Do I need to run aislop-tools after installing aislop?

Only if you want the bundled Python and Go linter coverage. Package installation does not run dependency lifecycle scripts, so Ruff and golangci-lint are absent until you run aislop-tools once. The core scanner works without it, on fewer findings for those two languages.

### How do I silence an aislop finding?

Use aislop-ignore-next-line, aislop-ignore-line or aislop-ignore-file in any comment syntax, optionally naming rules and adding a reason after a double dash. Suppressed findings are stripped before scoring and the run reports how many were silenced. Whole paths can be excluded in .aislopignore or the exclude list in .aislop/config.yml.

## Sources

- [License: MIT](https://github.com/scanaislop/aislop/blob/main/LICENSE)
- [Project website](https://scanaislop.com)
- [README](https://github.com/scanaislop/aislop/blob/main/README.md)
- [Releases](https://github.com/scanaislop/aislop/releases)
- [scanaislop/aislop on GitHub](https://github.com/scanaislop/aislop)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/scanaislop-aislop
