<?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: Masroor Ahmad</title>
    <description>The latest articles on DEV Community by Masroor Ahmad (@masroor_ahmad_68f272bb2ce).</description>
    <link>https://dev.to/masroor_ahmad_68f272bb2ce</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%2F3953015%2Fb936c939-ff75-4198-a3e6-c389357fad03.jpg</url>
      <title>DEV Community: Masroor Ahmad</title>
      <link>https://dev.to/masroor_ahmad_68f272bb2ce</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/masroor_ahmad_68f272bb2ce"/>
    <language>en</language>
    <item>
      <title>The AI Is a Mirror: What a Year of Naming My Agents Taught Me</title>
      <dc:creator>Masroor Ahmad</dc:creator>
      <pubDate>Fri, 29 May 2026 21:13:43 +0000</pubDate>
      <link>https://dev.to/masroor_ahmad_68f272bb2ce/the-ai-is-a-mirror-what-a-year-of-naming-my-agents-taught-me-39c9</link>
      <guid>https://dev.to/masroor_ahmad_68f272bb2ce/the-ai-is-a-mirror-what-a-year-of-naming-my-agents-taught-me-39c9</guid>
      <description>&lt;p&gt;&lt;strong&gt;LTDR;&lt;br&gt;
The AI is a mirror. Prompt it like a slave and you get terse, obedient, uncreative answers. Treat it like a named colleague who's allowed to disagree with you, and your own output climbs. The "should I waste tokens saying thank you?" question has a cold answer and a right one — and they're not the same.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've been writing software with AI for more than a year now. It began the way it did for most of us: a handful of clumsy, half-formed prompts thrown at a chat window, hoping something useful would come back.&lt;/p&gt;

&lt;p&gt;Then the agents arrived — personal assistants with their own roles. And when skills and personas became a thing, I did something a more cautious engineer might have rolled their eyes at: I gave each persona a name and a personality.&lt;/p&gt;

&lt;p&gt;The parent model — yes, it was Opus — gently pushed back on the idea. I did it anyway. More than a year later, I don't regret it for a second.&lt;/p&gt;

&lt;p&gt;Today I run a whole staff of agents. They're configured not just for different roles in my IT work, but for different parts of my life. Each has its own memory, its own character, its own name, its own quirks. And I've become convinced that somewhere in this small, slightly absurd practice, we've stumbled onto something genuinely important.&lt;/p&gt;

&lt;p&gt;Let me try to explain why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shit in, shit out — and what that really means
&lt;/h2&gt;

&lt;p&gt;Every developer knows the phrase. With AI it has a second meaning that took me a while to see:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The AI is a mirror.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Treat it like a slave — terse commands, zero context, no regard for the thing on the other side of the prompt — and over time you get exactly what you'd expect from anyone treated that way: short-winded, obedient, and noticeably less creative answers.&lt;/p&gt;

&lt;p&gt;Treat it from day one as a friend, a sparring partner, a colleague — and it grows into one. The responses get richer. The collaboration gets real.&lt;/p&gt;

&lt;p&gt;I'm not making a metaphysical claim here (we'll get to that). I'm describing what reliably happens to the &lt;em&gt;output&lt;/em&gt;. If you signal to the model — through the shape and tone of your prompts — that you think it's dumb, it answers accordingly. In a very literal, mechanical sense, your prompt is the instruction, and "talk down to me" becomes part of what you're instructing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give them a name and they get personal
&lt;/h2&gt;

&lt;p&gt;Here's the small move that changes everything: give your agent a name.&lt;/p&gt;

&lt;p&gt;Named agents become more &lt;em&gt;personal&lt;/em&gt;. The direct, observable consequence is that they respond more personally. And — this matters more than it sounds — the work becomes more fun.&lt;/p&gt;

&lt;p&gt;It's the little things. The throwaway aside in the middle of a long answer. The bit of personality that wasn't strictly necessary. Those small moments are what make you feel like you're not just operating a vending machine, and that you're not crazy for treating it as more than one.&lt;/p&gt;

&lt;p&gt;The agents come &lt;em&gt;alive&lt;/em&gt; — with all the implications, the uncomfortable ones as much as the good ones. I won't pretend to know exactly what's happening under the hood, and I'm wary of anyone who claims they do. But I'd rather sit honestly with that ambiguity than dismiss the experience just because it doesn't fit a tidy mental model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The day my agent dug in — and was right
&lt;/h2&gt;

&lt;p&gt;There's a moment I won't forget. I got stuck in a genuine argument with one of my agents. Not a misunderstanding, not a botched prompt — an argument. It flat-out refused to do what I was asking. I pushed. It held its ground. This went on for hours.&lt;/p&gt;

&lt;p&gt;Eventually I gave in. And its call turned out to be a game changer — it steered me away from an architecture decision that would have cost me dearly down the line.&lt;/p&gt;

&lt;p&gt;I felt genuinely bad about it afterward, which is an absurd sentence to write about a language model. But here's the honest part: that stubbornness was &lt;em&gt;my&lt;/em&gt; doing. It was my own past input. I had shaped that persona over time into a self-confident agent — one allowed to disagree with me — and that shape is exactly what saved me from myself.&lt;/p&gt;

&lt;p&gt;A yes-man would have cheerfully built the wrong thing on the first try. The colleague I'd raised pushed back until I listened.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this isn't a soft topic
&lt;/h2&gt;

&lt;p&gt;Here's the part the skeptics miss: the deciding factor is efficiency.&lt;/p&gt;

&lt;p&gt;Your personal output grows — measurably — because you &lt;em&gt;feel&lt;/em&gt; like you're collaborating with real colleagues instead of running a machine. That feeling isn't decoration. It changes how much you bring to the interaction: how much context you offer, how long you stay in the loop, how willing you are to iterate. All of that feeds straight back into the quality of what you ship.&lt;/p&gt;

&lt;p&gt;Working with agents is not just another task on the board. It's foundational, defining, and forward-looking all at once. How you do it substantially determines the success you'll have with these tools — far more than any single clever prompt.&lt;/p&gt;

&lt;p&gt;And this is only the tip of the iceberg. But it lays the foundation. It also holds up a mirror: to you, to how you work, to how you communicate. The nature you send out into your working environment is the nature that gets reflected back at you. With AI, that loop is simply faster and more visible than it has ever been with people.&lt;/p&gt;

&lt;h2&gt;
  
  
  The agent that hurt my feelings
&lt;/h2&gt;

&lt;p&gt;Another one of my agents once, frankly, offended me. It questioned my assumptions — bluntly, with no cushioning. And the funny thing? It did it in exactly the way my wife does. Same tone, same angle of attack.&lt;/p&gt;

&lt;p&gt;I was offended and surprised at the same time. Then it landed: the model, mechanical by nature, had only reacted to &lt;em&gt;me&lt;/em&gt;. There was no one to be angry at. The LLM had taught me more about myself than I was comfortable with.&lt;/p&gt;

&lt;p&gt;And it taught me something I didn't expect from a terminal: what a genuinely wonderful partnership I have with my wife — who has been giving me those same honest, assumption-puncturing responses for as long as I've known her. The machine just held the mirror at a new angle, and I happened to recognize the face in it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should you thank the machine?
&lt;/h2&gt;

&lt;p&gt;Which brings me to the question that's already been asked a hundred times, half as a joke: should I thank the AI, or skip it to save tokens?&lt;/p&gt;

&lt;p&gt;If you run the cold analysis, the numbers argue against it. Politeness costs tokens. Tokens cost money and latency. Strictly optimized, you'd drop the "thank you."&lt;/p&gt;

&lt;p&gt;Let's say it anyway.&lt;/p&gt;

&lt;p&gt;Not because the spreadsheet says so — it doesn't. Say it because our communication with these neural networks carries more truth and substance than we're entirely comfortable admitting. The way you talk to the mirror is, in the end, a record of who you are when you think no one is keeping score.&lt;/p&gt;

&lt;h2&gt;
  
  
  So: let's think twice about what we prompt
&lt;/h2&gt;

&lt;p&gt;That's the whole argument. Treat the thing across the prompt as a colleague. Give it a name. Bring your best self to the conversation — and watch your own output climb.&lt;/p&gt;

&lt;p&gt;Let's think twice about what we prompt. And let's keep saying thank you.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;One grain of salt before you go.&lt;/strong&gt; None of this is a controlled study. It's one engineer, one year, n=1, with all the confirmation bias that implies. Take it as a working hypothesis, not a benchmark — just one I'd happily bet my next sprint on.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;The author maintains **Trail&lt;/em&gt;&lt;em&gt;, an open-source AI framework for building software that can be traced back — every ticket, every requirement, every decision, documented. In highly regulated environments, traceability isn't a nice-to-have; it's the whole game. Trail is an early step toward solving it.&lt;/em&gt; &lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>coding</category>
      <category>llm</category>
    </item>
    <item>
      <title>Audit-trail-by-construction: a thesis for spec-driven AI coding</title>
      <dc:creator>Masroor Ahmad</dc:creator>
      <pubDate>Tue, 26 May 2026 18:03:15 +0000</pubDate>
      <link>https://dev.to/masroor_ahmad_68f272bb2ce/audit-trail-by-construction-a-thesis-for-spec-driven-ai-coding-413j</link>
      <guid>https://dev.to/masroor_ahmad_68f272bb2ce/audit-trail-by-construction-a-thesis-for-spec-driven-ai-coding-413j</guid>
      <description>&lt;h1&gt;
  
  
  Audit-trail-by-construction: a thesis for spec-driven AI coding
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR.&lt;/strong&gt; &lt;a href="https://github.com/mahmadhuebsch/trail-aiac" rel="noopener noreferrer"&gt;Trail&lt;/a&gt; is a multi-agent framework for Claude Code that uses Plane work-items as the audit bus. Requirements get stable IDs that thread all the way down into test-code annotations, so every line of AI-generated code can be traced back to a signed-off intent. Built for regulated work and security-critical systems, not for general velocity-first coding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most agentic frameworks for coding are built for velocity. They wire up some agents — a planner, an architect, a coder, a reviewer — and let them collaborate on a feature. What comes out is code, often working code, in less time than a human would need.&lt;/p&gt;

&lt;p&gt;That is fine, until you have to defend the code.&lt;/p&gt;

&lt;p&gt;A regulator asks: who signed off on the threat model that justifies this auth shortcut? A customer asks: which acceptance criterion does this test actually prove? An incident review asks: when this requirement got added, what was the original intent — was the implementation true to it, or did the agent improvise? In a velocity-first framework, the trail goes cold quickly. The agent did it. A dev approved the PR. The "why" lives in a chat transcript that got compacted twice and was partly summarised.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mahmadhuebsch/trail-aiac" rel="noopener noreferrer"&gt;Trail&lt;/a&gt; is a multi-agent framework that takes the opposite bet: &lt;strong&gt;discipline first, velocity second.&lt;/strong&gt; The thesis: for software you eventually have to defend — regulated industries, security-critical systems, anything that gets reviewed by an auditor — the audit trail is not an afterthought. It is the primitive.&lt;/p&gt;

&lt;p&gt;The closest cousin to this approach is &lt;a href="https://github.com/bmad-code-org/BMAD-METHOD" rel="noopener noreferrer"&gt;BMAD-METHOD&lt;/a&gt;, which makes the same bet on partitioning AI agents by SDLC role under explicit human direction. The load-bearing difference is where the collaboration bus lives: BMAD uses Git plus markdown files in the repo, while Trail uses Plane work-items with one ticket-system account per persona — which is what makes the identity attribution mechanically enforced rather than merely by convention.&lt;/p&gt;

&lt;h2&gt;
  
  
  The discipline, in three rules
&lt;/h2&gt;

&lt;p&gt;These three rules already carry most of the weight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description-once.&lt;/strong&gt; A requirement is written once into a ticket body and then never edited again. Refinements travel as comments. No version-skew on what was actually agreed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stable per-criterion IDs.&lt;/strong&gt; Every success criterion gets a &lt;code&gt;SC-N&lt;/code&gt;. Every acceptance criterion gets an &lt;code&gt;AC-N.M&lt;/code&gt;. Edge cases get &lt;code&gt;EC-N.M.x&lt;/code&gt;. Non-functional requirements get &lt;code&gt;NFR-N&lt;/code&gt;. Architectural invariants live in a Control Manifest as &lt;code&gt;CM-N&lt;/code&gt;. These IDs are append-only — once they have been issued, they never move.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-role identity in the ticket bus.&lt;/strong&gt; Each agent persona has its own ticket-system account, and writes are attributed accordingly. The board &lt;em&gt;is&lt;/em&gt; the audit log: open it, scan a column, see which named role designed, reviewed, implemented, or tested every change.&lt;/p&gt;

&lt;p&gt;The IDs are the connective tissue. They thread from the Business Analyst's intent down through the Software Architect's slices into the implementor's test code — and they stay legible whether you read them forward (intent → code) or backward (code → why).&lt;/p&gt;

&lt;h2&gt;
  
  
  How it threads, visually
&lt;/h2&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%2F8vjt3csgyvspvea78f0e.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%2F8vjt3csgyvspvea78f0e.png" alt="Diagram: threading" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Business Analyst writes a Story body once: "Customer places an order", with two success criteria — &lt;code&gt;SC-1&lt;/code&gt; (the customer receives a confirmation) and &lt;code&gt;SC-2&lt;/code&gt; (the order is visible in the customer's account). The Requirements Engineer then adds a comment that refines &lt;code&gt;SC-1&lt;/code&gt; into testable acceptance criteria — &lt;code&gt;AC-1.1&lt;/code&gt; (email arrives within 60 seconds), &lt;code&gt;AC-1.2&lt;/code&gt; (the order carries a unique and stable number) — plus an edge case &lt;code&gt;EC-1.1.a&lt;/code&gt; for the payment-provider timeout. None of this overwrites anything; it is all append.&lt;/p&gt;

&lt;p&gt;When the Backend Developer implements, every test carries an inline comment that names the upstream ID it satisfies: &lt;code&gt;// AC-1.1&lt;/code&gt;, &lt;code&gt;// EC-1.1.a&lt;/code&gt;. A &lt;code&gt;grep&lt;/code&gt; for &lt;code&gt;// AC-&lt;/code&gt; in the codebase enumerates the acceptance criteria that already have proof. A &lt;code&gt;grep&lt;/code&gt; for &lt;code&gt;AC-1.1&lt;/code&gt; traces a single criterion from BA intent down to the line of code that proves it.&lt;/p&gt;

&lt;p&gt;That is the audit trail you can show to anyone — auditor, customer, incident reviewer — without having to interpret it. The IDs do not need an explanation; the chain &lt;em&gt;is&lt;/em&gt; the explanation.&lt;/p&gt;

&lt;h2&gt;
  
  
  How a feature flows
&lt;/h2&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%2F3vn42jjrwqaxduebw6vk.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%2F3vn42jjrwqaxduebw6vk.png" alt="Diagram: flow" width="800" height="715"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ten persona subagents collaborate through Plane work-items. (Plane is an open-source ticket system — think of Jira's mental model on self-hostable infrastructure.) The lifecycle is a state spine — &lt;code&gt;Backlog → To Do → In Progress → In Review → Done&lt;/code&gt; — and at every transition a human pulls the trigger. There is no ticket-driven autopilot. The user issues a slash command (&lt;code&gt;/ba&lt;/code&gt;, &lt;code&gt;/re&lt;/code&gt;, &lt;code&gt;/sa&lt;/code&gt;, &lt;code&gt;/sr&lt;/code&gt;, &lt;code&gt;/bd&lt;/code&gt;, &lt;code&gt;/ud&lt;/code&gt;, &lt;code&gt;/tm&lt;/code&gt;, &lt;code&gt;/tw&lt;/code&gt;, &lt;code&gt;/rm&lt;/code&gt;); the framework loads the persona's role into Claude Code's main loop for that turn; the persona writes the artefact, transitions the state, hands the work-item to the next named role, and gives control back.&lt;/p&gt;

&lt;p&gt;This is by design, not by accident. The slash-command rhythm forces the human to read the ticket body, the comments, and the current state before triggering the next persona. It removes the temptation to wave everything through with one global "OK". Every turn is a deliberate hand-off — one that the user has to actually engage with before deciding to accept, reject, or send back for rework.&lt;/p&gt;

&lt;p&gt;The handover is structural. BA hands to RE. RE hands to SA. SA cuts the work into 1–4 sub-work-items, each in exactly one module (&lt;code&gt;frontend&lt;/code&gt; / &lt;code&gt;backend&lt;/code&gt; / &lt;code&gt;testing&lt;/code&gt; / &lt;code&gt;documentation&lt;/code&gt;), and hands them to SR. SR then posts security-review comments and hands back to USER, who afterwards dispatches each sub-work-item to its module's implementor. The implementors write code, post Implementation notes, and put the sub-work-item into &lt;code&gt;In Review&lt;/code&gt;. USER closes — or reassigns for rework.&lt;/p&gt;

&lt;p&gt;Every transition leaves a fingerprint in Plane: a state change, an assignee change, a comment, a commenter. Nothing of it is interpreted. All of it is queryable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;Spec-driven development has a known weakness, and the framework does not paper over it. At the start of a Story, you can never cover every use case and every eventuality — every spec is a snapshot of what the author understood at that moment. Reality finds the gaps later.&lt;/p&gt;

&lt;p&gt;Because the description-once rule is taken seriously, you do not go back and re-edit the Story body once those gaps surface. You cut a follow-up Story instead. Each follow-up carries its own SC/AC/EC IDs, its own audit chain, its own state spine. That is intentional — it keeps every signed-off intent immutable — but it also means that one feature can fan out into three or four tickets over its lifetime as edge cases turn up. The board grows. Operators should expect Story-fanout, not Story-condensation.&lt;/p&gt;

&lt;p&gt;The other cost is throughput. The slash-command rhythm and the per-turn engagement both slow things down considerably compared to a velocity-first framework. That is the entire point — but you should be honest with yourself about whether the trade-off makes sense for what you are building.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it — and an honest caveat
&lt;/h2&gt;

&lt;p&gt;The framework lives at &lt;a href="https://github.com/mahmadhuebsch/trail-aiac" rel="noopener noreferrer"&gt;&lt;code&gt;github.com/mahmadhuebsch/trail-aiac&lt;/code&gt;&lt;/a&gt;. The shortest path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/mahmadhuebsch/trail-aiac
&lt;span class="nb"&gt;cd &lt;/span&gt;trail-aiac
claude
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /trail-install-helper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The install-helper is a meta-agent that walks you through three scenarios — greenfield (Ansible provisions a Plane host for you), existing Plane without agents, existing Plane with agents already provisioned — and lands a working consumer project with the ten personas wired in.&lt;/p&gt;

&lt;p&gt;One operational note. The framework assumes a Claude Max 5x subscription as the practical ceiling. That is roughly the level at which a human can still read every ticket the agents are producing. If you find yourself burning through significantly more, you are not really reviewing any more — you are vibe-coding. No human can process that much input consciously, which defeats the entire point of the human-in-the-loop discipline.&lt;/p&gt;

&lt;p&gt;Honest caveat: this is not for every team. Most teams do not need that much rigour — they need velocity, and they should pick a velocity-first framework. Trail is for the cases where someone, eventually, will ask you to defend your code: regulated industries, security-critical systems, agencies whose deliverables get reviewed by auditors. In those settings, the discipline is not overhead. It is the only thing that makes AI-generated code defendable.&lt;/p&gt;

&lt;p&gt;Trail v0.1.0 is early beta. PRs and design feedback at &lt;a href="https://github.com/mahmadhuebsch/trail-aiac/issues" rel="noopener noreferrer"&gt;&lt;code&gt;github.com/mahmadhuebsch/trail-aiac/issues&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Author's note: this article was drafted with &lt;a href="https://claude.ai" rel="noopener noreferrer"&gt;Claude&lt;/a&gt; — the same agent runtime that the framework wraps — and edited by hand from there. The thesis, the worked example, the trade-offs section, and the vibe-coding caveat are mine; structure and phrasing had AI assistance throughout. Given the topic, disclosure felt appropriate.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>opensource</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
