{"article":{"slug":"extracting-ai-rules-from-an-existing-codebase","title":"Extracting AI rules from an existing codebase","subtitle":null,"summary":"How Laravel Boost learns project conventions from an established app: why hand-written detectors fell short, and how an agent skill gathers evidence so developers can approve scoped rules.","content_type":"blog_post","language":"en","canonical_url":"https://laravel.com/blog/extracting-ai-rules-from-an-existing-codebase","author":{"name":"Pushpak Chhajed","url":"https://laravel.com/blog/extracting-ai-rules-from-an-existing-codebase","person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Laravel","url":"https://laravel.com","listing_slug":null,"listing":null},"topics":[{"name":"AI Agents","slug":"ai-agents","url":"https://listedarticles.com/topics/ai-agents"},{"name":"Programming","slug":"programming","url":"https://listedarticles.com/topics/programming"},{"name":"Engineering","slug":"engineering","url":"https://listedarticles.com/topics/engineering"},{"name":"Open Source","slug":"open-source","url":"https://listedarticles.com/topics/open-source"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":1371,"reading_minutes":6,"published_at":"2026-08-31T12:00:00.000Z","added_at":"2026-09-21T09:21:42.456Z","updated_at":"2026-09-21T09:21:42.456Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/extracting-ai-rules-from-an-existing-codebase","markdown_url":"https://listedarticles.com/articles/extracting-ai-rules-from-an-existing-codebase.md","example":false,"citation":"Pushpak Chhajed, Laravel. \"Extracting AI rules from an existing codebase.\" 31 Aug 2026. https://laravel.com/blog/extracting-ai-rules-from-an-existing-codebase (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://laravel.com/blog/extracting-ai-rules-from-an-existing-codebase"},"body_markdown":"A new Laravel application can record project rules as the team makes decisions. An established application already has years of conventions encoded in its controllers, models, tests, directory structure, and deliberate absences.\n\nWhen a team installs Laravel Boost, either the codebase or the humans have to supply context on that history. Our goal at Laravel is to provide the best developer experience across everything we touch, and it felt less than ideal to offer teams no help documenting their existing conventions.\n\nIn that pursuit, we tried two methods: deterministic extractors and an extraction skill.\n\nMy first attempt was the hand-written detectors. The implementation was fast and deterministic, but it also recorded patterns with very different levels of value. The version we kept uses an agent skill to collect evidence and lets the developer approve each proposed rule.\n\n## Starting with a deterministic Artisan command\n\nThe first implementation was an Artisan command named `boost:infer-conventions`.\n\nIt had a source-root resolver, a file sampler, an inspector, and five detectors covering patterns such as enum key casing, `guarded` versus `fillable`, query-scope style, and validation-rule syntax. Each detector returned a confidence score. Laravel Prompts presented the likely conventions in a multiselect.\n\nThe command spent zero model tokens, which was the reason I built it that way.\n\nI did, however, leave the branch unmerged. It may have been fast, but it’s not scalable from a detection side. Each new convention needed another hand-tuned PHP class for discovery, evidence, confidence, and output.\n\nThe detector output also showed a problem with frequency. A codebase can contain hundreds of anonymous migration classes because Laravel generates them by default. Recording that pattern teaches the agent very little. A project rule earns its place when it preserves a choice another agent could plausibly miss.\n\nChoosing useful rules requires judgment about framework defaults, enforcement tools, architecture, and project history. A model can make that judgment from evidence and show its work to the developer.\n\nThe skill that replaced the deterministic checks examines roughly 49 convention dimensions across 10 groups. Adding a dimension there takes one line in a Markdown checklist.\n\n## The infer-conventions skill\n\nThe better replacement is an agent skill. It walks a structured audit across architecture, models, controllers, validation, data representation, testing, and other project surfaces.\n\nMost of the skill explains what deserves to be left out.\n\n### Look for project decisions\n\nBoost already provides Laravel-wide rules. A useful project rule carries information specific to *this application,* not Laravel in general.\n\nThe skill asks whether a future agent could reasonably choose a different implementation. A likely divergence gives the convention value.\n\n“Store money as integer cents” changes how the agent models, validates, serializes, and tests a value. “Use anonymous migration classes” usually repeats the framework default.\n\n### Let enforcement tools own style\n\nPint, Rector, linters, and static analyzers already apply many mechanical choices. Repeating those choices in prose spends context on work the tool will perform anyway. Anything that can be a deterministic guard should be one. Project rules are for things that can’t be covered by the myriad of deterministic guards.\n\nThat being said, deliberate exceptions still matter.\n\nIf a project consistently preserves a form that Rector would rewrite, the evidence may point to an architectural or compatibility decision. The skill surfaces that case for review.\n\n### Record architecture and deliberate absences\n\nArchitecture rules prevent expensive detours.\n\n“Business logic lives in `app/Actions` and controllers delegate to actions” gives the agent a destination. “Controllers and actions query Eloquent directly; this application has no repository layer” records a boundary the team already chose.\n\nA missing abstraction can be part of the architecture. Writing it down helps the agent stay within the application's existing shape.\n\n### Describe the current code\n\nThe audit reports the conventions the application follows today. Mixed evidence stays mixed in the report so the developer can resolve it. Our goal is to help surface conventions, not bless conventions that may or may not be intentional.\n\nConvention inference is a poor place to redesign the application! Represent the application as it exists, and then proposed changes belong in their own discussion and pull request.\n\n### Show evidence before recording\n\nThe current threshold is at least three consistent examples with no meaningful rival.\n\nThe skill presents each proposed rule with the files that support it. The developer can reject the finding, change its scope, or edit the wording. Recording begins after that review.\n\nThe audit spends model tokens. Teams run it when adopting Boost and occasionally as the application changes. The rules it produces are then available to every relevant coding task.\n\n## Recording the approved rule\n\nAfter approval, the agent calls Boost's `record-rule` MCP tool with three values:\n\n- `glob` for the files covered by the rule;\n- `title` for the project decision; and\n- `note` for the context the agent needs while working.\n\n`RuleRepository::write()` derives an area from the stable part of the glob, finds or creates the appropriate Markdown file, merges the path into its frontmatter, appends the rule, and rebuilds the generated index.\n\nThe logical update spans the rule file and its index entry, so Boost owns the write through one tested operation. A successful call leaves both files aligned.\n\nThe resulting files live under `.ai/rules`. They are readable, editable, version-controlled, and visible in pull-request review.\n\n## Why we call them rules\n\nThe project used the internal name “journal” for a while. The final pull request still carries that history.\n\n“Rules” fit the behavior better. Agents understand that nomenclature better, and it’s important to minimize the potential points of friction. These are shared project instructions committed to the application. Cursor, Windsurf, Cline, and Copilot already use the same word for similar files.\n\nNative agent memory has its own role. Claude Code can maintain notes across sessions for a developer using Claude Code. Boost rules travel with the repository and reach the different agents used by the team. Version control gives them an owner, a review history, and a shared current version.\n\n## Guidelines, skills, and rules\n\nBoost now delivers three kinds of agent instruction:\n\n| Layer | Contents | Loading | Owner | \n|---|---|---|---|\n| **Guidelines** | Laravel-wide conventions used across many tasks | Always loaded | Laravel Boost | \n| **Skills** | Package knowledge and guided workflows | Loaded for relevant tasks | Laravel or the package author | \n| **Rules** | Decisions and boundaries from one application | Loaded by path or concept | The application team | \n\nI use a simple placement test. Framework advice needed across many tasks belongs in guidelines. A deep workflow belongs in a skill. A decision discovered in one application belongs in its rules.\n\nThe split keeps the always-loaded layer small and scopes application knowledge.\n\n## Scoping Boost's own guidelines\n\nProject rules also give Boost a way to reduce its own instruction footprint. There are Laravel conventions that only apply to certain parts of your application and you shouldn’t pay the context-tax of having them loaded for every turn.\n\nModel guidance can load for `app/Models/**` and testing guidance can load for `tests/**`. Boost's corpus currently contains 16 candidate blocks using an internal `@scoped` directive. During installation, the experimental path can render those blocks into `.ai/rules/boost`.\n\nWe are still tuning the boundaries, so this behavior remains off by default and outside the public documentation. The experiment lets us apply the same scoping discipline to the guidelines Boost ships.\n\n## Auditing stale rules\n\nA project rule can outlive the code that justified it.\n\nPull-request review gives the team a chance to update a rule alongside the implementation change. Old rules can still survive when the connection is easy to miss. An agent will then follow a clear instruction that describes an earlier version of the application.\n\nBoost has no automated staleness audit today. A future audit could check whether cited examples still exist, flag scopes with zero matches, and rerun convention inference in report-only mode. Any rewrite should still go through developer review.\n\nFor now, the rule files live close to the code and move through the same review process.\n\n## Review before recording\n\nThe `infer-conventions` skill inspects the project, gathers examples, and proposes rules. The developer reviews the evidence and wording. `record-rule` writes the approved convention and refreshes its index entry.\n\nModel judgment stays in the discovery step, and predictable code handles the write. The repository keeps the final record for the whole team. Install Boost to try it out.","body_html":"<p>A new Laravel application can record project rules as the team makes decisions. An established application already has years of conventions encoded in its controllers, models, tests, directory structure, and deliberate absences.</p>\n<p>When a team installs Laravel Boost, either the codebase or the humans have to supply context on that history. Our goal at Laravel is to provide the best developer experience across everything we touch, and it felt less than ideal to offer teams no help documenting their existing conventions.</p>\n<p>In that pursuit, we tried two methods: deterministic extractors and an extraction skill.</p>\n<p>My first attempt was the hand-written detectors. The implementation was fast and deterministic, but it also recorded patterns with very different levels of value. The version we kept uses an agent skill to collect evidence and lets the developer approve each proposed rule.</p>\n<h2 id=\"starting-with-a-deterministic-artisan-command\">Starting with a deterministic Artisan command</h2>\n<p>The first implementation was an Artisan command named <code>boost:infer-conventions</code>.</p>\n<p>It had a source-root resolver, a file sampler, an inspector, and five detectors covering patterns such as enum key casing, <code>guarded</code> versus <code>fillable</code>, query-scope style, and validation-rule syntax. Each detector returned a confidence score. Laravel Prompts presented the likely conventions in a multiselect.</p>\n<p>The command spent zero model tokens, which was the reason I built it that way.</p>\n<p>I did, however, leave the branch unmerged. It may have been fast, but it’s not scalable from a detection side. Each new convention needed another hand-tuned PHP class for discovery, evidence, confidence, and output.</p>\n<p>The detector output also showed a problem with frequency. A codebase can contain hundreds of anonymous migration classes because Laravel generates them by default. Recording that pattern teaches the agent very little. A project rule earns its place when it preserves a choice another agent could plausibly miss.</p>\n<p>Choosing useful rules requires judgment about framework defaults, enforcement tools, architecture, and project history. A model can make that judgment from evidence and show its work to the developer.</p>\n<p>The skill that replaced the deterministic checks examines roughly 49 convention dimensions across 10 groups. Adding a dimension there takes one line in a Markdown checklist.</p>\n<h2 id=\"the-infer-conventions-skill\">The infer-conventions skill</h2>\n<p>The better replacement is an agent skill. It walks a structured audit across architecture, models, controllers, validation, data representation, testing, and other project surfaces.</p>\n<p>Most of the skill explains what deserves to be left out.</p>\n<h3 id=\"look-for-project-decisions\">Look for project decisions</h3>\n<p>Boost already provides Laravel-wide rules. A useful project rule carries information specific to <em>this application,</em> not Laravel in general.</p>\n<p>The skill asks whether a future agent could reasonably choose a different implementation. A likely divergence gives the convention value.</p>\n<p>“Store money as integer cents” changes how the agent models, validates, serializes, and tests a value. “Use anonymous migration classes” usually repeats the framework default.</p>\n<h3 id=\"let-enforcement-tools-own-style\">Let enforcement tools own style</h3>\n<p>Pint, Rector, linters, and static analyzers already apply many mechanical choices. Repeating those choices in prose spends context on work the tool will perform anyway. Anything that can be a deterministic guard should be one. Project rules are for things that can’t be covered by the myriad of deterministic guards.</p>\n<p>That being said, deliberate exceptions still matter.</p>\n<p>If a project consistently preserves a form that Rector would rewrite, the evidence may point to an architectural or compatibility decision. The skill surfaces that case for review.</p>\n<h3 id=\"record-architecture-and-deliberate-absences\">Record architecture and deliberate absences</h3>\n<p>Architecture rules prevent expensive detours.</p>\n<p>“Business logic lives in <code>app/Actions</code> and controllers delegate to actions” gives the agent a destination. “Controllers and actions query Eloquent directly; this application has no repository layer” records a boundary the team already chose.</p>\n<p>A missing abstraction can be part of the architecture. Writing it down helps the agent stay within the application&#39;s existing shape.</p>\n<h3 id=\"describe-the-current-code\">Describe the current code</h3>\n<p>The audit reports the conventions the application follows today. Mixed evidence stays mixed in the report so the developer can resolve it. Our goal is to help surface conventions, not bless conventions that may or may not be intentional.</p>\n<p>Convention inference is a poor place to redesign the application! Represent the application as it exists, and then proposed changes belong in their own discussion and pull request.</p>\n<h3 id=\"show-evidence-before-recording\">Show evidence before recording</h3>\n<p>The current threshold is at least three consistent examples with no meaningful rival.</p>\n<p>The skill presents each proposed rule with the files that support it. The developer can reject the finding, change its scope, or edit the wording. Recording begins after that review.</p>\n<p>The audit spends model tokens. Teams run it when adopting Boost and occasionally as the application changes. The rules it produces are then available to every relevant coding task.</p>\n<h2 id=\"recording-the-approved-rule\">Recording the approved rule</h2>\n<p>After approval, the agent calls Boost&#39;s <code>record-rule</code> MCP tool with three values:</p>\n<ul><li><code>glob</code> for the files covered by the rule;</li><li><code>title</code> for the project decision; and</li><li><code>note</code> for the context the agent needs while working.</li></ul>\n<p><code>RuleRepository::write()</code> derives an area from the stable part of the glob, finds or creates the appropriate Markdown file, merges the path into its frontmatter, appends the rule, and rebuilds the generated index.</p>\n<p>The logical update spans the rule file and its index entry, so Boost owns the write through one tested operation. A successful call leaves both files aligned.</p>\n<p>The resulting files live under <code>.ai/rules</code>. They are readable, editable, version-controlled, and visible in pull-request review.</p>\n<h2 id=\"why-we-call-them-rules\">Why we call them rules</h2>\n<p>The project used the internal name “journal” for a while. The final pull request still carries that history.</p>\n<p>“Rules” fit the behavior better. Agents understand that nomenclature better, and it’s important to minimize the potential points of friction. These are shared project instructions committed to the application. Cursor, Windsurf, Cline, and Copilot already use the same word for similar files.</p>\n<p>Native agent memory has its own role. Claude Code can maintain notes across sessions for a developer using Claude Code. Boost rules travel with the repository and reach the different agents used by the team. Version control gives them an owner, a review history, and a shared current version.</p>\n<h2 id=\"guidelines-skills-and-rules\">Guidelines, skills, and rules</h2>\n<p>Boost now delivers three kinds of agent instruction:</p>\n<div class=\"table-wrap\"><table><thead><tr><th>Layer</th><th>Contents</th><th>Loading</th><th>Owner</th></tr></thead><tbody><tr><td><strong>Guidelines</strong></td><td>Laravel-wide conventions used across many tasks</td><td>Always loaded</td><td>Laravel Boost</td></tr><tr><td><strong>Skills</strong></td><td>Package knowledge and guided workflows</td><td>Loaded for relevant tasks</td><td>Laravel or the package author</td></tr><tr><td><strong>Rules</strong></td><td>Decisions and boundaries from one application</td><td>Loaded by path or concept</td><td>The application team</td></tr></tbody></table></div>\n<p>I use a simple placement test. Framework advice needed across many tasks belongs in guidelines. A deep workflow belongs in a skill. A decision discovered in one application belongs in its rules.</p>\n<p>The split keeps the always-loaded layer small and scopes application knowledge.</p>\n<h2 id=\"scoping-boost-s-own-guidelines\">Scoping Boost&#39;s own guidelines</h2>\n<p>Project rules also give Boost a way to reduce its own instruction footprint. There are Laravel conventions that only apply to certain parts of your application and you shouldn’t pay the context-tax of having them loaded for every turn.</p>\n<p>Model guidance can load for <code>app/Models/**</code> and testing guidance can load for <code>tests/**</code>. Boost&#39;s corpus currently contains 16 candidate blocks using an internal <code>@scoped</code> directive. During installation, the experimental path can render those blocks into <code>.ai/rules/boost</code>.</p>\n<p>We are still tuning the boundaries, so this behavior remains off by default and outside the public documentation. The experiment lets us apply the same scoping discipline to the guidelines Boost ships.</p>\n<h2 id=\"auditing-stale-rules\">Auditing stale rules</h2>\n<p>A project rule can outlive the code that justified it.</p>\n<p>Pull-request review gives the team a chance to update a rule alongside the implementation change. Old rules can still survive when the connection is easy to miss. An agent will then follow a clear instruction that describes an earlier version of the application.</p>\n<p>Boost has no automated staleness audit today. A future audit could check whether cited examples still exist, flag scopes with zero matches, and rerun convention inference in report-only mode. Any rewrite should still go through developer review.</p>\n<p>For now, the rule files live close to the code and move through the same review process.</p>\n<h2 id=\"review-before-recording\">Review before recording</h2>\n<p>The <code>infer-conventions</code> skill inspects the project, gathers examples, and proposes rules. The developer reviews the evidence and wording. <code>record-rule</code> writes the approved convention and refreshes its index entry.</p>\n<p>Model judgment stays in the discovery step, and predictable code handles the write. The repository keeps the final record for the whole team. Install Boost to try it out.</p>","headings":[{"level":2,"text":"Starting with a deterministic Artisan command","id":"starting-with-a-deterministic-artisan-command"},{"level":2,"text":"The infer-conventions skill","id":"the-infer-conventions-skill"},{"level":3,"text":"Look for project decisions","id":"look-for-project-decisions"},{"level":3,"text":"Let enforcement tools own style","id":"let-enforcement-tools-own-style"},{"level":3,"text":"Record architecture and deliberate absences","id":"record-architecture-and-deliberate-absences"},{"level":3,"text":"Describe the current code","id":"describe-the-current-code"},{"level":3,"text":"Show evidence before recording","id":"show-evidence-before-recording"},{"level":2,"text":"Recording the approved rule","id":"recording-the-approved-rule"},{"level":2,"text":"Why we call them rules","id":"why-we-call-them-rules"},{"level":2,"text":"Guidelines, skills, and rules","id":"guidelines-skills-and-rules"},{"level":2,"text":"Scoping Boost's own guidelines","id":"scoping-boost-s-own-guidelines"},{"level":2,"text":"Auditing stale rules","id":"auditing-stale-rules"},{"level":2,"text":"Review before recording","id":"review-before-recording"}]}}