Why a framework, and what they share
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.
#17 - How Zalando Engineers Software & AI at Scale - Bartosz Ocytko (Executive Principal Engineer)
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:
Package.swift
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.
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.
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.
practitioners-05— the three maturity levels, 2025-10-15: Understanding Spec-Driven Development: Kiro, spec-kit, and Tessl.openspec-04— OpenSpec 1.13.1 and its release date, from the OpenSpec latest-release record as read on 2026-09-22; this course pins 1.13.1.openspec-06— theopenspec/specs/andopenspec/changes/archive/folders, from OpenSpec setup.openspec-07,openspec-08,openspec-09,openspec-10— the four slash commands, from OpenSpec getting started. That propose asks about material ambiguity first, stops after the planning artifacts and waits for you to start apply is from the pinned command file,starter/vendored/openspec-1.13.1/project-files/.claude/commands/opsx/propose.md.openspec-13,openspec-14,openspec-15,openspec-20— the delta headers and the date-prefixed archive folder, from OpenSpec concepts.openspec-17,lid-12,bmad-obs-11— each framework's criteria format: OpenSpec's scenario blocks, from OpenSpec: Concepts; LID's EARS requirements, from LID's AGENTS.md; BMAD'sSPEC.mdfor Change C, observed.lid-12,lid-13— the requirement markers and the semantic ID shape, from LID's AGENTS.md; the arrow is in the same file at831c1959, vendored understarter/vendored/lid-831c1959/lid/. The six phases and the stop after each of the first five are in the pinned linked-intent-dev skill,starter/vendored/lid-831c1959/lid/plugins/linked-intent-dev/skills/linked-intent-dev/SKILL.md. The shall-based sentence patterns are from LID's EARS syntax reference, pinned asreferences/ears-syntax.mdbeside that skill, and the LID checkpoint's EARS requirements are instarter/checkpoints/lid/docs/intent/statement-period/statement-period-specs.md.lid-25— commit831c1959and its date, from the LID main-branch commit record. The quotation in “A ladder to place yourself on” is from the Linked-Intent Development README, which also sets the bar of regenerating code from the design documents and calls them the source of truth; the pinned copy isstarter/vendored/lid-831c1959/lid/README.md.bmad-07— the minimal/bmad-buildinvocation, from BMAD: build your first change.bmad-09— the 6.11.0 renames ofbmad-quick-devtobmad-buildandbmad-dev-autotobmad-build-auto, from the BMAD-METHOD changelog (v6.11.0, 2026-08-09).bmad-12,bmad-13— the status values and the spec folder layout for work split into stories, from BMAD autonomous development loops. The two-section spec for a small change with no open questions and nothing irreversible, and the halts for open questions and plan approval, are fromstep-02-plan.mdof the pinnedbmad-buildskill understarter/vendored/bmad-6.12.0/.cc-core-36— skill descriptions load at session start, from Claude Code: the context window.cc-core-32— the version this course was checked against, from the Claude Code changelog.- Observed on the build machine:
openspec-obs-02,openspec-obs-07— OpenSpec's six installed skills and its change folder underopenspec/changes/;openspec-obs-03—openspec initwrites nothing intoCLAUDE.md.lid-obs-01— the pinned LID commit, 831c1959;lid-obs-04— the two LID plugins add about 531 and 559 always-on tokens to every session;lid-obs-05— the 29-line## LIDsection appended toCLAUDE.md;lid-obs-06— the map of LedgerKit;lid-obs-07— the mapping run could not load the plugin's own skill body.bmad-obs-01— 6.12.0 is the version on thelatesttag, fromnpm view bmad-method version;bmad-obs-05— the install leavesCLAUDE.mdunmodified;bmad-obs-07,bmad-obs-13— a default install recordsinstallShims: falsein its manifest, and the two old names are reported as unknown commands while the new names resolve; also BMAD's 29 installed skills and its spec folder for Change C under Exercise 2's prompt.