Introduce LLM guardrails to nudge Canvas contributors' AI use towards higher quality
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3591583. --> Reported by: [wim leers](https://www.drupal.org/user/99777) Related to !1151 >>> <h3 id="overview">Overview</h3> <p>It's 2026. The majority of software developers is either using <del>AI</del> LLMs (but everybody says "AI" despite it not actually being intelligent so I'll run with it anyway) voluntarily or is pressured to do so.</p> <p>Whichever your stance may be, it is the reality. In Drupal core (see <span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-8"><a href="https://www.drupal.org/project/drupal/issues/3585894" title="Status: Needs review">#3585894: LLM harm reduction in Drupal core contribution, AGENTS.md guidelines</a></span>). But also in Drupal Canvas. Drupal CMS already adopted it (<span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/drupal_cms/-/work_items/3569529" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/drupal_cms/-/work_items/3569529</a></span>).</p> <p>Most of Drupal Canvas is sponsored by Acquia: it pays dozens of people to work on it. I'm one of them. Acquia definitely expects us to build Drupal Canvas faster using AI.</p> <p>But there are also a solid number of community contributions to Canvas. In fact, increasingly so. And as one of the main reviewers of Canvas MRs, it's been a fact that for months most of those are generated by AI.</p> <p>So, today's reality: <strong>sprawl</strong>:</p> <ol> <li>High speed/throughput. (IOW: letting LLMs generate an abundance of code is easy. ) </li><li>Lots of #1 is hard to maintain. Much LLM-generated code is resulting in parallel (semi-duplicate) implementations of existing infrastructure (both in tests and actual code). It should do the necessary work: check both Drupal Canvas &amp; core for existing infrastructure and best practices for that infrastructure, generate code with that taken into account. </li><li>So far to a lesser degree in comments/prose (<a href="https://noslopgrenade.com">https://noslopgrenade.com</a>). </li></ol> <p>So: let's accept the reality. Just like @nod_'s core issue above, "LLM harm reduction" is a goal. For Canvas, I have no other choice but to go further than that though: "quality increase" is the main goal.</p> <p>References: Dries (<a href="https://dri.es/never-submit-code-you-do-not-understand">1</a>), Drupal CMS (<a href="https://git.drupalcode.org/project/drupal_cms/-/blob/2.x/AGENTS.md?ref_type=heads">1</a>), Matt (<a href="https://mglaman.dev/blog/drupalorg-cli-080-gitlab-issue-fork-and-merge-request-commands#:~:text=drupalorg%20mr%3Alogs-,Agent%20Skills,-The%20CLI%20ships">1</a>), Th&eacute;odore (<a href="https://tresbien.tech/blog/proposal-llm-policy-drupal-core-contribution/">1</a>1), webchick (<a href="https://www.drupal.org/project/drupal/issues/3585894#comment-16588685">1</a>), and many more.</p> <h3 id="proposed-resolution">Proposed resolution</h3> <p>Get an <u>initial set of minimal, generalist</u> <code>AGENTS.md</code> files committed to Canvas: <a href="https://git.drupalcode.org/issue/canvas-3591583/-/blob/3591583-AGENTS.md/AGENTS.md">rendered AGENTS.md in this MR</a>.</p> <dl> <dt>Out of scope</dt> <dd> To keep the scope of this issue manageable, these are for follow-ups: <ol> <li>modifying any existing files or docs &mdash; this MR is only adding new files </li><li>specialized agents for specific workflows or subdirectories </li><li>skills (either custom ones or existing ones) </li><li>prose guidance </li><li>provide extra guidance for known-to-be-organically-grown-and-immature areas of the codebase (internal HTTP API organization &rarr; <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3521041" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3521041</a></span>, ComponentSource plugin infrastructure &rarr; <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3520484" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3520484</a></span>, etc.) </li></ol> </dd> <dt>Principles</dt> <dd> <ol> <li><a href="https://en.wikipedia.org/wiki/KISS_principle">KISS</a></li> <li>Optimize for humans first, LLM agents second. (Not the <code>AGENTS.md</code> file itself, but the overall project organization.)</li> <li><code>CONTRIBUTING.md</code> is for humans, <code>AGENTS.md</code> for AI agents. Duplication between these two is okay. Both should point to more granular docs that can be used by both: LLMs should consume the same docs as humans wherever feasible.</li> <li><a href="https://docs.claude-mem.ai/progressive-disclosure#the-problem-context-pollution">Progressive disclosure to avoid context pollution.</a></li> <li>Use deterministic tools to avoid context pollution (e.g. linters).</li> <li>Strictly omit environment assumptions.</li> </ol> <p>Most of these speak for themselves. Context for a few:</p> <ul> <li>#2 + #3: <code>docs/intro.md</code> contains "big picture" docs by @phenaproxima. It should serve both humans and LLMs. So <code>AGENTS.md</code> should point to it.</li> <li>#3 ensures that tweaks to nudge the LLM to provide better results also improves docs for humans. This is why the existing <code>docs/*.md</code> files are reused.</li> <li>#5: use deterministic tools (PHPCS, PHPStan, eslint, stylelint, prettier &hellip;) rather than probabilistically hoping that the LLM will remember the thousand intricate code style details we'd have to describe in prose. Which would be &hellip;&nbsp;context pollution &mdash; see #4. </li><li>#5 bonus: this are essentially "automated reviews for baseline expectations", that also provide faster feedback to humans' MRs. Which means that once an MR passes linting, MR reviews can focus on the <em>actual</em> logic, organization, etc. </li><li>#6: @mglaman shared how much e.g. the <code>mcp_server</code>'s <a href="https://git.drupalcode.org/project/mcp_server/-/blob/65c454f6525e280a533ddac756b1218ec01f65af/AGENTS.md"><code>AGENTS.md</code> gets in the way</a> because it hard-codes the preferences of the lead maintainer. This is great for the lead maintainer, but is actually a barrier to contribution. </li> </ul> </dd> <dt>Dev environment</dt> <dd>Ideally, the LLM can spin up development environments as needed. <p>However, Canvas' recommended development environment is currently in an awkward state. There are four: 1) "bare metal" (local webserver etc), 2) core's recommend-project + <a href="https://github.com/drupal-canvas/ddev-drupal-xb-dev">a DDEV add-on</a>, 3) <a href="https://github.com/balintbrews/drupal-canvas-dev">https://github.com/balintbrews/drupal-canvas-dev</a>, 4) <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3587161" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3587161</a></span>.<br> &#128073; Work is happening to unify those. But it should be done in a way that doesn't violate principle #6. See <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3587161" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3587161</a></span>.</p> <p>Canvas' CI setup uses the <code>composer run &hellip;</code> + <code>npm run &hellip;</code> commands precisely to ensure consistency between development and CI, so stick to just those commands for now.<br> </p></dd> <dt>Prior work that facilitated this</dt> <dd> The following helped make this <code>AGENTS.md</code> file as lean as it is <ul> <li><span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3591245" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3591245</a></span></li> <li><span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3591249" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3591249</a></span></li> <li><span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3585788" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3585788</a></span></li> <li><span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3572401" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3572401</a></span> (and many since) &rarr; automate reviews using PHPCS &rArr; faster feedback for both humans &amp; LLMs</li> <li><span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3576694" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3576694</a></span> (and many since) &rarr; automate reviews using PHPStan &rArr; faster feedback for both humans &amp; LLMs</li> </ul> </dd> </dl> <h3 id="ui-changes">User interface changes</h3> <p>None.</p> > Related issue: [Issue #3569529](https://www.drupal.org/node/3569529) > Related issue: [Issue #3591245](https://www.drupal.org/node/3591245) > Related issue: [Issue #3587161](https://www.drupal.org/node/3587161)
issue