Laravel Packages

Sloppy: Static Analysis for AI-Written PHP

Published
Sloppy: Static Analysis for AI-Written PHP image

Sloppy is a static analysis tool by heyosseus for the maintenance problems AI coding agents can leave in PHP projects. It runs locally, without a model or API key, and checks for patterns such as swallowed exceptions, duplicate logic, and unfinished method bodies. The same checks apply to code you write yourself; Sloppy makes no attempt to identify AI authorship.

Sloppy complements type checkers such as PHPStan and Psalm, formatting tools such as Pint, and your existing test suite. Its checks focus on maintenance problems those tools may leave unreported. A method can have correct types and still hide a failed operation or run a database query on every iteration of a loop.

Checking PHP and Eloquent Code

Sloppy's general PHP rules cover complexity, unused constructor dependencies, redundant conditions, and other maintenance concerns. Each finding includes a location, measurements, a confidence level, and advice about what to change.

For example, this archive operation discards the exception and returns as though nothing happened:

use Illuminate\Support\Facades\Storage;
 
function archiveTranscript(string $sessionId, string $transcript): void
{
try {
Storage::disk('s3')->put("transcripts/{$sessionId}.txt", $transcript);
} catch (\Throwable $exception) {
}
}

The empty catch block matches SL107, Swallowed Exception. Whether you report the failure, retry it, or let the exception propagate depends on the operation. Sloppy identifies the missing handling; you still need to decide what failure should mean for the caller.

In Laravel projects, additional rules check controller responsibilities and Eloquent usage. Consider a count that loads records before filtering them:

use App\Models\PodcastEpisode;
 
$publishedCount = PodcastEpisode::all()
->where('status', 'published')
->count();

This matches SL205, Collection Instead Of Database Query. The database can do the filtering and counting:

$publishedCount = PodcastEpisode::query()
->where('status', 'published')
->count();

Other Laravel checks look for possible N+1 queries and queries inside loops. Sloppy also checks for placeholder implementations, including bodies left with an unfinished-code comment or a "not implemented" exception.

Checking an Agent's Edits

You can install Sloppy's Claude Code integration with:

vendor/bin/sloppy agents install

The installer adds project rules to CLAUDE.md and hooks to .claude/settings.json. The edit hook feeds new findings back to the agent. A finish hook can send it back to address findings at or above your configured threshold.

The finish check blocks once. If the agent tries to finish again, it can proceed with unresolved findings recorded in the transcript. Hook failures also allow the session to continue. Treat these hooks as feedback during development, and use a CI check when you need a build gate.

The package also documents hooks for Gemini CLI and Codex, generated instructions for other coding tools, and an MCP server for on-demand analysis.

Reviewing New Findings

For an existing application, you can review a branch without treating all its inherited problems as new work:

vendor/bin/sloppy diff main --merge-base
vendor/bin/sloppy review main --merge-base

Both commands compare against the branch's common ancestor with main. The review command orders the findings by risk. Uncommitted and untracked files are included, and findings use fingerprints rather than line numbers, so adding an import does not make an old finding new.

You can also record existing findings in a baseline:

vendor/bin/sloppy baseline

Sloppy provides CI reporting and Pest expectations for checking new debt. Its diff-only checks can also flag tests that a change skips, removes assertions from, or weakens with an assertion that cannot fail.

Installation and Fixes

Sloppy requires PHP 8.3 or later. Its Artisan commands and Laravel-specific rules support Laravel 12 and 13:

composer require --dev heyosseus/sloppy
 
vendor/bin/sloppy
# In Laravel:
php artisan sloppy

The standalone binary discovers source roots from composer.json. In Laravel, the service provider is discovered automatically, and you can publish configuration with php artisan vendor:publish --tag=sloppy-config.

For mechanical changes, preview a fix pass before applying it:

php artisan sloppy:fix --dry-run

Sloppy generates a Rector configuration scoped to files with fixable findings. When applying changes, it uses Laravel Pint to format the rewritten files and can remove comments that only repeat the code beneath them. Rector and Pint are optional dependencies that you install in the analysed project. Splitting a large class or deciding whether two similar methods should share an abstraction still requires review.

Sloppy is MIT licensed. You can find the source and documentation in the Sloppy repository on GitHub.

Yannick Lyn Fatt photo

Staff Writer at Laravel News and Full stack web developer.

Sponsored

masteringlaravel logo
Laravel Code Review

Get expert guidance in a few days with a Laravel code review

Visit Laravel Code Review

The latest

View all →
Deferred Schema Loading in Filament v5.8 image

Deferred Schema Loading in Filament v5.8

Read article
Mastering Laravel Testing: A Video Course on Laravel Tests image

Mastering Laravel Testing: A Video Course on Laravel Tests

Read article
NativePHP Mobile Security Advisories: Update to 4.6.1 image

NativePHP Mobile Security Advisories: Update to 4.6.1

Read article
Volker Dusch on the PHP RCE Vulnerabilities and Disclosure image

Volker Dusch on the PHP RCE Vulnerabilities and Disclosure

Read article
Decide with Jev: Turn AI Answers into Decisions with PHP Rules image

Decide with Jev: Turn AI Answers into Decisions with PHP Rules

Read article
Skuul: Open-Source School Management Built on Laravel image

Skuul: Open-Source School Management Built on Laravel

Read article