Je kunt de ontwikkeling niet pauzeren. Dat is het eerste dat je moet accepteren. Tickets blijven binnenkomen, klanten verwachten zendingen, en je bestaande code stopt niet met draaien alleen maar omdat je hebt besloten het te documenteren. Geen enkele engineering manager zal een maandlange freeze goedkeuren zodat het team de specificatie kan schrijven die er vanaf dag één had moeten zijn. OpenSpec is gebouwd voor de realiteit, niet voor greenfield-fantasieën. Het werkt het beste wanneer je het vastzet op wat je al hebt, inclusief de klanten.

Het doel hier is geen rewrite. Het is eerlijke archeologie. Je graaft op wat er daadwerkelijk in productie draait, beschrijft het nauwkeurig, en laat die beschrijving evolueren naarmate je code verandert. Wanneer je specificatie overeenkomt met je systeem, maak je het leven makkelijker voor de engineers die het volgende kwartaal instromen en voor de AI-tools die nu in je IDE zitten. Hier is hoe je dat doet zonder een enkele release te missen.

Begin met wat je daadwerkelijk doet

Open je repository en je zult mappen zien met de namen controllers, models, services en utils. Dit zijn technische lagen, en ze liegen tegen je. Ze beschrijven niet wat je systeem voor de business doet. Een map vol JavaScript-bestanden legt niet uit hoe een bestelling een verzending wordt. Om OpenSpec achteraf toe te passen, moet je in capabilities denken.

Zoek naar de stabiele bedrijfsprocessen die zouden overleven, zelfs als je de hele stack in een andere taal zou herschrijven. In de meeste productbedrijven komen deze steeds weer terug: Orders, Billing, Inventory, Customers en Notifications. Noem vijf tot acht van deze kern-capabilities.

Dwing jezelf voor elk van deze punten om vijf specifieke vragen te beantwoorden. Welk probleem in de echte wereld lost deze capability op? Waar bevindt de code zich daadwerkelijk — in één service, drie microservices, of een legacy-module waar niemand aan wil zitten? Wat triggert het: een gebruikersklik, een geplande cronjob, een inkomende webhook? Welke data gaat erin en welke data komt eruit? En tot slot, welke andere systemen zijn hiervan afhankelijk, wat betekent: wat gaat er kapot als dit onderdeel stopt met werken?

Wees meedogenloos eerlijk. Als je "Customers"-capability verspreid is over een Rails-monoliet, een Node API en een extern CRM, schrijf dat dan precies zo op. Je kaart moet lijken op het terrein, niet op de droom van een architect.

Schrijf de waarheid, niet de wensenlijst

De gevaarlijkste zin bij elk documentatieproces is: "Nu we dit toch opschrijven, kunnen we het maar beter meteen repareren." Stop. Je bent het checkout-proces niet aan het herontwerpen. Je beschrijft het checkout-proces dat op dit moment echte creditcards afrekent.

Als het plaatsen van een bestelling een onmiddellijke betalingsverwerking triggert en vervolgens een e-mail verstuurt via een background worker, documenteer dan exact die volgorde. Voeg geen event queue toe die je van plan bent het volgende kwartaal toe te voegen. Doe alsof de validatie plaatsvindt aan de rand van de API als deze in werkelijkheid diep in een service class zit. Nauwkeurigheid is veel belangrijker dan ambitie.

Onjuiste documentatie is erger dan helemaal geen documentatie. Het traint nieuwe medewerkers om gedrag te verwachten dat niet bestaat. Het stuurt AI-coding assistants op denkbeeldige paden op basis van wensen. Wanneer je specificatie overeenkomt met de productieomgeving, creëer je een betrouwbare baseline. Debuggen gaat sneller omdat je stopt met gissen naar de "bedoelde" flow. Refactoren wordt veiliger omdat je weet dat het startpunt echt is.

Extraheer contracten uit je API's

Je API-endpoints handhaven al regels. Ze houden ze alleen impliciet. Het achteraf toepassen van OpenSpec betekent dat je die regels naar de oppervlakte haalt.

Begin met inputs en validatie. Wat accepteert het endpoint daadwerkelijk? Documenteer de types, de verplichte velden, de maximale lengtes en de afhankelijkheden tussen velden. Beschrijf vervolgens het zakelijke gedrag. Creëert deze aanroep een record, triggert het een side effect, of valideert het simpelweg de status tegenover een andere service? Wees specifiek.

Catalogueer tot slot de responses. Wat geeft een succesvolle aanroep terug? Wat zijn de exacte foutcodes en onder welke omstandigheden treden ze op? Schrijf niet "geeft een foutmelding terug". Schrijf "geeft 422 terug wanneer het factuuradres ontbreekt en 409 wanneer de voorraad al door een ander proces is gereserveerd". Dat niveau van precisie verandert een vage route in een contract waar frontend-teams, QA-engineers en geautomatiseerde tools op kunnen vertrouwen.

Spoor de verborgen regels op

Some of the most expensive knowledge in your system lives in the gaps. It is buried in conditional blocks inside service classes, tucked into database triggers, or written into stored procedures that no one has touched in two years. These are your business rules, and they are usually rediscovered during outages or by cornering the one engineer who has been there since the beginning.

Pull them into daylight. Start with the ones you already know. Orders above a certain value need manager approval before they proceed. Inactive user accounts cannot create new orders. Refunds are only permitted before settlement completes. Write each rule next to the capability it governs, in language clear enough that a product manager could read it without a translator.

When you centralize these rules, you do more than document them. You expose duplication. You reveal conflicts. And you give the entire team a single place to debate policy before someone commits a one-line change that accidentally violates a constraint you forgot existed.

Map the Plumbing

Modern systems run on events. An action in one service ripples through half a dozen others before anything visible reaches the user. You need to chart those ripples. Map the flow from one event to the next for your core workflows. Order created leads to inventory reserved, which waits for payment confirmed. Draw the full chain, even if some links feel fragile or use different protocols.

Do not stop at internal traffic. External services are part of your system whether you treat them that way or not. For each integration, record its purpose, how your application authenticates, and how it fails. Does the payment gateway timeout after thirty seconds and return a generic 500? Does the shipping API return malformed JSON on weekends? Does the identity provider revoke refresh tokens earlier than its own documentation claims? These details look trivial