@mohammadhprp/system-prompt 0.12.2 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/framework/commands/README.md +1 -1
  2. package/framework/commands/review.md +1 -1
  3. package/framework/mcps/README.md +0 -1
  4. package/framework/plugins/ponytail/README.md +0 -1
  5. package/framework/plugins/ponytail/capabilities.md +1 -1
  6. package/framework/references/standards/api.md +0 -1
  7. package/framework/references/standards/architecture.md +0 -1
  8. package/framework/references/standards/database.md +0 -1
  9. package/framework/references/standards/debugging.md +0 -1
  10. package/framework/references/standards/documentation.md +0 -1
  11. package/framework/references/standards/logging.md +0 -1
  12. package/framework/references/standards/naming.md +0 -1
  13. package/framework/references/standards/observability.md +0 -1
  14. package/framework/references/standards/performance.md +0 -1
  15. package/framework/references/standards/pull-requests.md +0 -1
  16. package/framework/references/standards/security.md +0 -1
  17. package/framework/references/standards/testing.md +0 -1
  18. package/framework/skills/README.md +16 -12
  19. package/framework/skills/architect/SKILL.md +83 -0
  20. package/framework/skills/architect/examples.md +5 -0
  21. package/framework/skills/architect/references/design-red-flags.md +33 -0
  22. package/framework/skills/architect/references/rationale-template.md +35 -0
  23. package/framework/skills/architect/references/runner-prompt.md +20 -0
  24. package/framework/skills/arena/SKILL.md +71 -0
  25. package/framework/skills/arena/examples.md +5 -0
  26. package/framework/skills/bro/SKILL.md +7 -0
  27. package/framework/skills/bro/examples.md +5 -0
  28. package/framework/skills/changelog/SKILL.md +41 -0
  29. package/framework/skills/changelog/examples.md +5 -0
  30. package/framework/skills/commit/SKILL.md +28 -0
  31. package/framework/skills/commit/examples.md +5 -0
  32. package/framework/skills/how/SKILL.md +135 -0
  33. package/framework/skills/how/examples.md +5 -0
  34. package/framework/skills/how/references/critic-prompt.md +59 -0
  35. package/framework/skills/how/references/critique-rubric.md +58 -0
  36. package/framework/skills/how/references/explainer-prompt.md +55 -0
  37. package/framework/skills/how/references/explorer-prompt.md +52 -0
  38. package/framework/skills/improve/SKILL.md +1 -3
  39. package/framework/skills/improve/examples.md +1 -1
  40. package/framework/skills/laravel-best-practices/SKILL.md +56 -216
  41. package/framework/skills/laravel-best-practices/references/architecture.md +1 -1
  42. package/framework/skills/laravel-best-practices/references/checklist.md +139 -0
  43. package/framework/skills/laravel-best-practices/references/eloquent.md +4 -2
  44. package/framework/skills/laravel-best-practices/references/infer-conventions.md +97 -0
  45. package/framework/skills/laravel-best-practices/references/pest-testing.md +47 -18
  46. package/framework/skills/laravel-best-practices/references/security.md +1 -1
  47. package/framework/skills/laravel-best-practices/references/style.md +1 -1
  48. package/framework/skills/laravel-best-practices/references/tailwindcss.md +0 -1
  49. package/framework/skills/merge-request/SKILL.md +40 -0
  50. package/framework/skills/merge-request/examples.md +5 -0
  51. package/framework/skills/pull-request/SKILL.md +31 -0
  52. package/framework/skills/pull-request/examples.md +5 -0
  53. package/framework/skills/release/SKILL.md +30 -0
  54. package/framework/skills/release/examples.md +5 -0
  55. package/framework/skills/review/SKILL.md +18 -0
  56. package/framework/skills/review/examples.md +5 -0
  57. package/framework/skills/tdd/SKILL.md +44 -0
  58. package/framework/skills/tdd/examples.md +5 -0
  59. package/framework/skills/unslop/SKILL.md +81 -0
  60. package/framework/skills/unslop/examples.md +5 -0
  61. package/framework/skills/why/SKILL.md +230 -0
  62. package/framework/skills/why/examples.md +5 -0
  63. package/framework/skills/why/references/epistemics.md +144 -0
  64. package/framework/skills/why/references/investigator-prompt.md +103 -0
  65. package/framework/skills/why/references/source-playbook.md +17 -0
  66. package/framework/skills/why/references/sources/code-archaeology.md +88 -0
  67. package/framework/skills/why/references/sources/databricks.md +70 -0
  68. package/framework/skills/why/references/sources/datadog.md +99 -0
  69. package/framework/skills/why/references/sources/incident-postmortem.md +15 -0
  70. package/framework/skills/why/references/sources/linear.md +48 -0
  71. package/framework/skills/why/references/sources/notion.md +55 -0
  72. package/framework/skills/why/references/sources/sentry.md +100 -0
  73. package/framework/skills/why/references/sources/slack.md +54 -0
  74. package/framework/skills/why/references/synthesizer-prompt.md +135 -0
  75. package/package.json +1 -1
  76. package/src/catalog.js +13 -12
  77. package/framework/mcps/notion-mcp/README.md +0 -57
  78. package/framework/mcps/notion-mcp/capabilities.md +0 -118
  79. package/framework/mcps/notion-mcp/configs/opencode.json +0 -9
  80. package/framework/mcps/notion-mcp/install.md +0 -70
  81. package/framework/mcps/notion-mcp/troubleshooting.md +0 -95
  82. package/framework/skills/brainstorming/SKILL.md +0 -159
  83. package/framework/skills/brainstorming/examples.md +0 -49
  84. package/framework/skills/brainstorming/scripts/frame-template.html +0 -213
  85. package/framework/skills/brainstorming/scripts/helper.js +0 -167
  86. package/framework/skills/brainstorming/scripts/server.cjs +0 -723
  87. package/framework/skills/brainstorming/scripts/start-server.sh +0 -209
  88. package/framework/skills/brainstorming/scripts/stop-server.sh +0 -120
  89. package/framework/skills/brainstorming/visual-companion.md +0 -291
  90. package/framework/skills/code-review/SKILL.md +0 -72
  91. package/framework/skills/code-review/examples.md +0 -31
  92. package/framework/skills/codenavi/SKILL.md +0 -306
  93. package/framework/skills/codenavi/examples.md +0 -33
  94. package/framework/skills/codenavi/references/coding-principles.md +0 -143
  95. package/framework/skills/codenavi/references/notebook-spec.md +0 -171
  96. package/framework/skills/create-adr/SKILL.md +0 -429
  97. package/framework/skills/create-adr/examples.md +0 -35
  98. package/framework/skills/design/SKILL.md +0 -399
  99. package/framework/skills/design/examples.md +0 -34
  100. package/framework/skills/great-interface/SKILL.md +0 -43
  101. package/framework/skills/great-interface/references/animations.md +0 -205
  102. package/framework/skills/great-interface/references/better-accessibility.md +0 -106
  103. package/framework/skills/great-interface/references/better-colors.md +0 -100
  104. package/framework/skills/great-interface/references/better-interface.md +0 -132
  105. package/framework/skills/great-interface/references/better-layout.md +0 -76
  106. package/framework/skills/great-interface/references/better-typography.md +0 -157
  107. package/framework/skills/great-interface/references/better-ui.md +0 -107
  108. package/framework/skills/great-interface/references/better-writing.md +0 -109
  109. package/framework/skills/great-interface/references/choosing-fonts.md +0 -64
  110. package/framework/skills/great-interface/references/color-formats.md +0 -90
  111. package/framework/skills/great-interface/references/color-usage.md +0 -118
  112. package/framework/skills/great-interface/references/contrast.md +0 -79
  113. package/framework/skills/great-interface/references/css-cheat-sheet.md +0 -65
  114. package/framework/skills/great-interface/references/details-and-accessibility.md +0 -119
  115. package/framework/skills/great-interface/references/enter-exit.md +0 -147
  116. package/framework/skills/great-interface/references/explain-interface.md +0 -126
  117. package/framework/skills/great-interface/references/find-the-effect.md +0 -94
  118. package/framework/skills/great-interface/references/focus-and-keyboard.md +0 -131
  119. package/framework/skills/great-interface/references/forms.md +0 -84
  120. package/framework/skills/great-interface/references/from-an-image.md +0 -55
  121. package/framework/skills/great-interface/references/grouping-and-alignment.md +0 -123
  122. package/framework/skills/great-interface/references/hit-areas.md +0 -94
  123. package/framework/skills/great-interface/references/icon-transitions.md +0 -102
  124. package/framework/skills/great-interface/references/icons.md +0 -110
  125. package/framework/skills/great-interface/references/interface-review.md +0 -148
  126. package/framework/skills/great-interface/references/motion-and-zoom.md +0 -79
  127. package/framework/skills/great-interface/references/no-browser.md +0 -73
  128. package/framework/skills/great-interface/references/palette-generation.md +0 -104
  129. package/framework/skills/great-interface/references/palette-structure.md +0 -76
  130. package/framework/skills/great-interface/references/performance.md +0 -88
  131. package/framework/skills/great-interface/references/picker.md +0 -76
  132. package/framework/skills/great-interface/references/read-the-system.md +0 -178
  133. package/framework/skills/great-interface/references/removed-signals.md +0 -38
  134. package/framework/skills/great-interface/references/review-format.md +0 -46
  135. package/framework/skills/great-interface/references/scope-resolution.md +0 -88
  136. package/framework/skills/great-interface/references/screen-readers.md +0 -101
  137. package/framework/skills/great-interface/references/semantics-and-aria.md +0 -84
  138. package/framework/skills/great-interface/references/spacing-and-adaptivity.md +0 -159
  139. package/framework/skills/great-interface/references/spacing-and-sizing.md +0 -121
  140. package/framework/skills/great-interface/references/surfaces.md +0 -219
  141. package/framework/skills/great-interface/references/token-naming.md +0 -97
  142. package/framework/skills/great-interface/references/variable-fonts-and-opentype.md +0 -105
  143. package/framework/skills/great-interface/references/variant.md +0 -104
  144. package/framework/skills/great-interface/references/wrapping-and-punctuation.md +0 -55
  145. package/framework/skills/learning-opportunities/SKILL.md +0 -140
  146. package/framework/skills/learning-opportunities/examples.md +0 -34
  147. package/framework/skills/learning-opportunities/references/PRINCIPLES.md +0 -42
  148. package/framework/skills/notion-mcp/SKILL.md +0 -57
  149. package/framework/skills/notion-mcp/examples.md +0 -31
  150. package/framework/skills/notion-mcp/references/comments.md +0 -112
  151. package/framework/skills/notion-mcp/references/databases.md +0 -193
  152. package/framework/skills/notion-mcp/references/pages.md +0 -235
  153. package/framework/skills/spec-driven-eval/SKILL.md +0 -341
  154. package/framework/skills/spec-driven-eval/examples.md +0 -35
  155. package/framework/skills/spec-driven-eval/references/quickstart.md +0 -118
  156. package/framework/skills/spec-driven-eval/references/reference.md +0 -295
  157. package/framework/skills/technical-design-doc-creator/README.md +0 -411
  158. package/framework/skills/technical-design-doc-creator/SKILL.md +0 -1484
  159. package/framework/skills/technical-design-doc-creator/examples.md +0 -35
  160. package/framework/skills/web-design-guidelines/SKILL.md +0 -65
  161. package/framework/skills/web-design-guidelines/examples.md +0 -32
  162. package/framework/skills/web-design-guidelines/references/guideline.md +0 -174
@@ -1,229 +1,69 @@
1
1
  ---
2
2
  name: laravel-best-practices
3
- description: "Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code."
4
- version: 0.1.0
3
+ description: "Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code. This includes creating or modifying controllers, models, migrations, form requests, policies, jobs, scheduled commands, service classes, and Eloquent queries. Triggers for N+1 and query performance issues, caching strategies, authorization and security patterns, validation, error handling, queue and job configuration, route definitions, and architectural decisions. Also use for Laravel code reviews and refactoring existing Laravel code to follow best practices. Covers any task involving Laravel backend PHP code patterns."
4
+ license: MIT
5
+ metadata:
6
+ author: laravel
5
7
  ---
6
8
 
7
9
  # Laravel Best Practices
8
10
 
9
- Best practices for Laravel, prioritized by impact. Each rule teaches what to do and why. For exact API syntax, verify with `search-docs`.
11
+ Best practices for Laravel, organized as an index of reference files. Each reference file teaches what to do and why. For exact API syntax, verify with `search-docs`.
10
12
 
11
13
  ## Consistency First
12
14
 
13
- Before applying any rule, check what the application already does. Laravel offers multiple valid approaches the best choice is the one the codebase already uses, even if another pattern would be theoretically better. Inconsistency is worse than a suboptimal pattern.
15
+ Before applying any reference, check what the application already does. Laravel offers multiple valid approaches, and the best choice is the one the codebase already uses, even if another pattern would be theoretically better. Inconsistency is worse than a suboptimal pattern.
14
16
 
15
- Check sibling files, related controllers, models, or tests for established patterns. If one exists, follow it — don't introduce a second way. These rules are defaults for when no pattern exists yet, not overrides.
16
-
17
- ## Quick Reference
18
-
19
- ### 1. Database Performance → `references/db-performance.md`
20
-
21
- - Eager load with `with()` to prevent N+1 queries
22
- - Enable `Model::preventLazyLoading()` in development
23
- - Select only needed columns, avoid `SELECT *`
24
- - `chunk()` / `chunkById()` for large datasets
25
- - Index columns used in `WHERE`, `ORDER BY`, `JOIN`
26
- - `withCount()` instead of loading relations to count
27
- - `cursor()` for memory-efficient read-only iteration
28
- - Never query in Blade templates
29
-
30
- ### 2. Advanced Query Patterns → `references/advanced-queries.md`
31
-
32
- - `addSelect()` subqueries over eager-loading entire has-many for a single value
33
- - Dynamic relationships via subquery FK + `belongsTo`
34
- - Conditional aggregates (`CASE WHEN` in `selectRaw`) over multiple count queries
35
- - `setRelation()` to prevent circular N+1 queries
36
- - `whereIn` + `pluck()` over `whereHas` for better index usage
37
- - Two simple queries can beat one complex query
38
- - Compound indexes matching `orderBy` column order
39
- - Correlated subqueries in `orderBy` for has-many sorting (avoid joins)
40
-
41
- ### 3. Security → `references/security.md`, `references/passport.md`, `references/spatie-laravel-permission.md`
42
-
43
- - Define `$fillable` or `$guarded` on every model, authorize every action via policies or gates
44
- - No raw SQL with user input — use Eloquent or query builder
45
- - `{{ }}` for output escaping, `@csrf` on all POST/PUT/DELETE forms, `throttle` on auth and API routes
46
- - Validate MIME type, extension, and size for file uploads
47
- - Never commit `.env`, use `config()` for secrets, `encrypted` cast for sensitive DB fields
48
-
49
- ### 4. Caching → `references/caching.md`
50
-
51
- - `Cache::remember()` over manual get/put
52
- - `Cache::flexible()` for stale-while-revalidate on high-traffic data
53
- - `Cache::memo()` to avoid redundant cache hits within a request
54
- - Cache tags to invalidate related groups
55
- - `Cache::add()` for atomic conditional writes
56
- - `once()` to memoize per-request or per-object lifetime
57
- - `Cache::lock()` / `lockForUpdate()` for race conditions
58
- - Failover cache stores in production
59
-
60
- ### 5. Eloquent Patterns → `references/eloquent.md`
61
-
62
- - Correct relationship types with return type hints
63
- - Local scopes for reusable query constraints
64
- - Global scopes sparingly — document their existence
65
- - Attribute casts in the `casts()` method
66
- - Cast date columns, use Carbon instances in templates
67
- - `whereBelongsTo($model)` for cleaner queries
68
- - Never hardcode table names — use `(new Model)->getTable()` or Eloquent queries
69
-
70
- ### 6. Validation & Forms → `references/validation.md`
71
-
72
- - Form Request classes, not inline validation
73
- - Array notation `['required', 'email']` for new code; follow existing convention
74
- - `$request->validated()` only — never `$request->all()`
75
- - `Rule::when()` for conditional validation
76
- - `after()` instead of `withValidator()`
77
-
78
- ### 7. Configuration → `references/config.md`
79
-
80
- - `env()` only inside config files
81
- - `App::environment()` or `app()->isProduction()`
82
- - Config, lang files, and constants over hardcoded text
83
-
84
- ### 8. Testing Patterns → `references/testing.md`, `references/pest-testing.md`
85
-
86
- - `LazilyRefreshDatabase` over `RefreshDatabase` for speed
87
- - `assertModelExists()` over raw `assertDatabaseHas()`
88
- - Factory states and sequences over manual overrides
89
- - Use fakes (`Event::fake()`, `Exceptions::fake()`, etc.) — but always after factory setup, not before
90
- - `recycle()` to share relationship instances across factories
91
-
92
- ### 9. Queue & Job Patterns → `references/queue-jobs.md`
93
-
94
- - `retry_after` must exceed job `timeout`; use exponential backoff `[1, 5, 10]`
95
- - `ShouldBeUnique` to prevent duplicates; `ShouldBeUniqueUntilProcessing` for early lock release
96
- - Always implement `failed()`; with `retryUntil()`, set `$tries = 0`
97
- - `RateLimited` middleware for external API calls; `Bus::batch()` for related jobs
98
- - Horizon for complex multi-queue scenarios
99
-
100
- ### 10. Routing & Controllers → `references/routing.md`
101
-
102
- - Implicit route model binding
103
- - Scoped bindings for nested resources
104
- - `Route::resource()` or `apiResource()`
105
- - Methods under 10 lines — extract to actions/services
106
- - Type-hint Form Requests for auto-validation
107
-
108
- ### 11. HTTP Client → `references/http-client.md`
109
-
110
- - Explicit `timeout` and `connectTimeout` on every request
111
- - `retry()` with exponential backoff for external APIs
112
- - Check response status or use `throw()`
113
- - `Http::pool()` for concurrent independent requests
114
- - `Http::fake()` and `preventStrayRequests()` in tests
115
-
116
- ### 12. Events, Notifications & Mail → `references/events-notifications.md`, `references/mail.md`
117
-
118
- - Event discovery over manual registration; `event:cache` in production
119
- - `ShouldDispatchAfterCommit` / `afterCommit()` inside transactions
120
- - Queue notifications and mailables with `ShouldQueue`
121
- - On-demand notifications for non-user recipients
122
- - `HasLocalePreference` on notifiable models
123
- - `assertQueued()` not `assertSent()` for queued mailables
124
- - Markdown mailables for transactional emails
125
-
126
- ### 13. Error Handling → `references/error-handling.md`
127
-
128
- - `report()`/`render()` on exception classes or in `bootstrap/app.php` — follow existing pattern
129
- - `ShouldntReport` for exceptions that should never log
130
- - Throttle high-volume exceptions to protect log sinks
131
- - `dontReportDuplicates()` for multi-catch scenarios
132
- - Force JSON rendering for API routes
133
- - Structured context via `context()` on exception classes
134
-
135
- ### 14. Task Scheduling → `references/scheduling.md`
136
-
137
- - `withoutOverlapping()` on variable-duration tasks
138
- - `onOneServer()` on multi-server deployments
139
- - `runInBackground()` for concurrent long tasks
140
- - `environments()` to restrict to appropriate environments
141
- - `takeUntilTimeout()` for time-bounded processing
142
- - Schedule groups for shared configuration
143
-
144
- ### 15. Architecture → `references/architecture.md`
145
-
146
- - Single-purpose Action classes; dependency injection over `app()` helper
147
- - Prefer official Laravel packages and follow conventions, don't override defaults
148
- - Default to `ORDER BY id DESC` or `created_at DESC`; `mb_*` for UTF-8 safety
149
- - `defer()` for post-response work; `Context` for request-scoped data; `Concurrency::run()` for parallel execution
150
-
151
- ### 16. Migrations → `references/migrations.md`
152
-
153
- - Generate migrations with `php artisan make:migration`
154
- - `constrained()` for foreign keys
155
- - Never modify migrations that have run in production
156
- - Add indexes in the migration, not as an afterthought
157
- - Mirror column defaults in model `$attributes`
158
- - Reversible `down()` by default; forward-fix migrations for intentionally irreversible changes
159
- - One concern per migration — never mix DDL and DML
160
-
161
- ### 17. Collections → `references/collections.md`
162
-
163
- - Higher-order messages for simple collection operations
164
- - `cursor()` vs. `lazy()` — choose based on relationship needs
165
- - `lazyById()` when updating records while iterating
166
- - `toQuery()` for bulk operations on collections
167
-
168
- ### 18. Blade & Views → `references/blade-views.md`, `references/tailwindcss.md`
169
-
170
- - `$attributes->merge()` in component templates
171
- - Blade components over `@include`; `@pushOnce` for per-component scripts
172
- - View Composers for shared view data
173
- - `@aware` for deeply nested component props
174
-
175
- ### 19. Conventions & Style → `references/style.md`
176
-
177
- - Follow Laravel naming conventions for all entities
178
- - Prefer Laravel helpers (`Str`, `Arr`, `Number`, `Uri`, `Str::of()`, `$request->string()`) over raw PHP functions
179
- - No JS/CSS in Blade, no HTML in PHP classes
180
- - Code should be readable; comments only for config files
181
-
182
- ### 20. Feature Flags → `references/pennant.md`
183
-
184
- - `Feature::define()` to define features with resolver callbacks
185
- - `Feature::active()` / `@feature` Blade directive to check features
186
- - Scope features to specific users/entities with `Feature::for()`
187
- - `Feature::activate()` / `deactivate()` for runtime control
188
-
189
- ### 21. Monitoring → `references/pulse.md`
190
-
191
- - Gate-protect the dashboard with `viewPulse` gate
192
- - Configure built-in recorders in `config/pulse.php` (SlowQueries, SlowRequests, Exceptions, Queues, etc.)
193
- - Redis ingest for production performance; run `pulse:work` to drain the stream
194
- - Custom cards via Livewire components extending `Pulse\Card`
195
- - `Pulse::filter()` to exclude entries; `Pulse::resolveAuthenticatedUserId()` for multi-model apps
196
- - `pulse:check` daemon required for Servers card
197
-
198
- ### 22. Full-Text Search → `references/scout.md`
199
-
200
- - Add `Searchable` trait to models for automatic index sync
201
- - Choose engine: Database, Collection, Algolia, Meilisearch, Typesense
202
- - `toSearchableArray()` to control indexed data; `searchableAs()` for custom index names
203
- - `Model::search('query')->where(...)->paginate()` for search queries
204
- - `scout:import` / `scout:flush` for index management; `scout:sync-index-settings` for engine config
205
- - `Model::withoutSyncingToSearch()` / `SCOUT_DRIVER=null` for testing
206
-
207
- ### 23. Backup → `references/spatie-laravel-backup.md`
208
-
209
- - Schedule `backup:run`, `backup:clean`, `backup:monitor` in console kernel
210
- - Configure sources, destinations, notifications in `config/backup.php`
211
- - Custom cleanup strategies extending `CleanupStrategy`
212
- - Custom health checks extending `HealthCheck`
213
- - Enable encryption and Gzip compression via config
214
-
215
- ### 24. Media Library → `references/spatie-medialibrary.md`
216
-
217
- - Implement `HasMedia` interface + `InteractsWithMedia` trait on models
218
- - `addMedia()` / `addMediaFromRequest()` for file uploads
219
- - Media collections to organize related files per model
220
- - Conversions for image processing (thumbnails, crops, etc.)
221
- - Responsive images via conversion `withResponsiveImages()`
17
+ Check sibling files, related controllers, models, or tests for established patterns. If one exists, follow it. Don't introduce a second way. These references are defaults for when no pattern exists yet, not overrides.
222
18
 
223
19
  ## How to Apply
224
20
 
225
- Always use a sub-agent to read rule files and explore this skill's content.
226
-
227
- 1. Identify the file type and select relevant sections (e.g., migration §16, controller §1, §3, §5, §6, §10)
228
- 2. Check sibling files for existing patterns follow those first per Consistency First
229
- 3. Verify API syntax with `search-docs` for the installed Laravel version
21
+ 1. Check the changed files, nearby code, project configuration, and relevant tests for established patterns. Deviate only for a correctness or security defect, and call the deviation out.
22
+ 2. Map every affected concern to the reference index below. Read each mapped reference file before editing. Skip unrelated reference files.
23
+ 3. Make the smallest coherent change. Keep the application's architecture and naming instead of introducing a second pattern for the same job.
24
+ 4. Verify version-sensitive Laravel APIs for the installed version with `search-docs`, or inspect the installed framework when it is unavailable.
25
+ 5. Run the narrowest relevant tests first, then the project's formatting and static-analysis checks when the change warrants them.
26
+ 6. Re-read the diff against every mapped reference before finishing.
27
+
28
+ ## References Index
29
+
30
+ Cross-cutting changes often need more than one reference file.
31
+
32
+ | Concern | Read |
33
+ | --- | --- |
34
+ | Query count, eager loading, indexes, large datasets | [`references/db-performance.md`](references/db-performance.md) |
35
+ | Production monitoring, slow queries, exception dashboards | [`references/pulse.md`](references/pulse.md) |
36
+ | Subqueries, aggregates, complex ordering and query plans | [`references/advanced-queries.md`](references/advanced-queries.md) |
37
+ | Models, relationships, scopes, casts | [`references/eloquent.md`](references/eloquent.md) |
38
+ | Full-text search, indexing, searchable models | [`references/scout.md`](references/scout.md) |
39
+ | Authentication, authorization, input safety, secrets, uploads | [`references/security.md`](references/security.md) |
40
+ | OAuth2 servers, clients, token authentication | [`references/passport.md`](references/passport.md) |
41
+ | Roles and permissions with spatie/laravel-permission | [`references/spatie-laravel-permission.md`](references/spatie-laravel-permission.md) |
42
+ | Model media uploads, conversions, responsive images | [`references/spatie-medialibrary.md`](references/spatie-medialibrary.md) |
43
+ | Form Requests and validation references | [`references/validation.md`](references/validation.md) |
44
+ | Controllers, route binding, resources, middleware | [`references/routing.md`](references/routing.md) |
45
+ | Schema changes, columns, foreign keys, indexes | [`references/migrations.md`](references/migrations.md) |
46
+ | Jobs, retries, uniqueness, batches, Horizon | [`references/queue-jobs.md`](references/queue-jobs.md) |
47
+ | Cache lifetime, invalidation, locks, memoization | [`references/caching.md`](references/caching.md) |
48
+ | Outbound requests, retries, timeouts, fakes | [`references/http-client.md`](references/http-client.md) |
49
+ | Exceptions, reporting, rendering, log context | [`references/error-handling.md`](references/error-handling.md) |
50
+ | Events and notifications | [`references/events-notifications.md`](references/events-notifications.md) |
51
+ | Mailables and mail assertions | [`references/mail.md`](references/mail.md) |
52
+ | Scheduled tasks and overlap protection | [`references/scheduling.md`](references/scheduling.md) |
53
+ | Database backups, cleanup, monitoring, notifications | [`references/spatie-laravel-backup.md`](references/spatie-laravel-backup.md) |
54
+ | Collections, lazy iteration, bulk operations | [`references/collections.md`](references/collections.md) |
55
+ | Blade components, attributes, composers | [`references/blade-views.md`](references/blade-views.md) |
56
+ | Tailwind CSS classes, v4 configuration, extraction | [`references/tailwindcss.md`](references/tailwindcss.md) |
57
+ | Environment values and application configuration | [`references/config.md`](references/config.md) |
58
+ | Feature flags and per-user feature checks | [`references/pennant.md`](references/pennant.md) |
59
+ | Pest/PHPUnit patterns, factories, fakes | [`references/testing.md`](references/testing.md) |
60
+ | Pest 4 syntax, datasets, browser and architecture tests | [`references/pest-testing.md`](references/pest-testing.md) |
61
+ | Naming, helpers, file boundaries, PHP style | [`references/style.md`](references/style.md) |
62
+ | Actions, services, dependencies, application structure | [`references/architecture.md`](references/architecture.md) |
63
+ | Detecting and recording this app's conventions as rules | [`references/infer-conventions.md`](references/infer-conventions.md) |
64
+
65
+ ## Decision rule
66
+
67
+ - Prefer framework features and existing application abstractions over new helpers or dependencies.
68
+ - Avoid speculative abstractions. Extract code when it creates a clear domain boundary, removes meaningful duplication, or makes behavior independently testable.
69
+ - Keep database access out of Blade views and prevent hidden N+1 queries across controllers, resources, jobs, and serialization.
@@ -9,7 +9,7 @@ class CreateOrderAction
9
9
  {
10
10
  public function __construct(private InventoryService $inventory) {}
11
11
 
12
- public function execute(array $data): Order
12
+ public function handle(array $data): Order
13
13
  {
14
14
  $order = Order::create($data);
15
15
  $this->inventory->reserve($order);
@@ -0,0 +1,139 @@
1
+ # Detection Checklist
2
+
3
+ Every dimension here is a genuine fork: Laravel offers two or more valid approaches, the app's choice changes what the next agent writes, and no active project tool can pick for you. Left out on purpose: pure formatting (Pint owns it), any form an installed and enabled Rector rule rewrites to one canonical shape (`$casts` to `casts()`, `$fillable` to attributes, pipe-string rules to arrays, named to anonymous migrations, `$signature` to `#[Signature]`), and framework defaults any agent writes unprompted (`ShouldQueue` jobs, relation return types, `HasFactory`).
4
+
5
+ Each item gives the fork, then a hint (a grep or dir to spot which side the app takes). Hints are only a start. Read the matched files, never record on a raw count. Apply the ground rules to every verdict: a consistent choice that is a default or a tool's target form is not a pattern. Rows tagged (architecture) are the highest-signal, so record presence and deliberate absence.
6
+
7
+ ---
8
+
9
+ ## A. Validation & HTTP input
10
+
11
+ 1. Validation entry point: inline `$request->validate()` vs Form Request classes vs `Validator::make()`.
12
+ - Hint: `ls app/Http/Requests`; grep `->validate(` / `Validator::make(` in `app/Http/Controllers`.
13
+ 2. Custom rule location: invokable rule objects in `app/Rules` vs inline closures vs `Validator::extend()` in a provider. Rule objects are the default `make:rule` path, so record only if the app leans on closures or `Validator::extend` instead. "No rule objects" alone is just no-signal.
14
+ - Hint: `ls app/Rules`; grep `Validator::extend` in `app/Providers`.
15
+ 3. Typed input retrieval: typed getters (`$request->string()`, `->integer()`, `->enum()`, `->date()`) vs raw `$request->input()` / dynamic properties.
16
+ - Hint: grep `->string(` / `->integer(` / `->enum(` vs `->input(` in `app/Http`.
17
+ 4. Custom messages/attributes: `lang/*/validation.php` vs Form Request `messages()` / `attributes()` methods.
18
+ - Hint: `ls lang`; grep `function messages`, `function attributes` in `app/Http/Requests`.
19
+
20
+ ## B. Controllers & routing
21
+
22
+ 1. Controller shape: invokable single-action (`__invoke`) vs resource controllers vs plain multi-method.
23
+ - Hint: grep `__invoke` in controllers; `Route::resource` / `apiResource` vs verb routes.
24
+ 2. Business-logic location (architecture): fat controllers vs delegated to Actions / Services / Jobs.
25
+ - Hint: read a few controller methods; `ls app/Actions app/Services`.
26
+ 3. Route handler style: closures in `routes/*.php` vs controller classes.
27
+ - Hint: count `function ()` vs `::class` in `routes/web.php`, `routes/api.php`.
28
+ 4. Middleware assignment: route/group `->middleware()` vs controller `HasMiddleware::middleware()` vs `#[Middleware]` attribute.
29
+ - Hint: grep `implements HasMiddleware`, `#[Middleware(` in controllers vs `->middleware(` in routes.
30
+ 5. Route model binding: implicit (type-hinted models) vs explicit `Route::bind` vs manual `findOrFail`.
31
+ - Hint: typed model params in signatures vs `findOrFail(` in controllers; grep `Route::bind`.
32
+ 6. Rate limiting: named `RateLimiter::for()` + `throttle:name` vs inline `throttle:60,1`.
33
+ - Hint: grep `RateLimiter::for` in providers vs `throttle:` in route files.
34
+
35
+ ## C. Authorization
36
+
37
+ 1. Authorization home: Gates (`Gate::define`) vs Policy classes in `app/Policies`.
38
+ - Hint: `ls app/Policies`; grep `Gate::define` in `app/Providers`.
39
+ 2. Authorization call site: `$this->authorize()` / `Gate::authorize()` vs `$user->can()` vs `can` middleware vs `#[Authorize]` vs `@can` in Blade.
40
+ - Hint: grep `authorize(`, `->can(`, `middleware('can:`, `#[Authorize(`, `@can(`.
41
+
42
+ ## D. Eloquent & models
43
+
44
+ 1. Mass assignment: `$fillable` allow-list vs `$guarded` block-list.
45
+ - Hint: grep `protected $fillable` / `protected $guarded` in `app/Models`.
46
+ 2. Accessors/mutators: modern `Attribute` class vs legacy `getXxxAttribute()` / `setXxxAttribute()`. Record a legacy hold, it goes against the tool's grain.
47
+ - Hint: grep `: Attribute` / `Attribute::make` vs `function get[A-Z].*Attribute` in `app/Models`.
48
+ 3. Primary keys: auto-increment vs `HasUuids` vs `HasUlids`.
49
+ - Hint: grep `HasUuids` / `HasUlids` in `app/Models`; migration `id()` vs `uuid('id')`.
50
+ 4. Custom casts: dedicated `CastsAttributes` classes (`app/Casts`) vs inline `Attribute` vs built-in cast strings.
51
+ - Hint: `ls app/Casts`; grep `Cast::class`, `AsStringable::class` in models.
52
+ 5. Data/query layer (architecture): Eloquent directly in controllers vs repositories vs dedicated query objects (e.g. classes exposing `builder(): Builder`).
53
+ - Hint: `ls app/Repositories app/Queries`; see where non-trivial queries are built.
54
+ 6. Query scopes: local `scope`/`#[Scope]` methods vs dedicated builder classes.
55
+ - Hint: grep `function scope` / `#[Scope]` in models; `ls app/*/Builders`.
56
+ 7. Model events: observers (`app/Observers`, `#[ObservedBy]`) vs `booted()` closures vs event classes.
57
+ - Hint: `ls app/Observers`; grep `booted`, `::observe`, `#[ObservedBy]`.
58
+ 8. Eager-load posture: explicit per-query `->with()` vs model-level `$with` defaults. Treat `preventLazyLoading()` separately as a development guard because it can complement either posture.
59
+ - Hint: grep `protected $with`, `->with(`, and separately `preventLazyLoading` in `app/`.
60
+
61
+ ## E. Architecture & organization
62
+
63
+ 1. Action/Service structure (architecture): Action classes (invoked via `handle` / `execute` / `__invoke`) vs service objects vs neither. Cross-check the Step 0 `app/` map: any `Actions`/`Services`/`Pipelines`/`Jobs`-as-actions folder is this pattern, so record how it is invoked.
64
+ - Hint: `ls app/` (the whole tree, not just `Actions`/`Services`); grep the invocation method in the folder you find.
65
+ 2. DTOs (architecture): spatie/laravel-data vs plain readonly classes vs arrays everywhere.
66
+ - Hint: `ls app/Data`; grep `extends Data`, `readonly class` in `app/`.
67
+ 3. Dependency acquisition: constructor/method injection vs `app()` / `resolve()` / `App::make()` service location.
68
+ - Hint: grep `app(` / `resolve(` / `::make(` in `app/` vs promoted constructor deps.
69
+ 4. Decoupling: events + listeners vs direct service calls.
70
+ - Hint: `ls app/Events app/Listeners`; grep `event(`, `::dispatch(`.
71
+ 5. Helper vs facade idiom: global helpers (`config()`, `auth()`, `response()`) vs facades (`Config::`, `Auth::`, `Response::`).
72
+ - Hint: ratio of `config(` vs `Config::` (etc.) across `app/`.
73
+ 6. Namespace layout (architecture): default `app/` skeleton vs domain/module folders (`app/Domain/**`, modules).
74
+ - Hint: `ls app/`, look for `Domain/`, `Modules/`, bounded-context folders.
75
+ 7. Enums: backed vs pure; case naming; where they live.
76
+ - Hint: `ls app/Enums`; grep `enum .*: string`, `enum .*: int`.
77
+
78
+ ## F. Frontend & views
79
+
80
+ This app ships a frontend stack, so the items below apply.
81
+
82
+ 1. Frontend stack: Blade+Livewire vs Inertia (Vue/React/Svelte) vs Blade-only / API + separate SPA.
83
+ - Hint: `composer.json` + `package.json`; `ls resources/js/pages`, `resources/views`.
84
+ 2. Blade composition: class `<x-*>` components vs anonymous components (`@props`) vs `@include` partials.
85
+ - Hint: `ls app/View/Components`; grep `<x-`, `@include` in `resources/views`.
86
+ 3. Livewire component format: Volt functional/class components, native Livewire 4 single-file (SFC), multi-file (MFC), view-based, or class-based components. Evaluate full-page vs nested separately because it is an independent usage choice.
87
+ - Hint: check the installed Livewire major and `livewire/volt`; inspect `app/Livewire`, `resources/views/livewire`, and Livewire 4 component/page directories for `@volt`, SFC, MFC, view-based, and class-based formats.
88
+ 4. Localization: short keys (`lang/*/*.php` + `__('messages.welcome')`) vs JSON string keys (`lang/*.json` + `__('Full sentence')`).
89
+ - Hint: `ls lang`; grep dotted `__('` vs sentence keys.
90
+
91
+ ## G. Database & migrations
92
+
93
+ 1. Foreign keys: `foreignId()->constrained()` vs `foreignIdFor(Model::class)` vs manual `foreign()->references()->on()`.
94
+ - Hint: grep `foreignId(`, `foreignIdFor(`, `->foreign(` in `database/migrations`.
95
+ 2. `down()` methods: real reverse logic vs omitted / one-way migrations.
96
+ - Hint: grep `function down` vs the migration count.
97
+ 3. Enum storage: DB `enum()` column vs `string()` + PHP-enum cast on the model.
98
+ - Hint: grep `->enum(` in migrations vs string columns cast to enums.
99
+ 4. Transactions: `DB::transaction(fn ...)` closure vs manual `beginTransaction` / `commit` / `rollBack`.
100
+ - Hint: grep `DB::transaction`, `beginTransaction` in `app/`.
101
+ 5. Idempotent writes: `upsert` / `updateOrCreate` / `firstOrCreate` vs find-then-save.
102
+ - Hint: grep `upsert(`, `updateOrCreate(`, `firstOrCreate(` in `app/`.
103
+
104
+ ## H. Testing
105
+
106
+ 1. Framework: Pest (`it()` / `test()` / `expect()`) vs PHPUnit classes.
107
+ - Hint: `ls tests/Pest.php`; grep `it(` / `test(` vs `extends TestCase`.
108
+ 2. DB reset: `RefreshDatabase` vs `DatabaseTruncation` vs `DatabaseMigrations`.
109
+ - Hint: grep those trait names in `tests/`.
110
+ 3. Fixtures: compare how equivalent test-owned records are created, such as factories vs manual inserts. Track seeders separately for shared reference data because `$this->seed()` commonly and legitimately coexists with factories.
111
+ - Hint: grep `::factory(` and direct inserts in `tests/`; separately inspect `$this->seed(` calls and what those seeders provide.
112
+ 4. Collaborator isolation: how the app doubles its own classes, Mockery `mock()` / `spy()` vs real integration. Ignore facade fakes like `Mail::fake()` here, they isolate framework services by default and are not a fork against Mockery.
113
+ - Hint: grep `->mock(`, `->spy(`, `Mockery::` in `tests/`.
114
+ 5. Endpoint assertions: array `assertJson([...])` / `assertJsonFragment` vs fluent `AssertableJson`.
115
+ - Hint: grep `AssertableJson`, `assertJsonFragment` in `tests/`.
116
+
117
+ ## I. Responses & API resources
118
+
119
+ 1. Response shape: API Resource classes vs `response()->json()` vs returning models/arrays directly.
120
+ - Hint: `ls app/Http/Resources`; grep `JsonResource`, `->json(` in controllers.
121
+ 2. Resource relationship inclusion: `whenLoaded()` guards vs unconditional relationship access. Do not count ordinary scalar attributes as rivals to conditional relationships, and evaluate general `when()` fields separately.
122
+ - Hint: compare relationship fields using `whenLoaded(` with unconditional relationship property access in `app/Http/Resources`.
123
+ 3. Pagination contracts: within comparable endpoint categories, length-aware `paginate()` vs `simplePaginate()` vs `cursorPaginate()`. These have different totals, navigation, ordering, and performance contracts, so record only a stable path-scoped API policy, never a project-wide majority.
124
+ - Hint: grep those in `app/`, then group matches by endpoint type and client contract before comparing them.
125
+ 4. Web redirects/URLs: `route('name')` vs `url('/path')` vs `action([...])`.
126
+ - Hint: grep `route('`, `url('/`, `action([` in `app/Http` and views.
127
+
128
+ ## J. Strings, collections & dates
129
+
130
+ 1. Iteration idiom: `collect()->map()->filter()` pipelines vs `array_map` / `foreach`.
131
+ - Hint: grep `collect(`, `->map(` vs `array_map`, `foreach` density in `app/`.
132
+ 2. String API: fluent `Str::of()->...` (Stringable) vs static `Str::` vs native (`trim`, `strtoupper`).
133
+ - Hint: grep `Str::of(` vs `Str::` vs native string funcs.
134
+ 3. Dates: compare equivalent construction call styles (`now()` / `today()` helpers vs `Carbon::`) separately from the application's mutable/immutable date policy. `Date::use(CarbonImmutable::class)` can make helpers return immutable dates, so those signals are complementary rather than conflicting.
135
+ - Hint: grep `now(` and `Carbon::` for call style; separately inspect `CarbonImmutable` and `Date::use` for mutability policy.
136
+
137
+ ---
138
+
139
+ Genuine forks only. Every row survived the "no tool can decide this, and it isn't the default" filter. Give each applicable dimension exactly one verdict: pattern, conflict, default, no-signal, tooling-owned, or already-recorded. The rows tagged (architecture) are where the highest-value rules come from.
@@ -30,7 +30,8 @@ $articles = Article::whereHas('user', function ($q) {
30
30
 
31
31
  Correct:
32
32
  ```php
33
- public function scopeActive(Builder $query): Builder
33
+ #[Scope]
34
+ protected function active(Builder $query): Builder
34
35
  {
35
36
  return $query->where('verified', true)->whereNotNull('activated_at');
36
37
  }
@@ -58,7 +59,8 @@ class PublishedScope implements Scope
58
59
 
59
60
  Correct (local scope you opt into):
60
61
  ```php
61
- public function scopePublished(Builder $query): Builder
62
+ #[Scope]
63
+ protected function published(Builder $query): Builder
62
64
  {
63
65
  return $query->where('published', true);
64
66
  }
@@ -0,0 +1,97 @@
1
+
2
+ # Infer Conventions
3
+
4
+ Learn how this application writes Laravel, then record what you learn as durable, path-scoped rules other agents will read. You are documenting reality, not improving it.
5
+
6
+ ## Ground Rules (read before you start)
7
+
8
+ - Consistency first. The codebase's majority style is the convention. Never judge it, never propose a "better" pattern, never record what the code should do. If the app validates inline everywhere, that is the rule, even if Form Requests would be nicer.
9
+ - Skip what an active tool produces, keep what a tool would fight. Inspect the project's Pint and Rector configuration first; a Rector transformation is tooling-owned only when its package and relevant rule or set are installed and enabled. Active tools may rewrite code toward one canonical form: `$casts` to `casts()`, `$fillable` to attributes, magic accessors to the `Attribute` class, pipe-string rules to arrays, `$signature` to `#[Signature]`, named migrations to anonymous, and many more. When the app already sits at an active tool's target form, the tool owns it, so record nothing. But when the app deliberately holds a form an active tool would refactor away, such as legacy `getXxxAttribute()` accessors the `Attribute` class would replace, no tool can reproduce that choice and an agent defaults the other way. That against-the-grain hold is exactly what to record.
10
+ - Record decisions, not defaults. A consistent pattern earns a rule only when it reflects a choice: the app took one valid option where the framework or common practice offered others, or the pattern would surprise a competent agent. Framework defaults steer nothing, so skip them: anonymous migrations, `$signature` commands, `ShouldQueue` jobs, `casts()` on Laravel 11+, named routes, Rule objects in `app/Rules`, and `Mail::fake()` or `Bus::fake()` to isolate framework services. A real fork is not enough on its own. Weigh the side the app took, and record only the side an agent would not reach for by itself: inline closures everywhere, legacy accessors, a bespoke query layer. Watch for the false fork too. "No Mockery" next to facade fakes is not a choice against Mockery, because they double different things. The test for every candidate: without this rule, would the next agent plausibly write it differently? Only "yes" earns a rule.
11
+ - Architecture choices are the gold. Record presence and deliberate absence. The structural pattern the app commits to is the highest-signal convention and the one no tool can decide: Action classes and how they are invoked (`handle` / `execute` / `__invoke`), service objects, dedicated query objects exposing `builder()`, DTOs (spatie/laravel-data vs readonly classes), Form Request validation vs inline, an events and listeners spine vs direct calls, and domain or module folders. Also record a consistent non-pattern, such as "query Eloquent directly in controllers, no repository layer", so the next agent matches the app's altitude instead of over-engineering.
12
+ - Never duplicate `.ai/rules`. Read `.ai/rules/index.md` and the area files before the sweep. A dimension already covered there is marked done and skipped.
13
+ - Evidence or silence. A convention needs at least 3 consistent examples and no meaningful rival to become a candidate. Every Step 1 verdict applies this bar.
14
+ - The recorded rule states the convention, nothing else. One or two imperative lines: this project does X, so do X here. Keep detection evidence out. No counts, ratios, current usage, file lists, or example paths, because that is proof for the confirm step, not part of the rule. One short syntax fragment at most, and point to `search-docs` for API details.
15
+
16
+ ## Process
17
+
18
+ Each step ends on a checkable completion criterion. Do not advance until it holds.
19
+
20
+ Fan out when you can. The sweep is embarrassingly parallel. If your environment can spawn subagents (a Task, dispatch, or equivalent tool), do Step 0 yourself, then hand each checklist group (A to J) and the architecture map to its own subagent. Each subagent runs the greps, reads a few representative files, and returns structured verdicts (dimension, verdict, evidence, proposed glob / title / note). You aggregate, dedupe, then run Steps 3 to 5. It is far faster on a real app. No subagents available? Run the steps in sequence, with the same bar and the same output.
21
+
22
+ ### Step 0: Orient
23
+
24
+ Read `composer.json` (installed packages tell you which checklist groups apply), the `pint.json` / PHPStan / Rector config, `.ai/rules/index.md` if present, and most important, map the `app/` tree. List every directory under `app/` (and any `Modules/`, `src/`, `packages/`, or domain root). Every folder beyond Laravel's default skeleton (`Http`, `Models`, `Providers`, `Console`, `Exceptions`) is a structural pattern the app committed to and a high-value rule waiting to be written: `Actions`, `Services`, `Data` or DTOs, `Queries`, `Repositories`, `ViewModels`, `Pipelines`, `Support`, `Enums`, `Contracts`, `Observers`, or `Domain` and module roots. Note each one. You will confirm how it is used in Step 2.
25
+
26
+ This app ships a frontend stack, so the frontend checklist group applies. Sweep it.
27
+
28
+ Done when: you have the applicable checklist groups, the dimensions already recorded in `.ai/rules`, and a list of every non-default `app/` directory mapped to the pattern it represents.
29
+
30
+ ### Step 1: Predefined sweep
31
+
32
+ Open `references/checklist.md` and work every applicable dimension using its search hints. Give each exactly one verdict:
33
+
34
+ - Pattern. Clears the bar, rival under ~20% of sites, and reflects a real choice (passes the decisions-not-defaults test). A recording candidate. Cite 2 to 3 example files.
35
+ - Conflict. Both styles present in meaningful numbers. Report the split with counts and example files. Never record a preferred winner while the code remains mixed, even in yolo, because that would describe an aspiration rather than reality. Record only if the user identifies a stable path or context boundary that explains both styles; otherwise defer until the code is reconciled.
36
+ - Default. Consistent, but a framework or common-practice default the agent already writes unprompted. Skip it as a no-op, not a convention.
37
+ - No signal. Under the bar: feature unused, or too few examples. Skip silently (one summary line at most).
38
+ - Tooling-owned or Already-recorded. Skip per the ground rules.
39
+
40
+ Done when: every applicable dimension carries exactly one of those verdicts.
41
+
42
+ ### Step 2: Open-ended pass
43
+
44
+ First, close out the architecture map from Step 0. For every non-default `app/` directory you listed, confirm how the pattern is used and apply the same evidence and decisions-not-defaults tests as Step 1. Generator-standard or sparsely used directories such as `Rules`, `Observers`, `Mail`, and `Notifications` are signals to inspect, not automatic conventions. Make genuine structural patterns candidates: Action classes invoked via `handle` / `execute` / `__invoke`, Services constructor-injected, `Queries` objects exposing `builder(): Builder`, DTOs as readonly classes or spatie/laravel-data, module or domain folders as the unit of organization. Scope each qualifying pattern to its own directory glob. Also record a consistent deliberate absence, such as "no repository layer, controllers query Eloquent directly", so the next agent matches the app's altitude.
45
+
46
+ Then find what else makes this codebase itself: base or abstract classes most code extends, traits used everywhere, tenancy or authorization scoping woven through queries, naming schemes, and custom helpers. Same evidence bar, cite files. Record every genuine structural pattern, and cap the other house findings at ~5 so the pass stays high-signal.
47
+
48
+ Done when: every non-default `app/` directory from Step 0 has a verdict, and the pass has produced its cited house findings (or concluded there are none).
49
+
50
+ ### Step 3: Confirm
51
+
52
+ Present every candidate in one batch. Per item: dimension, verdict, evidence (counts and files), and the exact proposed `glob` or `globs` / `title` / `note`. Conflicts are presented as questions about an existing context boundary or deferred cleanup, not as a choice of future style.
53
+
54
+ Default mode is confirm: record only what the user approves. Switch to yolo only when the invocation said so ("yolo", "don't ask", "just record them"), then record all pattern candidates without asking. Conflicts still go to the user in yolo.
55
+
56
+ Done when: every candidate is approved, rejected, or (conflicts) decided.
57
+
58
+ ### Step 4: Record
59
+
60
+ Make one `record-rule` call for each glob an approved convention applies to. Choose the most specific globs that cover the cited evidence from the mapping table below; if a convention spans models and migrations, record it under both domains so agents discover it from either path. The `note` is the bare convention: strip every trace of detection (see the ground rule). If `record-rule` is unavailable (rules disabled), report the full rule text so the user can enable `BOOST_RULES_ENABLED` or add it by hand.
61
+
62
+ Record this:
63
+
64
+ > Accessors and mutators: use the legacy magic-method style (`getXxxAttribute()` / `setXxxAttribute()`), not the `Attribute` class. Match it in models.
65
+
66
+ Not this:
67
+
68
+ > Accessors/mutators use the legacy magic-method style; the `Attribute`-class style is not used anywhere (13 legacy, 0 Attribute-class), e.g. `app/Models/Post.php`. Match the legacy style in existing models.
69
+
70
+ Done when: every approved item has a successful tool response, and any failure is reported with its rule text.
71
+
72
+ ### Step 5: Summarize
73
+
74
+ List recorded rules (file and title), conflicts the user deferred, notable no-signals, and remind the user to commit `.ai/rules` so their team and agents share the conventions.
75
+
76
+ ## Glob mapping
77
+
78
+ Attach each rule to the most specific path that covers its evidence. Never a lazy `app/**` when a subtree fits. Match the glob to where the code actually lives, which is not the same in a default skeleton and in a modular or DDD layout. Use the Step 0 `app/` map to pick the real path.
79
+
80
+ Examples:
81
+
82
+ - Models: `app/Models/**` in a default app, or `app/Modules/Blog/Models/**` / `src/Domain/Blog/**` in a modular one.
83
+ - Controllers, routing, validation, responses: `app/Http/**`, or `app/Modules/*/Http/**` when each module owns its HTTP layer.
84
+ - Actions, Services, DTOs: `app/Actions/**`, `app/Services/**`, `app/Data/**`, or the module path the app actually uses.
85
+ - Tests: `tests/**`.
86
+ - Migrations and database: `database/migrations/**`.
87
+ - Truly app-wide (rare, e.g. auth retrieval): `app/**`.
88
+
89
+ `record-rule` takes one glob. When a convention genuinely spans two domains (e.g. UUID keys touch models and migrations), call it once per domain with the same title and note; mentioning another path in the note does not make the rule discoverable there.
90
+
91
+ ## Edge cases
92
+
93
+ - Rules disabled or `record-rule` missing: detection is read-only, so Steps 0 to 3 still run, and recording falls back to the manual path in Step 4.
94
+ - Tiny or fresh app: most dimensions land on no-signal. Say so honestly ("not enough code to infer conventions yet") and record nothing.
95
+ - Huge app: each dimension is a bounded grep plus a handful of file reads. Sample representative files, do not read everything.
96
+ - Re-runs: reading `.ai/rules` in Step 0 makes re-runs incremental, so only new or undecided dimensions surface.
97
+ - Non-standard layout (modules, DDD): the open-ended pass catches the layout itself as convention #1. Adapt the globs in the mapping table to the observed paths.