Why a framework, and what they share

Day 3: Choose your adventure · Lessons 1 and 2 of 5 · 16 min

A spec framework is a set of shared conventions for where specs live and how they move from brief to shipped code, installed as commands your agent runs. Its only benefit worth the ceremony is that it makes the loop you built on Days 1 and 2 run for people who did not build it. OpenSpec, LID and BMAD run the same five stages under different names and part in three places. If you work alone, read When to skip it first.

Watch first · 5 min

#17 - How Zalando Engineers Software & AI at Scale - Bartosz Ocytko (Executive Principal Engineer)

bynd code, 2026-09-20; the five minutes from 35:19 to 40:19. If you watched these five minutes from Day 2 Lesson 4, listening for who holds each credential, replay them for a different question. Watch for what the organization chose to make the same for every team, and what it left each team to decide. For each shared piece, ask whether it exists to make the output better or to let people who did not build a setup use it. Scale it down as you listen: the reasons survive at five people, the machinery does not.

What breaks when the second person joins

Your Day 2 loop works because you hold three things in your head: which spec is current, what counts as done, and which files a change may touch. Your own specs carry the answers because you start each one from specs/TEMPLATE.md. That every spec must start there is written nowhere.

Now a teammate picks up the next ticket. They paste it into a spec file of their own, with no bounds section, and run the same runner against the same repo. The tests go green, and the diff edits a file your bounds keep off limits:

Swift lane

Package.swift

Kotlin lane

build.gradle.kts

In the PR review you reject it for a reason they had no way to know. The agent did what it was given. The failure is an unwritten convention, and it gets worse with every person who joins.

What a framework actually standardizes

Every framework on offer standardizes four things: where the spec file lives, what shape it takes, which command moves it to the next stage, and what happens to it after the code ships. That is the whole list. A framework does not standardize your prompts, your tests, or your judgment about whether a criterion can fail. You are buying agreement: your teammate's spec lands in the same place, in the same shape, and moves through the same commands as yours.

Lesson 2: What the three share, and where they part

The same five stages under different names

Every spec framework moves a change through five stages: brief, spec (outcome and acceptance criteria), plan (steps and files), implement, and close. Days 1 and 2 did the first four by hand; the frameworks add the fifth, deciding what the spec becomes once the code ships.

OpenSpec drives the stages with four slash commands. The optional /opsx:explore surveys the problem first, /opsx:propose <feature description> creates a change holding spec and plan, /opsx:apply implements it, and /opsx:archive closes it.

LID calls its chain the arrow: HLD → LLD → EARS → Tests → Code, where HLD is the high-level design and LLD a low-level design per component. EARS (Easy Approach to Requirements Syntax) writes each requirement as one sentence built on shall, sometimes with its trigger in front, so it reads as one checkable statement. Exercise 2's LID checkpoint holds real ones.

BMAD routes the stages through skills. One skill takes the brief as its argument, /bmad-build write an implementation of mars rover kata in BMAD's own docs, and carries it through spec, plan, and implementation.

Three frameworks mapped onto the same five stages Time runs left to right across five stage columns: brief, spec, plan, implement, close. OpenSpec: the optional /opsx:explore under brief, drawn as an outlined bar, one bar labelled /opsx:propose spanning spec and plan, /opsx:apply under implement, and /opsx:archive under close. LID: HLD, the high-level design, under brief, one bar labelled LLD (the low-level design), EARS, audit spanning spec and plan, tests, code under implement, and the status markers [x] [ ] [D] under close. BMAD: your brief under brief, one bar labelled /bmad-build spanning spec, plan and implement, with Change C's SPEC.md under spec and stories.yaml under plan, and status: done under close. brief spec plan implement close OpenSpec /opsx:explore /opsx:apply /opsx:propose /opsx:archive LID HLD tests, code LLD, EARS, audit [x] [ ] [D] BMAD your brief /bmad-build SPEC.md status: done stories.yaml
Where one step covers several stages its bar spans them: OpenSpec's propose covers spec and plan, BMAD's one skill covers spec, plan and implementation, and LID's shared bar holds three of its phases: the low-level design, the EARS requirements and the edge audit. The outlined bar is optional, BMAD's file names are Change C's, and LID's close markers are explained under difference three.

Difference one: how many artifacts

OpenSpec's unit is a change folder under openspec/changes/, and its spec is a delta: sections headed ## ADDED Requirements, ## MODIFIED Requirements, and ## REMOVED Requirements state only what this change alters.

LID's unit is a design tree that persists, with requirement IDs that follow their path through the tree, such as PEVAL-RUN-014, and mapping an existing codebase writes many documents before any feature work.

BMAD sizes its spec to the change: work it splits into stories gets a spec folder, and a small change with no open questions and nothing irreversible gets a two-section spec file.

Difference two: how much review before code

Ceremony is the number of human reviews between the brief and the first line of implementation. By their own text at the pinned versions, LID's skill stops for your review after each of its first five phases, so the high-level design, the low-level design, the EARS requirements, an edge audit of those requirements, and the tests each get a review before any code. OpenSpec's /opsx:propose first asks about any ambiguity that would change scope or acceptance criteria, then writes the planning artifacts and stops, and nothing is implemented until you run /opsx:apply. /bmad-build investigates, then decides: a small change with no open questions and nothing irreversible goes straight to implementation, and anything else halts for your answers and your approval of its plan.

Difference three: living specs or expiring specs

OpenSpec's /opsx:archive moves a finished change into changes/archive/ under a date-prefixed folder and folds its deltas into the live specs in openspec/specs/. The change record expires; the requirement lives.

LID keeps the design tree as the source of truth after implementation. In LID's own specs each requirement carries a marker, [x] implemented, [ ] gap, or [D] deferred; Exercise 2's LID checkpoint records the same state as “Verified by: (no test yet).” BMAD tracks a spec through a frontmatter status, draft, ready-for-dev, in-progress, in-review, done or blocked. Ask which of these your team will re-read in six months.

A ladder to place yourself on

Birgitta Böckeler's three levels from Day 1's Lesson 4 are spec-first, spec-anchored and spec-as-source; Days 1 and 2 taught spec-first. OpenSpec's archive into live specs and LID's rule, “Specs win. Fix the code, or fix the spec and cascade,” are spec-anchored. BMAD's spec belongs to one change and anchors nothing after done unless your team goes back to it. LID's README aims higher, at code you could regenerate from the tree, but its rule still lets you fix the code, so none of the three is spec-as-source. Lesson 4 turns the rung you want into a decision.

The three costs you pay

The first cost is artifacts. More artifacts buy traceability, and every spec, design file and story a framework creates is a file someone has to keep current, or it starts misleading the agent that reads it. The artifact is the agent's input, not documentation written afterwards, so walking a tree to find the requirement that governs a change can also cost more context per turn than reading one file. The second cost is commands your team has to learn, in a specific order, before the framework does anything useful. The third is a version treadmill.

BMAD is the one whose treadmill you can price. A release renamed two skills, bmad-quick-dev to bmad-build and bmad-dev-auto to bmad-build-auto, and after a default install of the pinned version Claude Code answered /bmad-quick-dev as an unknown command. Every onboarding note that names a framework command has an expiry date you do not choose.

Pay these knowingly, and do the arithmetic first. Divide the minutes an adoption costs, summed across everyone who has to learn it, by the minutes it saves each ticket, and you have the number of tickets before it pays back. With illustrative figures, at ten minutes saved a ticket, one person's eight-hour day pays back after 48 tickets; the same day for a team of five needs 240.

A framework is not a substitute for Days 1 and 2

None of the three writes acceptance criteria that can fail for you. Each drafts criteria in its own format, and whether each one names a command that goes red without the change is still the review you learned on Day 1. If your criteria are unfalsifiable, a framework files the unfalsifiable criteria neatly, in the right folder, under the right name.

None of them keeps your context small for you, either. Each spends Day 1's context budget through the skill descriptions Claude Code loads at session start, and some through lines added to CLAUDE.md; Lesson 5 shows what lands there and how to keep it from growing.

How to tell in two weeks whether it worked

Pick one signal before you start, and pick it from the failure that sent you looking. Two work well for a mobile team: the number of tickets where someone had to ask what done meant, and the number of diffs sent back in review because the spec never said which files were off limits. Count it for two weeks before adoption and two weeks after.

One team, one signal, and no percentage you would quote to anyone else: a dozen tickets is not a study. If the count does not move, the framework standardized something that was not your problem. Lesson 4 has you write the signal into the decision itself, and Exercise 3's comparison card asks which failure you would adopt your track to fix.

When to skip it

Skip a framework in four cases. The first three are about coordination: you are the only person who touches the module, the code will be deleted before anyone re-reads its specs, or your team of two already agrees on where specs live and what done means. The ceremony is priced for coordination; with nobody to coordinate with, you are paying for nothing. A one-line fix in TransactionFormatter or a throwaway script falls under the first two: the review stops and artifacts cost more than they return, and a plain prompt or a short hand-written spec like Day 1's is the better tool. Lesson 4 treats no framework as a real answer.

The fourth case: the problem you want solved is quality. A framework fixes coordination between people, not the content of what they write. Adopting one to get better diffs from the same vague briefs is a mis-purchase, and six weeks later you have vague briefs in a standard folder. A useful team norm: adopt a framework only after two people have independently hit the same coordination failure.

What this comparison does not do

It does not rank them: research for this course found no talk comparing all three on the same work. Every claim here traces to a project's own documentation or pinned source, to a run on this course's build machine, or, for the ladder, to Böckeler's article.

It also has a short shelf life. It was written against the versions this course pins, which are not necessarily the latest: OpenSpec 1.13.1 (released 2026-09-17), LID commit 831c1959 (2026-08-12) and BMAD 6.12.0, the version npm served on 2026-09-22. On a newer install, re-check the command names first.

Quick check

Your team adopts a framework hoping the agent will stop turning vague briefs into vague diffs. Six weeks in, the briefs are still vague and so are the diffs. What did the framework standardize, and what did you expect it to standardize that it does not?

It standardized four things: where the spec file lives, what shape it takes, which command moves it to the next stage, and what happens to it after the code ships. It does not standardize content: your prompts, your tests, whether your acceptance criteria can fail, your judgment. A vague brief filed in a standard folder is still a vague brief, and the fix is Day 1's: criteria a command can fail.

A teammate says ‘our specs go stale, so specs are useless.’ Which axis is that complaint about, and which of the three frameworks are built to answer it?

It is the living-versus-expiring axis. OpenSpec answers it by folding a change's deltas into a live spec tree and archiving only the change record; LID answers it by making the design tree the source of truth and cascading fixes downstream. A framework that only produces per-change documents will not help.

Also worth watching, four optional minutes: Spec-Driven Dev Is Back. But Not How You Think • Daniel Terhorst-North & Gojko Adzic • GOTO 2026 (GOTO Conferences, 2026-04-27), 6:34 to 10:39, on the earlier generation of tools and what went wrong last time.

Sources

Every citation for this page

Each project's own documentation, Claude Code's documentation and Böckeler's article, accessed 2026-09-22. Observed entries were recorded on the course's build machine on the same date, in fresh copies of the Swift lane, one per framework.