Three AI Agents, One Refactor: MiniMax M3, Claude Opus 4.8, and Fable 5 Remove a Laravel Starter Kit

The experiment

Our insurance admin panel started life as the official Laravel Livewire starter kit. Over time, Filament v5 became the only UI we actually use — the starter kit's Fortify auth pages, Flux components, settings screens, and passkey support were dead weight.

So we gave three AI coding agents the identical prompt on the identical codebase:

Remove all traces of Livewire (the starter kit) and Fortify. Keep Filament.

Agent Branch Cost
MiniMax M3 chore/remove-livewire-starter-kit $0.80
Claude Opus 4.8 feature/remove-livewire-starter-kit $4.80
Claude Fable 5 claude/bold-wilson-5610d9 $7.00

A nuance worth flagging up front: "remove Livewire" here means the starter kit — Filament itself is built on livewire/livewire, so the core package has to stay. All three agents understood this correctly. Nobody broke Filament.

Where they agreed

The core of the diff is nearly identical across all three branches, and it's the bulk of the work:

  • Deleted all starter-kit Blade views: auth pages, settings pages, layouts, Flux component overrides, the welcome page, the dashboard (~2,500 lines)
  • Deleted FortifyServiceProvider, the Fortify actions, validation traits, and config/fortify.php
  • Deleted the auth, settings, and dashboard test suites (~600 lines)
  • Removed Fortify's PasskeyUser contract and 2FA/passkey traits from the User model
  • Rewired / to redirect to /admin and updated ExampleTest to assert the redirect
  • Cleaned passkeys.js out of the Vite config

Final diffstats: MiniMax −3,698/+16, Fable −3,641/+10, Opus −5,370/+289 (the extra volume is a regenerated composer.lock). For 95% of the lines, you could not tell the three branches apart. The interesting part is the other 5%.

Where they diverged

Dependencies: the decisive difference

MiniMax edited composer.json aggressively — removed laravel/fortify, livewire/flux, livewire/blaze, and even laravel/chisel — but never updated composer.lock. The lock file on its branch still contains Fortify. That means composer install fails validation on CI and the manifest and lock disagree. It also renamed the package to okanetsolutions/oka-insurance, a nice touch.

Opus did the full job: removed laravel/fortify, livewire/flux, and livewire/blaze from composer.json and regenerated composer.lock (1,938 lines churned). It left laravel/chisel alone — defensible, since chisel isn't a Livewire or Fortify package. It also renamed the package.

Fable did something nobody asked for: it left every dependency in place and instead added Fortify to dont-discover:

"extra": {
    "laravel": {
        "dont-discover": ["laravel/fortify"]
    }
}

Fortify, Flux, and Blaze all remain installed. The app boots fine and no stray auth routes register — but "remove all traces" this is not. It reads like an agent that couldn't (or wouldn't) run composer and chose the safest no-lock-touch path.

Migrations: a genuine judgment call

MiniMax and Opus deleted the passkeys table migration and the two-factor columns migration. Fable kept both — and, consistently, kept the two_factor_* properties in the User model's docblock and #[Hidden] attribute, since the columns still exist in its schema.

Here's the uncomfortable part: this app is already deployed. Those migrations have run in production. Deleting applied migration files creates drift — migrate:status shows orphaned entries and rollbacks break. Whether Fable kept them out of caution or omission, its commit message doesn't say. But it's the only branch that doesn't require a follow-up php artisan migrate conversation before deploy. (And the only one that should have added a drop-columns migration — which none of them did.)

Traces left behind

We grepped each branch for fortify, flux, and passkey outside lock files:

Leftover trace MiniMax Opus Fable
@laravel/passkeys in package.json ✅ removed ❌ left ❌ left
Fortify/Flux skills in boost.json ✅ removed ❌ left ❌ left
Fortify/Flux deps in composer.json ✅ removed ✅ removed ❌ left
Passkey/2FA migrations ✅ removed ✅ removed ❌ left
Dead initials() method on User ❌ left ❌ left ✅ removed

Ironically, the cheapest model was the most thorough trace-hunter: only MiniMax noticed the @laravel/passkeys npm dependency and the Boost skill registrations. Meanwhile only the most expensive model noticed that User::initials() became dead code once the user-menu Blade that called it was deleted — MiniMax and Opus both left an orphaned method (and its Str import) behind.

Small craft note: MiniMax was also the only one to preserve the ->name('home') on the root route, so its test still uses route('home') instead of a hardcoded /. And MiniMax added the FilamentUser contract with canAccessPanel() to the User model — unrequested, but exactly what Filament requires in production environments. That's the single highest-value line any of the three wrote.

Verification

Only Opus's commit message claims actual verification: "17 tests pass, Pint clean, no new PHPStan errors, npm build ok." Neither MiniMax nor Fable stated that they ran anything — and MiniMax's stale lock file suggests it didn't try composer install.

Scorecard

MiniMax M3 ($0.80) Opus 4.8 ($4.80) Fable 5 ($7.00)
Core deletion (views/routes/tests)
Dependency removal ⚠️ json edited, lock broken ✅ json + lock regenerated ❌ deps kept, discovery disabled
Trace-hunting thoroughness ✅ best ⚠️ missed npm + boost.json ❌ most leftovers
Dead-code awareness ✅ only one to catch it
Production-deploy safety ⚠️ ⚠️ migration drift ✅ accidentally safest
Stated verification ✅ tests, Pint, PHPStan, build
Mergeable as-is? No — lock file Closest — needs 2 small fixes No — task incomplete

Verdict

Opus 4.8 produced the most mergeable branch. It's the only one where the dependency story is complete and verified — fixing its two missed traces (package.json, boost.json) is a thirty-second follow-up.

MiniMax M3 was a shocking amount of refactor for 80 cents. It hunted traces more thoroughly than models costing 6–9× more, and made the two smartest discretionary calls (named route, FilamentUser contract). But the stale composer.lock is exactly the kind of "looks done, fails on CI" failure that makes cheap runs expensive.

Fable 5 was the most expensive and the least complete — yet also the most cautious, the only one to remove dead code, and the only branch you could deploy to the existing production database without a migration conversation. Whether that's wisdom or timidity depends on what you were grading for. At $7, we were grading for the task as written, and it didn't finish it.

The broader lesson: all three agents handled the 3,600 lines of obvious deletion identically. What separated them was everything around the code — lock files, deployed-schema awareness, manifest hygiene, verification. That's also exactly the part of a refactor where a human reviewer earns their keep. Price predicted none of it.