<?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.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>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>
