<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: arun rajkumar</title>
    <description>The latest articles on DEV Community by arun rajkumar (@mickyarun).</description>
    <link>https://dev.to/mickyarun</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3835684%2F4771b603-8faa-42b1-9e0e-0687faea63a3.jpg</url>
      <title>DEV Community: arun rajkumar</title>
      <link>https://dev.to/mickyarun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mickyarun"/>
    <language>en</language>
    <item>
      <title>Your MCP Eval Checklist Has an Auth Row. In Payments It's the Whole Table.</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Mon, 10 Aug 2026 14:16:19 +0000</pubDate>
      <link>https://dev.to/mickyarun/your-mcp-eval-checklist-has-an-auth-row-in-payments-its-the-whole-table-1n3e</link>
      <guid>https://dev.to/mickyarun/your-mcp-eval-checklist-has-an-auth-row-in-payments-its-the-whole-table-1n3e</guid>
      <description>&lt;p&gt;There's a good checklist going around dev.to for vetting an MCP server before you wire it into an agent. Four things to look at. Tool surface area: how many tools, and are they atomic or coarse. Auth model: API key, OAuth, token scope. Maintenance: last commit, open issues, is anyone home. Token profile: does it dump a full document when a summary would do.&lt;/p&gt;

&lt;p&gt;It's a genuinely good checklist. I've used a version of it. For most tooling categories it's exactly the right lens.&lt;/p&gt;

&lt;p&gt;Then you point an agent at something that moves money, and three of those four rows go quiet.&lt;/p&gt;

&lt;p&gt;Not because they stop mattering. Because one of them grows until it's the only thing you're really deciding.&lt;/p&gt;

&lt;h2&gt;
  
  
  A read tool and a write tool are not the same animal
&lt;/h2&gt;

&lt;p&gt;Here's the thing that took us a while to say out loud.&lt;/p&gt;

&lt;p&gt;If an agent calls a code-search tool twice, you get the same answer twice and waste a few tokens. If it reads a git diff twice, nobody notices. Reads are safe to repeat. That's the whole reason retries are the default everywhere in the agent stack. A tool call times out, the client tries again, you move on.&lt;/p&gt;

&lt;p&gt;A payment tool call is not a read. Retry it once and you've billed someone twice.&lt;/p&gt;

&lt;p&gt;We build open banking payments. The failure that actually keeps me up isn't a hallucinated argument or a server returning a forged result. It's the boring one. The connection blips mid-checkout, the client does what clients do and retries, and now there are two payment intents where the user meant one.&lt;/p&gt;

&lt;p&gt;So the eval question for a money-moving tool isn't "what's the auth model." It's "what happens on the second call I didn't mean to make."&lt;/p&gt;

&lt;h2&gt;
  
  
  Idempotency lives on the intent, not the turn
&lt;/h2&gt;

&lt;p&gt;The fix is old and unglamorous. Idempotency keys. Everyone in payments already knows them. The part people get wrong with agents is where the key lives.&lt;/p&gt;

&lt;p&gt;The instinct is to make the agent turn idempotent. Same prompt, same result. That's the wrong seam. The agent turn is fuzzy by design, and you don't want it to be the thing carrying the guarantee.&lt;/p&gt;

&lt;p&gt;Put the key on the payment intent. The client generates it once, before the tool is ever called, and it travels with the money, not with the conversation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The key is minted where the intent is born, not inside the agent loop.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;idempotencyKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// one per real-world payment&lt;/span&gt;
  &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GBP&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;payee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;merchant_8842&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Retries of the SAME intent collapse to one charge.&lt;/span&gt;
&lt;span class="c1"&gt;// A genuinely new payment gets a new key, on purpose.&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;paymentsTool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now a dropped connection is harmless. The retry carries the same key, the server recognises it, and the second call returns the first result instead of moving money again. The agent can be as jittery as it likes. The guarantee sits below it, where the stakes are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read paths open, write paths gated
&lt;/h2&gt;

&lt;p&gt;The other move is to stop treating "tools" as one category.&lt;/p&gt;

&lt;p&gt;On the read side we let the agent run. Fetch balances, list transactions, pull an account's status, look up a payout. If it over-calls, it wastes tokens and we tune it later. Low blast radius, no gate.&lt;/p&gt;

&lt;p&gt;On the write side, anything that changes state or moves money goes behind a human confirmation. Not the agent confirming to itself. A person, or a service acting under an explicit, narrow mandate, in the loop before the call executes.&lt;/p&gt;

&lt;p&gt;If you're on Claude Code or a similar setup, the cheap version of this is a pre-call hook that classifies the tool and decides whether it needs a gate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Classify by side effect, not by name.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NON_RETRYABLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;charge&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;refund&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;payout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mandate.create&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;preToolUse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NON_RETRYABLE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;requireHumanApproval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// blocks until a person says yes&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// reads sail through&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point isn't the code. It's the split. Reads and writes want different defaults, and a checklist that scores a server as one thing misses that the same server can hold both.&lt;/p&gt;

&lt;h2&gt;
  
  
  The credential is a mandate, not a key
&lt;/h2&gt;

&lt;p&gt;The auth row on the checklist usually asks whether it's an API key or OAuth. Fine question. Wrong altitude for payments.&lt;/p&gt;

&lt;p&gt;What you actually want to hand an agent is a mandate. Scoped to an amount and a payee. Time-boxed, so it expires whether or not anyone remembers to revoke it. Revocable mid-flight. And auditable after the fact, so when someone asks "why did this money move" there's a straight answer that doesn't depend on trusting the model.&lt;/p&gt;

&lt;p&gt;A key says "this caller is allowed." A mandate says "this caller is allowed to move this much, to this party, until this time, and here's the record." The second one is the only thing I'd let near a live payment rail.&lt;/p&gt;

&lt;p&gt;We already keep that audit spine for money movement, because we're regulated and there's no version of this job where you don't. The work with agents wasn't inventing it. It was extending the same discipline to tool calls, so an agent's action leaves the same trail a human's would.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, the checklist
&lt;/h2&gt;

&lt;p&gt;Keep all four rows. For a knowledge base or a code-search server, run the standard lens and move on.&lt;/p&gt;

&lt;p&gt;But the moment a tool can move money, promote one question above the rest and answer it first: is this call retryable, and if it isn't, what stops the second one? Everything else on the checklist is downstream of that.&lt;/p&gt;

&lt;p&gt;A read tool can be replayed all day. A payment tool replayed once bills a real person real money.&lt;/p&gt;

&lt;p&gt;Are you seeing any of the community MCP servers treat retryable and non-retryable tools as different classes yet, or is that still left entirely to whoever's calling them?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>agents</category>
      <category>security</category>
    </item>
    <item>
      <title>Gartner Says 40% of Apps Will Have AI Agents by December. Here's the Plumbing Nobody Puts on the Slide.</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Mon, 03 Aug 2026 08:09:14 +0000</pubDate>
      <link>https://dev.to/mickyarun/gartner-says-40-of-apps-will-have-ai-agents-by-december-heres-the-plumbing-nobody-puts-on-the-5196</link>
      <guid>https://dev.to/mickyarun/gartner-says-40-of-apps-will-have-ai-agents-by-december-heres-the-plumbing-nobody-puts-on-the-5196</guid>
      <description>&lt;p&gt;There's a number going around dev.to this week. Gartner says 40% of enterprise apps will ship a task-specific AI agent by the end of 2026. Last year it was under 5%.&lt;/p&gt;

&lt;p&gt;Every deck quotes it. Every thread argues about it. Fine.&lt;/p&gt;

&lt;p&gt;I run engineering at a UK payments company. We're FCA-authorised, SOC2, the whole regulated stack. On the side I build an open-source agent framework called Bodhiorchard, where a dozen agents do real work on a real codebase. So I've shipped the thing the slide is describing. And I can tell you the 40% isn't the hard part.&lt;/p&gt;

&lt;p&gt;The hard part is everything under the slide. And the biggest piece of it is money.&lt;/p&gt;

&lt;h2&gt;
  
  
  The demo is not the deployment
&lt;/h2&gt;

&lt;p&gt;An agent demo is easy. You give it a prompt, it writes some code or drafts a report, everyone claps.&lt;/p&gt;

&lt;p&gt;Then you try to put it near a live system and the questions start. What can this thing actually call? What happens when it's confidently wrong? Who gets paged?&lt;/p&gt;

&lt;p&gt;None of that shows up in a projection. All of it shows up in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real boundary isn't "no money." It's a signed mandate.
&lt;/h2&gt;

&lt;p&gt;The reflex guardrail is to forbid the scary thing. Don't let the agent move money. Read-only, propose-only, a human clicks the button.&lt;/p&gt;

&lt;p&gt;That reflex is already history. Agents are going to move money, because paying is half of what it means to finish a task. An agent that can research a supplier, compare options and fill a cart, then stops and waits for a human to tap "confirm," isn't an agent. It's an intern with a shopping list.&lt;/p&gt;

&lt;p&gt;This is the part of the 40% that actually rewires the economy. Not agents writing code. Agents that transact. The moment an agent can pay, it stops being an assistant and becomes an economic actor, and the rails for that are being built right now.&lt;/p&gt;

&lt;p&gt;That's what we're building at Atoa: &lt;a href="https://paywithatoa.co.uk/agentic-payments/" rel="noopener noreferrer"&gt;a regulated bank rail for AI agents&lt;/a&gt;. An agent settles a payment bank to bank, over an FCA-authorised rail, with a signed record on every move. Built for the protocols this is standardising on, AP2 for mandates, x402 for pay-per-request, MCP as the interface. So "never let it touch money" was never going to be our answer. The answer is where the authority lives.&lt;/p&gt;

&lt;p&gt;An agent's permission to spend can't be a line in a system prompt that a clever input talks its way around. It has to be a signed, scoped mandate: explicit about how much, to whom, within what limits, and verifiable on its own. Every payment gets a real-time affordability check. Every payment leaves a signed, provable record, who authorised it, what the funds check returned, where it settled.&lt;/p&gt;

&lt;p&gt;That's the shift worth internalising. The boundary moved from "can the agent act?" to "is the agent's authority explicit, scoped, and provable?" Money moving for an autonomous agent needs more oversight, not less. So you make the authority a hard artifact and the audit trail non-optional, and then you let it pay.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context in, not hope in
&lt;/h2&gt;

&lt;p&gt;Here's a real one from Bodhiorchard.&lt;/p&gt;

&lt;p&gt;An agent was asked to produce a payout report. Left to its own reading of the task, it started building a brand new service to generate that report. The report already existed. It was about to rebuild something we already had, in a slightly different shape, as new surface area to maintain.&lt;/p&gt;

&lt;p&gt;The fix wasn't a smarter prompt. It was context. We feed agents structured context through MCP before they write a line, what we call a BUD in Bodhiorchard. Once the agent could see the existing report and the decisions behind it, it did the sane thing. It extended what was there instead of spawning a duplicate.&lt;/p&gt;

&lt;p&gt;That's the difference between an agent that helps and one that quietly grows your tech debt. Not intelligence. Context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deterministic checks come before the probabilistic step
&lt;/h2&gt;

&lt;p&gt;An agent's output is a guess. A good guess, often. Still a guess.&lt;/p&gt;

&lt;p&gt;So the guess doesn't get to be the last word. Before anything an agent produces goes near a real code path, it runs the checks a human would have to pass. Types. Schema validation. The test suite. The design-pattern lints that encode decisions no off-the-shelf linter ships with. In the payments flow, the affordability check plays the same role: a deterministic gate the probabilistic step has to clear before anything settles.&lt;/p&gt;

&lt;p&gt;If that deterministic layer isn't there first, you haven't deployed an agent. You've deployed a very fast intern with commit access and no code review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Someone owns the failure
&lt;/h2&gt;

&lt;p&gt;This is the part nobody wants on the slide, because it's a headcount question, not a technology one.&lt;/p&gt;

&lt;p&gt;When an agent fails, it usually doesn't crash. It fails plausibly. The report looks right. The code compiles. The number is just wrong. That kind of failure needs a human owner who knows the domain well enough to smell it, and a record clean enough to trace it back.&lt;/p&gt;

&lt;p&gt;My mental model: an agent is an army of near-zero-mistake juniors. That's a gift to a senior engineer and a trap for a team without one. Enabling seniors with agents is the right move. Replacing seniors with agents is how you find out what plausible failure costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  So
&lt;/h2&gt;

&lt;p&gt;Yes, 40% of apps will probably have an agent by December. The slide will be right.&lt;/p&gt;

&lt;p&gt;But the agent isn't the work. The scoped mandate, the context feed, the deterministic gate, the human who owns the failure. That's the work. That's the 60% under the waterline.&lt;/p&gt;

&lt;p&gt;And the biggest piece of that iceberg is payments. The agent economy doesn't start when models get smarter. It starts when agents can pay, safely, over rails that were built for them. That's not a 2030 story. It's live now, and we're building one of the rails.&lt;/p&gt;

&lt;p&gt;If you're shipping an agent this year, which of those four do you already have, and which are you hoping the model handles for you?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>devops</category>
      <category>fintech</category>
    </item>
    <item>
      <title>AI Agents Ship Bugs When They're Blind. So We Stopped Building Blind.</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Fri, 31 Jul 2026 06:51:09 +0000</pubDate>
      <link>https://dev.to/mickyarun/ai-agents-ship-bugs-when-theyre-blind-so-we-stopped-building-blind-42ba</link>
      <guid>https://dev.to/mickyarun/ai-agents-ship-bugs-when-theyre-blind-so-we-stopped-building-blind-42ba</guid>
      <description>&lt;p&gt;Most AI coding mistakes don't look like mistakes.&lt;/p&gt;

&lt;p&gt;They compile. The tests pass. CI is green. The diff reads fine at 6pm on a Friday. Sometimes it's a bug that surfaces two weeks later when money moves where it shouldn't. And sometimes it's not a bug at all — the agent quietly rebuilds something you already had, and you don't notice until you're maintaining two versions of the same thing.&lt;/p&gt;

&lt;p&gt;Same root cause both times. The agent couldn't see. It had my prompt. It didn't have the codebase.&lt;/p&gt;

&lt;p&gt;I'm the CTO of a payments company. We're FCA-authorised, we move real money for real merchants, and we've leaned on AI agents hard for over a year. So I've watched this happen enough to stop blaming the model for it. Let me show you exactly what I mean, because it happened to me last week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The report that didn't need to exist
&lt;/h2&gt;

&lt;p&gt;We were adding multi-business support to payouts. One parent account, several businesses underneath it, each needing its own slice of the flow.&lt;/p&gt;

&lt;p&gt;The agent did the core work well. I want to be clear about that. On the multi-business payout logic itself, the code was correct. No complaints.&lt;/p&gt;

&lt;p&gt;Then I asked for a small follow-on: add callback parameters and a few dynamic fields into the payout report.&lt;/p&gt;

&lt;p&gt;The agent went and built a new reporting service. New repo, fresh scaffolding, a whole new report pipeline. It worked. It compiled, it ran, it produced exactly the report I'd asked for.&lt;/p&gt;

&lt;p&gt;One problem. We already had a payout report — the single-business one, live in production, tested against real settlements for months. The right move was to extend it to handle multiple businesses and the new fields. Instead I now had two report implementations for the same domain. One battle-tested, one freshly minted. And every future change to payout reporting would either be made twice or silently drift apart.&lt;/p&gt;

&lt;p&gt;That's not a bug. Nothing broke. It's worse in a quieter way. It's code-quality debt the agent created because it couldn't see that the thing it was building already existed.&lt;/p&gt;

&lt;p&gt;This is the part I keep coming back to. It's not only about bugs. It's about code quality. A blind agent doesn't just get logic wrong. It reinvents, it duplicates, it walks past the shared helper and writes a fourth one. Every instance of that is a small tax you pay forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a senior wouldn't have done this
&lt;/h2&gt;

&lt;p&gt;A coding agent is the best junior developer money can buy. Tireless, cheap, no ego, near-zero mistakes on routine work. An army of them at your terminal.&lt;/p&gt;

&lt;p&gt;But juniors write code. They don't ship products.&lt;/p&gt;

&lt;p&gt;A senior handed that report task would have opened with a different question. Not "how do I build a report" but "don't we already have one of these?" That instinct isn't in training data. It comes from having maintained a codebase long enough to know that a second implementation of anything is a liability, not a feature.&lt;/p&gt;

&lt;p&gt;The agent never asked that question. Not because it's dumb. Because it only had my sentence. It had no way to know the single-business report existed, where it lived, or that extending it was the whole job.&lt;/p&gt;

&lt;p&gt;So the problem stopped being "how do I get a smarter agent" and became "how do I put the judgment a senior carries in their bones somewhere the agent can read it — before it writes a line."&lt;/p&gt;

&lt;p&gt;That question is why I built &lt;a href="https://bodhiorchard.ai" rel="noopener noreferrer"&gt;Bodhiorchard&lt;/a&gt;. It's open source, Apache 2.0, self-hosted. We run it at Atoa now.&lt;/p&gt;

&lt;h2&gt;
  
  
  We stopped handing agents a prompt. We hand them a BUD.
&lt;/h2&gt;

&lt;p&gt;The unit of work in Bodhiorchard isn't a Jira ticket. It's a &lt;strong&gt;BUD&lt;/strong&gt; — a Business Understanding Document. One living source of truth for a feature: what it is, why it exists, who asked for it, the design, the tech spec, the decisions made along the way. Vector-indexed, full history, no scatter across Confluence and Slack and someone's memory.&lt;/p&gt;

&lt;p&gt;The point of a BUD is that the context is attached to the work, not floating around it. And crucially, Bodhiorchard traces a feature down to the actual code that implements it. A feature isn't a paragraph. It's a paragraph wired to the files, services, and procedures that make it real.&lt;/p&gt;

&lt;p&gt;Work moves through seven phases, each its own tab on the BUD:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Requirements → Design → Tech Spec → Development → Code Review → Testing → Prod&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Every phase has an agent. Every phase also has a toggle. Flip the agents off and it says "you're driving this BUD" — human in the loop, by design. This was never meant to run while you sleep.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same task, inside Bodhiorchard
&lt;/h2&gt;

&lt;p&gt;So I gave it the same job. Add callback params and dynamic fields to the payout report. Same class of model. Same one-line request.&lt;/p&gt;

&lt;p&gt;This time it didn't start blind. The request came in against the payout feature's BUD, and because the BUD is wired to code, the agent pulled the context over MCP and found the existing single-business report — the real procedure, in the real repo — before it wrote anything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;agent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;reads&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;context&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;before&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;writing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;finds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;what&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;already&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;exists&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/mcp&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;get_bud_context(bud_id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PAYOUTS-217"&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"feature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Payouts — multi-business support"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"add callback params + dynamic fields to the payout report"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"precedent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"report"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"services/reporting → PayoutReport (single-business, live in prod)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"guidance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extend this. do not stand up a second report pipeline."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"domain_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"One report implementation per domain"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Reporting reads the ledger projection, never writes to it"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It extended the existing report. Multi-business, dynamic fields, callback params, added to the code that was already there. No new service. No second pipeline. One report that now does more.&lt;/p&gt;

&lt;p&gt;The difference wasn't intelligence. It was sight. One agent could see the codebase and one couldn't.&lt;/p&gt;

&lt;p&gt;And notice what the agent gets to &lt;em&gt;do&lt;/em&gt; versus what it doesn't. The MCP write tools are bounded to the creative phases — it can create and update a BUD, draft the spec, propose the code. Nothing that moves money is a tool an agent can call directly. Read and propose across everything. Execute nothing with a blast radius. That line is drawn on purpose.&lt;/p&gt;

&lt;p&gt;Behind the context sits a mechanical gate. Design-pattern lints run in CI, and if an agent reaches for a banned pattern or stands up a duplicate where an ADR says there should be one, the build fails. Not "a reviewer might catch it." The gate fails, every time. And the test suite leans hard on the negative cases agents love to skip — the illegal state transition, the duplicate event, the report that should have been an extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scoreboard is pointed at the thing AI is worst at
&lt;/h2&gt;

&lt;p&gt;Bodhiorchard has a scoreboard, and it does not reward output. It rewards shipped, working value.&lt;/p&gt;

&lt;p&gt;You earn points when a BUD reaches production and when your code-review quality holds above a threshold. You lose a point for a bug caught in testing, and more for one that reaches production. The payout only lands when the feature is closed end-to-end, not when the PR merges.&lt;/p&gt;

&lt;p&gt;Read that incentive again. It pays for correctness that survives production and for quality that holds up in review — exactly the things a fast, blind agent erodes when it's optimising for a green checkmark. Volume of code earns you nothing. A duplicate report that passes its own tests earns you nothing. Shipping the right thing does.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest status
&lt;/h2&gt;

&lt;p&gt;I'm not going to tell you the agents run the whole SDLC while we sleep. They don't. The platform, the BUD lifecycle, the MCP context path, the feature-to-code indexing, the skill profiling — that's live and we use it daily. A fully autonomous execution loop is still being built. Today it's agent-assisted with a human in the loop at the phases that carry weight, and for anything touching payments that's exactly where I want it.&lt;/p&gt;

&lt;p&gt;Where do agents own a boundary? Reading context, finding precedent, proposing a spec, drafting code, linting against recorded decisions. Where do they never own one? Anything where the failure mode is money in the wrong account. That's not a limitation I'm apologising for. That's the design.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, back to blindness
&lt;/h2&gt;

&lt;p&gt;The new report was never a model failure. Neither was the duplicate-refund class of bug before it. Both came from the same place: handing something a blank prompt and hoping it would guess the code you'd already written and the decisions you'd already made.&lt;/p&gt;

&lt;p&gt;Give it the context a senior would carry into the review — the domain rules, the precedent, the boundaries, the code that already exists — and put a mechanical gate behind that context so nobody, human or agent, ships past it. The agent stops reinventing your codebase and starts extending it. It stops being a liability and starts being the army your seniors always wanted.&lt;/p&gt;

&lt;p&gt;The 80% was already solved. This is how you stop the other 20% from shipping bugs — and from quietly rotting your code quality — while you're not looking.&lt;/p&gt;

&lt;p&gt;What's the last thing an agent rebuilt in your codebase that already existed — and where was the context it needed to find it?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Arun, CTO and co-founder at &lt;a href="https://paywithatoa.co.uk" rel="noopener noreferrer"&gt;Atoa&lt;/a&gt;, building open banking payments for the UK. I built &lt;a href="https://bodhiorchard.ai" rel="noopener noreferrer"&gt;Bodhiorchard&lt;/a&gt;, it's open source, and we run it in our workflow. Repo's here if you want to poke at it — feedback over stars: &lt;a href="https://github.com/mickyarun/bodhiorchard" rel="noopener noreferrer"&gt;github.com/mickyarun/bodhiorchard&lt;/a&gt;. Find me on X &lt;a href="https://x.com/mickyarun" rel="noopener noreferrer"&gt;@mickyarun&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aiagents</category>
      <category>mcp</category>
      <category>devops</category>
    </item>
    <item>
      <title>I Got Obsessed With Killing Scrum. So I Built a World Out of 12 AI Agents.</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Sun, 12 Jul 2026 16:09:21 +0000</pubDate>
      <link>https://dev.to/mickyarun/i-got-obsessed-with-killing-scrum-so-i-built-a-world-out-of-12-ai-agents-1hl1</link>
      <guid>https://dev.to/mickyarun/i-got-obsessed-with-killing-scrum-so-i-built-a-world-out-of-12-ai-agents-1hl1</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-07-09"&gt;Weekend Challenge: Passion Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Bodhiorchard&lt;/strong&gt; — an open-source platform that replaces Scrum, Jira, and the team wiki with 12 specialised AI agents and a living 3D world you can actually walk around in.&lt;/p&gt;

&lt;p&gt;I call the methodology &lt;strong&gt;Agent-Driven Development (ADD)&lt;/strong&gt;. Instead of story points, planning poker, and a graveyard of stale Confluence pages, the work lives in one place: a &lt;strong&gt;BUD&lt;/strong&gt; (Business Understanding Document) — a single, vector-indexed source of truth that carries a feature from a Slack conversation all the way to production.&lt;/p&gt;

&lt;p&gt;The agents handle the busywork I never wanted humans doing: triage, design drafts, tech plans, standups, test plans, estimation, retros. Your repos show up as &lt;strong&gt;trees&lt;/strong&gt; in an orchard. Features are &lt;strong&gt;branches&lt;/strong&gt;. The whole team walks around as avatars — WASD to move, emotes, houses you upgrade with points you &lt;em&gt;only&lt;/em&gt; earn when something actually ships to prod and stays healthy.&lt;/p&gt;

&lt;p&gt;The scoreboard is the part I'm proudest of: it rewards &lt;strong&gt;quality, not output&lt;/strong&gt;. Ship a BUD to production: +1. A bug escapes to prod: -1. It scores the things AI is bad at and humans are good at.&lt;/p&gt;

&lt;p&gt;Honest status: the platform, the BUD lifecycle, the code-dependency graph, skill profiling, and the 3D world are all &lt;strong&gt;live&lt;/strong&gt;. The fully autonomous execution loop is still being built — today it's agents-assisted, human-in-the-loop. I'd rather undersell it than lie to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live site + walkthroughs:&lt;/strong&gt; &lt;a href="https://bodhiorchard.ai" rel="noopener noreferrer"&gt;https://bodhiorchard.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teaser — inside the virtual world:&lt;/strong&gt; &lt;a href="https://www.youtube.com/watch?v=OxoqBI7BNxU" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=OxoqBI7BNxU&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two views ship today: &lt;strong&gt;GARDEN&lt;/strong&gt; (the orchard) and &lt;strong&gt;GRAPH&lt;/strong&gt; (a cross-repo dependency graph with Bus Factor, Threats, and BUD-stage lenses). Two Slack bots sit on top — one triages new requests and kills duplicates before they become tickets; the other answers plain-English questions like "are we on track for go-live?" straight from the live BUD.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Open source, Apache 2.0, self-hosted — it runs on a Mac mini.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mickyarun" rel="noopener noreferrer"&gt;
        mickyarun
      &lt;/a&gt; / &lt;a href="https://github.com/mickyarun/bodhiorchard" rel="noopener noreferrer"&gt;
        bodhiorchard
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Bodhiorchard is the open-source, self-hosted alternative to Jira and Linear for AI-native software teams. Specialised agents draft every spec, forecast cycle times, and reason over your real repositories, commits, and pull requests — replacing story points, standups, and stale tickets so engineers can focus on building.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Bodhiorchard™&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Ship software, not Scrum ceremonies.&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;The open-source, self-hosted alternative to Jira &amp;amp; Scrum — AI agents run the process end-to-end, developers earn XP for what actually ships, and your data never leaves your machine.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://opensource.org/licenses/Apache-2.0" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5b60841bea9e11d9d0b0950d690c9bc554e06385634056a7d5d62a15d1a4eabe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4170616368655f322e302d626c75652e737667" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://bodhiorchard.ai/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b1c4add6708d0181275f1bbcc876781d07daf8873dc8aa20fc5cdb264b61dd11/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f776562736974652d626f6468696f7263686172642e61692d3245374433322e737667" alt="Website"&gt;&lt;/a&gt;
&lt;a href="https://www.python.org/downloads/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d447d7d53910a2d345c72845df16d927da9d7cdf1063cd4861c3d0b5eefea808/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31322b2d626c75652e737667" alt="Python 3.12+"&gt;&lt;/a&gt;
&lt;a href="https://vuejs.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4c10a2c0485e8ee3d7840c06fd105d8f68aa0acf869cba42709a72f1d1edec98/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5675652e6a732d332d3446433038442e737667" alt="Vue 3"&gt;&lt;/a&gt;
&lt;a href="https://www.docker.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f3cb62319dfd84f4edab1d619854d1d3bb2849bba63d58ff4b97c41623c40efd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446f636b65722d72656164792d3234393645442e737667" alt="Docker"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bodhiorchard.ai/" rel="nofollow noopener noreferrer"&gt;Website&lt;/a&gt; · &lt;a href="https://github.com/mickyarun/bodhiorchard#quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt; · &lt;a href="https://github.com/mickyarun/bodhiorchard#why-bodhiorchard" rel="noopener noreferrer"&gt;Why Bodhiorchard&lt;/a&gt; · &lt;a href="https://github.com/mickyarun/bodhiorchard#the-twelve-agents" rel="noopener noreferrer"&gt;The Twelve Agents&lt;/a&gt; · &lt;a href="https://github.com/mickyarun/bodhiorchard#documentation" rel="noopener noreferrer"&gt;Docs&lt;/a&gt; · &lt;a href="https://github.com/mickyarun/bodhiorchard#faq" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bodhiorchard.ai/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmickyarun%2Fbodhiorchard%2FHEAD%2Fdocs%2Fimages%2Fboard-ui.webp" width="85%" alt="The BUD board — every feature tracked from backlog to production in one view"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://youtu.be/i8kZdcL1bME" rel="nofollow noopener noreferrer"&gt;▶ Watch the demo&lt;/a&gt;&lt;/strong&gt; — a Slack message becomes a scoped, estimated BUD. No sprints, no story points, no standups.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Bodhiorchard&lt;/strong&gt; replaces sprint, scrum, and Jira ceremony with &lt;strong&gt;Agent-Driven Development (ADD)&lt;/strong&gt; — twelve specialised AI agents handle the busywork (triage, specs, estimates, test plans, retrospectives) while humans keep the decisions that matter, and developers earn XP for the work that actually reaches production. It's a &lt;strong&gt;self-hosted Jira alternative&lt;/strong&gt; for the full lifecycle: intake → spec → design → development → testing → deploy → retrospective. The data plane stays on your hardware; inference runs through your choice of agent CLI…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mickyarun/bodhiorchard" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;This is a solo project. Nights and weekends, on my own, because I couldn't leave it alone.&lt;/p&gt;

&lt;p&gt;The stack: &lt;strong&gt;FastAPI + Python 3.12&lt;/strong&gt; on the backend, &lt;strong&gt;Vue 3 + PlayCanvas&lt;/strong&gt; for the 3D world, &lt;strong&gt;Postgres + pgvector&lt;/strong&gt; for the BUD memory, and &lt;strong&gt;Redis&lt;/strong&gt; underneath. Inference runs through Claude Code today, with Ollama and OpenAI on the roadmap so you can bring your own model.&lt;/p&gt;

&lt;p&gt;The hard part wasn't the agents. It was the &lt;em&gt;ontology&lt;/em&gt; — deciding that a BUD, not a ticket, is the atom of work, and that everything (estimates, design, tests, the retro's estimated-vs-actual drift table) hangs off that one object. Once that clicked, the agents became small. Each one reads BUD context over a local MCP server and writes back only in the three creative phases where a human is still driving.&lt;/p&gt;

&lt;p&gt;The 3D layer looks like the toy. It's actually the point. A dependency graph as a spreadsheet is a chore. A dependency graph as an orchard you can lose an afternoon in — that's the thing that made &lt;em&gt;me&lt;/em&gt; want to open it every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Passion Angle
&lt;/h2&gt;

&lt;p&gt;I've spent years watching good engineers spend half their week on Jira instead of building. That quietly made me angry. This is the project I built to get that time back — mine first, then anyone else's who wants it.&lt;/p&gt;

&lt;p&gt;"Build well. Then go outside." That's the whole idea.&lt;/p&gt;

&lt;p&gt;Bodhi means awakening. An orchard is a grove you tend on purpose. The name is the pitch.&lt;/p&gt;

&lt;p&gt;If you've ever felt sprints were broken and wanted to do something about it instead of just complaining in retro — clone it, break it, tell me where I'm wrong. That feedback is the only prize I'm actually chasing.&lt;/p&gt;

</description>
      <category>weekendchallenge</category>
      <category>devchallenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>Are We in an AI Bubble? We've Built This Exact One Twice Before.</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Thu, 09 Jul 2026 13:37:41 +0000</pubDate>
      <link>https://dev.to/mickyarun/95-of-the-fiber-was-never-used-ai-is-digging-the-same-grave-bigger-2bei</link>
      <guid>https://dev.to/mickyarun/95-of-the-fiber-was-never-used-ai-is-digging-the-same-grave-bigger-2bei</guid>
      <description>&lt;p&gt;Railroads and dark fiber ran this exact playbook. Both times the technology won and the builders died. Here is why the AI build-out looks identical, and why your RAM got more expensive because of it.&lt;/p&gt;

&lt;p&gt;I build on this stuff for a living. My company runs on cloud infrastructure. We pay for AI tokens every month. And a few weeks ago I looked at a quote to add memory to a machine and did a double take. The price had nearly doubled in a year.&lt;/p&gt;

&lt;p&gt;That RAM quote is where this story starts. Because the reason memory got expensive is the same reason people keep asking if AI is a bubble. And to answer that honestly, you cannot just look at AI. You have to look at the two times we did almost exactly this before.&lt;/p&gt;

&lt;p&gt;The pattern is older than the internet&lt;/p&gt;

&lt;p&gt;Infrastructure bubbles all rhyme. Someone spots a genuinely world-changing technology. Money floods in. And then comes the move that defines every one of these episodes: companies build capacity far ahead of real demand, betting that demand will show up to fill it.&lt;/p&gt;

&lt;p&gt;Sometimes it does. Usually it does not, at least not on the schedule the spending assumed. The gap between capacity built and capacity used is where the money dies.&lt;/p&gt;

&lt;p&gt;We have run this experiment twice at national scale. First with railroads. Then with fiber. We are now running it a third time, with data centers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg2enesn72c2ig93x1r6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg2enesn72c2ig93x1r6w.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Railroads: the original overbuild&lt;/p&gt;

&lt;p&gt;Britain went first. During the Railway Mania of the 1840s, Parliament passed 263 acts in the single year of 1846 to set up new railway companies, for routes totalling around 9,500 miles. A lot of that track was planned on the assumption that traffic would arrive later. Much of it never earned back what it cost.&lt;/p&gt;

&lt;p&gt;America did it bigger. Between 1866 and 1873, roughly 35,000 miles of new track were laid across the country, a lot of it financed on optimism and shaky debt. Then the bill came due. In the Panic of 1873, 89 of the country’s 364 railroads went bankrupt, and around 18,000 businesses failed in two years.&lt;/p&gt;

&lt;p&gt;We did not even learn from it. Twenty years later, the Panic of 1893 hit for the same reason: too much railroad, financed too loosely. By mid-1894 a quarter of all US railroads had failed, more than 40,000 miles of them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flfu90o0i19z5ijo0pw13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flfu90o0i19z5ijo0pw13.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The technology was real. Railroads did reshape the world. But being right about the technology did not save the people who overbuilt it.&lt;/p&gt;

&lt;p&gt;Fiber: capacity nobody could use&lt;/p&gt;

&lt;p&gt;Fast forward a century. During the late-1990s telecom boom, companies laid more than 80 million miles of fiber optic cable across the US. The pitch was a number WorldCom kept repeating: internet traffic was doubling every 100 days. It was not. Real traffic was roughly doubling once a year, which is fast, but nowhere near the story the spending was built on.&lt;/p&gt;

&lt;p&gt;So what happened to all that glass? Barely any of it got used. By some estimates less than 5% of the fiber laid in the boom was ever lit. Even four years after the bubble burst, 85% to 95% of it was still sitting dark. The industry literally invented a name for capacity built and never used: dark fiber.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5yz2f3fg6wf0zpi3m2gc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5yz2f3fg6wf0zpi3m2gc.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The companies that laid it mostly did not survive to enjoy it. Global Crossing raised billions to wire the planet, then filed for bankruptcy in January 2002 with $12.4 billion of debt and thousands of miles of unused cable, after its chairman had quietly sold more than $700 million of his own stock. 360networks completed a $900 million IPO and was bankrupt about fourteen months later. WorldCom went down in July 2002 as the largest bankruptcy in US history at the time, $107 billion in assets, held up by roughly $11 billion of accounting fraud. Corning, which made the actual glass, fell from nearly $100 a share in 2000 to about $1 in 2002. All in, telecom stocks lost more than $2 trillion in value.&lt;/p&gt;

&lt;p&gt;And the purest version of the madness was next door, in dot-coms. Pets.com went public in February 2000 having booked $619,000 of revenue while spending $11.8 million on advertising. It sold products for about a third of what it paid for them. It went from IPO to switching off the lights in 268 days, its stock from $11 to 19 cents, roughly $300 million burned. It is a punchline now. At the time it was a stock people lined up to buy.&lt;/p&gt;

&lt;p&gt;Same shape as the railroads. Real technology. Genuine future. Ruinous timing.&lt;/p&gt;

&lt;p&gt;AI: same script, much bigger budget&lt;/p&gt;

&lt;p&gt;Now look at what is happening today.&lt;/p&gt;

&lt;p&gt;The five biggest US cloud and AI players, Microsoft, Alphabet, Amazon, Meta and Oracle, have signalled combined capital spending of roughly $660 to $690 billion for 2026, close to double what they spent in 2025. Across the largest data center operators globally, the spend is heading toward $750 billion in a single year, and about three quarters of that, roughly $450 billion, is tied directly to AI: the chips, the servers, the buildings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7leuqazxtj5oxq1elbc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7leuqazxtj5oxq1elbc8.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each of these data centers costs billions. They are being built now, at full speed, for demand that is expected later. That is the tell. It is the railroad move and the fiber move, in concrete and silicon.&lt;/p&gt;

&lt;p&gt;So here is the fair question. Is the money actually coming in to justify it?&lt;/p&gt;

&lt;p&gt;Look at the two names everyone points to. OpenAI is running at roughly a $24 billion revenue rate as of early 2026, and still projecting a $14 billion loss for the year, with no profit expected before 2029 or 2030, while preparing to ask investors to value it above a trillion dollars. Anthropic has grown fast too, to around a $30 billion annual run rate.&lt;/p&gt;

&lt;p&gt;Add up the frontier labs and you are somewhere in the range of $50 to $60 billion of annual revenue. Set that against roughly $450 billion of AI infrastructure spending in a single year. The revenue is real and growing quickly. It is also nowhere near what the build-out needs to break even.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa6xyksh98j3g64ibnpio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa6xyksh98j3g64ibnpio.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the demand everyone is counting on, enterprise adoption, is not showing up on schedule. An MIT report last year, looking at 300 deployments and 150-plus executive interviews, found that despite $30 to $40 billion of enterprise spending on generative AI, about 95% of organisations were seeing no measurable return. Only 5% were getting real value. Everyone is building for the enterprise wave. The enterprise wave, so far, is mostly stalled pilots.&lt;/p&gt;

&lt;p&gt;This is why your laptop got more expensive&lt;/p&gt;

&lt;p&gt;Here is the part that reaches people who never touch a data center.&lt;/p&gt;

&lt;p&gt;Three companies, Samsung, SK Hynix and Micron, make over 95% of the world’s DRAM, the memory in your laptop and your phone. AI accelerators need a special, more expensive kind of memory called HBM, and it is far more profitable to make. So those three quietly shifted capacity toward HBM for the AI build-out and away from the ordinary memory the rest of us buy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0tldiuw54mgqo3jm2i3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0tldiuw54mgqo3jm2i3.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
The result is a squeeze. Data centers now consume an estimated 70% of the memory chips produced worldwide. Prices have jumped hard. Samsung pushed a 32GB DDR5 module from about $149 to $239, a 60% jump. Contract prices for DDR5 have more than doubled. Samsung and SK Hynix are warning the shortage runs into 2027 and beyond, with customers reserving supply years ahead.&lt;/p&gt;

&lt;p&gt;That is the bubble touching your wallet. You did not buy an AI product. But the AI build-out bid up the memory in the device in your pocket, and you are paying for it anyway.&lt;/p&gt;

&lt;p&gt;So who actually won last time?&lt;/p&gt;

&lt;p&gt;This is the twist worth sitting with.&lt;/p&gt;

&lt;p&gt;When the fiber bubble burst, all that dark fiber did not vanish. It got sold off cheap. And the companies that scooped it up were not the ones that laid it. Google, Amazon and Facebook bought or leased that surplus capacity for a fraction of what it cost to build, and used it as the backbone for search, cloud and video. The infrastructure outlived the companies that funded it, and the winners were the ones who showed up after the crash with cash and a use for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fibq7h7ch8q1u0p8wa6on.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fibq7h7ch8q1u0p8wa6on.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is the honest hopeful side. Demand for fiber did eventually catch up. It just took more than a decade, and it arrived long after the original investors were wiped out. The glut was real. The future was also real. Both things were true.&lt;/p&gt;

&lt;p&gt;But this time the index is not made of Pets.coms&lt;/p&gt;

&lt;p&gt;Here is the fairest objection to all of this, and it is a strong one.&lt;/p&gt;

&lt;p&gt;The companies driving today’s build-out are nothing like Global Crossing or Pets.com. The fiber and dot-com bubbles floated on businesses with thin profits, sometimes almost no revenue, that needed a constant drip of fresh capital just to breathe. When the capital stopped, they were gone in months.&lt;/p&gt;

&lt;p&gt;The names leading the AI spend are the opposite. Microsoft, Alphabet, Amazon, Meta, Nvidia and Apple are some of the most profitable companies that have ever existed. The so-called Magnificent Seven throw off something like 70% of the entire economic profit of the S&amp;amp;P 500. They are funding most of this build-out from the cash their existing businesses already generate, not from speculators who can vanish overnight. Cisco traded at 200 times earnings in 2000 on a far shakier story than any of these carry now.&lt;/p&gt;

&lt;p&gt;So no, Google is not going to evaporate the way 360networks did. These giants can be wrong about AI for years and still be standing. That is a real difference, and it matters.&lt;/p&gt;

&lt;p&gt;But look closely at what that argument actually says. It says the incumbents survive. It does not say the spending pays off. A profitable company can pour hundreds of billions into capacity that demand never fills, take the writedown, and walk away intact. The build is still an overbuild. The money is still gone. It just does not take the company down with it.&lt;/p&gt;

&lt;p&gt;And the speculative layer has not disappeared. It has moved. Instead of Pets.com, this cycle has AI pure-plays and neocloud GPU landlords raising on the promise of the future, some of them buying chips with debt against contracts that only hold if the boom holds. If there is a Global Crossing hiding in this story, it is probably not Google. It is one of the names you only started hearing two years ago.&lt;/p&gt;

&lt;p&gt;So, are we in a bubble?&lt;/p&gt;

&lt;p&gt;Put it plainly. On the evidence, yes. Capacity is being built years ahead of the revenue and the adoption that would justify it, increasingly on debt, on a demand story that has not yet arrived. That is the exact pattern that broke railroads and telecom.&lt;/p&gt;

&lt;p&gt;But a bubble does not mean everyone dies. The last two times, the technology was real and the future did arrive. It just arrived for different people than the ones who paid for it, on a slower clock than the spending assumed. The builders ate the loss. The infrastructure, and the payoff, went to whoever was still standing afterward with cash and a use for it.&lt;/p&gt;

&lt;p&gt;The technology is not the bubble. The technology is probably the most important thing many of us will build on in our careers. The bubble is the belief that demand will arrive exactly when the spending needs it to. And “this time it is actually useful” is the line every bubble tells, right before it proves that being right and being early are two separate ways to go broke.&lt;/p&gt;

&lt;p&gt;So no, I am not betting against AI. I am building on it. But when I sign off on that doubled memory quote, I remember how the last two of these ended.&lt;/p&gt;

&lt;p&gt;Railroads were real. The people who overbuilt them went bankrupt, and someone else ran the trains. Fiber was real. Corning went from $100 to $1, and Google bought the cable for scrap. Both times, the future showed up exactly as promised. It just showed up for different people than the ones who paid for it.&lt;/p&gt;

&lt;p&gt;That is the part nobody spending $450 billion this year wants to hear. The winners of the AI era may not be the names on today’s invoices. They may be whoever is standing there with cash and a use for it after the correction, buying the future at the price of scrap.&lt;/p&gt;

&lt;p&gt;Twice is a coincidence. We are about to find out if three is a pattern.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foc1hdh6d54n3ykj0vz4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foc1hdh6d54n3ykj0vz4r.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Your Types Lie the Moment They Cross a Network Hop</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Tue, 07 Jul 2026 12:47:04 +0000</pubDate>
      <link>https://dev.to/mickyarun/your-types-lie-the-moment-they-cross-a-network-hop-577e</link>
      <guid>https://dev.to/mickyarun/your-types-lie-the-moment-they-cross-a-network-hop-577e</guid>
      <description>&lt;p&gt;A TypeScript type is a promise. And like any promise, it only holds while someone is around to keep it.&lt;/p&gt;

&lt;p&gt;That someone is the compiler. It watches your code, checks every shape, and yells the second something does not line up. It is very good at its job. But it has one hard limit nobody tells you about on day one. It stops at the edge of your process.&lt;/p&gt;

&lt;p&gt;The moment your data leaves the building, the compiler is gone. Over the network. Off a queue. Out of a webhook. Back from the database. Your type is still sitting there in the code, looking confident. But now it is just a sticky note that says "trust me." Nothing is checking it anymore.&lt;/p&gt;

&lt;p&gt;I learned this the annoying way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug that had no bug
&lt;/h2&gt;

&lt;p&gt;We had two services talking to each other. One sent a payment amount. The other received it. Both sides shared the same type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PaymentEvent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean. Typed on both ends. The compiler was happy everywhere I looked.&lt;/p&gt;

&lt;p&gt;Then one day the numbers in a report were slightly off. Not crashing-off. Just wrong enough to notice. No error. No stack trace. Nothing red anywhere.&lt;/p&gt;

&lt;p&gt;Took us a while to find it. The sending service had started putting &lt;code&gt;amount&lt;/code&gt; out as a string. &lt;code&gt;"1000"&lt;/code&gt; instead of &lt;code&gt;1000&lt;/code&gt;. Somewhere upstream a value got serialized, went through a queue, and the quotes crept in.&lt;/p&gt;

&lt;p&gt;On the receiving side, TypeScript still believed &lt;code&gt;amount&lt;/code&gt; was a &lt;code&gt;number&lt;/code&gt;. Because we told it so. It never looks at the wire. So &lt;code&gt;"1000" * 100&lt;/code&gt; did something silly, and the type sat there the whole time swearing everything was fine.&lt;/p&gt;

&lt;p&gt;The type did not lie on purpose. It just was not there when it mattered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where your types are actually guessing
&lt;/h2&gt;

&lt;p&gt;Here is the thing that clicked for me. Inside one process, types are real. The compiler saw the value get made and it saw it get used. It has the whole story.&lt;/p&gt;

&lt;p&gt;But the second data crosses a boundary, your type is a guess. A hopeful one. These are the spots where it is guessing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anything you &lt;code&gt;JSON.parse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A response from another service or a third-party API&lt;/li&gt;
&lt;li&gt;A message off a queue or an event bus&lt;/li&gt;
&lt;li&gt;A webhook you did not send&lt;/li&gt;
&lt;li&gt;A row from the database&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;process.env&lt;/code&gt; (every one of those is a string, even the ones you treat as numbers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all of those, you hand TypeScript a blob of data and say "this is a &lt;code&gt;PaymentEvent&lt;/code&gt;, take my word for it." And it does. That is the whole problem. It takes your word.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix is boring, and that is why it works
&lt;/h2&gt;

&lt;p&gt;You stop trusting the label and you check the actual shape at the door. Every time data comes in from outside, you parse it before you use it.&lt;/p&gt;

&lt;p&gt;We use Zod for this. You write the shape once as a schema. You get two things back from it: a real runtime check, and the type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PaymentEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PaymentEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;PaymentEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then at the boundary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PaymentEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;incoming&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;amount&lt;/code&gt; shows up as &lt;code&gt;"1000"&lt;/code&gt;, this throws right there, at the door, with a clear message. Not three services later in a wrong report. The bad data never gets in.&lt;/p&gt;

&lt;p&gt;And look at the last line of the schema. The type comes &lt;em&gt;from&lt;/em&gt; the check. You do not write the type by hand and hope the data matches it. The check is the source of truth, and the type just follows along. They cannot drift apart, because they are the same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule we live by now
&lt;/h2&gt;

&lt;p&gt;Trust types inside your own process. That is what they are for, and they are great at it.&lt;/p&gt;

&lt;p&gt;The moment data comes from somewhere else, treat the type as a wish until you have checked it. Parse at every boundary. Build the type from the parser, not the other way round.&lt;/p&gt;

&lt;p&gt;A type tells you what you meant. A parse tells you what you got. On a payments system, the gap between those two is real money.&lt;/p&gt;

&lt;p&gt;So next time a value crosses a wire and lands in a nice typed variable, ask one question: who actually checked this? If the answer is "the compiler," the compiler already went home.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>nestjs</category>
      <category>webdev</category>
    </item>
    <item>
      <title>We're Still Designing for Eyes. The Thing Reading Our Apps Now Doesn't Have Any.</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Fri, 03 Jul 2026 07:50:41 +0000</pubDate>
      <link>https://dev.to/mickyarun/were-still-designing-for-eyes-the-thing-reading-our-apps-now-doesnt-have-any-hnp</link>
      <guid>https://dev.to/mickyarun/were-still-designing-for-eyes-the-thing-reading-our-apps-now-doesnt-have-any-hnp</guid>
      <description>&lt;p&gt;I spent about an hour of WWDC watching Apple tell developers to make their apps more beautiful.&lt;/p&gt;

&lt;p&gt;Liquid Glass everywhere. A new transparency slider. Refined edges, better legibility. And this year you don't get to opt out. Recompile with Xcode 27 and your app adopts the new look whether you asked for it or not.&lt;/p&gt;

&lt;p&gt;Then, in more or less the same breath, Apple told us the look might not matter much longer.&lt;/p&gt;

&lt;p&gt;Because the other half of that keynote was App Intents. New entity and intent schemas that let your app push its content into Spotlight's semantic index, so Siri can find it and act on it through plain language. A View Annotations API so Siri can reach into what's on screen and do something with it. Foundation Models going open source. Xcode itself running coding agents from Anthropic, Google and OpenAI, wired in over MCP.&lt;/p&gt;

&lt;p&gt;Read those two stories next to each other and the message is hard to miss. Make the screen prettier. Also, assume something that can't see the screen is about to become your real user.&lt;/p&gt;

&lt;p&gt;Nobody at Apple stood up and said "the UI is dead." They rarely say the quiet part out loud. But it doesn't have to land in the App Review Guidelines as a hard rule to be true.&lt;/p&gt;

&lt;h2&gt;
  
  
  The front door moved
&lt;/h2&gt;

&lt;p&gt;Here's what I keep coming back to as someone who ships product.&lt;/p&gt;

&lt;p&gt;For years the front door to software was a screen. You designed the screen, you argued over the screen, you A/B tested the button on the screen. The screen was the product.&lt;/p&gt;

&lt;p&gt;That's shifting under us. The front door is becoming an agent. Siri, Copilot, Claude, whatever your customer happens to be talking to. It reads on their behalf and makes the call on their behalf. Increasingly it acts on their behalf too. It does not care about your hero animation. It cares whether it can understand what you do, and then do it.&lt;/p&gt;

&lt;p&gt;I ran into this with our own product. We're a payments company. We built an MCP server for our platform so an agent can look up a payment or kick off a refund without anyone opening the dashboard. Building that changed how I think about the whole thing. In that flow, our carefully designed dashboard wasn't the product. The clean, machine-readable version of it was.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then everyone rushes to llms.txt and gets it half wrong
&lt;/h2&gt;

&lt;p&gt;The reflex, once this clicks, is to drop an &lt;code&gt;llms.txt&lt;/code&gt; on your site and call yourself future-proofed.&lt;/p&gt;

&lt;p&gt;I had that instinct too. And clean, structured text genuinely helps. Serving markdown instead of a wall of HTML can cut the tokens an agent burns reading your page by half or more. Some teams report close to 10x. Fewer tokens means the model actually finishes your page instead of bailing halfway through. That part is real.&lt;/p&gt;

&lt;p&gt;But be honest about what &lt;code&gt;llms.txt&lt;/code&gt; is and isn't. After roughly eighteen months of noise, it's on about one in ten sites, and a big slice of that is Shopify quietly switching it on for every store by default. The bigger problem: the major crawlers from OpenAI, Google and Anthropic mostly don't fetch it. A study across 300,000 domains found it doesn't measurably move your AI citations. If you're adding it as an SEO cheat code, you'll be let down.&lt;/p&gt;

&lt;p&gt;Where it actually earns its place today is narrower and more useful. It works as a clean map for coding agents. Cursor, Claude Code, Copilot and the rest read it. Documentation sites get real mileage from it. That's the tell. The people getting value from agent-readable content treat it as plumbing, not marketing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm telling my team instead
&lt;/h2&gt;

&lt;p&gt;So I'm not chasing &lt;code&gt;llms.txt&lt;/code&gt; for citations. I'm asking for something duller and, I think, more durable.&lt;/p&gt;

&lt;p&gt;Treat the machine-readable version of every important surface as a real output, not an afterthought. If a page or a screen matters, there should be a clean text representation an agent can consume without scraping your DOM and guessing.&lt;/p&gt;

&lt;p&gt;Put a short summary at the top of everything. Two or three lines, plain language, saying what this page is and what you can do here. A summary block helps a human skimming on their phone. It also happens to be the first thing a model reads before deciding whether the rest of your content is worth its context window. You write it once and both readers win.&lt;/p&gt;

&lt;p&gt;Expose actions, not just words. Content is turning into table stakes. What an agent actually wants is a verb. "Refund this." "Book that." "Show me last month." App Intents on Apple's side, MCP on ours, a boring documented API underneath. The teams that do well in the agent era won't be the ones with the prettiest content. They'll be the ones whose product can be operated with no human in the room.&lt;/p&gt;

&lt;p&gt;And measure the thing that now matters. Can an agent complete your core task, start to finish, without a screenshot? We've started treating that as a first-class test, the same way we treat "can a new engineer run the whole stack in five minutes." If the answer is no, no amount of Liquid Glass is going to save you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The UI got demoted, not buried
&lt;/h2&gt;

&lt;p&gt;I don't think the UI is dead. I've got designers I'd go to bat for and screens I'm proud of. But it's been demoted. It used to be the product. Now it's one interface among several, and often the one your customer touches least.&lt;/p&gt;

&lt;p&gt;Apple just spent a keynote making the screen prettier and, at the same time, making it optional. That's not a contradiction. That's the shift, sitting in one room.&lt;/p&gt;

&lt;p&gt;So here's the question I keep putting to my team, and I'll put it to you. If the agent is the new user, what does your product look like to something that can't see?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>webdev</category>
      <category>startup</category>
    </item>
    <item>
      <title>I Deleted Our Confluence. The Code Is the Wiki Now.</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Mon, 29 Jun 2026 13:19:47 +0000</pubDate>
      <link>https://dev.to/mickyarun/i-deleted-our-confluence-the-code-is-the-wiki-now-ja9</link>
      <guid>https://dev.to/mickyarun/i-deleted-our-confluence-the-code-is-the-wiki-now-ja9</guid>
      <description>&lt;p&gt;A feature needed context. I opened the wiki.&lt;/p&gt;

&lt;p&gt;The page was six months old. It described an architecture we'd rebuilt twice since. It was wrong, top to bottom, and confident about it. Three engineers had already shipped decisions that week based on it.&lt;/p&gt;

&lt;p&gt;Nobody messed up. The page just got left behind by the code, the way they all do.&lt;/p&gt;

&lt;p&gt;So I deleted it. Then I deleted the habit that kept making it.&lt;/p&gt;

&lt;p&gt;This is the part of Bodhiorchard, the open-source dev workflow I've been building on my own, that I get the most pushback on. So let me actually make the case. Including where it doesn't hold.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every wiki you own is lying to you
&lt;/h2&gt;

&lt;p&gt;You just haven't caught it yet.&lt;/p&gt;

&lt;p&gt;It starts honest. Someone writes up how the payments service works, and that day it's perfect. Then the code moves. A field gets renamed. A flow reroutes. A service splits in two.&lt;/p&gt;

&lt;p&gt;Nobody updates the page. Not out of laziness. Updating the page is everyone's job, so it's nobody's.&lt;/p&gt;

&lt;p&gt;Six months later a new hire reads it, believes it, and ships a bug.&lt;/p&gt;

&lt;p&gt;By then the wiki isn't documentation. It's a museum of how things used to work.&lt;/p&gt;

&lt;p&gt;We've all quietly signed up for the same deal: pretend the wiki is current, then grep the code when you actually need an answer. The grep is the real documentation. The page is decoration.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reason docs rot isn't discipline
&lt;/h2&gt;

&lt;p&gt;It's that a wiki is a second copy of the truth.&lt;/p&gt;

&lt;p&gt;You write it by hand. You keep it next to the thing it describes. The two drift apart. Always. Two copies of one fact, updated by different people on different days, will diverge. That's not a team failing, it's just entropy.&lt;/p&gt;

&lt;p&gt;Code can't drift from itself. It's the thing that runs. When the doc and the code disagree, the code wins, because the code is what's live at 2am.&lt;/p&gt;

&lt;p&gt;So the whole thing rests on one line:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The code is the wiki.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not "we document well." Not "the docs sit near the code." The list of what your system does gets generated from the source, on its own, and never gets hand-written in the first place. You can't forget to update something that was never separate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The baseline scan
&lt;/h2&gt;

&lt;p&gt;Connect a repo and Bodhiorchard scans it. It doesn't ask you to describe anything. It reads the call graph, the module boundaries, the route handlers, the history, and pulls the live features straight out.&lt;/p&gt;

&lt;p&gt;My own run came back with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Baseline scan complete.
  4 repositories indexed
  19 active features extracted
  312 code locations linked
  0 pages written by a human
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nineteen features. Each one traceable to the exact files that back it. I typed none of it. Nobody keeps it current.&lt;/p&gt;

&lt;p&gt;Two things make this more than a fancy grep.&lt;/p&gt;

&lt;p&gt;First, it indexes code locations, not just words. Every fact points back to a real file and symbol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"feature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Idempotent refund webhook handling"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bank may resend the same refund webhook up to 3x; processed once."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"code_locations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"payments/src/webhooks/refund.handler.ts:24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"payments/src/guards/refundGuard.ts:8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"shared/db/migrations/0041_refund_dedupe.sql"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"linked_repos"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"payments"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"last_synced_commit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9f2c1ab"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask "how does refund idempotency work?" and the answer gets rebuilt from that. Not from a paragraph someone wrote at launch.&lt;/p&gt;

&lt;p&gt;Second, it links across repos. A frontend call gets wired to the backend handler it actually hits. The thing wikis are worst at, "where does this logic continue," is the thing a code graph is best at.&lt;/p&gt;

&lt;p&gt;And it doesn't go stale, because staleness is designed out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on PR merge to main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;-&amp;gt; re-scan the affected paths&lt;/span&gt;
  &lt;span class="s"&gt;-&amp;gt; update the feature's code_locations + commit history&lt;/span&gt;
  &lt;span class="s"&gt;-&amp;gt; re-embed for semantic search&lt;/span&gt;
  &lt;span class="s"&gt;-&amp;gt; flag anything the diff orphaned&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every merge updates the feature that changed. The next person, or agent, to touch it inherits today's truth. A daily job sweeps for drift, so it shows up as a flag instead of a production incident.&lt;/p&gt;

&lt;p&gt;You don't even open a dashboard to read any of this. You ask in plain English in Slack, and the answer comes back with a link to the code it came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it changes day to day
&lt;/h2&gt;

&lt;p&gt;Onboarding stops starting from a lie. A new engineer asks what the system does and gets an answer built from what it does today, files attached. Not the version from two refactors ago.&lt;/p&gt;

&lt;p&gt;Status questions get answered from reality. "Are we on track for the P3 item, and what's the go-live date?" comes back from the live record, not a number someone typed into a board last Tuesday.&lt;/p&gt;

&lt;p&gt;And your AI agents stop reasoning from stale context. This is the one I underrated. An agent is only as good as the context you hand it. Feed it a six-month-old wiki page and it'll cheerfully build on an architecture that's already gone. You get a clean PR that's wrong in a way that costs you an afternoon to spot.&lt;/p&gt;

&lt;p&gt;That's why I stopped treating AI context files and human docs as two separate things. They're one thing with two readers. Generate them from one source, or watch them split apart the way the wiki did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it stops
&lt;/h2&gt;

&lt;p&gt;I'm not going to tell you this kills documentation. It doesn't. And where it stops matters.&lt;/p&gt;

&lt;p&gt;Auto-extraction is great at what exists and where. It's useless at why.&lt;/p&gt;

&lt;p&gt;A scan can tell you there's an idempotency guard on the refund webhook and point you at the line. It can't tell you the guard is there because one bank resends webhooks three times and double-refunded a customer back in March. That's intent. You earn it through pain, and no scan will ever infer it.&lt;/p&gt;

&lt;p&gt;So the why still needs a person. In Bodhiorchard it lives in the BUD: one markdown file per feature, holding the intent, the criteria, the decisions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# BUD-241 · Idempotent webhook handler for refunds&lt;/span&gt;

&lt;span class="gu"&gt;## Intent&lt;/span&gt;
Bank resends the same refund webhook up to 3x. We must process exactly once.

&lt;span class="gu"&gt;## Why this is hard (the part a scan can't infer)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; 2026-03 incident: duplicate webhook -&amp;gt; double refund. Don't regress this.
&lt;span class="p"&gt;-&lt;/span&gt; An already-refunded txn must be REJECTED, not silently retried.

&lt;span class="gu"&gt;## Acceptance criteria&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Duplicate webhook IDs are a no-op (return 200, no state change)
&lt;span class="p"&gt;-&lt;/span&gt; Illegal transition complete -&amp;gt; pending is impossible
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The BUD is written by a human. But it's versioned, it's searchable, and it travels with the code as context for every agent. So even the human part stays alive instead of rotting in a tool nobody opens.&lt;/p&gt;

&lt;p&gt;That split is the point. Machines maintain what rots fastest. People own what machines can't. The busywork dies, the judgment stays.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it, and tell me where it breaks
&lt;/h2&gt;

&lt;p&gt;Bodhiorchard is Apache 2.0, self-hosted, and runs on a Mac mini in the corner of my room. Your repos, embeddings, and audit log never leave your hardware. I built it on my own time. The regulated fintech I run engineering at is where I felt this pain. It's not what owns the code.&lt;/p&gt;

&lt;p&gt;Repo, with six demo videos and four sample repos to point it at: &lt;a href="https://github.com/mickyarun/bodhiorchard" rel="noopener noreferrer"&gt;https://github.com/mickyarun/bodhiorchard&lt;/a&gt;&lt;br&gt;
Full methodology: &lt;a href="https://bodhiorchard.ai/" rel="noopener noreferrer"&gt;https://bodhiorchard.ai/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm not after stars. I'm stuck on one question.&lt;/p&gt;

&lt;p&gt;Does "the code is the wiki" survive contact with your team? Or does the why sprawl back across five tools no matter how good the extraction gets? And if it does, where does it leak first?&lt;/p&gt;

&lt;p&gt;I spent fifteen years maintaining wikis that were wrong by Friday. I finally stopped. If you've killed a doc tool and lived to tell it, what broke first: the tool, or your team's trust in it?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Arun, CTO and co-founder of Atoa, a UK open banking payments platform, and the solo author of Bodhiorchard. I write about what building with AI is actually like, not what the conference slides say. Find me on &lt;a href="https://x.com/mickyarun" rel="noopener noreferrer"&gt;X @mickyarun&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>We Keep Our Architecture Rules in the Repo. The AI and the New Hire Read the Same File.</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Tue, 23 Jun 2026 13:23:04 +0000</pubDate>
      <link>https://dev.to/mickyarun/we-keep-our-architecture-rules-in-the-repo-the-ai-and-the-new-hire-read-the-same-file-48me</link>
      <guid>https://dev.to/mickyarun/we-keep-our-architecture-rules-in-the-repo-the-ai-and-the-new-hire-read-the-same-file-48me</guid>
      <description>&lt;p&gt;A few weeks ago I watched an agent build a feature beautifully.&lt;/p&gt;

&lt;p&gt;Clean code. Tests passed. Did exactly what I asked.&lt;/p&gt;

&lt;p&gt;Three sessions later, I opened the same service and didn't recognise it. Nothing was &lt;em&gt;wrong&lt;/em&gt;, exactly. Every individual decision was reasonable. Stacked together, they'd quietly walked the codebase somewhere I would never have designed it.&lt;/p&gt;

&lt;p&gt;That's when it clicked. The problem wasn't the model. The model was great. The problem was that every session started from zero — no memory of the boundaries I'd been protecting, no idea which patterns were load-bearing, no clue about the trade-off I made three weeks ago for a reason I never wrote down.&lt;/p&gt;

&lt;p&gt;I'd seen this exact failure before. Just with humans.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new hire who never read the docs
&lt;/h2&gt;

&lt;p&gt;You know the version. Someone joins. They're sharp. They ship something in week one that works — and breaks an unwritten rule nobody told them about. Not their fault. The rule lived in my head, or in a Slack thread from last March, or in the muscle memory of whoever's been here longest.&lt;/p&gt;

&lt;p&gt;So we'd explain it. Then explain it again to the next person. The "why" never made it anywhere durable. It just got re-explained, badly, on demand.&lt;/p&gt;

&lt;p&gt;An AI session is a new hire who shows up brilliant, fast, and with total amnesia. Every single time. Re-explaining the codebase to a fresh chat window every morning is exhausting, and honestly I'd forget half of it under pressure anyway.&lt;/p&gt;

&lt;p&gt;Same problem. I'd just been solving it twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  One source of truth, two audiences
&lt;/h2&gt;

&lt;p&gt;Here's the shift that fixed it for us: the context an AI agent needs to not wreck your codebase is &lt;em&gt;the same context&lt;/em&gt; a new engineer needs on day one.&lt;/p&gt;

&lt;p&gt;Not similar. The same.&lt;/p&gt;

&lt;p&gt;Which patterns are deliberate. Where the boundaries are and why crossing them costs you. What "done" means here. Which decisions are settled and which are still up for debate. A human needs that to contribute without breaking things. An agent needs that to contribute without breaking things.&lt;/p&gt;

&lt;p&gt;So we stopped keeping it in our heads and started keeping it in the repo. Plain markdown. Committed. Versioned with the code it describes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;service-payments/
├── CLAUDE.md          # how this service works, and why
├── src/
├── test/
└── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A root &lt;code&gt;CLAUDE.md&lt;/code&gt; (or &lt;code&gt;AGENTS.md&lt;/code&gt; — pick the convention your tools read) carries the project-wide principles. Each service that has real rules of its own gets its own. When an agent opens that service, it loads the file automatically. When a human opens that service, the same file is sitting right there, written so a person can actually read it.&lt;/p&gt;

&lt;p&gt;One file. Two readers. Nothing to keep in sync, because there's only one of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually goes in the file
&lt;/h2&gt;

&lt;p&gt;This is where most teams get it wrong. They dump the obvious in there — "we use TypeScript," "run the tests before you push" — and the file becomes noise everyone scrolls past.&lt;/p&gt;

&lt;p&gt;The rule I use: &lt;strong&gt;a line earns its place only if leaving it out would let a plausible, reasonable-looking mistake sail through review.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That filter kills most of what you'd be tempted to write. What survives is the good stuff:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Boundaries&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Services talk over the message bus, never direct HTTP to each other.
  If you need another service's data synchronously, that's a design
  smell — raise it, don't route around it.

&lt;span class="gu"&gt;## Validation&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Every inbound payload is parsed by a schema at the edge. No raw
  request bodies past the controller. A missing field fails loud on
  the way in, not three layers deep at runtime.

&lt;span class="gu"&gt;## What "done" means here&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; A feature isn't done when it works. It's done when the next person
  can tell what it does without asking you.

&lt;span class="gu"&gt;## Settled vs open&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; SETTLED: how we do idempotency. Don't reinvent it; copy the pattern.
&lt;span class="p"&gt;-&lt;/span&gt; OPEN: our caching story. If you touch it, expect a conversation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice none of those are syntax. They're &lt;em&gt;judgment&lt;/em&gt;. The settled-vs-open split alone has saved me hours, because it tells both the agent and the human where to copy an existing pattern versus where to stop and ask a person.&lt;/p&gt;

&lt;p&gt;The "why" matters as much as the rule. "Don't call services directly" is an order. "Don't call services directly, because the moment you do you've created a hidden dependency that nobody can see until it breaks at 2am" is something a human will actually remember and an agent will actually respect.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest part
&lt;/h2&gt;

&lt;p&gt;This isn't free, and it isn't a silver bullet.&lt;/p&gt;

&lt;p&gt;The files rot if you let them. A rule that's no longer true is worse than no rule — it teaches the wrong thing to two audiences at once. So they get reviewed like code, because they &lt;em&gt;are&lt;/em&gt; code now. When a settled decision changes, the file changes in the same PR. If that feels like overhead, it's the overhead you were already paying in repeated explanations — just made visible.&lt;/p&gt;

&lt;p&gt;And no, I didn't stop using AI tools while waiting for the perfect setup. The point isn't to control the agent. It's to make sure my long-term thinking is still present in a codebase that's increasingly being written by someone — something — that wasn't in the room when the decisions got made.&lt;/p&gt;

&lt;h2&gt;
  
  
  When one file stops being enough
&lt;/h2&gt;

&lt;p&gt;A markdown file works until it doesn't. One service, a handful of rules — &lt;code&gt;CLAUDE.md&lt;/code&gt; is perfect. But spread it across a dozen services and the &lt;em&gt;tending&lt;/em&gt; becomes the whole job. The rules drift from the code they describe. The "why" behind a feature ends up split across a spec, a ticket, a PR description, and a conversation nobody can find six weeks later. The flat file can't keep up, and a stale rule teaches the wrong thing to both readers at once.&lt;/p&gt;

&lt;p&gt;That rot is what pushed me to build &lt;a href="https://bodhiorchard.ai" rel="noopener noreferrer"&gt;Bodhiorchard&lt;/a&gt; — an open-source, self-hosted project I've been working on independently (Apache 2.0, runs on Claude Code). Same idea as the file, taken further. Instead of one feature's knowledge scattered across tickets, everything for that feature lives in a single living document: the spec, the tech spec, the test plan, the acceptance criteria, the full history — tied to the actual code. And the knowledge layer stays current by syncing from the code and those docs automatically, so it's semantically searchable by a human and fed straight into every agent's prompt.&lt;/p&gt;

&lt;p&gt;That's the part I care about most. Not a wiki you have to remember to update. A wiki that's current &lt;em&gt;because&lt;/em&gt; it's wired into where the work already happens. Confluence goes stale the day you write it. This doesn't, because nobody's job is to keep it alive by hand.&lt;/p&gt;

&lt;p&gt;The principle never changed. One source of truth, two audiences. I just got tired of being the sync engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed
&lt;/h2&gt;

&lt;p&gt;Less re-explaining. That's the boring, real win.&lt;/p&gt;

&lt;p&gt;New engineers read the same file the agent reads, and it turns out the document you write for a machine that takes everything literally is a &lt;em&gt;really&lt;/em&gt; good onboarding doc. No assumed context. No "you'll pick it up." Just the actual shape of the thing.&lt;/p&gt;

&lt;p&gt;And the drift slowed down. Not because the agent got smarter — because it finally knew which walls were load-bearing.&lt;/p&gt;

&lt;p&gt;I used to think the codebase lived in the code. It doesn't. Half of it lives in the decisions &lt;em&gt;around&lt;/em&gt; the code — and for years I kept that half in my head, where exactly one reader could access it.&lt;/p&gt;

&lt;p&gt;Now it's in the repo. Where everyone can. Human or not.&lt;/p&gt;

&lt;p&gt;If you're letting AI write a meaningful share of your code: where do the rules of your codebase actually live right now? And who can read them?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nestjs</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Same Prompt, Four AI Tools, One Cricket Banner: ChatGPT Won the Image, Grok Won the Video, and Claude Built a Website Again</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Tue, 16 Jun 2026 12:30:00 +0000</pubDate>
      <link>https://dev.to/mickyarun/same-prompt-four-ai-tools-one-cricket-banner-chatgpt-won-the-image-grok-won-the-video-and-1gba</link>
      <guid>https://dev.to/mickyarun/same-prompt-four-ai-tools-one-cricket-banner-chatgpt-won-the-image-grok-won-the-video-and-1gba</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — A few weeks ago I tested four AI tools on a &lt;em&gt;build&lt;/em&gt; job: a website for my son's cricket academy. This time the job had nothing to do with code. The coach just wanted a banner he could post. Same four tools, totally different result. ChatGPT made the best image, Grok made the best video, Gemini wouldn't make anything, and Claude tried to solve a graphics problem by writing HTML.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you read &lt;a href="https://dev.to/mickyarun/i-asked-three-coding-agents-to-build-my-sons-cricket-coach-a-website-the-result-wasnt-decided-by-3fam"&gt;the last post&lt;/a&gt;, you've met my son's cricket coach. He runs MMCA — Maverick Master's Cricket Academy. Started in 2020, based in Bengaluru, genuinely good with the kids.&lt;/p&gt;

&lt;p&gt;The website is live now and parents have started messaging him on WhatsApp. So last weekend he came back with the next thing he needed, which is the thing every small academy actually runs on:&lt;/p&gt;

&lt;p&gt;"Can you make me a weekend batch banner? Something I can post in the parent groups."&lt;/p&gt;

&lt;p&gt;Now, this is a completely different job from the last one. That first experiment was design and development — agents writing real code, running tests, deploying to Cloudflare. This one is just graphics. No repo, no deploy, nobody reviewing a pull request. Just: here's my logo, here's a sample I like, make me something I'd be happy to send out.&lt;/p&gt;

&lt;p&gt;So I figured I'd run the same four tools again and see what happened. Same brief, same logo, everything on the &lt;strong&gt;default model with no special settings&lt;/strong&gt;: ChatGPT, Claude, Gemini, Grok.&lt;/p&gt;

&lt;p&gt;Here's roughly what I typed, the way a normal client would brief you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Similar to this banner, make one for MMCA Academy (since 2020, logo attached). Weekend batch Sat 4:30—7, Sun 7—9:30pm. Add a small phrase like the sample. Be creative, keep it simple, but don't copy the sample exactly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The whole test really came down to one instruction: be creative, but don't copy. Whatever each tool did with that told me everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Round 1: the static banner
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ChatGPT&lt;/strong&gt; got it on the first go. "WEEKEND BATCH. TRAIN. PLAY. GROW." Logo top-left, the "Since 2020" bit kept, timings in clean little cards, an enrol number, three badges across the bottom for coaching, skill, discipline. It clearly understood this was a flyer a coach would hand out at a school gate, and that's exactly what it gave me.&lt;/p&gt;

&lt;p&gt;Then I asked for one more version — smaller logo, add a human hero this time — and it came back with "DREAM. PRACTICE. PERFORM." and a photoreal batsman walking out under stadium lights. Looked like a film poster. Two prompts, two banners I'd genuinely use, no arguing with it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssnseem4i6oz3cwdo7xi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssnseem4i6oz3cwdo7xi.png" alt=" " width="800" height="1428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhal3bsgsxxtsxqkd3ezz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhal3bsgsxxtsxqkd3ezz.png" alt=" " width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude&lt;/strong&gt; is the one that made me laugh. I asked for a banner. It told me it would "create the MMCA banner as an HTML file you can download," ran six commands, and gave me a dark navy web page. "TRAIN HARDER. Play Smarter. Win Together," with Saturday/Sunday cards and a Register button. And to be fair it looked nice — same eye for design that won me over on the website build.&lt;/p&gt;

&lt;p&gt;But it's not a banner. It's a landing section. You can't drop a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; into a WhatsApp group and call it a poster.&lt;/p&gt;

&lt;p&gt;That's the part worth sitting with. The tool I actually shipped the website with, the one with the best taste when the medium is code, defaulted straight back to code the moment I asked for graphics. It's wired to build. Ask it to build something and it's brilliant. Ask it to draw something and it quietly turns your design job back into an engineering one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyw29dpksvoegs0s4cmfk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyw29dpksvoegs0s4cmfk.png" alt=" " width="800" height="1265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grok&lt;/strong&gt; at least made an actual image, which already put it ahead of half the field. Problem was it threw everything at the wall — three overlapping player photos, mismatched fonts, text everywhere, faded cricketers bleeding through the background. The exact opposite of "keep it simple." It knew what a banner was. It just didn't know when to stop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1ndew9k9ghtozmnjomv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1ndew9k9ghtozmnjomv.png" alt=" " width="800" height="985"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemini&lt;/strong&gt; gave me three attempts and three different ways of saying it couldn't quite generate that. The image guardrails kept tripping over what was, I'll remind you, a children's cricket flyer. I gave up after the third try. For a test that's purely about making graphics, a tool that won't make graphics doesn't really place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhcvd5nuj4hgk7qi3jw35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhcvd5nuj4hgk7qi3jw35.png" alt=" " width="800" height="889"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Round 1 goes to ChatGPT,&lt;/strong&gt; and it's not close. Two prompts, two finished banners, on brand, logo respected, the restraint Grok didn't have and an actual image Gemini wouldn't produce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Round 2: make it move
&lt;/h2&gt;

&lt;p&gt;Static was only half of what I was curious about. The real 2026 question is whether I can turn a flat banner into a short clip with a voiceover. So I took the good banner and gave two tools a single line: "make this banner live."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grok&lt;/strong&gt; nailed it. One prompt, six seconds. The banner came alive — the batsman moving, the paint-splash colours animating in, the timings resolving on screen — and over the top, a clean Indian-accented voiceover reading the academy out. "Where practice meets purpose." Honestly it looked like something an agency would charge ₹15,000 for.&lt;/p&gt;

&lt;p&gt;One caveat, and it's the CTO in me talking: check the details. The phone number that showed up in the video wasn't the one I'd put in the source banner. Motion tools will happily rewrite text you wanted left alone, so you proof it before it goes out. Gorgeous result, but you don't post it blind.&lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/5qiRJGbioDk"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Gemini&lt;/strong&gt;, the same tool that wouldn't make me a still image, decided it &lt;em&gt;would&lt;/em&gt; make me a video. Ten seconds of abstract paint-splash motion, a "WEEKEND BATCH" title card, a voiceover — but disconnected from the actual banner, and the on-screen text kept breaking apart and reflowing into gibberish. The idea was there, the execution wasn't. A trailer for a banner that never got made.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Camj5qn0CpU"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Round 2 goes to Grok.&lt;/strong&gt; For motion plus voice off a single prompt, nothing else came close.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scorecard
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Static banner&lt;/th&gt;
&lt;th&gt;Live video&lt;/th&gt;
&lt;th&gt;Read the brief?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ChatGPT&lt;/td&gt;
&lt;td&gt;Won it in 2 prompts&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Yes, with restraint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grok&lt;/td&gt;
&lt;td&gt;Cluttered, no restraint&lt;/td&gt;
&lt;td&gt;Won it, voice + motion&lt;/td&gt;
&lt;td&gt;Half — strong on motion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini&lt;/td&gt;
&lt;td&gt;No output, guardrails&lt;/td&gt;
&lt;td&gt;Out of context, broken text&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude&lt;/td&gt;
&lt;td&gt;Built an HTML page&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Wrong medium, nice taste&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Image goes to ChatGPT. Video goes to Grok.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed from the coding test, and what didn't
&lt;/h2&gt;

&lt;p&gt;Last time, on a development job, Claude was the tool I actually wanted to keep working with. The taste that made its website the nicest in that lineup is the same taste that made its HTML "banner" pleasant to look at here. None of that's a knock — it was just answering a question I hadn't asked. Point a code-native model at a design brief and it reaches for the thing it's best at.&lt;/p&gt;

&lt;p&gt;Switch the job from build to draw and the whole ranking flips. A few things I'm taking away:&lt;/p&gt;

&lt;p&gt;The best coding agent isn't automatically the best graphics agent. Obvious once you say it out loud, easy to forget when your whole team has standardised on one tool. The model that shipped my website couldn't make me a poster.&lt;/p&gt;

&lt;p&gt;Guardrails are a product decision you feel as a user. Gemini turned down a kids' cricket flyer three times and then made a broken video of it. Whatever the safety reasoning, what I experienced was a tool that wouldn't do the simplest creative thing I needed.&lt;/p&gt;

&lt;p&gt;And "done" beats "impressive." ChatGPT's banners weren't the flashiest pixels I've ever seen. They were finished, and I could post them in two prompts. Grok's video was the flashiest thing in the whole test and still needed me to catch a wrong phone number. For graphics, I'll take the tool that hands me something I can ship today over the one that wows me in the demo.&lt;/p&gt;

&lt;p&gt;So I'm not picking a winner overall. I'm picking one per medium. ChatGPT makes the still, Grok makes it move. That's the actual workflow now — not one model to rule them all, just the right one for the thing in front of you.&lt;/p&gt;

&lt;p&gt;The coach got his banner. Two of them, really, plus a video. Cost me a handful of prompts and one careful read-through.&lt;/p&gt;

&lt;p&gt;Last time the lesson was that taste decided a coding job. Turns out taste decides a graphics job too. It just lives in different tools.&lt;/p&gt;

&lt;p&gt;Which one are you reaching for when the job is graphics and not code? And has your favourite coding agent ever quietly tried to turn a design task back into a dev task on you? Curious to hear it.&lt;/p&gt;

&lt;h1&gt;
  
  
  AI #DesignTools #BuildInPublic #GenAI #Startup
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>designtools</category>
      <category>genai</category>
      <category>startup</category>
    </item>
    <item>
      <title>Open Banking vs Card Rails: Latency, Cost, and Developer Experience</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Wed, 10 Jun 2026 08:08:10 +0000</pubDate>
      <link>https://dev.to/mickyarun/open-banking-vs-card-rails-latency-cost-and-developer-experience-2knh</link>
      <guid>https://dev.to/mickyarun/open-banking-vs-card-rails-latency-cost-and-developer-experience-2knh</guid>
      <description>&lt;p&gt;I've integrated both. Cards and open banking. In production. Moving real money for real UK merchants.&lt;/p&gt;

&lt;p&gt;So when developers ask me "which is actually better to build on?" I don't give them the marketing answer. I give them the three numbers that decide it: how much it costs, how fast the money moves, and how much of your life you lose to the integration.&lt;/p&gt;

&lt;p&gt;Let me walk through all three. Honestly. Including where cards still win.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Cost — and why it's not close
&lt;/h2&gt;

&lt;p&gt;Here's the part nobody at the card networks wants in a headline.&lt;/p&gt;

&lt;p&gt;A UK card payment costs you somewhere between &lt;strong&gt;1.5% and 3%+&lt;/strong&gt; per transaction once you stack interchange, scheme fees, and your processor's margin. The "0.2% debit interchange cap" everyone quotes is the floor of the floor — it's not what lands on your statement.&lt;/p&gt;

&lt;p&gt;An open banking payment costs roughly &lt;strong&gt;0.1%–1.0%, or a flat 20p–50p&lt;/strong&gt;. No interchange. No scheme fee. Because there's no scheme. The customer authorises the payment inside their own banking app and the bank moves the money directly.&lt;/p&gt;

&lt;p&gt;The concrete version: a local garage takes £500 for a repair. A 1.5% card fee costs them £7.50. The same payment over open banking can cost around 10p. (&lt;a href="https://noda.live/articles/open-banking-costs-uk" rel="noopener noreferrer"&gt;Noda&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;That's not a rounding difference. That's the difference between a payments line item you tolerate and one you forget exists.&lt;/p&gt;

&lt;p&gt;And there's a second-order cost cards carry that nobody puts in the pricing table: &lt;strong&gt;chargebacks&lt;/strong&gt;. £20 a pop, plus the engineering time to fight them, plus the fraud surface you have to defend. Open banking payments are bank-authenticated at source. There's no card number to steal and no "I didn't authorise this" dispute when the customer tapped approve in their own banking app. The fraud surface is smaller, so the price &lt;em&gt;can&lt;/em&gt; be lower. The two facts are connected.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Latency — settlement, not the spinner
&lt;/h2&gt;

&lt;p&gt;This is where developers get the comparison wrong, so let me split it cleanly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authorisation latency&lt;/strong&gt; — the spinner the user stares at — is comparable. Both flows take a few seconds. A card auth round-trips the network; an open banking payment redirects the user to their bank's SCA and back. From the user's chair, both feel like "tap, wait, done."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Settlement latency&lt;/strong&gt; is where they diverge violently.&lt;/p&gt;

&lt;p&gt;A card payment authorises instantly but &lt;em&gt;settles&lt;/em&gt; in ~2 business days. The money is promised, then it sits in limbo, then it arrives — minus fees, and reversible for months.&lt;/p&gt;

&lt;p&gt;An open banking payment runs over &lt;strong&gt;Faster Payments&lt;/strong&gt;. Settlement is near-instant — seconds to minutes — straight bank-to-bank, 24/7. There's no two-day float, no "pending payout" dashboard, no reconciling Tuesday's sales against Thursday's deposit. (&lt;a href="https://payop.com/business/the-role-of-open-banking-in-enabling-faster-payments-and-real-time-settlement/" rel="noopener noreferrer"&gt;Payop&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;If you've ever written reconciliation code, you already feel why this matters. Half the complexity in payments tooling exists to model the gap between "authorised" and "settled." Close that gap to near-zero and a whole category of state machine — pending, settling, settled, partially-reversed — collapses into one event: paid.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Developer experience — where I'll be honest both ways
&lt;/h2&gt;

&lt;p&gt;Let me give cards their due first.&lt;/p&gt;

&lt;p&gt;Card SDKs are mature. Stripe's docs are art. The card flow is a solved, copy-paste problem with twenty years of Stack Overflow behind it. If you're doing global, card-first commerce, that maturity is worth real money. I'd still reach for cards there.&lt;/p&gt;

&lt;p&gt;Open banking is younger, and the early ecosystem was genuinely painful — you were integrating against dozens of bank APIs, each with its own quirks, its own auth dance, its own downtime. That's the part that earned open banking its "hard to build on" reputation a few years ago.&lt;/p&gt;

&lt;p&gt;But that reputation is now outdated, and here's why: the bank-by-bank mess is exactly what a good PISP abstracts away. You don't integrate 40 banks. You integrate &lt;strong&gt;one API&lt;/strong&gt; that speaks Payment Initiation, handles SCA, manages the consent lifecycle, and fans out to Faster Payments for you.&lt;/p&gt;

&lt;p&gt;In practice, the flow is short:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Create a payment — you describe intent, not card mechanics&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;atoa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="c1"&gt;// £49.99 in minor units&lt;/span&gt;
  &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GBP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;order_10472&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;redirectUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://yourapp.com/return&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Send the customer to their bank to authorise (SCA happens here)&lt;/span&gt;
&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorisationUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 3. The bank moves the money over Faster Payments.&lt;/span&gt;
&lt;span class="c1"&gt;//    You get told when it's actually settled — not "authorised, check back Thursday."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Webhook: the event you actually care about is real, not a promise&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/webhooks/atoa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;              &lt;span class="c1"&gt;// verify signature&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payment.completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fulfilOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// money is already in the bank&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice what's &lt;em&gt;missing&lt;/em&gt; from that code. No card object. No PCI scope to inherit. No tokenisation vault to secure. No &lt;code&gt;requires_capture&lt;/code&gt; → &lt;code&gt;capture&lt;/code&gt; two-step. No chargeback webhook to handle. You describe a payment, the customer approves it in their bank, the money arrives, you fulfil. The thing you're modelling is the thing that actually happens.&lt;/p&gt;

&lt;p&gt;That's the DX argument in one sentence: &lt;strong&gt;open banking lets you write code that matches reality instead of code that models a 1970s settlement delay.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest scorecard
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Card rails&lt;/th&gt;
&lt;th&gt;Open banking&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cost per txn&lt;/td&gt;
&lt;td&gt;1.5%–3%+&lt;/td&gt;
&lt;td&gt;0.1%–1% / 20p–50p&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Settlement&lt;/td&gt;
&lt;td&gt;~2 business days&lt;/td&gt;
&lt;td&gt;Near-instant (Faster Payments)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chargebacks&lt;/td&gt;
&lt;td&gt;Yes, £20+ each&lt;/td&gt;
&lt;td&gt;Structurally absent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PCI scope&lt;/td&gt;
&lt;td&gt;Yours to carry&lt;/td&gt;
&lt;td&gt;Not your problem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDK maturity&lt;/td&gt;
&lt;td&gt;Excellent, 20 yrs&lt;/td&gt;
&lt;td&gt;Younger, but abstracted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Global, card-first&lt;/td&gt;
&lt;td&gt;UK consumers, instant settlement&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cards aren't dead. If your customers are international and card-native, build on cards. I mean that.&lt;/p&gt;

&lt;p&gt;But if you're a UK SaaS, marketplace, or merchant tool charging UK consumers — you're paying card prices and eating card latency for an experience your users don't need. The numbers back the switch, and they're moving in one direction: UK open banking payments are up &lt;strong&gt;53% year on year&lt;/strong&gt;, with nearly 1 in 3 adults already using it. (&lt;a href="https://www.openbanking.org.uk/news/open-banking-surges-to-15-million-uk-users-as-july-marks-record-adoption/" rel="noopener noreferrer"&gt;Open Banking Ltd&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;The fastest way to feel the difference is to build it. Atoa's sandbox gives you a real Payment Initiation API, real Faster Payments settlement, and webhooks that fire when money actually moves — not when it's promised. &lt;a href="https://docs.atoa.me" rel="noopener noreferrer"&gt;docs.atoa.me&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spin up a test payment. Watch it settle in seconds instead of days. Then look at what you'd have paid in card fees for the same transaction.&lt;/p&gt;

&lt;p&gt;That second number is the one that changes your mind.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you shipped both card and open banking flows in production? I want to hear where the DX actually broke down for you — the messy bits, not the brochure version.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  OpenBanking #Payments #Fintech #API #BuildInPublic
&lt;/h1&gt;

</description>
      <category>openbanking</category>
      <category>payments</category>
      <category>fintech</category>
      <category>api</category>
    </item>
    <item>
      <title>I Replaced Scrum, Jira, and Our Wiki With 12 AI Agents on a Mac Mini</title>
      <dc:creator>arun rajkumar</dc:creator>
      <pubDate>Mon, 08 Jun 2026 16:33:49 +0000</pubDate>
      <link>https://dev.to/mickyarun/i-replaced-scrum-jira-and-our-wiki-with-12-ai-agents-on-a-mac-mini-o7o</link>
      <guid>https://dev.to/mickyarun/i-replaced-scrum-jira-and-our-wiki-with-12-ai-agents-on-a-mac-mini-o7o</guid>
      <description>&lt;p&gt;A survey last week put it at 54%. More than half the code shipped today is AI-generated.&lt;/p&gt;

&lt;p&gt;In my own work the number is probably higher. AI writes the first draft. AI estimates the work. AI generates the tests. I've written before about &lt;a href="https://bodhiorchard.ai/" rel="noopener noreferrer"&gt;the dangerous 20%&lt;/a&gt; — the edge cases, the illegal state transitions, the judgment AI quietly skips. That 20% is why I still need senior engineers.&lt;/p&gt;

&lt;p&gt;But there's a second 20% problem nobody talks about. Not in the code. Around it.&lt;/p&gt;

&lt;p&gt;Sprints. Story points. Standups. Jira boards no one updates. Confluence pages that went stale the day they were written. Every one of those tools assumes a human does the work and another human tracks the work.&lt;/p&gt;

&lt;p&gt;That's not my team anymore.&lt;/p&gt;

&lt;p&gt;So I stopped bending fifteen-year-old process around an AI-native team. I built my own way of working and open-sourced it. It runs on a Mac mini in the corner of my room. This is what's inside.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvi1z23hgj1eqg5uuabxo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvi1z23hgj1eqg5uuabxo.jpg" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your whole org as a grove. Each repo is a tree, each feature a branch, each teammate present in the world. More on this below — but yes, that's the actual dashboard.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The thing that finally broke me: the wiki
&lt;/h2&gt;

&lt;p&gt;Here's the moment it clicked.&lt;/p&gt;

&lt;p&gt;A new feature needed context. I opened our wiki. The page was six months old. It described an architecture we'd refactored twice since. The "source of truth" was confidently, completely wrong — and three engineers had made decisions based on it that week.&lt;/p&gt;

&lt;p&gt;Documentation lies the moment you stop maintaining it. And nobody maintains it, because maintaining it is the busywork we all silently agree to skip.&lt;/p&gt;

&lt;p&gt;Source code doesn't lie. It can't. It's the thing that actually runs.&lt;/p&gt;

&lt;p&gt;So the first rule of the system I built: &lt;strong&gt;the code is the wiki.&lt;/strong&gt; Knowledge is extracted from the repository — the call graph, the module boundaries, the patterns, the history — and indexed continuously. When an agent or a human asks "how does settlement work?", the answer is reconstructed from what's true &lt;em&gt;right now&lt;/em&gt;, not from a page someone wrote last quarter and abandoned.&lt;/p&gt;

&lt;p&gt;No Confluence. No Notion graveyard. The only document that's allowed to be authoritative is the one that compiles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprdkldeibebkbp5iwzjw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprdkldeibebkbp5iwzjw.jpg" alt=" " width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Nobody wrote this wiki. A baseline scan read the repositories and produced it — 19 live features across 4 repos, each one traceable to the code that backs it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And you don't even open the dashboard to read it. Ask in Slack, in plain English — "are we progressing on the P3 backlog item? what's the go-live date?" — and a bot answers from the live BUD: status, assignee, target date, a link back to the source. Not a number someone typed into a board last Tuesday. The thing that's actually true, right now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Finmclkcrllcudohyp0be.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Finmclkcrllcudohyp0be.jpg" alt=" " width="800" height="1031"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The same emoji-react, thread-reply Slack you already live in — except the answers come from the source of truth, not from memory.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So "the code is the wiki" isn't a slogan — it's an architecture. Knowledge lives in four layers that stay in sync on their own:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The repos themselves&lt;/strong&gt; — source code plus a per-repo &lt;code&gt;CLAUDE.md&lt;/code&gt;, synced on every PR merge to main.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent skills&lt;/strong&gt; — org standards, design guidelines, API patterns; synced on change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The central store&lt;/strong&gt; — BUDs, enterprise rules, architecture decisions; real-time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vector search&lt;/strong&gt; — semantic search across all of it, auto-indexed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Two things make this more than a fancy &lt;code&gt;grep&lt;/code&gt;. It indexes &lt;strong&gt;code locations&lt;/strong&gt;, so any knowledge captured during development points back to the exact file and symbol it came from — and it links &lt;strong&gt;across repos&lt;/strong&gt;, so a frontend call is connected to the backend handler it actually hits, not left as two disconnected facts in two different wikis. And it never goes stale: after every PR merge, the affected feature is updated with the new commit history and the new code locations automatically, so the next agent that touches it inherits the &lt;em&gt;current&lt;/em&gt; truth, not last month's.&lt;/p&gt;

&lt;p&gt;That's the whole pitch against Confluence — auto-synced from source instead of hand-maintained, semantically searchable instead of keyword-matched, always current with daily staleness detection, and wired straight into the agents' prompts so they're never reasoning from a stale page.&lt;/p&gt;




&lt;h2&gt;
  
  
  Agent-Driven Development, in one table
&lt;/h2&gt;

&lt;p&gt;I call the methodology Agent-Driven Development (ADD). The simplest way to explain it is to put it next to the thing it replaces.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agile ceremony&lt;/th&gt;
&lt;th&gt;What it assumed&lt;/th&gt;
&lt;th&gt;Agent-Driven Development&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sprint planning&lt;/td&gt;
&lt;td&gt;Humans do all the work, so plan their hours&lt;/td&gt;
&lt;td&gt;Agents draft; humans decide what's worth building&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Story points / planning poker&lt;/td&gt;
&lt;td&gt;Gut-feel proxy for time&lt;/td&gt;
&lt;td&gt;AI-PERT + Monte Carlo → real P50/P70/P85 &lt;strong&gt;dates&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jira tickets&lt;/td&gt;
&lt;td&gt;Work scattered across a board&lt;/td&gt;
&lt;td&gt;One &lt;strong&gt;BUD&lt;/strong&gt; per feature: spec + tech plan + tests + history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confluence / wiki&lt;/td&gt;
&lt;td&gt;Someone keeps docs current (nobody does)&lt;/td&gt;
&lt;td&gt;Knowledge syncs from the source code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daily standup&lt;/td&gt;
&lt;td&gt;Humans report status out loud&lt;/td&gt;
&lt;td&gt;A Status Agent reads the PRs and tells you what moved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retrospective&lt;/td&gt;
&lt;td&gt;A meeting you forget by Friday&lt;/td&gt;
&lt;td&gt;A Learning Agent mines the actual diffs and incidents&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pattern underneath all six rows is the same: &lt;strong&gt;let the machines handle the noise, so humans spend their judgment where judgment actually matters.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The 12 agents
&lt;/h2&gt;

&lt;p&gt;Here's the whole cycle on one diagram before I break it down — twelve agents around a loop, with a human reviewing at the centre and at every gate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frshmr16yk8wnd5wm50gm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frshmr16yk8wnd5wm50gm.jpg" alt=" " width="800" height="614"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Chat Intake (Triage) → BUD → Design → Tech Architecture (Tech Lead reviews; Smart Assignment picks the dev) → Development (AI + Human) → Test Generation → Testing (QA) → UAT &amp;amp; Deploy (Status) → Feature → Learning &amp;amp; Skills. An external bug reopens the feature. The loop never pretends it's a straight line.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;ADD runs a feature from a chat message to production through a chain of specialised agents. Each owns one phase. A human reviews and decides at every gate — this is human-in-the-loop by design, not lights-out automation.&lt;/p&gt;

&lt;p&gt;It starts in Slack. You drop a request; the &lt;strong&gt;Intake agent&lt;/strong&gt; doesn't just file it — it checks for existing features and BUDs so you don't build a duplicate, then asks the questions a good PM would: who is this for, why now, what's the timeline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3tweovntidxq7zzu2wf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3tweovntidxq7zzu2wf.jpg" alt=" " width="800" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Change the notification icon to modern design?" → the agent checks for duplicates, then interrogates the intent before a single line is written.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From there, every feature moves through the same seven-phase lifecycle, each phase a tab on its BUD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Slack idea → Intake → Requirements → Design → Tech Spec
   → Development → Code Review → Testing → Prod
        ↑ estimation, status, learning and skills run alongside ↑
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pb4wyc64lt9ch3isj1n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pb4wyc64lt9ch3isj1n.jpg" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Every phase can run on an agent — or you flip it off and drive it yourself from your local AI via MCP. "Stage agents are off, you're driving this BUD" is a real toggle, per phase, per assignee. That's what human-in-the-loop actually looks like.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Around that spine sit the agents that kill the ceremonies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Estimation&lt;/strong&gt; — AI-PERT + Monte Carlo instead of story points (below).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status&lt;/strong&gt; — reads the PRs so you never run another standup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning&lt;/strong&gt; — mines the real diffs and incidents when a BUD closes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skills&lt;/strong&gt; — profiles who's strong at what from git history, and feeds it back into estimation and routing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agents do the busywork. You do the deciding. That division is the whole philosophy.&lt;/p&gt;




&lt;h2&gt;
  
  
  The standup reads the work, not the people
&lt;/h2&gt;

&lt;p&gt;I haven't run a status standup in months. The Standup Agent does it at 08:30 on a cron — but the interesting part is &lt;em&gt;where it reads from&lt;/em&gt;. It doesn't ask anyone "what did you do yesterday." It reads what actually happened.&lt;/p&gt;

&lt;p&gt;Hooks and an MCP server in each dev's local setup post the real signal back to the BUD: the prompts, the commits, the sessions. A TODO gets auto-claimed when work starts on it and auto-marked done when the agent finishes the code — so the board reflects reality without anyone updating it. The agent then aggregates the git, PR, bug and chat activity into a summary with risk flags on anything lagging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyb8wuyjxldlffnofdi85.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyb8wuyjxldlffnofdi85.jpg" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjfqenbi7dao1rdvuxo2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjfqenbi7dao1rdvuxo2.jpg" alt=" " width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Four file-level TODOs, all ticked by the work itself. PR #50 merged, 4 commits, 2 files, 5 sessions, 0 errors — captured from hooks, not typed into a board. The status is a side effect of building, not a separate chore.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And because the Design Agent generates wireframes from your project's &lt;strong&gt;design system extracted out of the code&lt;/strong&gt; — the real CSS tokens, not a guess — what it produces is on-brand by construction. Same with the tech spec: it's written against your actual architecture and tokens, so "follows the brand guidelines" stops being a review comment and becomes the default.&lt;/p&gt;




&lt;h2&gt;
  
  
  The quality loop that reassigns itself
&lt;/h2&gt;

&lt;p&gt;This is the part I'm proudest of, because it's where most teams quietly accumulate debt.&lt;/p&gt;

&lt;p&gt;The Test Plan Agent auto-generates the test plan from the BUD's acceptance criteria and the code — Playwright e2e, unit and integration, security, and the &lt;strong&gt;manual&lt;/strong&gt; UAT cases a human still has to sign off. An MCP token wires your QA automation repo in, so test commits flow straight back to the BUD.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85p31iol8hr6j0dzvw6u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85p31iol8hr6j0dzvw6u.jpg" alt=" " width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dgrs9v452zspng225w7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dgrs9v452zspng225w7.jpg" alt=" " width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;24 test cases for one small feature — and notice the manual ones marked "neither can ship as silent regressions, require human sign-off." The agent writes the tests; it doesn't get to wave them through.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Code review is auto-triggered against your org's rules and submitted back on the PR. And here's the loop that closes itself: testing has a &lt;strong&gt;bug threshold&lt;/strong&gt; — complexity × a configurable multiplier. Cross it, and the work auto-reassigns. The original developer moves to bug review, QA rotates to the next waiting BUD, and each bug is auto-classified as a &lt;em&gt;missed feature&lt;/em&gt; versus a &lt;em&gt;development bug&lt;/em&gt; so it takes the right fix path. Quality debt doesn't pile up quietly, because the system reacts to it before a human notices.&lt;/p&gt;




&lt;h2&gt;
  
  
  The BUD: one document instead of three tools
&lt;/h2&gt;

&lt;p&gt;Every feature lives in a single markdown document called a &lt;strong&gt;BUD&lt;/strong&gt; — Business Understanding Document. Spec, technical spec, test plan, and decision history, all in one place, vector-indexed so any agent can pull it as context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# BUD-241 · Idempotent webhook handler for refunds&lt;/span&gt;

&lt;span class="gu"&gt;## Intent&lt;/span&gt;
Bank sends the same refund webhook up to 3x. We must process once.

&lt;span class="gu"&gt;## Acceptance criteria&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Duplicate webhook IDs are a no-op (return 200, no state change)
&lt;span class="p"&gt;-&lt;/span&gt; A refund on an already-refunded txn is rejected, not retried
&lt;span class="p"&gt;-&lt;/span&gt; Illegal transition complete → pending is impossible

&lt;span class="gu"&gt;## Tech plan&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Dedup key: (provider, webhook_id) unique in Postgres
&lt;span class="p"&gt;-&lt;/span&gt; Reuse shared &lt;span class="sb"&gt;`refundGuard`&lt;/span&gt; util — do NOT reinvent

&lt;span class="gu"&gt;## History&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; 2026-06-05 design approved (human gate)
&lt;span class="p"&gt;-&lt;/span&gt; 2026-06-05 estimation: P70 = 2 days
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the whole feature. No ticket in Jira, no spec in Confluence, no test plan in a Google Doc that nobody opens. One file. It travels with the code, and it's the context every agent reads before it touches anything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Killing story points with statistics
&lt;/h2&gt;

&lt;p&gt;Story points always bothered me. They're a proxy for time that we then pretend isn't a proxy for time, and they don't compose across a team where one person knows a module cold and another has never opened it.&lt;/p&gt;

&lt;p&gt;ADD replaces them with AI-PERT plus a Monte Carlo simulation.&lt;/p&gt;

&lt;p&gt;For each phase the model generates optimistic / likely / pessimistic estimates — classic PERT — but weighted by a per-developer, per-module &lt;strong&gt;skill score&lt;/strong&gt; (0–1.0, derived from git and BUD history), current load, and backlog depth. Then 10,000 simulated runs turn that distribution into dates with confidence intervals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;&lt;span class="kd"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Idempotent refund webhooks
  P50  →  Jun 9   (50% chance done by)
  P70  →  Jun 10  (70% chance done by)
  P85  →  Jun 12  (85% chance done by)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"85% confident by the 12th" is the shape a stakeholder actually wants. It's also honest in a way "8 points" never was — it shows you the uncertainty instead of hiding it inside a fake integer.&lt;/p&gt;

&lt;p&gt;Where do those skill scores come from? Git history. The system reads who has actually shipped what, per module, and builds a profile — expertise you can see instead of guess at.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfztbj1g43qsv4iz0b9u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfztbj1g43qsv4iz0b9u.jpg" alt=" " width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Five developers, eighteen modules, scored from real commits. This is what feeds estimation and routing — not a manager's hunch about who "knows the auth code."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Is the skill-score input perfect? No. It's derived from who happened to touch what, so it can encode bias. That's one of the two things I most want feedback on.&lt;/p&gt;

&lt;p&gt;And the loop closes itself. When a BUD ships, the &lt;strong&gt;Learning Agent&lt;/strong&gt; writes the retrospective from the actual diffs — including an estimated-vs-actual table that tells you exactly where the model was wrong, so the next estimate is better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3oksjjoeczf99vxesju.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3oksjjoeczf99vxesju.jpg" alt=" " width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;No retro meeting. The agent reads the merges and the timeline and hands you the drift — Design −25%, Development +603% — so estimation actually learns.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The part that sounds whimsical and isn't: the virtual world
&lt;/h2&gt;

&lt;p&gt;The whole organisation renders as a living 3D world — and it's &lt;strong&gt;multiplayer&lt;/strong&gt;. Not a dashboard you look at. A place your team is actually &lt;em&gt;in&lt;/em&gt;, together.&lt;/p&gt;

&lt;p&gt;Each repository is a tree. Each feature is a branch. Each agent is an orchardist tending the grove. A feature in progress is a branch growing; a merged one bears fruit; a stalled one needs pruning. Health is visible at a glance: a thriving tree versus one quietly dying.&lt;/p&gt;

&lt;p&gt;And every teammate is there with you. You walk around with WASD, sprint, jump, orbit the camera over the grove. Your colleagues are avatars with their own houses, present in real time. You can wave, cheer, greet, invite someone over. It sounds like a game because part of it is one — but the effect is presence. A standup is people reading status out loud. This is people standing in the same place, looking at the same living map of the work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4go4l7gvz2ef3ykkqrht.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4go4l7gvz2ef3ykkqrht.jpg" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your team, present. Move, sprint, wave, cheer, invite. The status bar is real controls, not decoration.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It started as a visualisation. It became the most honest org chart I've ever had — because it's drawn from the code, not from a slide. &lt;a href="https://youtu.be/OxoqBI7BNxU" rel="noopener noreferrer"&gt;Here's a walkthrough.&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Shipping quality is the game
&lt;/h2&gt;

&lt;p&gt;Here's the part I didn't expect to care about and now love.&lt;/p&gt;

&lt;p&gt;The world is gamified — but it rewards the &lt;em&gt;right&lt;/em&gt; thing. You earn XP and Skill Points, level up, unlock vehicles, upgrade your house. Crucially, the economy is tuned to quality, not output. Ship a BUD to production: &lt;strong&gt;+1 SP&lt;/strong&gt;. Give a code review: &lt;strong&gt;+0.25&lt;/strong&gt;. Quality score above 80%: &lt;strong&gt;+0.5&lt;/strong&gt;. Bug found in testing: &lt;strong&gt;−0.25&lt;/strong&gt;. Bug found in &lt;em&gt;production&lt;/em&gt;: &lt;strong&gt;−1&lt;/strong&gt;. And the points for shipping don't pay out until the BUD actually reaches CLOSED — through testing, UAT, prod. You don't get rewarded for the green checkmark. You get rewarded for the thing surviving contact with reality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vgo2bglkoghgy6a0y5m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vgo2bglkoghgy6a0y5m.jpg" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Read the numbers: a production bug costs you more than shipping earns. That's the whole point. In a world where AI can churn out code that passes tests, the scoreboard has to reward what AI is bad at — code that holds up.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That ties straight back to where I started. AI nails the 80%. The 20% — the part that doesn't blow up in production — is what we actually want to incentivise. So that's what the game scores.&lt;/p&gt;




&lt;h2&gt;
  
  
  It runs on a Mac mini, and your data never leaves it
&lt;/h2&gt;

&lt;p&gt;This is the part I care about most, and the part most "AI dev platform" pitches skip.&lt;/p&gt;

&lt;p&gt;Bodhiorchard is &lt;strong&gt;self-hosted by design.&lt;/strong&gt; Postgres with pgvector, your repositories, the embeddings, and the full audit log live on your hardware. For me, that hardware is a Mac mini. No repo content is shipped to anyone's cloud. For a regulated shop — and I lead engineering at an FCA-authorised fintech, so this is not theoretical for me — that's the difference between "interesting demo" and "allowed to exist."&lt;/p&gt;

&lt;p&gt;Inference is your choice. It runs on Claude Code today; Ollama and OpenAI are on the roadmap for fully air-gapped setups. The agent layer is engine-independent — swapping the model is API rewiring, not a redeploy.&lt;/p&gt;

&lt;p&gt;The stack, for the curious:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Backend   FastAPI · Python 3.12
Frontend  Vue 3 · PlayCanvas (the 3D world)
Data      Postgres + pgvector · Redis
Agents    Local MCP server (read + bounded write tools)
License   Apache 2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's also built for real orgs, not just a solo demo: detailed roles and permissions, multi-org support out of the box, and capacity planning baked into triage and assignment — the Triage Agent defers work when the team is full, and Smart Assignment balances by real-time utilisation rather than who shouts loudest. So the "self-hosted toy" worry doesn't really hold; it'll sit inside an org's access model on day one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Honest status, because HN will ask anyway
&lt;/h2&gt;

&lt;p&gt;I'd rather tell you this up front than have you find it.&lt;/p&gt;

&lt;p&gt;What's live today: the platform, the BUD lifecycle, the MCP write-path, repository and code-graph indexing, skill profiling, and the 3D living-tree dashboard. The agents are real and they work with a human in the loop at every gate.&lt;/p&gt;

&lt;p&gt;What I'm still building: the fully autonomous execution loop. The direction I'm taking it is deliberately narrow — auto mode first for &lt;em&gt;small, low-risk BUDs&lt;/em&gt;, where one agent chain runs tech spec → code → code review → test → deploy end to end, then stops and waits for a human to approve the release. Not "point the swarm at production and walk away." Lights-out on the small stuff, a human gate where it counts. That's the active work, not a shipped claim. So today this is &lt;em&gt;agents-assisted, human-in-the-loop&lt;/em&gt;, and anyone who tells you their agent swarm ships production code fully unattended is selling something.&lt;/p&gt;

&lt;p&gt;This is an independent project. I built it solo, on my own time, not affiliated with any employer — the fintech is where I felt the pain, not the thing that owns the code.&lt;/p&gt;




&lt;h2&gt;
  
  
  You don't have to start from zero
&lt;/h2&gt;

&lt;p&gt;If you're on Jira today, you don't throw your backlog away. Connect Jira Cloud and import your existing issues straight into BUDs — point Bodhiorchard at the work you already have and watch the grove fill in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3w0z37pm641e4pxe486.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3w0z37pm641e4pxe486.jpg" alt=" " width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The on-ramp is a migration, not a rewrite. Your tickets become BUDs; the agents take it from there.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There's also a cross-repo graph view — bus-factor analysis, threat detection, BUD-stage filtering across every repo — for when you want the dependency map instead of the grove. Same data, different lens.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I actually want from you
&lt;/h2&gt;

&lt;p&gt;Not stars. Feedback. Two questions I'm genuinely stuck on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Does "the BUD is the single source of truth" survive contact with your reality?&lt;/strong&gt; Or does real-world ticketing always sprawl back across five tools no matter what you do?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where would self-hosted + bring-your-own-inference actually change your mind&lt;/strong&gt; versus a hosted SaaS PM tool — and where is it just more ops burden you don't want?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The full methodology is written up at &lt;strong&gt;&lt;a href="https://bodhiorchard.ai/" rel="noopener noreferrer"&gt;bodhiorchard.ai&lt;/a&gt;&lt;/strong&gt; — the twelve agents, the manifesto, the Agile-vs-ADD table, all of it. The repo has six demo videos and four sample repositories you can point it at: &lt;strong&gt;&lt;a href="https://github.com/mickyarun/bodhiorchard" rel="noopener noreferrer"&gt;https://github.com/mickyarun/bodhiorchard&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I spent fifteen years being told the ceremony &lt;em&gt;was&lt;/em&gt; the engineering. Sprints felt broken long before AI. AI just made it impossible to keep pretending.&lt;/p&gt;

&lt;p&gt;So I replaced them. If you've killed a ceremony and lived to tell the tale — which one did you kill first?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Arun — CTO &amp;amp; Co-Founder of Atoa, a UK open banking payments platform, and the solo author of Bodhiorchard. I write about what building with AI is actually like, not what the conference slides say. Find me on &lt;a href="https://x.com/mickyarun" rel="noopener noreferrer"&gt;X @mickyarun&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
