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-basevendor/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.