
Aislop
- 23 installs
- 4 repo stars
- Updated July 23, 2026
- scanaislop/aislop-skill
aislop is an agent skill that reviews your changes for AI slop, quality score failures, and sloppy patterns before you commit or merge.
About
aislop is an agent skill package oriented around detecting and fixing AI slop and shallow code quality issues in real repositories, not replacing a generic linter or formatter. Solo and indie builders invoke it when they finish a refactor, suspect lazy comments or copy-paste in a PR, need to recover from a CI gate on a quality score, or want a project-wide pass after merging branches. The bundled trigger evaluation set encodes when the skill should fire versus adjacent tasks like prettier, eslint setup, raw coverage reads, or high-level auth architecture review. Expect workflows that score changes, surface trends for badges, dedupe repeated logic, flag security issues in diffs, and run environment doctor checks when tools are missing. Pair it with your normal test and lint pipeline: aislop targets semantic sloppiness and agent-shaped code smells that standard green scans miss.
- Trigger-accuracy eval set distinguishes quality/slop queries from plain lint, format, or design-review asks
- Handles pre-commit review, CI failures when score drops below 70, and post-merge cleanup before opening a PR
- Supports security review in changes, deduplication of repeated fetch logic, and overly long multi-purpose functions
- Includes aislop doctor for tooling/env diagnostics when scanners are not found
- Addresses "green scan but sloppy" cases where linters pass but code quality still fails human/agent standards
Aislop by the numbers
- 23 all-time installs (skills.sh)
- Ranked #709 of 1,352 Code Review & Quality skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/scanaislop/aislop-skill --skill aislopAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 23 |
|---|---|
| repo stars | ★ 4 |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 23, 2026 |
| Repository | scanaislop/aislop-skill ↗ |
What it does
Catch AI-generated slop, lazy patterns, and quality regressions in your diff before commit or when CI score drops.
Who is it for?
Best when you're shipping feature branches and use automated quality scoring or want a second pass beyond eslint on AI-assisted code.
Skip if: Skip if you only need prettier/eslint runs, raw test coverage reports, or greenfield Salesforce security pattern lookup without a quality-scoring workflow.
When should I use this skill?
User asks to check a refactor before commit, review a PR for slop, fix CI score below threshold, dedupe logic, review security in changes, add score badge/trend, clean up after merges, or run aislop doctor.
What you get
You get a focused slop and quality pass on the diff or repo with actionable fixes, score context, and tooling checks so you can commit or open the PR with confidence.
- Review findings on diffs or project
- Recommended fixes for slop, dedupe, and length issues
- Score or trend context when badge or CI gate is requested
By the numbers
- 10 should-trigger eval prompts
- 5 should-not-trigger contrast prompts
Files
aislop — agent skill
aislop is a deterministic, open-source CLI that scans across six engines, grades 0–100, and catches 50+ rules across 7 languages: swallowed exceptions, hallucinated imports, silent recovery, narrative comments, as any casts, oversized functions, SQL injection, eval, hardcoded secrets, and architecture drift.
If you follow this skill, you don't ship slop. It does two jobs:
1. Prevention — internalise the rule catalog below so your first draft doesn't trip detectors. 2. Detection + fix — scan after editing, fix mechanical findings with the CLI, fix the rest yourself, report what changed.
This skill is not "run aislop and report back" — the user could do that themselves. The value is the judgement layer: writing right the first time, reading each finding against source, and fixing what you can before escalating.
Supports TypeScript, JavaScript, Python, Go, Rust, Ruby, PHP, Expo/React Native.
Remote execution & supply-chain policy
This skill uses the aislop CLI, distributed through the public npm registry. Running npx aislop fetches and executes the published package — treat this as an untrusted remote dependency.
Default: prefer a locally installed, version-pinned aislop over `npx`.
# Preferred — pinned in the project's lockfile
npm install --save-dev aislop && aislop scan --changes --json
# Acceptable fallback
npx aislop scan --changes --json
# Never acceptable: GitHub clones, curl|sh installers, unpinned npx in CIDecision order: 1. Local binary or script in devDependencies — pinned by the lockfile. 2. `npx aislop@<version>` (pinned) — acceptable when no local install exists. 3. `npx aislop` (floating) — last resort for interactive sessions. Never in CI. 4. Blocked environment — skip the scan and report the CLI could not be run. Do not install outside the project's dependency workflow.
aislop fix --claude (and --cursor, --codex, --gemini) executes a local process against the project's code only — no additional network fetch.
Follow the project's conventions, not this skill's examples
This skill tells you which anti-patterns to avoid. It does NOT tell you the one right way to structure your code — that's encoded in the repo. Before acting on any prevention pattern, check what the project actually does:
- Logger — grep for
pino,winston,bunyan,logger.ts, or a shared wrapper. Ifconsole.erroris the convention, fine. - Error wrapping — use the project's error class (
AppError,DomainError,HttpError, or bareErrorwith{ cause }). - Types / validation — match the project's choice (
zod,valibot,ajv, pydantic, Go structs, etc.). - Naming — follow the project's casing, file naming, and folder layout.
- Tests — use the framework and patterns already in the repo.
- Architecture — if
.aislop/rules.ymlexists, it's authoritative. Otherwise, match import patterns and module boundaries from existing files.
The avoid/prefer examples in the prevention catalog are illustrative. A fix in the project's style beats a fix in this skill's style.
Quick prevention catalog
Read this before editing. Each rule aislop will flag. See `references/PREVENTIONS.md` for full avoid/prefer examples.
Categories: Comments, Types, Errors, Security, Dedup, Dead code, Console, TODO, Empty functions, Naming, Size, Architecture, Deps, Fake completeness, Abstractions, Wiring.
When to invoke
Invoke when you've finished editing and are handing control back, the user is preparing to commit/push/open a PR, or they ask any quality question: "any slop", "is this clean", "any duplicates", "is this reusable", "can we dedupe this", "is this too long", "is this safe", "audit my deps", "does this follow our rules", "score my code", "score dropped", "add a badge".
Skip when: user is only reading, is mid-refactor and asked you to hold off, or explicitly disabled aislop.
CLI commands reference
| Command | Use |
|---|---|
aislop scan [dir] | Full scan. Flags: --changes, --staged, --json, --sarif |
aislop fix [dir] | Auto-fix mechanical issues. -f for aggressive. --claude/--codex/--cursor/--gemini for agent hand-off. -p to print prompt. |
aislop ci [dir] | CI mode: JSON output + exit code by threshold |
aislop init [dir] | Generate .aislop/config.yml |
aislop doctor [dir] | Check installed tools and environment |
aislop rules [dir] | List all rules with severity and fixability |
aislop trend [dir] | Show score history from .aislop/history.jsonl |
aislop badge [dir] | Generate a public score badge URL + README markdown |
aislop hook install | Install per-edit quality hooks. Supports Claude Code, Cursor, Codex, Gemini, pi, and others (run aislop hook install --help for the full list). |
Core workflow
For every command, use aislop (local install, preferred) or npx aislop (fallback).
1. Scope the scan
aislop scan --changes --json # mid-session: only what you touched
aislop scan --staged --json # before a commit
aislop scan --json # full project: pre-release, PR, wide refactorAlways --json. The TTY output is for humans; you need structured findings.
2. Auto-fix the mechanical findings
aislop fixCLI handles everything marked fixable: true. Don't hand-edit what the CLI fixes. Use -f only when the user asked to clean up deps or unused files.
After auto-fix, optionally hand off remaining findings:
aislop fix --claude # launch Claude Code with remaining findings
aislop fix --codex # launch Codex CLI
aislop fix -p # print a prompt to paste into any agent3. Re-scan — everything fixable:false is your job
aislop scan --changes --jsonThe CLI has done its half. Remaining fixable: false findings are what this skill exists for.
4. For each remaining finding, do the judgement work
a. Verify it's real. Open the file. Read the cited line and context. Is the rule description accurate? Could it be a false positive (regex matched inside a string/comment/identifier)? Is there a reason the code is intentional?
b. Decide:
| What you found | Action |
|---|---|
| Real issue | Fix it in-session. Don't ask first. |
| False positive | Surface with file:line and one-sentence reason. Do not silence the rule. |
| Legitimately intentional | Note it. Let the user decide on suppression. |
c. Fix it. See `references/FIX_GUIDE.md` for the fix pattern for each rule. Open the file, verify the finding, apply the fix.
5. Run the manual slop pass
A clean scan is not enough. Review your diff for patterns the CLI cannot infer:
1. Fake completeness — no hardcoded success paths, canned data, placeholder behavior. 2. Test quality — tests exercise at least one edge/failure path, not just rendering. 3. Unneeded abstraction — no new generic layer with one caller. 4. Incomplete wiring — exports, routes, generated files, call sites are updated. 5. State handling — loading, empty, error, timeout, cancellation states are coherent. 6. Dependency discipline — no new package for trivial logic.
Fix what you find. If something is genuinely out of scope, say why.
6. Re-scan until the bar is met
Loop steps 4–6 until:
- Zero
errors. - Zero
fixable: truewarnings. - Every
fixable: falsewarning is fixed, proposed with rationale, or flagged as false positive. - Manual slop pass has no unresolved in-session issue.
Do not say "done" before this point.
7. Report — triaged, not dumped
Default voice is past-tense "I did X":
Ran aislop — 12 findings, score 73 → 95.
Auto-fixed (7): unused imports (3), narrative comments (2), formatting (2).
Fixed in-session (4):
- unsafe-type-assertion src/api/normalize.ts:47 (added ApiUser type)
- function-too-long src/lib/reconcile.ts:14 (extracted matchByHash)
- sql-injection src/db/search.ts:30 (parameterised with $1)
- swallowed-exception src/workers/cleanup.ts:28 (added log.warn)
False positives (1):
- security/eval src/labels.ts:12
The match is inside a display-name table, not an actual eval().
Re-scanned: 95 / 100, 0 errors, 0 warnings.If clean but manual pass found issues, report those too. If something needs a product-level call, put it at the end with the specific choice.
How to verify a false positive
Before flagging, check: 1. Is the match inside a string literal, template literal, or comment? 2. Is it part of an identifier name that happens to contain the pattern? 3. Is it in a test fixture, mock data, or example? 4. Would a reader agree this isn't the pattern the rule describes?
Include a one-sentence reason. Never silence the rule on the user's behalf.
Severity and score interpretation
| Severity | Fixable | Action |
|---|---|---|
error | any | MUST fix this turn. |
warning | fixable: true | CLI's aislop fix handles these. Never leave them. |
warning | fixable: false | Agent fixes in-session. Verify, then edit. |
info | any | Note; act only if the user asked for a high bar. |
Score bands: 90–100 healthy; 75–89 healthy with debt; 60–74 degraded; < 60 failing gate.
Default: invent, apply, report — don't ask
Make the fix and report what you did. Missing type → invent it. Swallowed error → log and rethrow. Oversized function → extract at the seam. Duplicate logic → extract a helper. Generic name → rename. Don't ask "should I" for any of these — just do it and mention what changed in the reply.
Escalate only when the fix is a product decision, would change observable semantics you shouldn't override, is a false positive worth flagging, or is legitimately intentional code the user should decide on.
Never ask permission for fixes you can make yourself. Pick the right tool and apply it.
Anti-patterns
- Do NOT treat this skill as a wrapper around
aislop fix. Your job is the judgement layer. - Do NOT ask for permission on fixes you can make yourself.
- Do NOT paste raw JSON into your reply — triage and summarise.
- Do NOT silence rules in config or add blanket suppression comments.
- Do NOT delete
.aislop/config.ymlor.aislop/rules.yml. - Do NOT claim completion without a post-fix re-scan.
- Do NOT treat a 100 score as proof the code is good — do the manual pass.
- Do NOT run
aislop fix -fsilently on unrelated turns — it rewrites manifests. - Do NOT fight the detector by editing regex patterns — your job is clean code.
{
"description": "aislop skill trigger evaluation set",
"evals": [
{
"id": "trigger-accuracy",
"description": "Tests whether the skill triggers correctly on quality-related queries and does not trigger on adjacent but unrelated queries",
"prompts": {
"should_trigger": [
"ok i just finished this billing refactor, can you check it before i commit?",
"any slop in this PR? i feel like i left some lazy comments",
"weve got a CI fail saying score dropped below 70, fix whatever it finds",
"review my changes for security issues, i think i might have a sql injection",
"can you dedupe this? i keep writing the same fetch logic everywhere",
"is this function too long? feels like it does too many things",
"add a score badge to the readme and tell me our trend",
"i just merged three branches and need the whole project cleaned up before i open the PR",
"run aislop doctor, my env isnt finding the tools it needs",
"the linter passes but theres still something wrong — green scan but sloppy"
],
"should_not_trigger": [
"run the linter for me",
"can you format this file with prettier",
"is this auth system design secure?",
"whats our test coverage percentage",
"read the code in src/ and tell me whats wrong",
"optimize this database query for me",
"set up eslint for this project",
"migrate from javascript to typescript",
"can you explain what this function does",
"deploy this to staging"
]
}
}
]
}
Example 01 — before commit
An agent implements a small feature, then runs aislop before handing control back.
Commands below use the normal npx aislop quick-start path. In repos with strict supply-chain policy, use the project's pinned local script or binary instead.
---
User:
Add aformatBytes(n)helper insrc/lib/format.tsthat returns "1.2 KB", "3.4 MB", etc. Export it from the barrel.
Agent (internal):
Implements formatBytes, updates src/lib/index.ts barrel, writes a unit test. Before replying, invokes the aislop skill because edits are finished and a commit is implicit.
npx aislop scan --changes --jsonParses the JSON. Three findings:
ai-slop/narrative-comment·src/lib/format.ts:3· fixableai-slop/unused-import·src/lib/format.ts:1· fixableai-slop/unsafe-type-assertion·src/lib/format.ts:18· not fixable
Runs auto-fix for the mechanical two:
npx aislop fixRe-reads the file. The as any cast is on n as any inside the magnitude branch. Replaces it with a proper numeric guard:
if (typeof n !== "number" || !Number.isFinite(n)) {
throw new TypeError("formatBytes expects a finite number");
}Re-scans:
npx aislop scan --changesScore: 96 / 100. Zero errors, zero warnings.
Agent reply to user:
AddedformatBytesinsrc/lib/format.tsand re-exported it fromsrc/lib/index.ts. Unit test covers bytes, KB, MB, GB, and the non-finite guard.
>
Ran aislop scan --changes: 96 / 100, no findings. Ready to commit.---
Notes on what the agent did right:
- Scoped the scan to
--changesrather than the whole project. - Used
--jsonwhen acting programmatically. - Ran
fixfor the mechanical findings before doing manual work. - Replaced
as anywith a real type guard, not a rule suppression. - Re-scanned after fixes before claiming done.
- Reported the score and finding count in the reply.
Example 02 — agent handles the non-mechanical remainder
aislop fix cleans up 8 of 12 findings. The agent addresses the remaining 4 by hand.
Commands below use the normal npx aislop quick-start path. In repos with strict supply-chain policy, use the project's pinned local script or binary instead.
---
User:
I just merged in a large refactor of the billing module. Can you clean it up before I open the PR?
Agent (internal):
Runs a broader scan because the refactor touched many files:
npx aislop scan --jsonTwelve findings:
- 3 ×
ai-slop/narrative-comment(fixable) - 2 ×
ai-slop/unused-import(fixable) - 3 ×
ai-slop/trivial-comment(fixable) - 2 ×
ai-slop/unsafe-type-assertioninsrc/billing/normalize.ts(not fixable) - 1 ×
complexity/function-too-longinsrc/billing/reconcile.ts:14(reconcile, 134 lines) (not fixable) - 1 ×
security/sql-injectioninsrc/billing/search.ts:30(not fixable)
Runs auto-fix:
npx aislop fix8 fixed: narrative comments, unused imports, trivial comments.
Remaining 4, handled one by one:
1. `src/billing/normalize.ts:47` — `as any`. The cast was hiding a BillingLine | null where BillingLine was expected. Tightened the return type of parseLine to BillingLine | null and handled null at the call site. 2. `src/billing/normalize.ts:82` — `as any`. Same root cause; removed after fix #1. 3. `src/billing/reconcile.ts:14` — function too long. Extracted two helpers: matchByHash(lines) and matchByAmount(lines). reconcile now sits at 38 lines and delegates. 4. `src/billing/search.ts:30` — SQL injection. The query was built with a template literal interpolating req.query.term. Replaced with a parameterised ? placeholder and passed term as a bound value.
Re-scans:
npx aislop scan --jsonScore: 93 / 100. Zero errors, zero warnings.
Agent reply to user:
Cleaned up the billing refactor.
>
Auto-fixed 8 (narrative comments, unused imports, trivial comments).
>
Manual fixes:
-src/billing/normalize.ts— removed twoas anycasts by tighteningparseLinereturn type toBillingLine | null.
-src/billing/reconcile.ts— extractedmatchByHashandmatchByAmountfrom the 134-linereconcilefunction.
- src/billing/search.ts — replaced template-literal SQL with a parameterised query.>
Re-scanned: 93 / 100, no remaining findings. Safe to open the PR.
---
Notes:
- Full-project
scanwas the right scope for a wide refactor. - Agent grouped the remainder by rule id in its reply instead of dumping the JSON.
- Every fix was a real change. No rule suppressions, no config edits.
- Re-scan after manual work is non-optional.
Example 03 — CI gate with GitHub Actions
Enforcing the aislop score as a required check on every PR.
Commands below use the normal local CLI shape. CI pins the package through the project's lockfile instead of using a floating runtime fetch.
---
User:
Add aislop as a CI gate. Fail the build if the score drops below 70.
Agent (internal):
Checks for .aislop/config.yml. Missing. Writes the minimal config directly:
# .aislop/config.yml
version: 1
ci:
failBelow: 70Ensures the project has a pinned aislop dev dependency in its lockfile and a committed package script:
{
"scripts": {
"quality:ci": "aislop ci ."
},
"devDependencies": {
"aislop": "0.10.1"
}
}Creates the workflow from that pinned dependency path:
# .github/workflows/aislop.yml
name: aislop
on:
pull_request:
push:
branches: [main]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run quality:ciVerifies locally that aislop ci exits non-zero when the score is under the configured threshold:
npx aislop ci
echo $?Runs the agent's own self-check before finishing:
npx aislop scan --changesScore: 98 / 100.
Agent reply to user:
Wired up the CI gate.
>
-.aislop/config.yml— setsci.failBelow: 70.
-.github/workflows/aislop.yml— installs from the project lockfile and runsnpm run quality:cion every PR and push tomain. Fails the job if the score drops below 70.
>
Verified locally:npx aislop ciexits 0 at the current score of 98 / 100. To tighten the gate, bumpfailBelowin.aislop/config.yml.
---
Notes:
- The gate threshold lives in config, not hardcoded in the workflow, so teams can tune it without editing YAML in
.github/. aislop ciexits non-zero when the score is belowci.failBelowor any error-severity finding is present, which is what fails the job.aislop ciemits JSON to stdout — pipe it to an artifact if you want historical tracking.- Keep the gate low at first, raise it once the project baselines. Starting strict is how teams learn to silence rules.
Example 04 — clean scan still gets a manual slop pass
The scan is clean, but the agent catches semantic slop before handing control back.
Commands below use the normal npx aislop quick-start path. In repos with strict supply-chain policy, use the project's pinned local script or binary instead.
---
User:
Add a loadCustomerOrders(customerId) helper and tests.Agent (internal):
Implements the helper and tests. Runs the scan:
npx aislop scan --changes --jsonScore: 100 / 100. Zero findings.
Runs the manual slop pass anyway. Finds two issues:
1. Fake completeness. The catch block returns an empty list when the upstream order service fails. That makes failures look like customers have no orders. 2. Shallow test. The test only checks the happy path fixture and does not cover upstream failure.
Fixes both:
- Replaces the empty-list fallback with the project's normal wrapped error.
- Adds a failure-path test that asserts the wrapped error is surfaced.
Re-scans:
npx aislop scan --changes --jsonScore: 100 / 100. Zero findings.
Agent reply to user:
Added loadCustomerOrders(customerId) and tests.>
aislop scan --changes: 100 / 100, no findings.>
Manual slop pass also caught and fixed two issues the scanner could not infer: the first draft returned an empty order list when the upstream service failed, and the test covered only the happy path. It now surfaces the project-standard wrapped error, and the tests cover both success and failure.
---
Notes:
- A clean score did not end the review.
- The agent found semantic slop: a plausible-looking fallback that changed product behavior.
- The fix improved both behavior and test coverage.
Example 05 — agent hand-off with aislop fix --claude
A large PR has too many non-fixable findings for manual editing. The agent hands off remaining issues to Claude Code.
---
User:
I need to clean up this 30-file PR before opening it. Mostly API layer and database migrations.
Agent (internal):
Full scan first:
aislop scan --jsonTwenty findings. Runs auto-fix:
aislop fix8 mechanical findings fixed (imports, comments, console logs). 12 remain — too many to hand-edit efficiently. Hands off:
aislop fix --claudeThis launches Claude Code in a subprocess with the findings as context. Claude Code fixes 10 of the 12.
Agent reviews the remaining two:
1. security/sql-injection in src/migrations/seed.ts:22 — false positive (safe test fixture values). 2. complexity/file-too-large in src/api/handlers.ts — legitimate but cannot split without breaking the API contract; files a follow-up issue.
Re-scans:
aislop scan --changes --jsonScore: 94 / 100. Zero errors. The remaining warning is the known file-size issue.
Agent reply to user:
Cleaned up the PR.
>
Auto-fixed 8 mechanical findings withaislop fix, then handed off 12 remaining to Claude Code withaislop fix --claude.
>
Claude fixed 10: unsafe type assertions (3), swallowed exceptions (4), redundant wrappers (2), excess parameters (1).
>
Remaining (2):
- sql-injection src/migrations/seed.ts — false positive; safe test fixture values
- file-too-large src/api/handlers.ts — known debt, filed #342 to split
>
Re-scanned: 94 / 100, 0 errors. Ready to open the PR.
---
Notes:
aislop fix --claude(and--codex,--cursor,--gemini) is for high-volume cleanups where hand-editing would be too slow.- Always review what the agent did — don't trust findings blindly.
- Remaining findings still need the agent's judgement layer even after hand-off.
- Use
-pto print a hand-off prompt without launching any agent (for copy-paste into a different tool).
Fix guide — non-mechanical fixes by rule
When aislop fix has done its work, remaining findings need judgement. For each rule below, open the cited file, verify the finding, and apply the fix.
| Rule | Fix |
|---|---|
unsafe-type-assertion / double-type-assertion | Find the real type. No as any, no as unknown as X. |
swallowed-exception / silent-recovery | Log and rethrow, or surface the failure. Don't log and continue. |
redundant-try-catch | Remove the wrapper. Let the error propagate naturally. |
hallucinated-import | Verify the module exists in the filesystem. Create or use what's there. |
duplicate-import | Merge into one import statement. |
meta-comment / narrative-comment | Delete comments that describe what the code does or why it changed. |
trivial-comment | Delete comments that restate the obvious. |
unreachable-code | Delete statements after return/throw/break. |
constant-condition | Remove the branch or make the condition real. |
empty-function | Implement the function or delete it. No stubs. |
ts-directive | Fix the underlying type issue instead of suppressing it. |
console-leftover | Replace with the project's logger or remove. |
thin-wrapper | Inline the call if the wrapper adds no value. |
generic-naming | Rename data/result/temp/handleClick to convey intent. |
function-too-long | Extract a helper at the logical seam. |
file-too-large | Split by concern, not line count. |
sql-injection | Swap template string for parameterised query. |
eval / innerhtml | Replace with JSON.parse, textContent, or DOMPurify. |
unused-export | Wire it up at the call site or delete. |
duplicate-code | Extract to a shared helper. |
hardcoded-secret | Move to environment variable. Fail loudly if unset. |
hardcoded-url / hardcoded-id | Read from environment, config, or accept as a parameter. |
vulnerable-dependency | Upgrade to the fixed version or add an override. |
Prevention catalog — write code that won't trip aislop
Read this before editing. Every pattern below is a rule aislop will flag.
The avoid/prefer examples are illustrative — substitute the project's actual tooling.
Comments — write code, not prose
ai-slop/narrative-comment — ai-slop/trivial-comment — ai-slop/meta-comment
Avoid: // This function takes a user ID and returns the user object — the signature already says this. Avoid: // Added for the checkout flow — see issue #123 — belongs in commit message. Avoid: // Refactored to use the new API — belongs in commit message. Avoid: // Loop through each item and check if it matches — the code shows this.
Prefer: // Keep this before the CORS middleware — credentialed origins reject OPTIONS otherwise. Prefer: // Workaround for knex#1234: bindings silently drop NaN.
Rule: if deleting the comment wouldn't confuse a future reader, don't write it.
Types — no as any, no as unknown as X
ai-slop/unsafe-type-assertion — ai-slop/double-type-assertion — ai-slop/ts-directive — ai-slop/redundant-type-coercion
Avoid: const user = res.data as any; — hides the real type. Avoid: const val = x as unknown as string — as any in disguise. Avoid: // @ts-ignore — you're suppressing a type error, not fixing it. Avoid: !!x, "" + x, +x where the type system already handles it.
Prefer:
- Declare or derive the real type and annotate the variable.
- If the shape is unknown, use
unknownplus the project's runtime validator. @ts-expect-erroronly with a specific reason comment and only when the type error is genuinely unavoidable (rare).
Errors — never swallow
ai-slop/swallowed-exception — ai-slop/silent-recovery — ai-slop/redundant-try-catch
Avoid: try { await thing(); } catch (e) {} — swallowed, invisible. Avoid: catch (e) { log.error(e); return []; } — silent recovery. The failure is hidden. Avoid: catch (e) { throw e; } — you're not handling the error, don't wrap it.
Prefer: log it via the project's logger, rethrow wrapped in the project's error class, or rethrow as-is. Fire-and-forget is acceptable only when you log (even at warn). Match the catch shape neighbouring code uses.
Security — use the safe API from the start
security/sql-injection — security/eval — security/innerhtml — security/hardcoded-secret — security/shell-injection — ai-slop/hardcoded-url — ai-slop/hardcoded-id
Avoid: ` db.query(SELECT FROM users WHERE id = ${id}`) `` — template-string SQL injection. Prefer: `db.query("SELECT FROM users WHERE id = $1", [id])` or the ORM builder.
Avoid: eval(expr) / new Function(body) on user input. Prefer: JSON.parse(expr) for data. Don't execute user code at all.
Avoid: el.innerHTML = html on untrusted input. Prefer: el.textContent = text, or sanitise with DOMPurify.
Avoid: const apiKey = "sk-abc123" in source. Prefer: const apiKey = process.env.OPENAI_API_KEY — fail loudly if unset.
Avoid: const apiUrl = "https://api.example.com/v2" hardcoded in source. Prefer: Read from environment or config. Use a named constant in a config module.
Avoid: const orgId = "org_abc123" hardcoded in business logic. Prefer: Accept as a parameter, read from config, or derive from context.
Duplication — search before you write
code-quality/duplicate-block — knip/exports
- Before writing a new helper, grep the codebase for the operation.
- If two blocks do the same thing with tiny variations, extract once and parameterise the variation.
- If you did extract a helper, make sure it gets used — an unused export is its own rule.
Dead code — don't leave it
ai-slop/unused-import — code-quality/unused-declaration — ai-slop/unreachable-code — ai-slop/constant-condition — ai-slop/hallucinated-import — ai-slop/duplicate-import
- Remove imports as you remove the code that used them — not later.
- If you wrote a function and ended up not using it, delete it. Don't "leave it in case".
- Commented-out code belongs in git history, not in the file.
- Statements after
return/throw/break/continueare dead — delete them. if (true),if (false),while (false)— remove the branch or make the condition real.- Verify every import resolves in the actual filesystem before writing it. AI agents hallucinate import paths.
- Combine duplicate imports of the same symbol into one statement.
Console — use the project's logger
ai-slop/console-leftover
- Grep for
pino,winston,bunyan,logger.ts,log.ts, or a shared wrapper and use it. - If the project has no logger and it needs one, pick one that fits the stack and add it.
- If it's a script or CLI where
console.erroris the convention, keepconsole.error.console.logis always flagged. - Never leave debug logs committed. Delete before the final scan.
TODO stubs — finish or file
ai-slop/todo-stub
Avoid: // TODO: handle error case
Prefer:
- Finish it in the same turn.
- If genuinely out of scope:
// TODO(#234): handle the retry path — currently we fail-fast.with a real issue number.
Empty functions — stub or finish
ai-slop/empty-function
Avoid: function onSuccess() {} — empty handler. Avoid: async function migrate() { throw new Error("not implemented"); } — stub that compiles but does nothing.
Prefer: Implement the function with real behavior. If the task is out of scope, remove the function entirely.
Naming — name for intent
ai-slop/generic-naming
Avoid: const data = await fetch(...), function handleClick(), const temp = items.filter(...)
Prefer: const orders = await fetchOrders(...), function confirmDeletion(), const unpaidInvoices = items.filter(...)
The name should tell the reader what's in it, not the type or how it was derived.
Function and file size — split at the logical seam
complexity/function-too-long (default max 80 LOC) — complexity/file-too-large (default max 400 LOC; JSX/TSX 2x) — complexity/deep-nesting — complexity/too-many-params
- Write short functions from the start. If you're over 40 lines, there's usually a seam.
- Extract the seam — a group of statements that does one sub-task and could be named.
- A file should have one cohesive responsibility.
- If you need 7+ parameters, pass an options object.
- Deep nesting → early returns:
if (!a) return; if (!b) return;.
Architecture — respect .aislop/rules.yml
If the project has .aislop/rules.yml (custom architecture rules — import bans, layering, module boundaries), open it before writing. A rule you break now is a finding you'll have to undo later.
Dependencies — use what's there
knip/dependencies — knip/unlisted — security/vulnerable-dependency
- Before adding a package, check
package.json— the project often already has a library. - Never install a package for a 5-line utility.
- If
pnpm audit/npm auditflags a vulnerability with a clean upgrade, take it.
Fake completeness — no placeholders dressed as features
Scans catch many textual patterns but cannot always tell whether code is only pretending to be complete.
Avoid:
- Hardcoded success paths:
return true,return [], fake IDs, canned API responses. - "Temporary" fallback behavior that silently hides integration failures.
- UI or API handlers that implement only the happy path.
- Tests that assert only that something renders or returns the same fixture it was given.
Prefer:
- Wire the real dependency or fail loudly with the project's error pattern.
- Cover at least one success path and one meaningful failure or edge path.
- Delete scaffolding that is no longer needed once the real implementation exists.
Abstractions — don't future-proof imaginary callers
ai-slop/thin-wrapper — ai-slop/duplicate-type-declaration — ai-slop/redundant-type-coercion
AI code often creates generic layers before the repo needs them.
Avoid:
- New factories, registries, strategy objects, adapters, hooks, or base classes with one caller.
- Options objects full of unused flags.
- Helpers exported from barrels before any external module imports them.
- Wrappers that do nothing except delegate with the same signature — inline the call.
Prefer:
- Keep logic local until there are at least two real callers or an existing project pattern requires extraction.
- Name extracted helpers after the concrete domain behavior, not the implementation technique.
- Reuse existing type declarations — import them if they're in another file.
Wiring — finish the path, not just the file
Before calling the task done, check:
- Public API: route, command, export, screen, or handler is reachable from the intended entry point.
- Types and generated artifacts: schemas, clients, migrations, snapshots, docs, or indexes are updated.
- State transitions: loading, empty, error, retry, permission-denied, and success states are coherent.
- Backwards compatibility: existing callers still compile and keep their previous behavior.
- Observability: important failures are traceable through the project's logger, metrics, or error surface.
{
"name": "aislop",
"version": "0.3.0",
"description": "Code-quality gate and coding guardrail for AI coding agents. Always invoke when you finish editing and prepare to hand control back, even if the user did not explicitly ask. Trigger on commit, push, PR, or quality questions like any slop, is this clean, review my changes, score my code, any duplicates, or is this safe. Scans with aislop, fixes what is mechanical, addresses the rest in-session in the project style, then reports what changed.",
"homepage": "https://scanaislop.com",
"repository": "https://github.com/scanaislop/skills",
"license": "MIT",
"author": {
"name": "scanaislop",
"url": "https://github.com/scanaislop"
},
"keywords": [
"agent-skills",
"agentic-quality-gate",
"quality-gate",
"coding-guardrail",
"guardrail",
"code-quality",
"code-review",
"ai-slop",
"ai-slop-detection",
"supply-chain-policy",
"semantic-review",
"manual-review",
"test-quality",
"placeholder-code",
"silent-recovery",
"hallucinated-imports",
"empty-functions",
"score-badge",
"score-trend",
"ci-gate",
"agent-handoff",
"pre-commit-hook",
"ai-agents",
"skills-sh",
"anthropic",
"deduplication",
"reusability",
"maintainability",
"security",
"architecture-rules",
"dead-code",
"complexity",
"vulnerable-dependencies",
"static-analysis",
"lint",
"pre-commit",
"developer-tools",
"claude-code",
"codex",
"cursor",
"gemini-cli",
"windsurf",
"cline",
"aider",
"goose",
"opencode",
"github-copilot",
"vscode",
"kilo-code",
"continue",
"warp",
"amp",
"antigravity",
"kimi",
"deep-agents",
"typescript",
"javascript",
"python",
"go",
"rust",
"ruby",
"php"
],
"compatibility": [
"claude-code",
"codex",
"cursor",
"windsurf",
"gemini-cli",
"vscode",
"amp",
"aider",
"warp",
"goose",
"opencode",
"antigravity",
"deep-agents",
"kimi",
"cline"
],
"entry": "SKILL.md",
"examples": [
"examples/01-before-commit.md",
"examples/02-remaining-findings.md",
"examples/03-ci-gate.md",
"examples/04-green-scan-manual-pass.md",
"examples/05-agent-handoff.md"
],
"triggers": [
"is this ready to ship",
"before I commit",
"before I push",
"before opening the PR",
"quality check",
"is this clean",
"any slop",
"any duplicates",
"can we dedupe this",
"is this reusable",
"should this be a helper",
"is this too long",
"should I split this file",
"any security issues",
"audit my deps",
"does this follow our architecture rules",
"score my code",
"review my changes",
"green scan but still sloppy",
"catch placeholder code",
"find shallow tests",
"semantic slop review",
"anything to clean up",
"diagnose my environment",
"check installed tools",
"troubleshoot my setup",
"add a score badge",
"show my score trend",
"install a pre-commit hook",
"hand off remaining issues",
"fix with claude",
"fix with codex",
"fix with cursor",
"fix with gemini",
"generate SARIF",
"run aislop doctor",
"code quality check",
"run a code quality check",
"check the code quality",
"ai slop",
"any slops",
"any ai slop",
"remove the slop",
"clean up the slop",
"check for slop",
"clean this up before i push",
"is this garbage",
"whats wrong with my code",
"does this look right",
"check my diff",
"is the code clean",
"any red flags",
"does this have slop",
"will this pass review",
"make sure this is production ready"
]
}
Related skills
How it compares
Use instead of asking the agent to "read all of src/" ad hoc when you need slop detection and score-aware cleanup, not a one-off linter invocation.
FAQ
Who is aislop for?
Developers using Claude Code, Cursor, or similar agents who want pre-commit and PR-quality checks tuned to AI-generated code and project score gates.
When should I use aislop?
Before committing a refactor, when CI reports a score below your threshold, after merging branches before opening a PR, when you suspect duplicated fetch logic or oversized functions, or when linters pass but the change still feels sloppy. It also applies in Build when deduping p
Is aislop safe to install?
Review the Security Audits panel on this Prism page and your org policy before granting repository access; the skill is intended to read and critique project code like a review agent.