Two commits landed in the Laravel Boost repository on August 26, 2026 that significantly update the AI guidance rules baked into the package. The changes touch all 19 best-practice rule files and add a new section on controller resource design. Here is what changed and why it matters.
The big picture: from prescriptive to contextual
The first commit (d165b9ea) touches 1,427 lines across every rule file. The headline change is not a new feature — it is a deliberate softening of absolute language.
Rules that previously said "Incorrect" / "Correct" now use labels like:
- "Manual lookup:" / "Use route model binding:"
- "Hidden dependency:" / "Injected dependency:"
- "Unsafe:" / "Preferred:"
- "Queued and durable:" / "Deferred in the current process:"
The intent is clear: the guidance now presents trade-offs and context instead of moral verdicts. This matters because AI coding agents (and developers) following these rules were previously being trained to treat "Incorrect" examples as always wrong, even in situations where the pattern was actually fine.
Key Changes by Area
Queries — advanced-queries.md
The old guidance said whereHas() was flat-out wrong because it "re-executes per row." The new version is more honest:
whereHas()typically produces anEXISTSsubquery, whilewhereIn()can express the same filter with anINsubquery. Either form may be faster depending on the database engine, indexes, cardinality, and query plan. Measure both forms with representative data.
The section title changed from "Prefer whereIn + Subquery Over whereHas" to "Compare whereHas() with an IN Subquery". Similarly, the compound index rule now says "verify the query plan" rather than asserting a single correct approach.
A technical fix also snuck in: the dynamic relationship example now correctly passes the foreign key to belongsTo():
// Before (broken — missing the FK argument):
return $this->belongsTo(Login::class);
// After (correct):
return $this->belongsTo(Login::class, 'last_login_id');
Architecture — architecture.md
Two notable shifts:
Dependency injection: The old rule said constructor injection was always correct and method injection was a code smell. The new rule aligns with how Laravel actually works:
Prefer constructor injection for dependencies required throughout an object's lifetime. Method injection is appropriate for dependencies needed by one controller action, listener, job handler, or other container-invoked method.
Default sort order: Instead of "always use latest()", the guidance now recommends a stable two-column sort with a tie-breaker for reliable pagination:
Post::query()
->orderByDesc('created_at')
->orderByDesc('id')
->paginate();
Caching — caching.md
The Cache::remember() section now explicitly warns about the false-cache-miss bug:
The manual version below incorrectly treats valid falsy values, such as
falseor0, as cache misses.
It also adds an honest caveat: Cache::remember() does not prevent concurrent requests from computing the same missing value — you still need Cache::lock() for that.
Routing — routing.md
The "Keep Controllers Thin" rule (with its arbitrary "under 10 lines" target) is gone. In its place:
Controllers should coordinate HTTP input, authorization, validation, an application operation, and the response. Extract substantial or reusable business logic, but do not introduce an action or service merely to satisfy an arbitrary line limit.
Migrations — migrations.md
The file shrank significantly (78 → 24 deletions vs. 24 additions). Several overly prescriptive examples were removed. The foreign-key section now includes a practical note:
Do not add a duplicate single-column index without checking the database driver's treatment of foreign-key indexes and the indexes already created by the migration.
Security — security.md
Two nuanced additions stand out:
-
$guarded = []is no longer labeled universally "Incorrect." The new text acknowledges that mass-assignment protection controls which attributes can be set, not values or authorization — and that deliberate conventions using$guardedare valid. -
The SQL injection example now uses the fluent string helper properly:
User::whereRaw('LOWER(name) = ?', [$request->string('name')->lower()->toString()])->get();
- A new explicit note: "Public actions intentionally available to everyone do not need a redundant authorization check."
Queues — queue-jobs.md
The Amazon SQS footnote is new and important:
Amazon Simple Queue Service uses its visibility timeout instead of Laravel's
retry_after; configure that timeout at the queue level.
The ShouldBeUnique section now notes that all dispatching processes must share a cache store that supports locks — a silent gotcha that has burned teams before.
New section: organize controllers around resources
The second commit (b19e98a8) adds a standalone section to routing.md covering a pattern that often gets debated on Laravel teams.
The guidance establishes a clear default: organize controllers around one resource using standard resource actions (index, show, create, store, edit, update, destroy). When a custom verb like publish, approve, or archive appears, treat it as a design signal — it might represent a separate resource.
The canonical example models podcast publishing as a dedicated controller:
// Route
Route::post('/published-podcasts/{podcast}', [PublishedPodcastController::class, 'store'])
->name('published-podcasts.store');
Route::delete('/published-podcasts/{podcast}', [PublishedPodcastController::class, 'destroy'])
->name('published-podcasts.destroy');
// Controller
class PublishedPodcastController extends Controller
{
public function store(Podcast $podcast): RedirectResponse
{
$podcast->publish();
return back();
}
public function destroy(Podcast $podcast): RedirectResponse
{
$podcast->unpublish();
return back();
}
}
The guidance ends with an important escape hatch:
Treat a custom verb as a design signal, not proof that another controller is required. Use query parameters for simple filtering, and keep an explicit action route when modeling the operation as a resource would obscure the domain or conflict with established project conventions.
Why this matters for AI-assisted development
Laravel Boost feeds these rules directly to AI coding agents as context when generating code. Overly prescriptive "always/never" rules cause agents to reject valid patterns and to add unnecessary abstractions (action classes for trivial logic, for example). The new tone should lead to more pragmatic, context-aware suggestions — and fewer unnecessary "Incorrect" rewrites of perfectly reasonable code.
The shift also signals a broader direction: good AI guidance reads like a senior developer explaining trade-offs, not a linter listing violations.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.