PageSourceSearch

https://coryrylan.com/blog/your-context-files-are-a-code-smell

html coryrylan.com collected 2026-10-03 19:43:47 UTC 28,750 bytes, 288 lines download raw bytes

1
2<!doctype html>
3<html lang="en">
4  <head>
5    
6<meta charset="utf-8">
7<meta name="author" content="Cory Rylan">
8<meta http-equiv="X-UA-Compatible" content="IE=edge">
9<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
10<title>Your Context Files Are a Code Smell</title>
11<link rel="canonical" href="https://coryrylan.com/blog/your-context-files-are-a-code-smell">
12<meta name="description" content="Learn how to separate useful project context from enforceable engineering rules when working with coding agents.">
13<meta name="keywords" content="ai, linting, architecture, Cory Rylan">
14<link rel="alternate" type="application/atom+xml" title="Cory Rylan | Web Development Articles" href="https://coryrylan.com/atom.xml">
15<link href="/assets/icon-fK_zQfBf.png" rel="shortcut icon" type="image/x-icon">
16<link rel="apple-touch-icon" href="/assets/icon-fK_zQfBf.png">
17<link rel="manifest" href="/assets/manifest-BvXaw4_F.json">
18<meta name="theme-color" content="#2f2f2f">
19<meta name="twitter:site" content="@coryrylan">
20<meta name="twitter:title" content="Your Context Files Are a Code Smell" />
21<meta name="twitter:description" content="Learn how to separate useful project context from enforceable engineering rules when working with coding agents." />
22<meta name="twitter:card" content="summary" />
23<meta name="twitter:image" content="https://coryrylan.com/assets/images/posts/types/default-800x800.png" />
24<meta property="og:type" content="article" />
25<meta property="og:title" content="Your Context Files Are a Code Smell" />
26<meta property="og:description" content="Learn how to separate useful project context from enforceable engineering rules when working with coding agents." />
27<meta property="og:url" content="https://coryrylan.com/blog/your-context-files-are-a-code-smell" />
28<meta property="og:image" content="https://coryrylan.com/assets/images/posts/types/default-800x800.png" />
29
30
31<script type="application/ld+json">
32  {
33    "@context": "https://schema.org",
34    "@type": "Article",
35    "@id": "https://coryrylan.com/blog/your-context-files-are-a-code-smell",
36    "keywords": "ai, linting, architecture",
37    "discussionUrl": "https://coryrylan.com/blog/your-context-files-are-a-code-smell",
38    "audience": "web developers",
39    "mainEntityOfPage": "https://coryrylan.com/blog/your-context-files-are-a-code-smell",
40    "name": "Your Context Files Are a Code Smell",
41    "headline": "Your Context Files Are a Code Smell",
42    "description": "Learn how to separate useful project context from enforceable engineering rules when working with coding agents.",
43    "datePublished": "2026-07-18T00:00:00.000Z",
44    
45    "image": [
46      {
47        "@type": "ImageObject",
48        "url": "https://coryrylan.com/assets/images/posts/types/default-800x800.png",
49        "width": "800",
50        "height": "800"
51      },
52      {
53        "@type": "ImageObject",
54        "url": "https://coryrylan.com/assets/images/posts/types/default-1280x720.png",
55        "width": "1280",
56        "height": "720"       
57      },
58      {
59        "@type": "ImageObject",
60        "url": "https://coryrylan.com/assets/images/posts/types/default-1280x960.png",
61        "width": "1280",
62        "height": "960"
63      },
64      {
65        "@type": "ImageObject",
66        "url": "https://coryrylan.com/assets/images/cory-rylan.jpg",
67        "width": "258",
68        "height": "258"
69      }
70    ],
71    "author": {
72      "@type": "Person",
73      "name": "Cory Rylan",
74      "url": "https://coryrylan.com/about",
75      "image": {
76        "@type": "ImageObject",
77        "url": "https://coryrylan.com/assets/images/cory-rylan.jpg",
78        "width": "258",
79        "height": "258"
80      }
81    },
82    "publisher": {
83      "@type": "Organization",
84      "name": "Cory Rylan",
85      "logo": {
86        "@type": "ImageObject",
87        "url": "https://coryrylan.com/assets/images/publisher/publisher.png",
88        "width": "600",
89        "height": "60"
90      }
91    }
92  }
93</script>
vendor: 69 bytes, lines 93-95
93
94
95    <script async src="https://www.googletagmanager.com/gtag/js?id=
95G-2S59GR7YB2
vendor: 16 bytes, lines 95-96
95"></script>
96    
96<script>
97      
vendor: 145 bytes, lines 97-100
97window.dataLayer = window.dataLayer || [];
98      function gtag(){dataLayer.push(arguments);}
99      gtag('js', new Date());
100      gtag('config', '
100G-2S59GR7YB2
vendor: 8 bytes, lines 100-101
100');
101    
101</script>
101
102    <link rel="stylesheet" crossorigin href="/assets/_styles-CE886zVE.css">
103  </head>
104  <body bp-layout="block gap:lg">
105    <div class="body-secondary"></div>
106    <nav class="primary-nav">
107      <a class="primary-nav__link--active" href="/">Articles</a>
108      <a href="/speaking">Speaking</a>
109      <!-- <a href="https://training.coryrylan.com/">Training</a> -->
110      <a href="https://www.youtube.com/channel/UC2psqmFgEHGQ3PnfUf1j8vw">Videos</a>
111    </nav>
112    <main class="primary-main">
113      
114<section class="profile" itemscope itemtype="http://schema.org/Person">
115  <div class="profile__description" itemprop="description">
116    <picture>
117      <source srcset="/assets/cory-rylan-DCneJRb0.jpg" type="image/webp">
118      <img src="/assets/cory-rylan-DCneJRb0.jpg" alt="Cory Rylan" class="profile__img" itemprop="image">
119    </picture>
120    <div class="profile__text">
121      <p>
122        My name is <a href="https://coryrylan.com" itemprop="url"><span itemprop="name">Cory Rylan</span></a>,
123        <span itemprop="jobTitle">Software Developer</span> and <a href="https://coryrylan.com/speaking">Speaker</a>.
124        Building <a href="https://nvidia.github.io/elements/">Design Systems</a> and <a href="https://github.com/nvidia/elements" aria-label="give a star on GitHub">Web Components</a>.
125      </p>
126      <a href="https://bsky.app/profile/coryrylan.com" class="btn-bluesky" title="Follow @coryrylan on Bluesky">
127        <svg class="btn-bluesky__icon" fill="none" viewBox="0 0 64 57"><path fill="#fff" d="M13.873 3.805C21.21 9.332 29.103 20.537 32 26.55v15.882c0-.338-.13.044-.41.867-1.512 4.456-7.418 21.847-20.923 7.944-7.111-7.32-3.819-14.64 9.125-16.85-7.405 1.264-15.73-.825-18.014-9.015C1.12 23.022 0 8.51 0 6.55 0-3.268 8.579-.182 13.873 3.805Zm36.254 0C42.79 9.332 34.897 20.537 32 26.55v15.882c0-.338.13.044.41.867 1.512 4.456 7.418 21.847 20.923 7.944 7.111-7.32 3.819-14.64-9.125-16.85 7.405 1.264 15.73-.825 18.014-9.015C62.88 23.022 64 8.51 64 6.55c0-9.818-8.578-6.732-13.873-2.745Z"/></svg>  
128        <span class="btn-bluesky__label">Follow @coryrylan</span>
129      </a>
130    </div>
131  </div>
132  <meta itemprop="sameAs" content="https://bsky.app/profile/coryrylan.com" />
133  <meta itemprop="sameAs" content="https://github.com/coryrylan" />
134  <meta itemprop="sameAs" content="https://stackblitz.com/@coryrylan" />
135  <meta itemprop="sameAs" content="https://www.youtube.com/channel/UC2psqmFgEHGQ3PnfUf1j8vw" />
136</section>
137  
138      
139    <div bp-layout="grid gap:sm">
140      <div bp-layout="col:9@md" class="post-container">
141        <article class="post" bp-layout="block gap:md">
142          <header class="post-header" bp-layout="block gap:md">
143            <div class="post-header-overlay"></div>
144            <img src="data:image/svg+xml,%3csvg%20width='100'%20height='100'%20viewBox='0%200%2036%2036'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill='%23999'%20d='M13.71%2012.59a1%201%200%2000-1.39-.26l-6.53%204.45a1%201%200%20000%201.65l6.53%204.45a1%201%200%20101.13-1.65l-5.32-3.62L13.45%2014a1%201%200%2000.26-1.41zM30.21%2016.78l-6.53-4.45A1%201%200%201022.55%2014l5.32%203.63-5.32%203.63a1%201%200%20001.13%201.65l6.53-4.45a1%201%200%20000-1.65zM19.94%209.83a.9.9%200%2000-1.09.66l-3.44%2013.8a.9.9%200%2000.66%201.09h.22a.9.9%200%2000.87-.68l3.44-13.81a.9.9%200%2000-.66-1.06z'/%3e%3cpath%20fill='none'%20d='M0%200h36v36H0z'/%3e%3c/svg%3e" alt="Cory Rylan Blog" class="ai" />
145            <h1>Your Context Files Are a Code Smell</h1>
146          </header>
147          <div bp-layout="block gap:xs">
148            <p>By <a href="/about">Cory Rylan</a></p>
149            <div bp-layout="inline gap:sm">
150              <span bp-layout="inline gap:xs">
151                <time datetime="2026-07-18T00:00:00.000Z">Jul 18, 2026</time>
152                <p class="read-time">- 5 minutes</p>
153              </span>
154              <div bp-layout="inline gap:xs inline:end">
155                <a href="/tags#ai" class="btn-tag">ai</a><a href="/tags#linting" class="btn-tag">linting</a><a href="/tags#architecture" class="btn-tag">architecture</a>
156              </div>
157            </div>
158            
159          </div>
160          
161          <div bp-layout="block gap:md" class="js-post-content"><p>You know the file. <code>AGENTS.md</code>, <code>CLAUDE.md</code>, <code>.cursorrules</code>, whatever your harness calls it. It started as a few lines. Now it's four hundred. &quot;Always use design tokens.&quot; &quot;Never hardcode hex values.&quot; &quot;Don't add a dependency without checking the bundle size.&quot; &quot;Prefer composition over inheritance.&quot; A wall of <em>please comply</em>
161.</p>
162<p>Every one of those normative lines is a guardrail you didn't write. The file isn't the solution to your agent problems. It's a symptom of your codebase problems. The more of it you have, the more likely it is that something underneath should have been enforced and isn't.</p>
163<p>This isn't really a post about agents. It's a post about all the stuff we should have been doing as engineers the whole time. Agents just turned the lights on.</p>
164<h2 id="context-vs-instruction" tabindex="-1">Context vs Instruction <a class="post-anchor" href="#context-vs-instruction" aria-label="heading permalink"><svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><path d="M17.6 24.32l-2.46 2.44a4 4 0 01-5.62 0 3.92 3.92 0 010-5.55l4.69-4.65a4 4 0 015.62 0 3.86 3.86 0 011 1.71 2 2 0 00.27-.27l1.29-1.28a5.89 5.89 0 00-1.15-1.62 6 6 0 00-8.44 0l-4.7 4.69a5.91 5.91 0 000 8.39 6 6 0 008.44 0l3.65-3.62h-.5a8 8 0 01-2.09-.24z"/><path d="M28.61 7.82a6 6 0 00-8.44 0l-3.65 3.62h.49a8 8 0 012.1.28l2.46-2.44a4 4 0 015.62 0 3.92 3.92 0 010 5.55l-4.69 4.65a4 4 0 01-5.62 0 3.86 3.86 0 01-1-1.71 2 2 0 00-.28.23l-1.29 1.28a5.89 5.89 0 001.15 1.62 6 6 0 008.44 0l4.69-4.65a5.92 5.92 0 000-8.39z"/><path fill="none" d="M0 0h36v36H0z"/></svg></a></h2>
165<p>Not every line in your context file is problematic. There are two very different things living in there.</p>
166<p><strong>Descriptive context.</strong> Where auth lives. The domain glossary. Which package owns what. Where the test guards are. A new human hire needs the exact same document on day one. None of it is enforceable, none of it implies bad code, and you should keep it. This is onboarding, not a smell.</p>
167<p><strong>Normative instructions.</strong> &quot;Always use tokens.&quot; &quot;Never do X.&quot; &quot;Don't add a dep.&quot; Every single one of these is a rule a parser could check — and you wrote it as prose and shipped it on a hope.</p>
168<p>The rest of this post is about the second pile. This is the signal that the enforcement by the system and codebase was never built.</p>
169<h2 id="%22but-judgment-can't-be-encoded%22" tabindex="-1">&quot;But judgment can't be encoded&quot; <a class="post-anchor" href="#%22but-judgment-can't-be-encoded%22" aria-label="heading permalink"><svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><path d="M17.6 24.32l-2.46 2.44a4 4 0 01-5.62 0 3.92 3.92 0 010-5.55l4.69-4.65a4 4 0 015.62 0 3.86 3.86 0 011 1.71 2 2 0 00.27-.27l1.29-1.28a5.89 5.89 0 00-1.15-1.62 6 6 0 00-8.44 0l-4.7 4.69a5.91 5.91 0 000 8.39 6 6 0 008.44 0l3.65-3.62h-.5a8 8 0 01-2.09-.24z"/><path d="M28.61 7.82a6 6 0 00-8.44 0l-3.65 3.62h.49a8 8 0 012.1.28l2.46-2.44a4 4 0 015.62 0 3.92 3.92 0 010 5.55l-4.69 4.65a4 4 0 01-5.62 0 3.86 3.86 0 01-1-1.71 2 2 0 00-.28.23l-1.29 1.28a5.89 5.89 0 001.15 1.62 6 6 0 008.44 0l4.69-4.65a5.92 5.92 0 000-8.39z"/><path fill="none" d="M0 0h36v36H0z"/></svg></a></h2>
170<p>Sure, determinism has a ceiling. Type checks, tests, and lint catch a lot, but some calls really do come down to taste. &quot;Don't abstract this prematurely.&quot; &quot;This feels over-engineered.&quot; You can't write a fitness function for that.</p>
171<p>However, here's the thing the objection misses: <strong>that ceiling is shared.</strong> A rule that's too contextual to encode as a check is also too contextual to encode as an instruction. &quot;Use good taste about premature abstraction&quot; is exactly as useless sitting in a markdown file as it would be as an ESLint rule. The agent can't act on it either. Anything genuinely above the ceiling lives in code review and in the moment — it never lived in your context file to begin with.</p>
172<p>So the judgment ceiling doesn't rescue context files. A normative line in <code>AGENTS.md</code> is just a lower-fidelity, unenforced fitness function. Everything below the ceiling should be a real check. Everything above it can't be written down usefully anywhere. The middle, where the file pretends to live, is empty.</p>
173<h2 id="closing-the-box" tabindex="-1">Closing the box <a class="post-anchor" href="#closing-the-box" aria-label="heading permalink"><svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><path d="M17.6 24.32l-2.46 2.44a4 4 0 01-5.62 0 3.92 3.92 0 010-5.55l4.69-4.65a4 4 0 015.62 0 3.86 3.86 0 011 1.71 2 2 0 00.27-.27l1.29-1.28a5.89 5.89 0 00-1.15-1.62 6 6 0 00-8.44 0l-4.7 4.69a5.91 5.91 0 000 8.39 6 6 0 008.44 0l3.65-3.62h-.5a8 8 0 01-2.09-.24z"/><path d="M28.61 7.82a6 6 0 00-8.44 0l-3.65 3.62h.49a8 8 0 012.1.28l2.46-2.44a4 4 0 015.62 0 3.92 3.92 0 010 5.55l-4.69 4.65a4 4 0 01-5.62 0 3.86 3.86 0 01-1-1.71 2 2 0 00-.28.23l-1.29 1.28a5.89 5.89 0 001.15 1.62 6 6 0 008.44 0l4.69-4.65a5.92 5.92 0 000-8.39z"/><path fill="none" d="M0 0h36v36H0z"/></svg></a></h2>
174<p>Take any normative line in your context file. It is exactly one of two things:</p>
175<ol>
176<li><strong>Encodable.</strong> Then it's a smell. You just didn't write the rule. (And you no longer have a cost excuse.)</li>
177<li><strong>Un-encodable <em>and</em> one-shot.</strong> Then it isn't durable policy. It belongs in the prompt or the PR de
177scription — not in a file that reloads on every single run.</li>
178</ol>
179<p>There's no third bucket. The only thing that could justify a permanent block of prose is &quot;recurring <em>and</em> un-encodable&quot; — and that category is about to disappear.</p>
180<p>The <a href="https://nvidia.github.io/elements/docs/internal/guidelines/agent-tooling/">Elements team</a> puts it: <em>prompts are runtime hints, not durable data. If a fact lives only in a prompt or a README, the harness doesn't own it.</em> If your enforcement only exists as a sentence you're hoping the model reads, you don't have enforcement.</p>
181<h2 id="we-always-should-have-done-this" tabindex="-1">We always should have done this <a class="post-anchor" href="#we-always-should-have-done-this" aria-label="heading permalink"><svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><path d="M17.6 24.32l-2.46 2.44a4 4 0 01-5.62 0 3.92 3.92 0 010-5.55l4.69-4.65a4 4 0 015.62 0 3.86 3.86 0 011 1.71 2 2 0 00.27-.27l1.29-1.28a5.89 5.89 0 00-1.15-1.62 6 6 0 00-8.44 0l-4.7 4.69a5.91 5.91 0 000 8.39 6 6 0 008.44 0l3.65-3.62h-.5a8 8 0 01-2.09-.24z"/><path d="M28.61 7.82a6 6 0 00-8.44 0l-3.65 3.62h.49a8 8 0 012.1.28l2.46-2.44a4 4 0 015.62 0 3.92 3.92 0 010 5.55l-4.69 4.65a4 4 0 01-5.62 0 3.86 3.86 0 01-1-1.71 2 2 0 00-.28.23l-1.29 1.28a5.89 5.89 0 001.15 1.62 6 6 0 008.44 0l4.69-4.65a5.92 5.92 0 000-8.39z"/><path fill="none" d="M0 0h36v36H0z"/></svg></a></h2>
182<p>Step back from agents for a second. Types. Tests. Lint. Static analysis. Structural fitness functions. None of this is new. We've been preaching deterministic guarantees for years. Agents didn't invent the need, they just made the cost of <em>not</em> having it impossible to ignore.</p>
183<p>An agent is a fast, tireless junior dev who does exactly what your enforcement allows and quietly ignores everything your prose merely requests. That's not a knock on the model. That's a mirror. Every &quot;please don't&quot; in your context file is a rule your CI should have been failing on, aimed at a contributor who finally takes you at your literal word.</p>
184<p>&quot;Agentic-ready codebase&quot; is a fancy way of saying the hygiene we already knew we wanted, now with a forcing function holding us to it.</p>
185<h2 id="the-cost-excuse-is-dead" tabindex="-1">The cost excuse is dead <a class="post-anchor" href="#the-cost-excuse-is-dead" aria-label="heading permalink"><svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><path d="M17.6 24.32l-2.46 2.44a4 4 0 01-5.62 0 3.92 3.92 0 010-5.55l4.69-4.65a4 4 0 015.62 0 3.86 3.86 0 011 1.71 2 2 0 00.27-.27l1.29-1.28a5.89 5.89 0 00-1.15-1.62 6 6 0 00-8.44 0l-4.7 4.69a5.91 5.91 0 000 8.39 6 6 0 008.44 0l3.65-3.62h-.5a8 8 0 01-2.09-.24z"/><path d="M28.61 7.82a6 6 0 00-8.44 0l-3.65 3.62h.49a8 8 0 012.1.28l2.46-2.44a4 4 0 015.62 0 3.92 3.92 0 010 5.55l-4.69 4.65a4 4 0 01-5.62 0 3.86 3.86 0 01-1-1.71 2 2 0 00-.28.23l-1.29 1.28a5.89 5.89 0 001.15 1.62 6 6 0 008.44 0l4.69-4.65a5.92 5.92 0 000-8.39z"/><path fill="none" d="M0 0h36v36H0z"/></svg></a></h2>
186<p>&quot;Writing a custom lint rules for every little thing isn't worth it the effort.&quot;</p>
187<p>That was a real argument in 2022. Authoring a custom lint rule used to cost the better part of a day. It isn't anymore. Writing a custom rule now costs minutes, and you write it <em>with the agent itself</em>. The economics that justified the prose collapsed. Deferral stopped being a tradeoff and went back to being laziness.</p>
188<p>Migration state is the cleanest example, because it looks the most like legitimate prose and isn't. &quot;We're moving from X to Y, prefer Y&quot; is just a deprecation rule: error on new usage, baseline the existing call sites, let CI hold the line. The file that tracks the migration was never documentation. It was an unwritten rule wearing a trench coat.</p>
189<h2 id="what-it-looks-like-done-right" tabindex="-1">What it looks like done right <a class="post-anchor" href="#what-it-looks-like-done-right" aria-label="heading permalink"><svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><path d="M17.6 24.32l-2.46 2.44a4 4 0 01-5.62 0 3.92 3.92 0 010-5.55l4.69-4.65a4 4 0 015.62 0 3.86 3.86 0 011 1.71 2 2 0 00.27-.27l1.29-1.28a5.89 5.89 0 00-1.15-1.62 6 6 0 00-8.44 0l-4.7 4.69a5.91 5.91 0 000 8.39 6 6 0 008.44 0l3.65-3.62h-.5a8 8 0 01-2.09-.24z"/><path d="M28.61 7.82a6 6 0 00-8.44 0l-3.65 3.62h.49a8 8 0 012.1.28l2.46-2.44a4 4 0 015.62 0 3.92 3.92 0 010 5.55l-4.69 4.65a4 4 0 01-5.62 0 3.86 3.86 0 01-1-1.71 2 2 0 00-.28.23l-1.29 1.28a5.89 5.89 0 001.15 1.62 6 6 0 008.44 0l4.69-4.65a5.92 5.92 0 000-8.39z"/><path fill="none" d="M0 0h36v36H0z"/></svg></a></h2>
190<p>I help maintain <a href="https://github.com/nvidia/elements">NVIDIA Elements</a>, a design system. We have roughly sixty-five custom lint rules across two packages. Every one of them encodes an intention that a lazier repo would have dumped into <code>AGENTS.md</code> as a bullet point.</p>
191<p>&quot;No hardcoded hex, use the token&quot; isn't a sentence in a markdown file. It's <code>no-unexpected-css-variable.ts</code>. The migration I just described? Six additional rules: <code>no-deprecated-attributes</code>, <code>no-deprecated-css-variable</code>, <code>no-deprecated-packages</code>, <code>no-deprecated-icon-names</code>, <code>no-deprecated-popover-attributes</code>, <code>no-deprecated-global-attributes</code>.</p>
192<p>The detail that makes the whole approach hold up: <strong>nearly every one of those rules has a co-located test.</strong> The guardrails are themselves verified. That's the answer to &quot;aren't you just moving trust around from the model to the linter?&quot; No. The enforcement is deterministic <em>and</em> tested. The model's compliance is a property of the system, not a property of how nicely I asked.</p>
193<p><strong>Harness engineering</strong> is treating an agent failure as a system-design problem you solve permanently, not a prompt you retry. When the agent misuses a component, the answer isn't a better instruction, it's a rule that makes the misuse impossible. The supporting model is a &quot;policy compiler&quot; that runs from durable to disposable: metadata, then static tools, then CLI and skills, and only at the far disposable end, contextual markdown. Context files sit at the throwaway end of that gradient <em>by design</em>.</p>
194<h2 id="it-takes-time" tabindex="-1">It Takes Time <a class="post-anchor" href="#it-takes-time" aria-label="heading permalink"><svg width="36" height="30" xmlns="http://www.w3.org/2000/svg"><path d="M17.6 24.32l-2.46 2.44a4 4 0 01-5.62 0 3.92 3.92 0 010-5.55l4.69-4.65a4 4 0 015.62 0 3.86 3.86 0 011 1.71 2 2 0 00.27-.27l1.29-1.28a5.89 5.89 0 00-1.15-1.62 6 6 0 00-8.44 0l-4.7 4.69a5.91 5.91 0 000 8.39 6 6 0 008.44 0l3.65-3.62h-.5a8 8 0 01-2.09-.24z"/><path d="M28.61 7.82a6 6 0 00-8.44 0l-3.65 3.62h.49a8 8 0 012.1.28l2.46-2.44a4 4 0 015.62 0 3.92 3.92 0 010 5.55l-4.69 4.65a4 4 0 01-5.62 0 3.86 3.86 0 01-1-1.71 2 2 0 00-.28.23l-1.29 1.28a5.89 5.89 0 001.15 1.62 6 6 0 008.44 0l4.69-4.65a5.92 5.92 0 000-8.39z"/><path fill="none" d="M0 0h36v36H0z"/></svg></a></h2>
195<p><strong>Sixty-five tested rules is an end state, not an entry fee</strong> You don't sit down and write them upfront. You add a rule the moment the agent actually fails at something, not preemptively. The mature repo is where you <em>end up</em> after enough of those moments, not the cost of getting started. Start with almost nothing.</p>
196<p><strong>Descriptive context stays.</strong> Domain intent, architecture orientation, where the guards live — keep all of it, lean. The target here is narrow: normative <em>code and architecture</em> rules masquerading as documentation. That's the smell. Project-layer enforcement written as prose instead of code.</p>
197<p>A large context file is liability laundering at the config layer. It's the same move as shipping code you didn't review and hoping it's fine, just pushed one step earlier in the pipeline. You're hoping the model complies instead of making compliance structural.</p>
198<p>The metric isn't how many context files you have. It's the ratio of <em>pleading</em> to <em>enforcement</em>
198. Every line that pleads is a rule you owe your future self. Go count the imperatives in your <code>AGENTS.md</code>. That number is your backlog.</p>
199</div>
200          
201        </article>
202      </div>
203      <aside bp-layout="col:3@md" class="post-side-bar">
204        <div bp-layout="block gap:sm" class="sticky-ads">
205          <div class="carbon-ad">
206            
206<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CKYILKJ7&placement=coryrylancom" id="_carbonads_js"></script>
206
207          </div>
208        </div>
209      </aside>
210    </div>
211    
212<div class="share-buttons">
213  <a href="https://bsky.app/intent/compose?text=Your Context Files Are a Code Smell+https://coryrylan.com/blog/your-context-files-are-a-code-smell">
214    <img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20512%20512'%3e%3cpath%20fill='%23fff'%20d='M111.8%2062.2C170.2%20105.9%20233%20194.7%20256%20242.4c23-47.6%2085.8-136.4%20144.2-180.2c42.1-31.6%20110.3-56%20110.3%2021.8c0%2015.5-8.9%20130.5-14.1%20149.2C478.2%20298%20412%20314.6%20353.1%20304.5c102.9%2017.5%20129.1%2075.5%2072.5%20133.5c-107.4%20110.2-154.3-27.6-166.3-62.9l0%200c-1.7-4.9-2.6-7.8-3.3-7.8s-1.6%203-3.3%207.8l0%200c-12%2035.3-59%20173.1-166.3%2062.9c-56.5-58-30.4-116%2072.5-133.5C100%20314.6%2033.8%20298%2015.7%20233.1C10.4%20214.4%201.5%2099.4%201.5%2083.9c0-77.8%2068.2-53.4%20110.3-21.8z'/%3e%3c/svg%3e" alt="Bluesky" loading="lazy" />
215  </a>
216
217  <a href="https://www.facebook.com/sharer.php?u=https://coryrylan.com/blog/your-context-files-are-a-code-smell">
218    <img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20264%20512'%20fill='%23fff'%3e%3cpath%20d='M76.7%20512V283H0v-91h76.7v-71.7C76.7%2042.4%20124.3%200%20193.8%200c33.3%200%2061.9%202.5%2070.2%203.6V85h-48.2c-37.8%200-45.1%2018-45.1%2044.3V192H256l-11.7%2091h-73.6v229'/%3e%3c/svg%3e" alt="Facebook" loading="lazy" />
219  </a>
220
221  <a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=https://coryrylan.com/blog/your-context-files-are-a-code-smell&title=Your Context Files Are a Code Smell">
222    <img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20448%20512'%20fill='%23fff'%3e%3cpath%20d='M100.3%20480H7.4V180.9h92.9V480zM53.8%20140.1C24.1%20140.1%200%20115.5%200%2085.8%2
22200%2056.1%2024.1%2032%2053.8%2032c29.7%200%2053.8%2024.1%2053.8%2053.8%200%2029.7-24.1%2054.3-53.8%2054.3zM448%20480h-92.7V334.4c0-34.7-.7-79.2-48.3-79.2-48.3%200-55.7%2037.7-55.7%2076.7V480h-92.8V180.9h89.1v40.8h1.3c12.4-23.5%2042.7-48.3%2087.9-48.3%2094%200%20111.3%2061.9%20111.3%20142.3V480z'/%3e%3c/svg%3e%3c!--%20Font%20Awesome%20Pro%205.3.1%20by%20@fontawesome%20-%20https://fontawesome.com%20License%20-%20https://fontawesome.com/license%20(Commercial%20License)%20--%3e" alt="LinkedIn" loading="lazy" />
223  </a>
224
225  <a href="/cdn-cgi/l/email-protection#78472b0d1a121d1b0c4521170d0a5d4a483b17160c1d000c5d4a483e11141d0b5d4a48390a1d5d4a48195d4a483b171c1d5d4a482b151d14145e191508433a171c0145100c0c080b4257571b170a010a01141916561b1715571a14171f5701170d0a551b17160c1d000c551e11141d0b55190a1d5519551b171c1d550b151d1414">
226    <img src="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20512%20512'%20fill='%23fff'%3e%3cpath%20d='M464%2064H48C21.5%2064%200%2085.5%200%20112v288c0%2026.5%2021.5%2048%2048%2048h416c26.5%200%2048-21.5%2048-48V112c0-26.5-21.5-48-48-48zM48%2096h416c8.8%200%2016%207.2%2016%2016v41.4c-21.9%2018.5-53.2%2044-150.6%20121.3-16.9%2013.4-50.2%2045.7-73.4%2045.3-23.2.4-56.6-31.9-73.4-45.3C85.2%20197.4%2053.9%20171.9%2032%20153.4V112c0-8.8%207.2-16%2016-16zm416%20320H48c-8.8%200-16-7.2-16-16V195c22.8%2018.7%2058.8%2047.6%20130.7%20104.7%2020.5%2016.4%2056.7%2052.5%2093.3%2052.3%2036.4.3%2072.3-35.5%2093.3-52.3%2071.9-57.1%20107.9-86%20130.7-104.7v205c0%208.8-7.2%2016-16%2016z'/%3e%3c/svg%3e%3c!--%20Font%20Awesome%20Pro%205.3.1%20by%20@fontawesome%20-%20https://fontawesome.com%20License%20-%20https://fontawesome.com/license%20(Commercial%20License)%20--%3e" alt="Email" loading="lazy" />
227  </a>
228</div>
229  
230    <div id="disqus-preload" style="height: 1px;">&nbsp;</div>
231    <div bp-layout="block gap:md align:block-stretch m-t:sm">
232      
233  <section bp-layout="block gap:md">
234    <h3>Related Posts</h3>
235    <div bp-layout="grid cols:12 cols:6@sm cols:4@lg gap:sm inline:stretch block:stretch">
236      
237    </div>
238  </section>
239  
240      
241<div id="disqus_thread" style="width: 100%"></div>
242<noscript>
243  Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a>
244</noscript>
vendor: 109 bytes, lines 244-245
244
245<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
245<script>
246  document.addEventListener('DOMContentLoaded', () => {
247    if ('IntersectionObserver' in window) {
248      const lazyCommentsObserver = new IntersectionObserver((entries, observer) => {
249        entries.forEach(entry => {
250          if (entry.isIntersecting) {
251            initializeDisqus();
252            lazyCommentsObserver.unobserve(entry.target);
253          }
254        });
255      });
256
257      lazyCommentsObserver.observe(document.getElementById('disqus-preload'));
258    } else {
259      initializeDisqus();
260    }
261  });
262
263  function initializeDisqus() {
264    var disqus_shortname = 'splintercode';
265    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
266    dsq.src = 'https://' + disqus_shortname + '.disqus.com/embed.js';
267    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
268  }
269</script>
269
270    </div>
271
272    </main>
273    <footer class="primary-footer">
274      <div>
275        <a href="https://bsky.app/profile/coryrylan.com" rel="me">Bluesky</a>
276        <a href="https://github.com/coryrylan" rel="me">Github</a>
277        <a href="https://stackblitz.com/@coryrylan" rel="me">StackBlitz</a>
278        <a href="https://codepen.io/coryrylan/" rel="me">Codepen</a>
279        <a href="https://www.youtube.com/channel/UC2psqmFgEHGQ3PnfUf1j8vw" rel="me">YouTube</a>
280        <a href="/blog/all">All Posts</a>
281        <a href="/tags">Topics</a>
282        <a href="/about">About Cory</a>
283        <a href="/atom.xml">Atom Feed</a>
284      </div>
285    </footer>
286  
286<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"f10d51470af541af9587651d2e7bf914","r":1,"spa":2}' crossorigin="anonymous"></script>
286
287</body>
288</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.