Goede specificaties schrijven
Je schrijft zelden een specificatie vanaf een leeg blad. Je beschrijft een wijziging in gewone taal, /opsx:propose stelt de vereisten en scenario's op, en daarna maak je ze goed. Deze pagina gaat over dat laatste deel — hoe ‘goed’ eruitziet, en hoe je de AI daarnaartoe stuurt.
Dit is de aanvulling op Een wijziging beoordelen: beoordelen is het opmerken van zwakke plekken in een concept, schrijven is weten waaruit een sterke specificatie bestaat.
Een specificatie beschrijft gedrag, niet code
Een specificatie zegt wat je systeem doet, in termen die iedereen kan controleren — niet hoe het in elkaar zit. Het bestaat uit vereisten (gedragsverklaringen) en scenario's (concrete voorbeelden die ze bewijzen).
### Requirement: Session Timeout
The system SHALL expire a session after 30 minutes of inactivity.
#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 30 minutes pass with no activity
- THEN the session is invalidated and the user must re-authenticateBewaar het hoe — de wachtrij, de bibliotheek, het tabelschema — in design.md of de code. Als gedrag en implementatie in één vereiste worden vermengd, houdt de vereiste op testbaar te zijn en begint deze te verouderen zodra de code verandert.
Wat maakt een goed vereiste
Een goed vereiste is één gedraging, zo duidelijk gesteld dat je het aan iemand anders kunt geven om te testen.
Eén verklaring, één
SHALL/MUST. Als een vereiste drie ‘en ook’-clausules bevat, zijn het eigenlijk drie vereisten. Splits ze op.Waarneembaar. Iemand buiten de code moet kunnen vaststellen of het klopt. ‘Het systeem ZAL een foutmelding tonen wanneer de upload de 10 MB overschrijdt’ is waarneembaar. ‘Het systeem ZAL grote uploads netjes afhandelen’ is dat niet.
De juiste kracht. OpenSpec gebruikt de RFC 2119-sleutelwoorden, en die betekenen verschillende dingen:
Sleutelwoord Betekenis MUST/SHALLEen harde vereiste. Niet onderhandelbaar. SHOULDEen sterke aanbeveling, met ruimte voor een gegronde uitzondering. MAYWerkelijk optioneel. Gebruik standaard
MUST/SHALL. GebruikSHOULDalleen als je echt bedoelt ‘tenzij er een goede reden is om het niet te doen’.
De toets voor een vereiste: zou een tester die de code nog nooit heeft gezien kunnen zeggen of het geslaagd is? Zo niet, dan moet het worden aangescherpt.
Wat maakt een goed scenario
Scenario's zijn de plek waar een vereiste zijn waarde bewijst. Elk is een concreet GIVEN / WHEN / THEN dat een geautomatiseerde test zou kunnen worden.
- Het oefent zijn vereiste. Een scenario dat het vereiste alleen maar in andere woorden herhaalt, test niets. Maak er een specifieke situatie van met een specifieke uitkomst.
- Dek de gevallen die ertoe doen, niet alleen de ideale situatie. De geldige login is gemakkelijk. De lege invoer, het verlopen token, de tweede klik, het mislukken — dat is waar bugs zitten, en waar een scenario het meeste waard is.
- Noem het geval in de titel. ‘Scenario: Weigert een verlopen token’ vertelt een beoordelaar in één oogopslag wat er gedekt wordt; ‘Scenario: Test 2’ doet dat niet.
Een nuttige gewoonte: vraag voordat je goedkeurt welk ene geval ik graag kapot zou zien? — en zorg dat een scenario dat geval noemt.
Kies het juiste type delta
Een wijziging beschrijft de aanpassingen aan de specificaties met drie sectietypen. Het juiste type gebruiken houdt je gearchiveerde specificaties eerlijk:
## ADDED Requirements— gloednieuw gedrag dat eerder niet bestond.## MODIFIED Requirements— gedrag dat al bestond en nu verandert. Voeg de volledige nieuwe versie toe; een korte opmerking over wat er veranderd is, helpt een beoordelaar.## REMOVED Requirements— gedrag dat verdwijnt, met een regel waarom.
Bij archivering wordt ADDED toegevoegd aan de hoofdspecificatie, MODIFIED vervangt de oude versie en REMOVED wordt eruit verwijderd. Verwijder het laatste vereiste dat een mogelijkheid heeft en je trekt deze terug: in plaats van een specificatie zonder inhoud achter te laten, verwijdert het archief openspec/specs/<capability>/spec.md. Omdat dat de enige archiefstap is die een bestand verwijdert, moet er om gevraagd worden — voeg retire_capabilities: true toe aan de .openspec.yaml van de wijziging, naast de schema: die dat bestand al nodig heeft. Zonder dat stopt het archiveren en wordt dat gemeld. Terugtrekking verwijdert het hele bestand, dus het wordt ook geweigerd als de specificatie iets bevat buiten de titel, ## Purpose en de vereisteblokken — een ## Notes-sectie, een opmerking onder een vereiste. Het afbreken noemt die regels; verplaats ze naar ## Purpose of een vereiste, of verwijder de specificatie handmatig. Voor een specificatie in de checkout van de aanroeper, noemt de archiefuitvoer ook de git checkout die een vastgelegd bestand herstelt; geselecteerde opslagplaatsen ontvangen in plaats daarvan checkout-gebonden hersteladvies. Als je een echte wijziging als ADDED markeert, krijg je twee concurrerende vereisten; als je nieuw gedrag als MODIFIED beschrijft, is er niets om te vervangen. Bij twijfel open je de huidige specificatie en kijk of het vereiste al aanwezig is.
Er is nog een sectietype dat de moeite waard is om te kennen. Wanneer je delta een mogelijkheid creëert die nog niet bestaat, begin dan met ## Purpose — een of twee zinnen over waar de mogelijkheid voor dient. Het archief gebruikt dit als de Purpose van de hoofdspecificatie die het aanmaakt; sla het over en je krijgt een TBD-aanduiding die je handmatig moet invullen. Een bestaande specificatie heeft al een Purpose, dus die van een delta wordt daar genegeerd — bewerk openspec/specs/<capability-path>/spec.md rechtstreeks om er een aan te passen. Hierbij is <capability-path> de map relatief ten opzichte van specs/, zoals user-auth in een plat project of identity/user-auth in een op domein georganiseerd project.
Houd de wijziging passend van omvang
De meest voorkomende auteursfout is niet een slecht geformuleerd vereiste — het is een wijziging die er drie tegelijk probeert te zijn.
Een goede wijziging heeft één bedoeling die je in één zin kunt uitdrukken. ‘Een donkere-modus-schakelaar toevoegen.’ ‘Het login-eindpunt rate-limiten.’ ‘Sessies van cookies migreren.’ Als het beschrijven van de wijziging veel ‘en ook’ nodig heeft, is dat het signaal om het op te splitsen.
Tekenen dat een wijziging te groot is:
- De scope van het voorstel leest als een lijst van ongerelateerde functies.
- Het beoordelen ervan zou een middag duren, dus niemand zal het doen.
- Twee mensen zouden er niet aan kunnen werken zonder in conflict te komen.
- De helft van de taken zou op zichzelf kunnen worden opgeleverd.
Kleinere wijzigingen zijn makkelijker te beoordelen, makkelijker om in één gerichte sessie te bouwen, en makkelijker om over een half jaar te begrijpen wanneer alleen het archief nog over is. Je kunt altijd verschillende wijzigingen parallel uitvoeren — zie Bewerken & itereren en Workflows.
Het tegenovergestelde gebeurt ook: een simpele typefoutherstel heeft geen drie vereisten en een ontwerpdocument nodig. Stem de ceremonie af op de belangen.
Hoe je de AI naar een goed concept stuurt
Omdat /opsx:propose het eerste concept maakt, hangt de kwaliteit van wat je terugkrijgt samen met de kwaliteit van wat je erin stopt. Je hoeft vereisten niet met de hand te schrijven — je moet de AI goed richten:
- Noem de bedoeling en de grens. "Voeg een donkere-modus-schakelaar toe die bij de eerste keer laden de OS-instelling volgt — raak de bestaande thema-API niet aan." Het buiten-de-scope-deel is even belangrijk als het binnen-de-scope-deel.
- Noem de gevallen waar je om geeft. "Zorg dat er een scenario is voor een gebruiker die al handmatig een thema heeft gekozen." De AI dekt waar jij op wijst.
- Bewerk vervolgens. Het is gewone Markdown. Maak een vaag
SHALLscherper, verwijder een scenario dat niets test, voeg het gemiste geval toe — of vraag de AI om: "het time-out-vereiste is vaag, prik het vast op 30 minuten."
Concept, verscherpen, herhalen. Een paar rondes daarvan levert een specificatie op die je vertrouwt, en daar gaat het precies om.
Een snelle checklist
Waar nu heen
- Een wijziging beoordelen — de tweeminutenronde die vastlegt wat er tussendoor glipte.
- Concepten — het diepere model achter specificaties, wijzigingen en delta's.
- Voorbeelden & Recepten — echte wijzigingen van begin tot eind.