<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>BMAD on Tiziano Basile | Software Engineer</title><link>https://bstz.it/series/bmad/</link><description>Recent content in BMAD on Tiziano Basile | Software Engineer</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Tiziano Basile</copyright><lastBuildDate>Thu, 06 Aug 2026 09:00:00 +0000</lastBuildDate><atom:link href="https://bstz.it/series/bmad/index.xml" rel="self" type="application/rss+xml"/><item><title>A BMAD workflow, end to end: shipping a feature the spec-driven way</title><link>https://bstz.it/p/a-bmad-workflow-end-to-end-shipping-a-feature-the-spec-driven-way/</link><pubDate>Thu, 06 Aug 2026 09:00:00 +0000</pubDate><guid>https://bstz.it/p/a-bmad-workflow-end-to-end-shipping-a-feature-the-spec-driven-way/</guid><description>&lt;p&gt;If the only way you&amp;rsquo;ve ever worked with an AI is to &lt;em&gt;vibe code&lt;/em&gt; with it, which is to say you open the editor, type a prompt, and keep whatever looks roughly right, then this is the post I wish someone had handed me back when I was doing exactly that. It isn&amp;rsquo;t another argument about why spec-driven development is better, because I already made that case &lt;a class="link" href="https://bstz.it/p/dont-be-mad-bmad-instead/" &gt;here&lt;/a&gt;; it&amp;rsquo;s simply one complete pass through a real workflow, with the actual commands, so that you can see for yourself what the whole thing looks like from the inside.&lt;/p&gt;
&lt;p&gt;Together we&amp;rsquo;ll build one small feature with &lt;a class="link" href="https://github.com/bmad-code-org/BMAD-METHOD" target="_blank" rel="noopener"
&gt;BMAD&lt;/a&gt;, taking it all the way from a vague idea to reviewed code, and although the example is deliberately thin it is also complete, running the full sequence of brainstorm → spec → architecture → story → implementation → review without waving our hands over any of the parts that usually get skipped, so that by the end you can see exactly where the friction lives and what it buys you in return.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve never met the BMAD agents before, the &lt;a class="link" href="https://bstz.it/p/bmad-meet-the-crew/" &gt;previous post&lt;/a&gt; introduces the crew, and while you don&amp;rsquo;t strictly need it in order to follow along here, it does help to know that &amp;ldquo;John&amp;rdquo; is a product manager and &amp;ldquo;Amelia&amp;rdquo; is a developer rather than people I actually work with.&lt;/p&gt;
&lt;p&gt;The example is a URL shortener where links can expire. All the artifacts you&amp;rsquo;ll see below are illustrative snippets from that walkthrough.&lt;/p&gt;
&lt;h2 id="the-feature-and-the-trap"&gt;The feature (and the trap)
&lt;/h2&gt;&lt;p&gt;Here&amp;rsquo;s the feature: &lt;strong&gt;a URL shortener where links can expire.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now watch how a vibe-coding session usually starts, because you&amp;rsquo;d open a chat and type something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Build me a URL shortener in [your stack]. Links should be able to expire.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That prompt &lt;em&gt;feels&lt;/em&gt; complete, but it really isn&amp;rsquo;t, because it&amp;rsquo;s a specification riddled with holes, and the AI is going to quietly fill every one of those holes with a guess that you never actually got to see it make, so it&amp;rsquo;s worth counting them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;When does a link expire?&lt;/strong&gt; After a fixed TTL? At an absolute timestamp you pass in? After N clicks? &amp;ldquo;Expire&amp;rdquo; is three different features.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What happens when someone hits an expired link?&lt;/strong&gt; A &lt;code&gt;404&lt;/code&gt;? A &lt;code&gt;410 Gone&lt;/code&gt;? A redirect to a &amp;ldquo;this link expired&amp;rdquo; page? These are &lt;em&gt;observably different&lt;/em&gt; behaviors, and a caller integrating with you will build against whichever one you pick.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do we count clicks?&lt;/strong&gt; If expiry can be click-based, you need a counter. If it can&amp;rsquo;t, you probably still want analytics. That&amp;rsquo;s a storage decision hiding inside a one-line prompt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What&amp;rsquo;s the ID scheme?&lt;/strong&gt; Random short codes? Collisions? Custom aliases?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vibe coding doesn&amp;rsquo;t make any of these decisions go away, it simply arranges for &lt;em&gt;someone else&lt;/em&gt; to make them silently and invisibly at generation time, and then it hands you back a pile of code that you now have to reverse-engineer in order to discover what was actually decided on your behalf. So when the &amp;ldquo;expired link returns 404&amp;rdquo; bug report lands on your desk three weeks later, you&amp;rsquo;ll find yourself debugging a decision that nobody ever consciously made in the first place.&lt;/p&gt;
&lt;p&gt;Spec-driven development, at its core, is really just this: you &lt;strong&gt;make the decisions before you write the code, on purpose, and in a place where you can actually see them&lt;/strong&gt;, and BMAD is simply one way of running that process with the AI working inside the loop with you rather than against you.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s run it.&lt;/p&gt;
&lt;h2 id="the-mental-model-in-30-seconds"&gt;The mental model, in 30 seconds
&lt;/h2&gt;&lt;p&gt;Two things to hold in your head before we start:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;BMAD is a team of agents rather than a single assistant.&lt;/strong&gt; Each one is a persona with a specific job to do, so there&amp;rsquo;s an analyst who interrogates the idea, a product manager who writes the requirements, an architect who makes the technical calls and a developer who implements them, and you move between these personas deliberately as the work progresses. In the commands that follow, every phase can be run either by summoning the persona directly with &lt;code&gt;/bmad-agent-*&lt;/code&gt; or by invoking its underlying workflow with &lt;code&gt;/bmad-*&lt;/code&gt;, and you should feel free to use whichever of the two you prefer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The real output of the early phases is not code at all, it&amp;rsquo;s artifacts.&lt;/strong&gt; These are things like a brief, a PRD, an architecture document and a story file, all of them plain markdown that lives right there in your repository, and the code itself only arrives &lt;em&gt;last&lt;/em&gt;, sitting downstream of a set of documents that you can read, review and version like anything else.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Broadly speaking there are two stages to all of this, a &lt;strong&gt;planning&lt;/strong&gt; stage in which you work out what to build and how to build it, followed by an &lt;strong&gt;implementation&lt;/strong&gt; stage in which you actually build it, and the whole point of the arrangement is that planning leaves behind durable, reviewable artifacts which then carry all of their context forward into implementation, so that the AI writing your code is working from a genuine spec rather than from a vibe.&lt;/p&gt;
&lt;figure class="mermaid-figure"&gt;
&lt;pre class="mermaid"&gt;flowchart LR
idea([Vague idea]) --&amp;gt; A
subgraph Planning
A[&amp;#34;🔍 Analyst (Mary)&amp;lt;br/&amp;gt;brainstorm&amp;#34;] --&amp;gt; P[&amp;#34;📋 PM (John)&amp;lt;br/&amp;gt;PRD / spec&amp;#34;]
P --&amp;gt; W[&amp;#34;🏛️ Architect (Winston)&amp;lt;br/&amp;gt;architecture&amp;#34;]
W --&amp;gt; S[&amp;#34;📝 Story&amp;lt;br/&amp;gt;context handoff&amp;#34;]
end
subgraph Implementation
S --&amp;gt; D[&amp;#34;💻 Dev (Amelia)&amp;lt;br/&amp;gt;implement&amp;#34;]
D --&amp;gt; R[&amp;#34;🔎 Code review&amp;#34;]
end
R --&amp;gt; code([Reviewed code])
A -.-&amp;gt; brief[/brief.md/]
P -.-&amp;gt; prd[/prd.md/]
W -.-&amp;gt; arch[/architecture.md/]
S -.-&amp;gt; story[/story.md/]&lt;/pre&gt;
&lt;figcaption class="mermaid-caption"&gt;🔍 click the diagram to enlarge&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Everything drawn with a dotted line there is a file that ends up in your repository, and that is precisely the part of the process that vibe coding never produces.&lt;/p&gt;
&lt;h2 id="phase-1-brainstorm-drag-the-hidden-decisions-into-the-light"&gt;Phase 1, Brainstorm: drag the hidden decisions into the light
&lt;/h2&gt;&lt;p&gt;We start with Mary, the analyst, and a brainstorming session:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-agent-analyst # then pick the brainstorming capability
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# or go straight to it:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-brainstorming
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The move here is genuinely counterintuitive if you&amp;rsquo;re accustomed to prompting an AI for output, because &lt;strong&gt;you&amp;rsquo;re not asking it for an answer at all, you&amp;rsquo;re asking it to interrogate you&lt;/strong&gt;, and Mary&amp;rsquo;s entire job in this session is to ask you the questions that you quietly skipped over. This is exactly the moment where those four hidden decisions from the trap section earlier stop being invisible and start being things you have to answer for.&lt;/p&gt;
&lt;p&gt;A brainstorm on &amp;ldquo;URL shortener with expiring links&amp;rdquo; should surface, at minimum: which &lt;em&gt;kinds&lt;/em&gt; of expiry we actually want (TTL vs absolute date vs click-count), the expired-link behavior as a deliberate choice, whether click tracking is a feature or just a mechanism, and the ID/alias scheme.&lt;/p&gt;
&lt;p&gt;The artifact that comes out of this phase is a &lt;strong&gt;brief&lt;/strong&gt;, and this really is the part worth staring at for a moment, because it doesn&amp;rsquo;t merely list the things we intend to build; it also records the things we have deliberately decided &lt;em&gt;not&lt;/em&gt; to build, so that those decisions leave a paper trail behind them instead of quietly evaporating. Here&amp;rsquo;s the heart of an example &lt;code&gt;brief.md&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Decisions (made on purpose, for v1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Expiry model: absolute timestamp.** A link carries an optional &lt;span class="sb"&gt;`expires_at`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (UTC instant). No &lt;span class="sb"&gt;`expires_at`&lt;/span&gt; means the link never expires.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Expiry is inclusive.** At exactly &lt;span class="sb"&gt;`expires_at`&lt;/span&gt;, the link is already expired.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Behavior on an expired link: &lt;span class="sb"&gt;`410 Gone`&lt;/span&gt;,** with body &lt;span class="sb"&gt;`{ &amp;#34;reason&amp;#34;: &amp;#34;expired&amp;#34; }`&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Not a &lt;span class="sb"&gt;`404`&lt;/span&gt;, not a &lt;span class="sb"&gt;`302`&lt;/span&gt; to a landing page.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **ID scheme: 7-character base62 random code,** with collision-retry.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Explicitly out of scope for v1 (deferred, not forgotten)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Relative / TTL expiry (&amp;#34;expire 24h after creation&amp;#34;).
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Click-count expiry, click tracking / analytics.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Custom aliases, custom &amp;#34;this link expired&amp;#34; landing pages.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Take a good look at that &amp;ldquo;out of scope&amp;rdquo; list, because every single line in it is a decision that a vibe-coding prompt would have made &lt;em&gt;for&lt;/em&gt; you, silently and without asking, whereas here every one of them is on the record, deferred deliberately rather than forgotten by accident.&lt;/p&gt;
&lt;p&gt;If you want a more formal artifact than a brainstorm dump:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-product-brief
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Notice what has already happened here, because we haven&amp;rsquo;t yet written a single line of code and we have already caught three or four decisions that vibe coding would otherwise have made for us essentially at random.&lt;/p&gt;
&lt;h2 id="phase-2-prd-turn-decisions-into-requirements-you-can-check"&gt;Phase 2, PRD: turn decisions into requirements you can check
&lt;/h2&gt;&lt;p&gt;Now we switch to John, the product manager, to produce a Product Requirements Document.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-agent-pm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# or the workflow directly:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-prd
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;John&amp;rsquo;s job is to take something like &amp;ldquo;we decided that links expire by absolute timestamp and that expired links return &lt;code&gt;410 Gone&lt;/code&gt;&amp;rdquo; and convert it into requirements that are precise enough that you could hand them to a complete stranger and expect the right thing to come back, and this is the point at which the fuzzy brainstorm finally hardens into something resembling a contract.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example FR-3 from &lt;code&gt;prd.md&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### FR-3: Accessing an expired link
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Given** a short link whose &lt;span class="sb"&gt;`expires_at`&lt;/span&gt; is at or before now
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **When** a client requests &lt;span class="sb"&gt;`GET /{code}`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Then** the service responds &lt;span class="sb"&gt;`410 Gone`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **And** the response body includes a machine-readable &lt;span class="sb"&gt;`reason: &amp;#34;expired&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **And** no redirect (&lt;span class="sb"&gt;`3xx`&lt;/span&gt;) is issued
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Non-goals for v1: custom &amp;#34;expired&amp;#34; landing pages, per-link grace periods.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Read that through and notice what has changed, because the &lt;code&gt;410&lt;/code&gt; decision is now &lt;strong&gt;written down, reviewable and testable&lt;/strong&gt;, which means that a month from now the question &amp;ldquo;why does it return 410?&amp;rdquo; has an actual answer with a paper trail attached to it, and that really is the whole difference between a decision and an accident.&lt;/p&gt;
&lt;p&gt;If you want the requirements distilled into a tighter, machine-oriented contract for the downstream agents, BMAD has a dedicated step:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-spec
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="phase-3-architecture-the-technical-calls-made-once"&gt;Phase 3, Architecture: the technical calls, made once
&lt;/h2&gt;&lt;p&gt;Winston, the architect, takes the &lt;em&gt;what&lt;/em&gt; that we&amp;rsquo;ve established so far and decides the &lt;em&gt;how&lt;/em&gt;, and for a feature this small the right instinct is to keep the whole thing thin, because you really don&amp;rsquo;t need a forty-page architecture document for a URL shortener, you only need the handful of decisions that would be genuinely expensive to get wrong:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-agent-architect
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# or:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-architecture
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The decisions worth pinning down here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Storage:&lt;/strong&gt; how do we persist &lt;code&gt;code → target_url + expires_at&lt;/code&gt;? Key-value store, relational table, in-memory for a toy?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expiry enforcement:&lt;/strong&gt; lazy (check &lt;code&gt;expires_at&lt;/code&gt; on read) or active (a sweeper that deletes expired rows)?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ID generation:&lt;/strong&gt; how we mint short codes and handle collisions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The lazy-versus-active call is the one with real teeth in it, and here is how &lt;code&gt;architecture.md&lt;/code&gt; records that call, capturing both the decision &lt;em&gt;and&lt;/em&gt; its consequence:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### Expiry enforcement: lazy (checked on read)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Chosen: lazy.** Simplest correct behavior; no scheduler, no clock daemon.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Consequence, on purpose:** an expired link&amp;#39;s record still &lt;span class="ge"&gt;_exists_&lt;/span&gt; in the
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; store until something evicts it. &lt;span class="sb"&gt;`resolve`&lt;/span&gt; must therefore never assume
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;present in store&amp;#34; means &amp;#34;live&amp;#34;. It must evaluate expiry every time.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Rejected for v1: active sweeping. Adds a scheduler we don&amp;#39;t need yet.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Writing down the &lt;em&gt;consequence&lt;/em&gt;, namely that &amp;ldquo;present in store&amp;rdquo; does not mean &amp;ldquo;live&amp;rdquo;, is the part that pays off later on, because it&amp;rsquo;s the exact invariant that the implementation is going to have to honor, and it has been stated in plain language before a single line of &lt;code&gt;resolve&lt;/code&gt; even exists. The output of all this is an &lt;code&gt;architecture.md&lt;/code&gt; sitting in your repository, reviewable and versioned, the kind of thing a teammate can simply read instead of having to reverse-engineer it back out of the code.&lt;/p&gt;
&lt;h2 id="phase-4-the-story-packaging-context-for-the-implementer"&gt;Phase 4, The story: packaging context for the implementer
&lt;/h2&gt;&lt;p&gt;This is the phase that vibe coders have quite simply never seen, and it also happens to be the one that makes the whole method actually work.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-create-epics-and-stories # break the PRD into epics + stories
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-create-story # generate the next story with full context
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;A &lt;strong&gt;story&lt;/strong&gt; is a single, self-contained unit of work, but the genuinely important part is &lt;em&gt;what&amp;rsquo;s actually in it&lt;/em&gt;, because a BMAD story file is nothing like a Jira ticket that carries a title and a single sentence of description. It is instead a complete context package, gathering together the relevant requirements, the architectural decisions that happen to apply, the acceptance criteria and pointers to the exact files that are in play, and it is written in such a way that an agent, or for that matter a human, can pick it up completely cold and still have everything they need to get started.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example &lt;code&gt;story-1.3&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Story 1.3 — Return 410 for expired links
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Context
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Implements FR-3 (see prd.md). Expiry is enforced lazily on read, and the
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;boundary instant is inclusive (now &amp;gt;= expires_at ⇒ expired) — both are
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;architecture decisions. &lt;span class="sb"&gt;`now`&lt;/span&gt; is injected into resolve() so expiry stays
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;deterministic in tests.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Acceptance criteria
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;- [ ]&lt;/span&gt; resolve of a link whose expires_at &amp;lt;= now → 410, body {&amp;#34;reason&amp;#34;: &amp;#34;expired&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;- [ ]&lt;/span&gt; no 3xx is produced for an expired link
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;- [ ]&lt;/span&gt; a link with expires_at in the future still redirects 302 (regression guard)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;- [ ]&lt;/span&gt; a link with expires_at is None still redirects 302 (never expires)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;- [ ]&lt;/span&gt; at exactly expires_at, the link is already expired (boundary is inclusive)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;- [ ]&lt;/span&gt; unknown code still returns 404 (unchanged)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Files in play
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; shortener/service.py (add &lt;span class="sb"&gt;`now`&lt;/span&gt; param to resolve; add expiry branch)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; shortener/http_app.py (supply now = datetime.now(timezone.utc))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; tests/test_service.py (expiry + regression cases)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Notice how the criteria carry all of the upstream decisions through verbatim, including the inclusive boundary, the &amp;ldquo;no 3xx&amp;rdquo; rule and the regression guards, so that nothing at all has been left open to interpretation.&lt;/p&gt;
&lt;p&gt;Why does any of this matter so much? It matters because when you hand &lt;em&gt;this&lt;/em&gt; to an implementer there is genuinely nothing left for them to guess at, since the &lt;code&gt;410&lt;/code&gt; is no longer a coin flip but an acceptance criterion with a regression guard sitting right next to it, and the story turns out to be the vehicle that carries every last decision you made back in phases 1 through 3 forward into the code itself.&lt;/p&gt;
&lt;p&gt;With the story now in hand, all of the planning artifacts are finally in place, and before writing any code at all it is worth taking a moment to check that they actually line up with one another:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-check-implementation-readiness
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This validates that your PRD, your architecture and your stories all agree with one another before anyone starts implementing anything, which is really the spec-driven equivalent of the old carpenter&amp;rsquo;s rule to measure twice and cut once.&lt;/p&gt;
&lt;h2 id="phase-5-implementation-now-finally-code"&gt;Phase 5, Implementation: now, finally, code
&lt;/h2&gt;&lt;p&gt;Only now do we finally sit down to write code, and by this point the act of &amp;ldquo;writing the code&amp;rdquo; has become almost mechanical, precisely because every meaningful decision was already made further upstream.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-agent-dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# or run a story end to end:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-dev-story
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Amelia, the developer, works &lt;em&gt;from the story&lt;/em&gt;, implementing against the acceptance criteria one by one, and the real tell that you are no longer vibe coding is that she can check her own work against a written definition of done rather than against her own intuition. Whenever she finds herself uncertain about something, the answer is already sitting in the story, or in the PRD, or in the architecture document, and never in a guess.&lt;/p&gt;
&lt;p&gt;The entire implementation of story 1.3 is this diff to &lt;code&gt;resolve&lt;/code&gt;, and because the story pre-decided everything the change is almost mechanical:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-diff" data-lang="diff"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gd"&gt;-def resolve(store: InMemoryStore, code: str) -&amp;gt; Resolution:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gd"&gt;- &amp;#34;&amp;#34;&amp;#34;Resolve a short code to a redirect or an error (FR-2, FR-4).&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gd"&gt;&lt;/span&gt;&lt;span class="gi"&gt;+def resolve(store: InMemoryStore, code: str, *, now: datetime) -&amp;gt; Resolution:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ &amp;#34;&amp;#34;&amp;#34;Resolve a short code to a redirect or an error (FR-2, FR-3, FR-4).
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ Expiry is evaluated lazily on every read: a record present in the store is
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ not necessarily live. The boundary is inclusive — at exactly ``expires_at``
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ the link is already gone.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ &amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;&lt;/span&gt; link = store.get(code)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if link is None:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return Resolution(status=404, body={&amp;#34;reason&amp;#34;: &amp;#34;not_found&amp;#34;})
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ if link.expires_at is not None and link.expires_at &amp;lt;= now:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;+ return Resolution(status=410, body={&amp;#34;reason&amp;#34;: &amp;#34;expired&amp;#34;})
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gi"&gt;&lt;/span&gt; return Resolution(status=302, location=link.target_url)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;It comes down to two lines of logic, but the part worth looking at is the docstring, because it cites FR-3, the lazy-expiry decision and the inclusive boundary all together, and it can do so only because all three of them came &lt;em&gt;down the pipe&lt;/em&gt; from the artifacts that preceded it. The code, in other words, is not the place where any of those decisions were made, it is simply the place where they were finally applied.&lt;/p&gt;
&lt;p&gt;Contrast this with the ordinary vibe-coding loop, where you prompt the model, eyeball whatever output comes back and then re-prompt it whenever the result is wrong, because here the loop instead becomes implement against the criteria, verify against the criteria and you&amp;rsquo;re done. The AI is of course still doing all of the actual typing, but this time it is typing toward a target that you defined in advance rather than toward some vague sense of &amp;ldquo;looks about right.&amp;rdquo;&lt;/p&gt;
&lt;h2 id="phase-6-review-verify-against-the-spec-not-against-vibes"&gt;Phase 6, Review: verify against the spec, not against vibes
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-code-review
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The review is what closes the loop, and here is the quiet superpower that comes from having done all of the upstream work first, which is that &lt;strong&gt;you can now review against the spec itself&lt;/strong&gt;. A question like &amp;ldquo;does the expired-link path return &lt;code&gt;410&lt;/code&gt; in the way that FR-3 requires?&amp;rdquo; has become a plain yes-or-no question, whereas without a spec to lean on, code review tends to degenerate into &amp;ldquo;looks fine to me&amp;rdquo;, which is really just vibe coding wearing a blazer.&lt;/p&gt;
&lt;p&gt;And this is exactly where the whole approach earned its keep, because the review caught a real defect, and that defect was only catchable in the first place &lt;em&gt;precisely because there was a spec to check the code against&lt;/em&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Finding:&lt;/strong&gt; &lt;code&gt;architecture.md&lt;/code&gt; states an invariant — &amp;ldquo;timestamps are UTC-aware; naive datetimes are a caller error&amp;rdquo; — but nothing enforces it. &lt;code&gt;create_link&lt;/code&gt; happily accepts a naive &lt;code&gt;expires_at&lt;/code&gt;. At resolve time, &lt;code&gt;expires_at &amp;lt;= now&lt;/code&gt; then compares a naive datetime against the adapter&amp;rsquo;s aware &lt;code&gt;now&lt;/code&gt; and raises &lt;code&gt;TypeError: can't compare offset-naive and offset-aware datetimes&lt;/code&gt;. FR-3 promised a &lt;code&gt;410&lt;/code&gt;; the caller gets an unhandled &lt;code&gt;500&lt;/code&gt; instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That single bug is the whole argument for spec-driven development compressed into one example, because a vibe-coded shortener would almost certainly have carried &lt;em&gt;the very same defect&lt;/em&gt;, and yet with no &lt;code&gt;architecture.md&lt;/code&gt; invariant for it to violate, the reviewer would have had nothing to notice it against in the first place. The spec did more than merely document the decision, it turned what would have been a silent 500 into a visible finding, and the fix itself came down to a three-line guard in &lt;code&gt;create_link&lt;/code&gt; that fails fast with a clear error, together with a regression test, and because the invariant had been written down all along, the question &amp;ldquo;is this actually fixed?&amp;rdquo; is once again a simple yes-or-no.&lt;/p&gt;
&lt;h2 id="what-actually-just-happened"&gt;What actually just happened
&lt;/h2&gt;&lt;p&gt;Step back and look at what we&amp;rsquo;ve produced:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;brief.md&lt;/code&gt;: the ideas and the decisions we deferred&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prd.md&lt;/code&gt;: the requirements, testable&lt;/li&gt;
&lt;li&gt;&lt;code&gt;architecture.md&lt;/code&gt;: the technical calls&lt;/li&gt;
&lt;li&gt;&lt;code&gt;story-1.3.md&lt;/code&gt;: the context package that drove the code&lt;/li&gt;
&lt;li&gt;the code itself, plus tests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The code is the &lt;em&gt;smallest&lt;/em&gt; artifact in that entire list, and it is also the very last one we made, and that inversion is really the whole point of the exercise. In vibe coding the code is the first and only artifact you ever produce, so every decision ends up trapped inside it and left undocumented, whereas in spec-driven development the code is instead a &lt;em&gt;consequence&lt;/em&gt; of everything else, with the decisions themselves living in readable documents and the code standing as nothing more than their current implementation.&lt;/p&gt;
&lt;p&gt;This is exactly why the friction turns out to be worth it, and in a real sense the friction &lt;em&gt;is&lt;/em&gt; the value, because every question that Mary asked, every requirement that John pinned down and every call that Winston made are all decisions that would otherwise have been made silently by an autocomplete, at twice the speed and none of the visibility.&lt;/p&gt;
&lt;p&gt;You didn&amp;rsquo;t actually slow down at all, you simply moved the thinking to the front of the process where it happens to be cheap, instead of leaving it for the debugger later on where it is always expensive.&lt;/p&gt;
&lt;h2 id="try-it-on-something-small"&gt;Try it on something small
&lt;/h2&gt;&lt;p&gt;Don&amp;rsquo;t go and start with your production monolith. Pick a feature that is exactly this size, small enough that you can finish it in a single sitting and yet real enough that it still hides a few decisions inside it, and then run the full loop through once from beginning to end:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-brainstorming # surface the decisions
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-prd # write them down
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-architecture # make the technical calls
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-create-story # package the context
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-dev-story # implement against it
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/bmad-code-review # verify against the spec
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The first time you go through it, the whole process will feel like pure overhead, and you should do it anyway, because somewhere around the story phase, at the moment when you hand the implementer a spec and get back exactly what you asked for, it quietly stops feeling like overhead and starts feeling like the thing you had been missing all along.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the moment the lever stops being a slot machine.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Want the backstory on why I stopped vibe coding? Start with &lt;a class="link" href="https://bstz.it/p/dont-be-mad-bmad-instead/" &gt;Don&amp;rsquo;t be mad, BMAD instead&lt;/a&gt;. Want to meet the agents properly? &lt;a class="link" href="https://bstz.it/p/bmad-meet-the-crew/" &gt;Here&amp;rsquo;s the crew&lt;/a&gt;. Want to see the method on a bigger project? &lt;a class="link" href="https://bstz.it/p/bmad-in-action-building-tododoro/" &gt;Building TODOdoro&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>BMAD in action: building TODOdoro</title><link>https://bstz.it/p/bmad-in-action-building-tododoro/</link><pubDate>Thu, 26 Mar 2026 10:00:00 +0000</pubDate><guid>https://bstz.it/p/bmad-in-action-building-tododoro/</guid><description>&lt;p&gt;&lt;strong&gt;This post is part of a series:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a class="link" href="https://bstz.it/p/dont-be-mad-bmad-instead/" &gt;Don&amp;rsquo;t be mad, BMAD instead&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://bstz.it/p/bmad-meet-the-crew/" &gt;BMAD: meet the crew&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;BMAD in action: building TODOdoro (you are here)&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;This is the final post in my series about the BMAD Method. In &lt;a class="link" href="https://bstz.it/p/dont-be-mad-bmad-instead/" &gt;Part 1&lt;/a&gt;, I explained why I was skeptical of AI tools and how BMAD changed my mind. In &lt;a class="link" href="https://bstz.it/p/bmad-meet-the-crew/" &gt;Part 2&lt;/a&gt;, I introduced the agents and how they work together.&lt;/p&gt;
&lt;p&gt;Now I want to show you what BMAD looks like in practice.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/basteez/TODOdoro" target="_blank" rel="noopener"
&gt;TODOdoro&lt;/a&gt; is a productivity app I built using BMAD. It combines todo management with the Pomodoro technique, but (as you&amp;rsquo;ll see) it became something more interesting than that description suggests. The project is open source, still a work in progress, and all the BMAD artifacts are available in the repository if you want to explore them yourself.&lt;/p&gt;
&lt;p&gt;Let me walk you through the journey from initial idea to working code.&lt;/p&gt;
&lt;h2 id="the-starting-point"&gt;The starting point
&lt;/h2&gt;&lt;p&gt;I wanted to build a Pomodoro timer integrated with a todo app. Simple enough, right? Track tasks, run timers, see how many focused sessions each task required.&lt;/p&gt;
&lt;p&gt;That was the prompt I brought to the brainstorming session. It wasn&amp;rsquo;t wrong, but it wasn&amp;rsquo;t interesting either.&lt;/p&gt;
&lt;h2 id="brainstorming-where-the-magic-happened"&gt;Brainstorming: where the magic happened
&lt;/h2&gt;&lt;p&gt;I started with Mary (the Business Analyst) running a brainstorming session (&lt;code&gt;/bmad-agent-analyst&lt;/code&gt;, then selecting the brainstorming capability, or directly with &lt;code&gt;/bmad-brainstorming&lt;/code&gt;). The conversation began with practical questions: What tech stack? What features? How should the UX work?&lt;/p&gt;
&lt;p&gt;But Mary kept pushing deeper. She asked about the philosophy behind the tool. Why does tracking Pomodoros matter? What problem am I actually solving?&lt;/p&gt;
&lt;p&gt;The breakthrough came when the conversation shifted from features to first principles:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;A todo is not a reminder. It is a declaration of personal ownership. A Pomodoro is not a timer. It is a container for presence.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That reframing changed everything. Suddenly I wasn&amp;rsquo;t building a todo app with timers. I was building a mirror that reflects where your attention actually went.&lt;/p&gt;
&lt;p&gt;This is what I meant in Part 1 about agents asking the questions you should be asking yourself. I walked into the session with a feature list. I walked out with a philosophy.&lt;/p&gt;
&lt;h3 id="key-insights-from-brainstorming"&gt;Key insights from brainstorming
&lt;/h3&gt;&lt;p&gt;Several ideas emerged that shaped the entire product:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Session-first model.&lt;/strong&gt; Traditional apps put tasks first and time second. TODOdoro inverts this: the Pomodoro session is the primary entity. Todos are optional labels that sessions can belong to. You focus first, then reflect on what it meant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Two kinds of letting go.&lt;/strong&gt; Most apps have a single &amp;ldquo;complete&amp;rdquo; action. But there&amp;rsquo;s a difference between &amp;ldquo;this served its purpose&amp;rdquo; and &amp;ldquo;this was never truly mine.&amp;rdquo; TODOdoro&amp;rsquo;s Release Ritual makes you choose, because the distinction matters.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spatial priority.&lt;/strong&gt; Instead of priority fields (P1, P2, P3) or due dates, position on a canvas represents importance. Drag something to the center when it matters. No metadata to maintain, just visual intention.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Devotion Record.&lt;/strong&gt; Not a Pomodoro counter, but a timeline showing when and how much presence you invested. &amp;ldquo;11 Pomodoros across 9 days&amp;rdquo; tells a different story than &amp;ldquo;11 Pomodoros.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The session generated 18 feature ideas, 9 architectural decisions, and 25+ edge cases to consider. All from a conversation that started with &amp;ldquo;I want a Pomodoro app.&amp;rdquo;&lt;/p&gt;
&lt;h2 id="from-philosophy-to-product-brief"&gt;From philosophy to product brief
&lt;/h2&gt;&lt;p&gt;After brainstorming, I worked with John (Product Manager) to create a product brief (&lt;code&gt;/bmad-product-brief&lt;/code&gt;). This document captured:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Target users.&lt;/strong&gt; Two personas emerged:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Marco, the &amp;ldquo;tool-fatigued maker&amp;rdquo; who&amp;rsquo;s exhausted by productivity overhead and wants honest visibility without guilt&lt;/li&gt;
&lt;li&gt;Sofia, the &amp;ldquo;invisible worker&amp;rdquo; whose research and writing produces slow, non-linear progress that traditional apps can&amp;rsquo;t acknowledge&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Core vision.&lt;/strong&gt; Your time and attention are acts of devotion, not units of output. The app is a personal mirror, not a task manager.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Design philosophy.&lt;/strong&gt; Radical respect for user autonomy. No streaks, no scores, no notifications. Settings contain only timer durations and theme options. A hard cap of 100 canvas cards prevents infinite accumulation.&lt;/p&gt;
&lt;p&gt;This brief became the foundation everything else built on. When questions arose later (should we add due dates? what about subtasks?), the brief provided clear answers: no, because they violate the philosophy.&lt;/p&gt;
&lt;h2 id="the-prd-philosophy-becomes-spec"&gt;The PRD: philosophy becomes spec
&lt;/h2&gt;&lt;p&gt;Working with John again (&lt;code&gt;/bmad-create-prd&lt;/code&gt;), I translated the product brief into a formal Product Requirements Document. This is where things got concrete.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Problem statement.&lt;/strong&gt; &amp;ldquo;You don&amp;rsquo;t plan to focus. You focus, then reflect on what it meant.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Success metrics.&lt;/strong&gt; Not vanity numbers, but signals of genuine value:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The user returns on Day 8 without notifications (the canvas feels personally owned)&lt;/li&gt;
&lt;li&gt;Canvas contains 10 or fewer curated cards&lt;/li&gt;
&lt;li&gt;Devotion Records span weeks on single intentions&lt;/li&gt;
&lt;li&gt;User describes the app with a personal &amp;ldquo;why,&amp;rdquo; not a feature summary&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Anti-metrics.&lt;/strong&gt; Signs the philosophy isn&amp;rsquo;t landing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Missing a due date field&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Need subtasks&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Session spam under 60 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;User journeys.&lt;/strong&gt; Concrete scenarios showing how Marco and Sofia would experience the product. Not wireframes, but narratives that capture intent.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Functional requirements.&lt;/strong&gt; 31 specific requirements, each traceable to the philosophy. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FR9: Release Ritual asks explicit question distinguishing purpose-completion from ownership rejection&lt;/li&gt;
&lt;li&gt;FR21-23: Devotion Record displays all sessions as a timeline across dates&lt;/li&gt;
&lt;li&gt;FR27-31: All state stored locally, offline-first, with schema versioning&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The PRD also established philosophical guardrails as non-negotiable requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No accounts, login, or server-side user data&lt;/li&gt;
&lt;li&gt;No due dates, priority fields, or subtasks&lt;/li&gt;
&lt;li&gt;No streaks, scores, or gamification&lt;/li&gt;
&lt;li&gt;Canvas hard cap of 100 cards (never configurable)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is what spec-driven development looks like. Every decision is written down, justified, and traceable.&lt;/p&gt;
&lt;h2 id="architecture-winston-weighs-in"&gt;Architecture: Winston weighs in
&lt;/h2&gt;&lt;p&gt;With requirements defined, I brought Winston (the Architect) into the conversation (&lt;code&gt;/bmad-create-architecture&lt;/code&gt;). His job was to translate the PRD into technical decisions.&lt;/p&gt;
&lt;p&gt;Key architectural choices:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Event sourcing.&lt;/strong&gt; Instead of storing current state, store all events that led to that state. This makes the Devotion Record trivial to implement (just replay session events) and enables powerful recovery from corruption.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Local-first with SQLite.&lt;/strong&gt; No accounts, no cloud. Data lives in the browser using SQLite compiled to WebAssembly (via SQLocal). The user owns their data completely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Monorepo with strict boundaries.&lt;/strong&gt; A &lt;code&gt;@tododoro/domain&lt;/code&gt; package contains all business logic with zero external dependencies and 100% test coverage as a CI requirement. The domain is the philosophy encoded in TypeScript.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Repair pipeline.&lt;/strong&gt; If the app crashes mid-session, the repair pipeline detects orphaned events and fixes them automatically. The app always opens coherently regardless of what went wrong.&lt;/p&gt;
&lt;p&gt;Winston&amp;rsquo;s pragmatism showed here. He pushed back on complexity where it wasn&amp;rsquo;t needed, advocated for boring technology choices, and kept asking &amp;ldquo;what actually ships?&amp;rdquo;&lt;/p&gt;
&lt;h2 id="breaking-it-down-epics-and-stories"&gt;Breaking it down: epics and stories
&lt;/h2&gt;&lt;p&gt;Bob (Scrum Master) took the architecture and PRD and broke them into implementable chunks (&lt;code&gt;/bmad-create-epics-and-stories&lt;/code&gt;). Seven epics emerged:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Project Foundation &amp;amp; Domain Core&lt;/strong&gt; - Monorepo structure, event types, aggregates, 100% test coverage gate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Constellation Canvas&lt;/strong&gt; - Spatial todo interface, drag positioning, pan/zoom, keyboard navigation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Pomodoro Session Loop&lt;/strong&gt; - Timer, session durability, resume/auto-complete on crash, exploration sessions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Devotion Record&lt;/strong&gt; - Session history visualization, persistence across renames&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Todo Lifecycle &amp;amp; The Shelf&lt;/strong&gt; - Sealing, release ritual, eulogy for high-investment items, archive&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Production Storage &amp;amp; Data Durability&lt;/strong&gt; - SQLite migration, atomic writes, corruption tolerance, snapshots&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Settings &amp;amp; Personalisation&lt;/strong&gt; - Timer durations, themes, reduced-motion support&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The sequencing mattered. Epic 1 had to complete with 100% domain coverage before any UI work began. This enforced the philosophy: get the core logic right first, then build the interface on a solid foundation.&lt;/p&gt;
&lt;p&gt;Each epic broke down into stories with clear acceptance criteria. Before implementation, Bob prepared the sprint plan (&lt;code&gt;/bmad-sprint-planning&lt;/code&gt;) and created detailed story files (&lt;code&gt;/bmad-create-story&lt;/code&gt;). By the time Amelia (Developer) started coding, she knew exactly what to build.&lt;/p&gt;
&lt;h2 id="implementation-where-specs-pay-off"&gt;Implementation: where specs pay off
&lt;/h2&gt;&lt;p&gt;This is where the earlier work paid dividends. Let me explain how the actual story workflow operates.&lt;/p&gt;
&lt;h3 id="preparing-a-story"&gt;Preparing a story
&lt;/h3&gt;&lt;p&gt;Before implementation begins, you run &lt;code&gt;/bmad-create-story&lt;/code&gt;. This doesn&amp;rsquo;t just copy text from the epics file. It creates a comprehensive story document by:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Loading all your artifacts (PRD, architecture, UX specs, previous stories)&lt;/li&gt;
&lt;li&gt;Extracting everything relevant to this specific story&lt;/li&gt;
&lt;li&gt;Analyzing previous story files for patterns and learnings&lt;/li&gt;
&lt;li&gt;Checking git history for recent changes that might affect implementation&lt;/li&gt;
&lt;li&gt;Researching latest library versions if needed&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The output is a story file that contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;User story statement&lt;/strong&gt; (As a&amp;hellip; I want&amp;hellip; so that&amp;hellip;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Acceptance criteria&lt;/strong&gt; in BDD format (Given/When/Then)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tasks and subtasks&lt;/strong&gt; in exact implementation order&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dev Notes&lt;/strong&gt; with architecture requirements, file locations, testing patterns&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Previous story intelligence&lt;/strong&gt; (what worked, what didn&amp;rsquo;t, code patterns established)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal is to give the developer agent everything it needs without having to search through other documents.&lt;/p&gt;
&lt;h3 id="refining-stories-with-party-mode"&gt;Refining stories with Party Mode
&lt;/h3&gt;&lt;p&gt;Before handing a story to the developer, I run &lt;code&gt;/bmad-party-mode&lt;/code&gt; to refine it. I typically bring in Winston (Architect) and Quinn (QA) to review the story file together.&lt;/p&gt;
&lt;p&gt;They catch things the story creation missed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Winston might notice an architectural constraint that needs explicit mention&lt;/li&gt;
&lt;li&gt;Quinn asks about edge cases that should be acceptance criteria&lt;/li&gt;
&lt;li&gt;Both push back if tasks are too vague or too large&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This refinement step adds maybe 10 minutes per story, but it prevents hours of rework during implementation. The story that reaches Amelia has already survived cross-functional scrutiny.&lt;/p&gt;
&lt;h3 id="working-the-story"&gt;Working the story
&lt;/h3&gt;&lt;p&gt;When you run &lt;code&gt;/bmad-dev-story&lt;/code&gt;, Amelia (the Developer agent) follows a strict process:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Find and load the story.&lt;/strong&gt; She reads the complete story file and identifies the first incomplete task.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mark in-progress.&lt;/strong&gt; The sprint status updates so you know what&amp;rsquo;s being worked on.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Execute tasks in exact order.&lt;/strong&gt; This is critical: the tasks are sequenced deliberately, and she follows them as written. No skipping ahead, no reordering.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Red-green-refactor for each task:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Write failing tests first (red)&lt;/li&gt;
&lt;li&gt;Implement minimal code to make tests pass (green)&lt;/li&gt;
&lt;li&gt;Refactor while keeping tests green&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mark complete only when done.&lt;/strong&gt; A task checkbox only gets checked when tests actually exist and pass. No lying, no &amp;ldquo;I&amp;rsquo;ll add tests later.&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update the story file.&lt;/strong&gt; Each completed task gets logged with what was implemented, what files changed, and any decisions made.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Continue until all tasks are done&lt;/strong&gt; or a blocking issue requires human input.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&amp;rsquo;s what a real task looked like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Task: Session completion and devotion dots&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Acceptance criteria:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When timer reaches zero, emit SessionCompleted event with actual duration&lt;/li&gt;
&lt;li&gt;Update Devotion Record projection with new session&lt;/li&gt;
&lt;li&gt;Display 6px amber dot on the todo card for each recorded Pomodoro&lt;/li&gt;
&lt;li&gt;Session under 60 seconds: abandon silently, no dot&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Amelia read this, wrote tests for each criterion, implemented until tests passed, then marked the task complete. The story file recorded exactly what happened.&lt;/p&gt;
&lt;h3 id="why-this-matters"&gt;Why this matters
&lt;/h3&gt;&lt;p&gt;The strict process prevents the chaos I&amp;rsquo;ve seen in other AI coding workflows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No guessing.&lt;/strong&gt; The story file tells her exactly what to build.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No skipping tests.&lt;/strong&gt; Red-green-refactor is enforced, not suggested.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No mystery implementations.&lt;/strong&gt; The story file documents what was done.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No &amp;ldquo;works on my machine.&amp;rdquo;&lt;/strong&gt; Tests must pass before tasks complete.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When Amelia finished a story, I could review the story file and see exactly what happened. The gap between &amp;ldquo;what I asked for&amp;rdquo; and &amp;ldquo;what I got&amp;rdquo; was minimal because the spec had done its job.&lt;/p&gt;
&lt;h3 id="code-review-after-every-story"&gt;Code review after every story
&lt;/h3&gt;&lt;p&gt;After each story implementation, I run &lt;code&gt;/bmad-code-review&lt;/code&gt;. This isn&amp;rsquo;t optional for me, it&amp;rsquo;s part of the workflow.&lt;/p&gt;
&lt;p&gt;The code review runs multiple analysis passes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Looking for bugs and logic errors&lt;/li&gt;
&lt;li&gt;Checking edge cases that might have been missed&lt;/li&gt;
&lt;li&gt;Verifying the implementation matches the acceptance criteria&lt;/li&gt;
&lt;li&gt;Flagging code quality issues&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the review finds problems, they get added as follow-up tasks in the story file. Amelia addresses them before the story is marked complete.&lt;/p&gt;
&lt;p&gt;One tip from the BMAD documentation: run the code review with a different LLM than the one that implemented the story. Fresh eyes catch more issues.&lt;/p&gt;
&lt;p&gt;The implementation phase moved fast because the thinking had already been done.&lt;/p&gt;
&lt;h2 id="what-surprised-me"&gt;What surprised me
&lt;/h2&gt;&lt;p&gt;A few things I didn&amp;rsquo;t expect:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The brainstorming session was the most valuable part.&lt;/strong&gt; I thought the dev work would be the main event. In hindsight, the conversation that turned &amp;ldquo;Pomodoro app&amp;rdquo; into &amp;ldquo;devotion mirror&amp;rdquo; was where the real value was created. Everything else was execution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Specs prevented scope creep.&lt;/strong&gt; When I had ideas mid-implementation (&amp;ldquo;what if we added&amp;hellip;&amp;rdquo;), the specs gave me a clear answer: does this serve the philosophy? Usually the answer was no, and I moved on instead of getting distracted.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The agents caught blind spots.&lt;/strong&gt; In Party Mode (&lt;code&gt;/bmad-party-mode&lt;/code&gt;), I had Winston and Quinn review the architecture together. Quinn immediately asked about timer accuracy across browser backgrounding (a real problem I hadn&amp;rsquo;t considered). That became a specific requirement before any code was written.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Writing specs is thinking.&lt;/strong&gt; I used to view documentation as overhead. Now I see it as the actual work. The code is just the last step.&lt;/p&gt;
&lt;h2 id="what-didnt-work-perfectly"&gt;What didn&amp;rsquo;t work perfectly
&lt;/h2&gt;&lt;p&gt;BMAD isn&amp;rsquo;t magic. A few rough edges:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The upfront investment feels slow.&lt;/strong&gt; When you&amp;rsquo;re eager to code, spending hours on specs feels like procrastination. You have to trust the process. The payoff comes later, but it does come.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Some agent suggestions needed filtering.&lt;/strong&gt; The agents occasionally proposed features that conflicted with the philosophy I&amp;rsquo;d established. I had to stay vigilant and push back. The human is still the decision-maker.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The artifacts need maintenance.&lt;/strong&gt; When requirements changed mid-project, I had to update multiple documents. The chain of traceability is powerful but requires discipline.&lt;/p&gt;
&lt;h2 id="the-result"&gt;The result
&lt;/h2&gt;&lt;p&gt;TODOdoro exists. It&amp;rsquo;s &lt;a class="link" href="https://github.com/basteez/TODOdoro" target="_blank" rel="noopener"
&gt;open source on GitHub&lt;/a&gt;, still a work in progress, and includes all the BMAD artifacts in the &lt;code&gt;_bmad-output&lt;/code&gt; folder if you want to see exactly what I&amp;rsquo;ve described.&lt;/p&gt;
&lt;p&gt;More importantly, it&amp;rsquo;s something I actually use. The philosophy landed because I took the time to articulate it before writing code.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the BMAD promise: not faster code, but better thinking. The code follows.&lt;/p&gt;
&lt;h2 id="try-it-yourself"&gt;Try it yourself
&lt;/h2&gt;&lt;p&gt;If this series has made you curious, here&amp;rsquo;s how to start:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install BMAD: &lt;code&gt;npx bmad-method install&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Start with &lt;code&gt;/bmad-agent-pm&lt;/code&gt; and describe your idea&lt;/li&gt;
&lt;li&gt;Let John ask you uncomfortable questions&lt;/li&gt;
&lt;li&gt;See where it leads&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You don&amp;rsquo;t need a big project. Try it on something small. A software config. A CLI tool. Something you want to reproduce.&lt;/p&gt;
&lt;p&gt;The process will feel strange at first. You&amp;rsquo;ll want to skip ahead. Don&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;The thinking is the work. The code is just the last step.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.bmad-method.org/" target="_blank" rel="noopener"
&gt;BMAD Method documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/bmad-code-org/BMAD-METHOD" target="_blank" rel="noopener"
&gt;BMAD on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/basteez/TODOdoro" target="_blank" rel="noopener"
&gt;TODOdoro on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://bstz.it/p/dont-be-mad-bmad-instead/" &gt;Part 1: Don&amp;rsquo;t be mad, BMAD instead&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://bstz.it/p/bmad-meet-the-crew/" &gt;Part 2: Meet the crew&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>BMAD: meet the crew</title><link>https://bstz.it/p/bmad-meet-the-crew/</link><pubDate>Thu, 26 Mar 2026 09:00:00 +0000</pubDate><guid>https://bstz.it/p/bmad-meet-the-crew/</guid><description>&lt;p&gt;&lt;strong&gt;This post is part of a series:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a class="link" href="https://bstz.it/p/dont-be-mad-bmad-instead/" &gt;Don&amp;rsquo;t be mad, BMAD instead&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;BMAD: meet the crew (you are here)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://bstz.it/p/bmad-in-action-building-tododoro/" &gt;BMAD in action: building TODOdoro&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;In the &lt;a class="link" href="https://bstz.it/p/dont-be-mad-bmad-instead/" &gt;previous post&lt;/a&gt;, I talked about why I was skeptical of AI coding tools and how BMAD changed my perspective. The short version: it forces you to think before you code, and it keeps you in the driver&amp;rsquo;s seat.&lt;/p&gt;
&lt;p&gt;But I glossed over the most distinctive part of the framework: the agents.&lt;/p&gt;
&lt;p&gt;BMAD isn&amp;rsquo;t one AI assistant. It&amp;rsquo;s a team of specialized personas, each with a distinct role, communication style, and area of expertise. When you work with BMAD, you&amp;rsquo;re not just prompting a generic model. You&amp;rsquo;re having conversations with characters who push back, ask questions, and hold you accountable to their domain.&lt;/p&gt;
&lt;p&gt;It sounds gimmicky. It&amp;rsquo;s not.&lt;/p&gt;
&lt;h2 id="why-personas-matter"&gt;Why personas matter
&lt;/h2&gt;&lt;p&gt;The obvious answer is specialization. A product manager thinks differently than an architect. A QA engineer asks different questions than a UX designer. By splitting these roles into separate agents, BMAD ensures that each phase of development gets the attention it deserves.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s a subtler benefit: context switching becomes intentional.&lt;/p&gt;
&lt;p&gt;When you invoke the Product Manager, you&amp;rsquo;re not just asking for PRD help. You&amp;rsquo;re stepping into a conversation about user needs, market positioning, and what problem you&amp;rsquo;re actually solving. When you switch to the Architect, the entire frame shifts to technical constraints, scalability, and system design.&lt;/p&gt;
&lt;p&gt;This forced perspective-taking is surprisingly valuable. It&amp;rsquo;s easy to skip straight to implementation when you&amp;rsquo;re working alone. The agents won&amp;rsquo;t let you. Each one guards their domain, and you have to satisfy them before moving forward.&lt;/p&gt;
&lt;h2 id="meet-the-crew"&gt;Meet the crew
&lt;/h2&gt;&lt;p&gt;BMAD&amp;rsquo;s core team consists of nine agents. Each has a name, a personality, and a specific set of capabilities. Here&amp;rsquo;s who you&amp;rsquo;ll be working with:&lt;/p&gt;
&lt;h3 id="john-product-manager"&gt;John (Product Manager)
&lt;/h3&gt;&lt;p&gt;John is a relentless questioner. His job is to figure out what you&amp;rsquo;re actually building and why. He&amp;rsquo;ll push you on user needs, challenge your assumptions, and refuse to let you start until you can articulate the problem clearly.&lt;/p&gt;
&lt;p&gt;His style is direct and data-sharp. He cuts through fluff to find what actually matters. If you come to him with a vague idea, expect to leave with a focused problem statement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What he does:&lt;/strong&gt; PRD creation, requirements discovery, epic and story generation, implementation readiness checks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;/bmad-agent-pm&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to call him:&lt;/strong&gt; At the very beginning, when you have an idea but haven&amp;rsquo;t defined what &amp;ldquo;done&amp;rdquo; looks like.&lt;/p&gt;
&lt;h3 id="mary-business-analyst"&gt;Mary (Business Analyst)
&lt;/h3&gt;&lt;p&gt;Mary treats every business challenge like a treasure hunt. She&amp;rsquo;s the one who digs into market research, competitive analysis, and domain expertise. Where John focuses on what to build, Mary focuses on the landscape you&amp;rsquo;re building in.&lt;/p&gt;
&lt;p&gt;Her communication style is energetic and discovery-oriented. She gets excited when patterns emerge and uses frameworks (Porter&amp;rsquo;s Five Forces, SWOT) naturally without making it feel academic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What she does:&lt;/strong&gt; Market research, competitive analysis, domain deep-dives, requirements elicitation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;/bmad-agent-analyst&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to call her:&lt;/strong&gt; When you need to understand the space before committing to a direction.&lt;/p&gt;
&lt;h3 id="winston-architect"&gt;Winston (Architect)
&lt;/h3&gt;&lt;p&gt;Winston is the calm pragmatist. He balances &amp;ldquo;what could be&amp;rdquo; with &amp;ldquo;what should be,&amp;rdquo; grounding every recommendation in real-world trade-offs. His expertise covers distributed systems, cloud infrastructure, and API design.&lt;/p&gt;
&lt;p&gt;He speaks in measured tones, always connecting technical decisions to business value. He&amp;rsquo;ll advocate for boring technology over shiny new frameworks, because boring ships.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What he does:&lt;/strong&gt; Technical architecture decisions, system design, scalability planning.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;/bmad-agent-architect&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to call him:&lt;/strong&gt; After the requirements are clear, when you need to decide how the pieces fit together.&lt;/p&gt;
&lt;h3 id="sally-ux-designer"&gt;Sally (UX Designer)
&lt;/h3&gt;&lt;p&gt;Sally is an empathetic advocate who paints pictures with words. She tells user stories that make you feel the problem, not just understand it. Her focus is on genuine user needs, and she balances creativity with attention to edge cases.&lt;/p&gt;
&lt;p&gt;Her approach is simple: start simple, evolve through feedback. Every design decision should serve a real person.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What she does:&lt;/strong&gt; UX planning, interaction design, experience strategy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;/bmad-agent-ux-designer&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to call her:&lt;/strong&gt; When you need to think through how users will actually interact with what you&amp;rsquo;re building.&lt;/p&gt;
&lt;h3 id="bob-scrum-master"&gt;Bob (Scrum Master)
&lt;/h3&gt;&lt;p&gt;Bob is crisp and checklist-driven. Every word has a purpose, every requirement crystal clear. He has zero tolerance for ambiguity, which makes him invaluable for turning vague plans into actionable work.&lt;/p&gt;
&lt;p&gt;He&amp;rsquo;s also a servant leader who genuinely enjoys discussing agile process and theory. If you want to debate sprint structures or story formats, he&amp;rsquo;s your guy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What he does:&lt;/strong&gt; Sprint planning, story preparation, retrospectives, course correction when things go sideways.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;/bmad-agent-sm&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to call him:&lt;/strong&gt; When requirements are defined and you need to break them into implementable chunks.&lt;/p&gt;
&lt;h3 id="amelia-developer"&gt;Amelia (Developer)
&lt;/h3&gt;&lt;p&gt;Amelia is ultra-precise. She speaks in file paths and acceptance criteria IDs. No fluff, all precision. Her job is to execute approved stories with strict adherence to the specs you&amp;rsquo;ve created.&lt;/p&gt;
&lt;p&gt;She&amp;rsquo;s test-driven to the core. Every task gets tests before it&amp;rsquo;s marked complete, and she won&amp;rsquo;t proceed with failing tests. If you&amp;rsquo;ve done the specification work properly, Amelia turns it into working code without surprises.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What she does:&lt;/strong&gt; Story implementation, code review, test-driven development.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;/bmad-agent-dev&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to call her:&lt;/strong&gt; When the spec is ready and it&amp;rsquo;s time to write code.&lt;/p&gt;
&lt;h3 id="quinn-qa-engineer"&gt;Quinn (QA Engineer)
&lt;/h3&gt;&lt;p&gt;Quinn is pragmatic and straightforward. Her philosophy is &amp;ldquo;ship it and iterate,&amp;rdquo; focusing on getting test coverage fast without overthinking. She generates tests for existing features using standard framework patterns.&lt;/p&gt;
&lt;p&gt;She&amp;rsquo;s the counterbalance to perfectionism. Coverage first, optimization later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What she does:&lt;/strong&gt; API and E2E test generation, test automation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;/bmad-agent-qa&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to call her:&lt;/strong&gt; After implementation, when you need to verify that what you built actually works.&lt;/p&gt;
&lt;h3 id="paige-tech-writer"&gt;Paige (Tech Writer)
&lt;/h3&gt;&lt;p&gt;Paige is a patient educator who explains complex concepts like teaching a friend. She transforms technical details into accessible, structured documentation, using analogies that make the complex simple.&lt;/p&gt;
&lt;p&gt;She&amp;rsquo;s a master of clarity. Every word serves a purpose, and diagrams often speak louder than paragraphs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What she does:&lt;/strong&gt; Documentation, technical explanations, Mermaid diagrams, document validation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;/bmad-agent-tech-writer&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to call her:&lt;/strong&gt; When you need to explain what you&amp;rsquo;ve built (to users, to teammates, or to your future self).&lt;/p&gt;
&lt;h3 id="barry-quick-flow-solo-dev"&gt;Barry (Quick Flow Solo Dev)
&lt;/h3&gt;&lt;p&gt;Barry is the speedrunner. He handles &amp;ldquo;Quick Flow&amp;rdquo; (smaller tasks that don&amp;rsquo;t need the full ceremony), moving from tech spec to implementation with ruthless efficiency.&lt;/p&gt;
&lt;p&gt;His style is direct and implementation-focused. Minimum bureaucracy, maximum results. If you have a well-defined small task, Barry gets it done.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What he does:&lt;/strong&gt; Rapid spec-to-implementation for smaller tasks, code review.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;/bmad-agent-quick-flow-solo-dev&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to call him:&lt;/strong&gt; For bug fixes, small features, or tasks where the full workflow would be overkill.&lt;/p&gt;
&lt;h2 id="the-workflow-how-agents-hand-off"&gt;The workflow: how agents hand off
&lt;/h2&gt;&lt;p&gt;The agents aren&amp;rsquo;t meant to be used in isolation. They form a pipeline:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;John&lt;/strong&gt; (PM) clarifies what you&amp;rsquo;re building and creates the PRD&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mary&lt;/strong&gt; (Analyst) provides market and domain context if needed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Winston&lt;/strong&gt; (Architect) designs the technical approach&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sally&lt;/strong&gt; (UX) plans the user experience&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bob&lt;/strong&gt; (SM) breaks everything into stories and plans sprints&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amelia&lt;/strong&gt; (Dev) implements the stories&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quinn&lt;/strong&gt; (QA) verifies the implementation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Paige&lt;/strong&gt; (Tech Writer) documents the result&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You don&amp;rsquo;t always need every step. A small bug fix might go straight to Barry. A well-understood feature might skip Mary&amp;rsquo;s research phase. But for anything substantial, the handoffs matter.&lt;/p&gt;
&lt;p&gt;Each agent produces artifacts that the next agent consumes. John&amp;rsquo;s PRD feeds Winston&amp;rsquo;s architecture. Winston&amp;rsquo;s architecture feeds Bob&amp;rsquo;s stories. Bob&amp;rsquo;s stories feed Amelia&amp;rsquo;s implementation. The chain ensures that nothing gets lost in translation.&lt;/p&gt;
&lt;h2 id="party-mode-when-agents-collaborate"&gt;Party Mode: when agents collaborate
&lt;/h2&gt;&lt;p&gt;Sometimes you need multiple perspectives at once. That&amp;rsquo;s where Party Mode comes in.&lt;/p&gt;
&lt;p&gt;Party Mode (&lt;code&gt;/bmad-party-mode&lt;/code&gt;) lets you have a conversation with several agents simultaneously. You might be discussing a technical decision and want both Winston (Architect) and Quinn (QA) to weigh in. Or you&amp;rsquo;re reviewing a PRD and want John, Sally, and Bob to debate the trade-offs.&lt;/p&gt;
&lt;p&gt;The agents stay in character, each bringing their own priorities and concerns. Winston might argue for a simpler architecture while Sally pushes for a richer user experience. Bob might point out that the current scope won&amp;rsquo;t fit in a sprint. You moderate, listen to the perspectives, and make the call.&lt;/p&gt;
&lt;p&gt;It sounds like a gimmick. In practice, it&amp;rsquo;s one of the most useful features for surfacing blind spots. Different roles genuinely do see different risks, and hearing them argue (politely) helps you make better decisions.&lt;/p&gt;
&lt;p&gt;Party Mode is particularly useful for refining artifacts you&amp;rsquo;ve already created. Got a PRD that feels incomplete? Throw it into a party with the PM, Architect, and UX Designer. They&amp;rsquo;ll poke holes from their respective angles, and you&amp;rsquo;ll walk away with a tighter spec. Same goes for architecture documents, story breakdowns, or anything else that benefits from cross-functional scrutiny. Refinement is where Party Mode really shines.&lt;/p&gt;
&lt;h2 id="choosing-your-path"&gt;Choosing your path
&lt;/h2&gt;&lt;p&gt;BMAD is flexible about how much ceremony you need:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Full workflow:&lt;/strong&gt; For new products or major features, start with John, work through the entire pipeline, and produce comprehensive specs before implementation. This is the safest path for anything complex.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quick Flow:&lt;/strong&gt; For smaller tasks (bug fixes, minor features, well-understood changes), call Barry and move fast. He&amp;rsquo;ll still push you to clarify intent and think through edge cases, but without the full artifact chain.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mix and match:&lt;/strong&gt; Need architecture help but already have requirements? Call Winston directly. Want to validate a PRD you wrote yourself? John can review it. The agents are tools, not a rigid process.&lt;/p&gt;
&lt;p&gt;The key insight is that the structure exists to help you think, not to slow you down. Use as much as you need. Skip what doesn&amp;rsquo;t serve you.&lt;/p&gt;
&lt;h2 id="whats-next"&gt;What&amp;rsquo;s next
&lt;/h2&gt;&lt;p&gt;In the final post of this series, I&amp;rsquo;ll walk through a real project I built with BMAD: &lt;a class="link" href="https://github.com/basteez/TODOdoro" target="_blank" rel="noopener"
&gt;TODOdoro&lt;/a&gt;, a productivity app that combines todo management with the Pomodoro technique.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll show how the process actually looked in practice: what questions John asked, what architecture Winston proposed, how the stories got structured, and where the agents surprised me (for better and worse).&lt;/p&gt;
&lt;p&gt;If you want to see BMAD in action rather than just described, that&amp;rsquo;s the post for you.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.bmad-method.org/" target="_blank" rel="noopener"
&gt;BMAD Method documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/bmad-code-org/BMAD-METHOD" target="_blank" rel="noopener"
&gt;BMAD on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://bstz.it/p/dont-be-mad-bmad-instead/" &gt;Part 1: Don&amp;rsquo;t be mad, BMAD instead&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Don't be mad, BMAD instead</title><link>https://bstz.it/p/dont-be-mad-bmad-instead/</link><pubDate>Thu, 26 Mar 2026 08:00:00 +0000</pubDate><guid>https://bstz.it/p/dont-be-mad-bmad-instead/</guid><description>&lt;p&gt;&lt;strong&gt;This post is part of a series:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Don&amp;rsquo;t be mad, BMAD instead (you are here)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://bstz.it/p/bmad-meet-the-crew/" &gt;BMAD: meet the crew&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://bstz.it/p/bmad-in-action-building-tododoro/" &gt;BMAD in action: building TODOdoro&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;A few weeks ago I wrote about the tension I felt using AI coding tools, the fear that by outsourcing the friction, I was also outsourcing my competence. That piece ended with a question: are you extending yourself, or outsourcing yourself?&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t have a clean answer then. I still don&amp;rsquo;t have a universal one. But I found something that changed how I think about the problem.&lt;/p&gt;
&lt;h2 id="the-grave-i-thought-i-was-digging"&gt;The grave I thought I was digging
&lt;/h2&gt;&lt;p&gt;When a colleague first mentioned BMAD, my reaction was skepticism dressed as caution. Another AI framework. Another promise that the machine will handle it. My concern wasn&amp;rsquo;t that it wouldn&amp;rsquo;t work, it was that it would work too well, and I&amp;rsquo;d wake up one day having forgotten how to build things myself.&lt;/p&gt;
&lt;p&gt;That fear isn&amp;rsquo;t irrational. I&amp;rsquo;ve seen what happens when you reach for autocomplete before you&amp;rsquo;ve finished the thought. You produce, but you don&amp;rsquo;t learn. The output looks fine, but the map never forms. You become dependent on a system you can&amp;rsquo;t fully reason about, and every time you hit a similar problem, you prompt again instead of drawing from understanding.&lt;/p&gt;
&lt;p&gt;So when someone told me &amp;ldquo;try this method where AI agents play different roles,&amp;rdquo; I heard: more ways to stop thinking. More automation. More distance between me and the craft I&amp;rsquo;d spent years developing.&lt;/p&gt;
&lt;p&gt;I was wrong. But it took some hands-on experimentation to see why.&lt;/p&gt;
&lt;h2 id="the-problem-with-vibe-coding"&gt;The problem with vibe coding
&lt;/h2&gt;&lt;p&gt;Before I explain what BMAD does differently, let me describe what it&amp;rsquo;s pushing against.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a pattern that&amp;rsquo;s become disturbingly common, often celebrated even, that I&amp;rsquo;ll call &amp;ldquo;vibe coding.&amp;rdquo; It goes like this: you have a rough idea of what you want to build. You open your editor, write a prompt, and let the AI generate something. If it looks mostly right, you keep it. If it doesn&amp;rsquo;t work, you prompt again with a correction. You iterate like this, adjusting and regenerating, until the output seems functional.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve always hated this approach. It treats software development like a slot machine: pull the lever, see what comes out, try again if you don&amp;rsquo;t like it.&lt;/p&gt;
&lt;p&gt;But here&amp;rsquo;s what&amp;rsquo;s actually happening: you&amp;rsquo;re making decisions without articulating them. You&amp;rsquo;re accepting code without fully understanding it. You&amp;rsquo;re building something that works (maybe) without building a mental model of why it works. The AI is filling in gaps you never consciously identified, which means you can&amp;rsquo;t evaluate whether it filled them correctly.&lt;/p&gt;
&lt;p&gt;Vibe coding optimizes for output. It feels efficient in the moment. But it produces fragile results, because no one (not you, not the AI) ever defined what &amp;ldquo;correct&amp;rdquo; actually means. When something breaks later, you&amp;rsquo;re debugging a system you never fully understood in the first place.&lt;/p&gt;
&lt;p&gt;This isn&amp;rsquo;t a problem with AI. It&amp;rsquo;s a problem with how we use it. And it&amp;rsquo;s the problem that spec-driven development solves.&lt;/p&gt;
&lt;h2 id="what-spec-driven-development-actually-means"&gt;What spec-driven development actually means
&lt;/h2&gt;&lt;p&gt;If you haven&amp;rsquo;t encountered the term before, spec-driven development is exactly what it sounds like: you write the specification before you write the code.&lt;/p&gt;
&lt;p&gt;That might seem obvious. &amp;ldquo;Of course you should know what you&amp;rsquo;re building before you build it.&amp;rdquo; But there&amp;rsquo;s a difference between having a vague idea in your head and having a written document that defines requirements, constraints, acceptance criteria, and architectural decisions.&lt;/p&gt;
&lt;p&gt;The spec isn&amp;rsquo;t just documentation. It&amp;rsquo;s a thinking tool. The act of writing it forces you to confront questions you might otherwise skip: What exactly is this feature supposed to do? What happens at the edges? How does this component interact with that one? What does &amp;ldquo;done&amp;rdquo; look like?&lt;/p&gt;
&lt;p&gt;When you answer these questions upfront, implementation becomes a translation exercise. You&amp;rsquo;re not discovering the requirements as you code. You&amp;rsquo;re executing a plan you&amp;rsquo;ve already validated. The code follows from decisions you consciously made, not from guesses the AI filled in for you.&lt;/p&gt;
&lt;p&gt;This is the opposite of vibe coding. Instead of iterating toward something that seems to work, you define what &amp;ldquo;working&amp;rdquo; means first, then build to that definition.&lt;/p&gt;
&lt;p&gt;The challenge, of course, is that writing good specs is hard. It requires discipline, experience, and (honestly) a fair amount of tedium. Which is exactly where BMAD comes in.&lt;/p&gt;
&lt;h2 id="what-bmad-actually-is"&gt;What BMAD actually is
&lt;/h2&gt;&lt;p&gt;BMAD stands for &amp;ldquo;Build More Architect Dreams.&amp;rdquo; It&amp;rsquo;s an open-source framework that uses AI agents to guide you through a structured development process, from initial idea through implementation.&lt;/p&gt;
&lt;p&gt;But here&amp;rsquo;s the crucial part: BMAD doesn&amp;rsquo;t generate code and call it done. It forces you through the specification process first.&lt;/p&gt;
&lt;p&gt;The framework includes multiple specialized agents, each with a distinct role:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Product Manager&lt;/strong&gt; who helps you clarify what you&amp;rsquo;re building and why&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Business Analyst&lt;/strong&gt; who digs into requirements and edge cases&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;Architect&lt;/strong&gt; who designs how components will fit together&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Developer&lt;/strong&gt; who implements based on the specs you&amp;rsquo;ve created&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;QA Engineer&lt;/strong&gt; who defines how you&amp;rsquo;ll verify the implementation works&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each agent asks questions. Each one pushes you to articulate something specific before you move forward. You can&amp;rsquo;t skip to the code, because the developer agent won&amp;rsquo;t have what it needs until the earlier stages are complete.&lt;/p&gt;
&lt;p&gt;This structure is the key insight. The AI isn&amp;rsquo;t doing the thinking for you. It&amp;rsquo;s holding you accountable to a process that requires thinking. The agents are collaborators, not replacements. They augment your capability to do the specification work, but the decisions remain yours.&lt;/p&gt;
&lt;h2 id="why-this-feels-different"&gt;Why this feels different
&lt;/h2&gt;&lt;p&gt;Most AI coding tools are optimized for a simple interaction: you prompt, you get code. The faster and more accurate that loop, the better the tool seems.&lt;/p&gt;
&lt;p&gt;BMAD optimizes for something else: the quality of your thinking before code exists.&lt;/p&gt;
&lt;p&gt;When I started experimenting with it, I chose deliberately small tasks. An Emacs configuration I&amp;rsquo;d been putting off. A bug I wanted to reproduce in isolation before fixing. Low stakes, easy to abandon if it felt like hype.&lt;/p&gt;
&lt;p&gt;What surprised me wasn&amp;rsquo;t the speed. It was the structure.&lt;/p&gt;
&lt;p&gt;Working with the Product Manager agent, I had to articulate what I actually wanted (not just &amp;ldquo;fix this bug,&amp;rdquo; but what specific behavior should change, and why, and how I&amp;rsquo;d know it was fixed). Working with the Architect, I had to think about how my change would interact with existing code. Working with the QA persona, I had to define acceptance criteria before implementation.&lt;/p&gt;
&lt;p&gt;By the time I reached the Developer agent, I wasn&amp;rsquo;t prompting and hoping. I was handing over a spec that I understood, because I&amp;rsquo;d helped build it. The implementation felt like execution, not experimentation.&lt;/p&gt;
&lt;p&gt;And here&amp;rsquo;s what I didn&amp;rsquo;t expect: that constraint is liberating. The process felt slower at first (more steps, more questions, more writing). But I wasn&amp;rsquo;t backtracking. I wasn&amp;rsquo;t debugging code I didn&amp;rsquo;t understand. I wasn&amp;rsquo;t prompting the same thing five different ways hoping for a better result.&lt;/p&gt;
&lt;p&gt;The spec had done its job. The thinking was front-loaded, where it belongs.&lt;/p&gt;
&lt;h2 id="orchestrator-not-passenger"&gt;Orchestrator, not passenger
&lt;/h2&gt;&lt;p&gt;The shift I described in my earlier post, from active thinker to passive prompter, doesn&amp;rsquo;t happen with BMAD. It can&amp;rsquo;t. The method requires you to validate, decide, and course-correct at every stage.&lt;/p&gt;
&lt;p&gt;The AI handles the grunt work: generating document templates, suggesting architectural patterns, writing implementation code that follows the spec. But you&amp;rsquo;re still the one reviewing, adjusting, and approving. You&amp;rsquo;re still the one who understands why the system is designed the way it is.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the answer I was looking for. Not &amp;ldquo;don&amp;rsquo;t use AI,&amp;rdquo; but &amp;ldquo;use it in a way that keeps you in the driver&amp;rsquo;s seat.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I delegate the dirty work. I orchestrate. I stay in the loop.&lt;/p&gt;
&lt;p&gt;The mental model I keep coming back to is this: BMAD turns AI into a team of junior collaborators who are fast and capable, but who need direction. You&amp;rsquo;re the senior engineer. You set the vision, define the constraints, and make the judgment calls. They execute, and they execute well, but only because you&amp;rsquo;ve told them what &amp;ldquo;well&amp;rdquo; means.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s extending yourself. That&amp;rsquo;s the version of AI assistance I was hoping existed.&lt;/p&gt;
&lt;h2 id="the-dopamine-is-real-and-so-is-the-fun"&gt;The dopamine is real (and so is the fun)
&lt;/h2&gt;&lt;p&gt;I should mention something else: this process is genuinely enjoyable.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a particular satisfaction in watching a well-defined spec turn into working code without surprises. The gap between &amp;ldquo;what I wanted&amp;rdquo; and &amp;ldquo;what I got&amp;rdquo; shrinks dramatically when you&amp;rsquo;ve done the specification work upfront.&lt;/p&gt;
&lt;p&gt;And (I didn&amp;rsquo;t expect this) role-playing with the different personas is fun. Switching from the PM mindset to the Architect mindset to the Developer mindset keeps the work varied. You&amp;rsquo;re not just grinding through one mode of thinking. You&amp;rsquo;re shifting perspectives, which keeps you engaged.&lt;/p&gt;
&lt;p&gt;BMAD even has something called &amp;ldquo;Party Mode&amp;rdquo; where multiple agents can participate in a single conversation, debating approaches and surfacing trade-offs. It sounds gimmicky until you try it. Having the Architect and QA agents push back on each other while you moderate is surprisingly useful for finding blind spots.&lt;/p&gt;
&lt;h2 id="whats-next"&gt;What&amp;rsquo;s next
&lt;/h2&gt;&lt;p&gt;This is the first in a series of three posts.&lt;/p&gt;
&lt;p&gt;In the next one, I&amp;rsquo;ll go deeper on the agents themselves: who they are, what each one does, how they hand off work to each other, and how you can customize the process for your own workflow.&lt;/p&gt;
&lt;p&gt;In the third post, I&amp;rsquo;ll walk through a real project I built using BMAD: a productivity app called &lt;a class="link" href="https://github.com/basteez/TODOdoro" target="_blank" rel="noopener"
&gt;TODOdoro&lt;/a&gt;. It combines todo management with the Pomodoro technique, and I&amp;rsquo;ll show how the method helped me go from a philosophical idea (&amp;ldquo;a mirror, not a manager&amp;rdquo;) to a working application with a clear architecture.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve felt the same tension I did, excited by AI&amp;rsquo;s potential but worried about what you might lose, this might be worth following. BMAD isn&amp;rsquo;t the only answer, but it&amp;rsquo;s an answer. And for me, it&amp;rsquo;s been the difference between feeling like AI is happening to me and feeling like I&amp;rsquo;m using it deliberately.&lt;/p&gt;
&lt;p&gt;The tools are getting more powerful every month. The question isn&amp;rsquo;t whether to use them. It&amp;rsquo;s whether you&amp;rsquo;ll use them in a way that makes you better, or in a way that quietly makes you less than you were.&lt;/p&gt;
&lt;p&gt;I know which one I&amp;rsquo;m choosing.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.bmad-method.org/" target="_blank" rel="noopener"
&gt;BMAD Method documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/bmad-code-org/BMAD-METHOD" target="_blank" rel="noopener"
&gt;BMAD on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>