Spec-driven development: Arbetsflöde från krav till kod

Fem faser från avsikt till verifierad kod.

Sidinnehåll

Spec-Driven Development (SDD) fungerar när specifikationen är en arbetsflödesprocess, inte ett dokument man arkiverar efter startskottet. Syftet är inte att producera ett stort produktkravdokument.

Syftet är att gå igenom en sekvens av granskbara artefakter som var och en minskar oklarhet innan någon – människa eller AI-agent – ändrar produktionskod.

Om du inte vet vad SDD är konceptuellt, börja med Vad är Spec-Driven Development? för definitioner, jämförelser med TDD och BDD, samt argumentet för att behandla specifikationen som källan till sanningen. Denna artikel i App Architecture-dokumentationsklustret är den operativa guiden. Den går igenom de fem faserna, visar vad varje artefakt bör innehålla, förklarar var AI-agenter passar in och ger återanvändbara mallar som du kan kopiera till ditt repository idag.

Arbetsflöde för spec-driven development – krav, design, uppgifter, implementering, validering

SDD är ett arbetsflöde, inte ett dokument

Den vanligaste misslyckandemoden i spec-driven development är att behandla specifikationen som pappersarbete. Ett team skriver ett långt kravdokument, lagrar det i en wiki och koder sedan utifrån minne och chatttrådar. Specifikationen finns, men den driver inget. Det är dokumentationsteater, och det är värre än ingen specifikation alls eftersom det skapar falsk trygghet.

Ett fungerande SDD-arbetsflöde producerar en kedja av artefakter, där varje granskas innan nästa fas påbörjas. Krav minskar produktnär oklarhet. Design minskar teknisk oklarhet. Uppgifter minskar utförandeoklarhet. Implementering producerar kod mot ett känd mål. Validering bevisar att kedjan höll. När någon fas avslöjar ett misstag, fixar du artefakten och kör om från den punkten – inte efter tre tusen rader av drift har landat i main.

flowchart LR A[Specificera] --> B[Planera] B --> C[Uppgifter] C --> D[Implementera] D --> E[Validera] E -->|drift upptäckt| A E -->|skicka| F[Klart]

Arbetsflödet är verktygsneutralt. Du kan köra det med markdown-filer i Git, med GitHub Spec Kit, med Cursor-planer eller med en vanlig textredigerare och en disciplinerad granskare. Det som räknas är sekvensen och granskningsgrinderna, inte varumärket på verktygen.

Fas 1 – Specificera kraven

Specificeringsfasen besvarar vilket problem du löser och vad “klart” ser ut. Den undviker medvetet hur man bygger det. Ögonblicket då din kravspecifikation säger “använd Redis sorted sets”, har du slutat specificera och börjat designa i fel dokument. Håll implementering utanför kraven. Lägg det i planen.

Problemstatement och användare

Börja med ett stycke som beskriver problemet i enkel språkbruk. Namnge de påverkade användarna och situationen som gör problemet smärtsamt. Ett bra problemstatement låter en granskare som inte var med på planeringsmötet avgöra om ett föreslaget faktiskt löser smärtan.

Exempel för en API-begränsningsfunktion (rate-limiting):

API-konsumenter på den fria nivån kan skicka obegränsat antal förfrågningar, vilket orsakar kostnadspeak och påverkar betalande hyresgäster (noisy-neighbor). Plattformsoperatörer behöver en genomförbar per-nyckel-gräns utan manlig ingripande.

Mål, icke-mål och acceptanskriterier

Mål beskriver resultat du kommer leverera. Icke-mål beskriver frestande intilliggande arbete du explicit inte kommer göra. Tillsammans begränsar de agentens kreativitet, vilket är avgörande när AI-verktyg annars “hjälpsamt” expanderar omfattningen.

Avsnitt Bra exempel Svagt exempel
Mål Avvisa förfrågningar över per-nyckel-gränsen med HTTP 429 Gör API:t snabbare
Icke-mål Betalningsdashboards per hyresgäst Förbättra all API-prestanda
Acceptanskriterium Oautentiserade förfrågningar får 401 innan gränskontrollen körs Slutpunkten är säker

Acceptanskriterier bör vara tillräckligt precisa så att varje kriterium motsvarar minst ett test. “Slutpunkten är säker” är inte ett acceptanskriterium. “Oautentiserade förfrågningar får HTTP 401” är det. Om du inte kan skriva ett konkret kriterium, är kravet fortfarande för vagt för att implementera.

Öppna frågor

Lista alla beslut som inte ännu är avgjorda. Oklara frågor är inte ett tecken på misslyckande. Det är specificeringsfasen som gör sitt jobb. Lös dem innan du skriver designplanen, eller så betalar du för oklarheten i implementeringsomarbete.

En minimal kravmall:

## Problem
[Ett stycke: vem lider, varför, och vad utlöser smärtan.]

## Användare
- [Primär användarroll]
- [Sekundär användarroll]

## Mål
1. [Mätbart resultat]
2. [Mätbart resultat]

## Icke-mål
- [Explicit utanför scope]
- [Explicit utanför scope]

## Acceptanskriterier
- [ ] [Verifierbart beteende]
- [ ] [Verifierbart beteende]

## Öppna frågor
- [ ] [Fråga som blockerar planering]

Fas 2 – Planera designen

Planeringsfasen översätter avsikt till tekniska beslut. Det är här Redis sorted sets hör hemma, tillsammans med modulgränser, schemaändringar, API-kontrakt, migreringssteg, säkerhetsbegränsningar och teststrategi. Planen härleds från kravspecifikationen plus ditt projekts befintliga begränsningar – stackval, beskedsdokument och konventioner som lagras i filer som AGENTS.md eller en projektkonstitution.

Arkitektur och påverkade moduler

Namnge de moduler, tjänster eller paket som kommer att ändras och sammanfatta integrationsmönstret. Om funktionen korsar en tjänstegräns, dokumentera kontraktet på båda sidor. Agenter hallucinerar API:n när kontrakt är implicita. Att göra dem explicita i planen förhindrar uppfunna slutpunkter och felaktiga svarsstrukturer.

Datamodell, API-kontrakt och migrationer

Dokumentera schemaändringar, nya tabeller eller fält, indexkrav och bakåtkompatibilitetsregler. För HTTP-API:n, skriv metod, sökväg, förfrågningsstruktur, svarsstruktur och felkoder. För händelser, skriv ämnesnamn, payload-scheman och leveranssemantik. Inkludera migreringssteg och rollback-noteringar när datamodellen ändras.

Säkerhet, observabilitet och teststrategi

Säkerhetsbegränsningar hör hemma i planen, inte som eftertankar i kodgranskning. Notera autentiseringskrav, auktoriseringsregler, gränser för indatavalidering och data som inte får visas i loggar. Observabilitet bör täcka metrik, loggar eller spår som behövs för att bekräfta att funktionen fungerar i produktion.

Teststrategin kopplar tillbaka till acceptanskriterierna. Identifiera vilka kriterier som behöver enhetstester, vilka som behöver integrationstester och vilka som behöver manuell verifiering. Om du använder enhetstestning i Go eller enhetstestning i Python, namnge de paket och testfiler du förväntar dig att lägga till. En plan utan teststrategi är en plan som kommer levereras med luckor som du upptäcker i produktion.

flowchart TB subgraph plan [Innehåll i designplanen] R[Kravspecifikation] C[Projektkonstitution / ADR] R --> D[Arkitekturbeslut] C --> D D --> M[Datamodell och migrationer] D --> A[API-kontrakt] D --> S[Säkerhetsbegränsningar] D --> T[Teststrategi] end

Fas 3 – Bryt ned implementeringsuppgifter

Uppgiftsfasen dekomponerar planen i skivor som är tillräckligt små för att implementera, granska och validera oberoende. Det är det som gör agentassisterad utveckling granskbar. Istället för en enorm diff får du en sekvens av fokuserade ändringar som var och en kopplas tillbaka till ett namngivet krav.

Uppgiftsstorlek och beroenden

En bra uppgift rör en begränsad uppsättning filer, slutförs i en agent-session och avslutas med ett verifieringssteg. Uppgifter bör deklarera beroenden explicit. Migreringsuppgifter körs innan kod som läser det nya schemat. Ändringar i gemensamma bibliotek körs innan konsumenter. Ändringar i autentiseringsmiddleware körs innan slutpunkter som beror på det nya beteendet.

flowchart TD T1[Uppgift 1 -- schemamigration] --> T2[Uppgift 2 -- lager för repository] T2 --> T3[Uppgift 3 -- HTTP-handläggare] T2 --> T4[Uppgift 4 -- metrikinstrumentering] T3 --> T5[Uppgift 5 -- integrationstester] T4 --> T5

Filerna, validering och granskningskontroller

Varje uppgift bör lista de filer som sannolikt kommer att ändras, de acceptanskriterier den uppfyller och hur man validerar slutförande. Validering kan vara ett testkommando, ett curl-exempel eller en manuell kontroll beskriven i kopiera-och-klistra-steg. Varje uppgift avslutas vid en mänsklig granskningskontroll. Granskaren bekräftar att diff:n matchar uppgiftsbeskrivningen innan nästa uppgift påbörjas.

En minimal uppgiftspost:

### Uppgift 3 -- Lägg till rate-limit-middleware

**Beror på:** Uppgift 1 (schema), Uppgift 2 (repository)
**Filer:** middleware/ratelimit.go, middleware/ratelimit_test.go, server.go
**Uppfyller:** AC-2 (429 över gräns), AC-3 (gränshuvuden i svar)
**Validera:** `go test ./middleware/...` lyckas; curl över gräns returnerar 429 med Retry-After
**Granskningskontroll:** Bekräfta att middleware körs efter auth, före handläggare

Passa på genererade uppgiftsexplosioner. AI-agenter kan producera 50-uppgiftsplaner på sekunder. De flesta av dessa uppgifter kommer att vara redundanta eller för korniga för att granska effektivt. En användbar uppgiftslista för en medelstor funktion har ofta fem till femton poster, inte femtio.

Fas 4 – Implementera en uppgift i taget

Implementering är medvetet smal. Välj en uppgift, ge agenten bara den kontext den behöver för den uppgiften, och stoppa när valideringen lyckas. Kontextåterställningar mellan uppgifter är en funktion, inte en bugg. De förhindrar att tidigare antagningar förorenar senare arbete och håller diffarna granskbara.

Tillämpa begränsningar från spec-stacket

Den implementerande agenten bör läsa kravspecifikationen, designplanen, den aktuella uppgiftsbeskrivningen och projektbegränsningar. Begränsningar är det avsnitt med högst ROI som de flesta team hoppa över. De berättar för agenten vad den inte ska göra – refaktorera inte orelaterade moduler, ändra inte offentliga API-signaturer utanför denna funktion, introducera inte nya beroenden utan att uppdatera planen.

Uppdatera planen när verkligheten skiljer sig

Implementeringen kommer att avslöja överraskningar. Ett bibliotek stöder inte det antagna beteendet. En migration tar längre tid än förväntat. En randcase saknades i acceptanskriterierna. När detta händer, uppdatera specifikationen innan du fortsätter. Fixa kraven eller planen, få en snabb granskning, och återuppta implementeringen mot den korrigerade artefakten. Kod som tyst avviker från specifikationen är hur drift blir permanent.

sequenceDiagram participant H as Mänsklig granskare participant A as AI-agent participant S as Spec-artefakter H->>S: Godkänn uppgift N A->>S: Läs uppgift + plan + begränsningar A->>A: Implementera uppgift N A->>A: Kör uppgiftsvalidering A->>H: Skicka diff för granskning H->>H: Granska diff mot uppgift alt drift eller överraskning H->>S: Uppdatera spec/plan H->>A: Kör om med korrigerad kontext else godkänd H->>S: Markera uppgift N som klar H->>A: Gå vidare till uppgift N+1 end

Fas 5 – Validera mot specifikationen

Validering är där SDD intjänar sitt värde. Utan det är specifikationen en planeringsövning. Med det är specifikationen ett kontrakt du kan kontrollera mot den levererade koden.

Automatiserade kontroller

Kör hela testsuiten, lint och typkontroller i CI. Koppla in dessa i din pipeline med mönster från GitHub Actions cheatsheet om du behöver ett praktiskt startpunkter. Automatiserade kontroller fångar regressioner. De fångar inte fel funktioner som byggts korrekt, vilket är varför granskning av acceptanskriterier fortfarande är viktig.

Acceptanskriterier och manuell granskning

Gå igenom varje acceptanskriterium från kravspecifikationen. Markera varje som uppfylld, misslyckad eller uppskjuten med motivering. Manuell granskning fångar UX-problem, säkerhetshål och felaktigt beteende som tester missade eftersom testerna skrevs för att matcha en felaktig specifikation.

Spec-till-kod-diff

Det sista valideringssteget jämför implementeringen mot designplanen. Matchade de filer som ändrades med de filer planen förutspådde? Matchade arkitekturbeslut i koden med de registrerade besluten? Oväntade filer i diff:n är en signal – antingen var planen ofullständig eller så vandrade agenten. Båda förtjänar uppmärksamhet innan merge.

Valideringslager Fångar
Enhet- och integrationstester Regressioner och felaktig logik inom scope
Lint och typkontroller Stileller och typfel
Genomgång av acceptanskriterier Fel beteende byggt enligt spec
Spec-till-kod-diff Arkitektonisk drift och scope creep

Var AI-agenter passar in i arbetsflödet

AI-agenter är acceleratorer i varje fas, inte ersättare för granskning. Den produktiva mönstret är utkast, granska, förfin, och sedan fortsätt. Be en agent att utkast kravspeckifikationen från en problembeskrivning, redigera sedan avsikt tills mål, icke-mål och acceptanskriterier är rätt. Be en agent att utkast designplanen från de godkända kraven, granska sedan arkitekturbeslut innan någon kod existerar. Be en agent att implementera en uppgiftsskiva i taget, med dig som godkänner varje diff innan nästa uppgift påbörjas.

flowchart LR subgraph human [Människan äger] H1[Avsikt och prioriteringar] H2[Arkitekturgodkännande] H3[Diffgranskning vid kontrollpunkter] H4[Slutlig acceptans] end subgraph agent [Agenten accelererar] A1[Utkaft krav] A2[Utkaft designplan] A3[Generera uppgiftslista] A4[Implementera uppgiftsskivor] A5[Utkaft tester] end H1 --> A1 --> H1 A1 --> A2 --> H2 H2 --> A3 --> A4 --> H3 H3 --> A4 A4 --> A5 --> H4

Agenterna är särskilt användbara för att producera första utkast och boilerplate-tester. Människor är särskilt användbara för att fånga fel mål, osäker arkitektur och subtil scope creep. Arbetsflödet misslyckas när någon sida hoppas över – när agenter implementerar utan specifikationer, eller när människor skriver specifikationer utan att någonsin validera dem mot kod.

Denna arbetsflödesartikel är verktygsneutral av syftande. Verktygsspecifika utförandeguides – redigerarinställningar, slash-kommandon, agentkonfiguration – hör hemma under AI Developer Tools-klustret. Processpelaren finns här under dokumentationspraxis eftersom artefakterna är viktigare än leverantören.

Vanliga misstag som dödar Spec-Driven Development

Enorma specifikationer innan någon validering. Ett 30-sidigt kravdokument skrivet innan en prototyp eller spike är vattenfalls-papperarbete, inte SDD. Skriv den minimala specifikation som tar bort oklarhet för nästa fas, validera sedan antagningar tidigt. Inte varje funktion behöver hela fem-fasslingan – Spec-Driven Development vs Vibe Coding förklarar när lättare struktur räcker.

Vaga acceptanskriterier. Adjektiv som “snabb”, “ren” och “användarvänlig” är inte acceptanskriterier. Ersätt dem med mätbart beteende. Om du inte kan testa det, kan du inte implementera det pålitligt – särskilt med en AI-agent.

Saknade icke-mål. Utan icke-mål expanderar agenter scope som standard. De lägger till cachelager, refaktorerar intilliggande moduler och introducerar beroenden du inte bad om. Icke-mål är hur du säger nej i förväg.

Ingen testplan i designfasen. Tester som skrivs först efter implementering tenderar att bekräfta vad som byggdes, inte vad som avsågs. Planen bör namnge vilka acceptanskriterier som kartläggs till vilka testtyper innan första produktionsfilen ändras.

Hoppa över granskning vid fasgränser. Specifikationen granskad innan planen. Planen granskad innan uppgifter. Uppgifter granskade innan implementering. Varje grind är billig. Att fixa drift efter en stor merge är dyrt.

Låta genererade uppgifter explodera. Behandla en 50-posters AI-genererad uppgiftslista som ett utkast, inte ett schema. Merge redundanta poster, dela upp för stora, och radera uppgifter som inte kartläggs till ett krav.

SDD fungerar när varje fas minskar oklarhet. Den misslyckas när den skapar papperarbete.

Återanvändbara mallar

Kopiera dessa till ditt repository och anpassa dem. Lagra specifikationer alongside feature-branchen, granska dem i pull requests, och håll dem i versionskontroll så att agenter och människor läser samma källa.

Kravmall

# Funktion -- [namn]

## Problem
## Användare
## Mål
## Icke-mål
## Acceptanskriterier
## Öppna frågor

Designmall

# Design -- [funktionsnamn]

## Sammanfattning
## Påverkade moduler
## Datamodelländringar
## API-kontrakt
## Migrationer
## Säkerhet
## Observabilitet
## Teststrategi
## Risker och mitigeringsåtgärder

Uppgiftslistamall

# Uppgifter -- [funktionsnamn]

## Uppgift 1 -- [titel]
Beror på:
Filer:
Uppfyller:
Validera:
Granskningskontroll:

## Uppgift 2 -- [titel]
...

Valideringschecklista

# Validering -- [funktionsnamn]

## Automatiserat
- [ ] Alla tester lyckas
- [ ] Lint rent
- [ ] Typkontroll ren

## Acceptanskriterier
- [ ] AC-1 --
- [ ] AC-2 --

## Spec-till-kod
- [ ] Ändrade filer matchar plan
- [ ] Inga odokumenterade arkitekturbeslut
- [ ] Spec uppdaterad om implementering skiljde sig

Slutsats

Spec-driven development handlar inte om att skriva fler dokument. Det handlar om att gå igenom specificera, planera, uppgift, implementera och validera med en granskningsgrind vid varje steg. Varje fas bör lämna nästa aktör – människa eller agent – med mindre gissningsarbete än fasen innan.

Börja smått. Kör hela arbetsflödet på en medelstor funktion. Håll artefakter i markdown i repositoryt. Uppdatera specifikationen när verkligheten avviker. Validera före merge. När kedjan fungerar, får du mindre drift, mindre granskbara diffar och en hållbar inspelning av avsikt som överlever sessionåterställningar och teamöverlämningar.

När kedjan blir papperarbete, klipp scope – inte granskning. En tvåsidig specifikation som validerats slår en 30-sidig specifikation som ingen läste.

Användbara länkar

Prenumerera

Få nya inlägg om system, infrastruktur och AI-ingenjörskonst.