Documentația ca JSON
ForkTex Engineering · 5 septembrie 2026 · 4 min
Documentația de inginerie putrezește dintr-un motiv structural, nu unul cultural.
Diagnosticul obișnuit e disciplina: lumea n-a ținut-o la zi. Dar uită-te la ce cere formatul de la tine. O regulă despre cum gestionează serviciile erorile e un paragraf de proză. Severitatea ei e sugerată de un adverb. Dacă ceva o impune efectiv e o propoziție pe care cineva a scris-o o dată și nimeni n-a mai verificat-o de atunci. Relația ei cu alte trei documente e un hyperlink care se rupe când un fișier e redenumit.
Nimic din toate astea nu e verificabil. Proza n-are schemă, așa că nimic nu-ți poate spune când un document a devenit fals. Doar un om care-l recitește poate, iar nimeni nu recitește documentație pe care n-a scris-o chiar el.
Așa că am renunțat s-o scriem manual. Sursa de adevăr e JSON, validat față de modele tipizate. Markdown-ul pe care-l citește toată lumea e generat din el.
Structura e ce o face verificabilă
Un document e o înregistrare cu câmpuri obligatorii: un id stabil, un titlu, un rezumat de lungime reală și o dată. Corpul lui e blocuri tipizate. Reguli, exemple lucrate, linkuri către alte documente, întrebări deschise.
Unitatea care poartă greutatea e regula:
{
"id": "errors:one-envelope",
"title": "One error envelope",
"statement": "Every service serialises failures into the shared envelope.",
"severity": "blocker",
"enforcement": "tests/test_architecture/test_conventions.py",
"rationale": "A client written against two error shapes handles neither."
}enforcement e obligatoriu și nu poate fi gol. Această singură constrângere schimbă caracterul întregului corpus.
O regulă pe care nimic n-o dovedește e o preferință îmbrăcată în haine de regulă. Mai rău, o impunere inventată e mai dăunătoare decât una onest slabă, pentru că următorul cititor are încredere în ea și încetează să mai verifice. Deci "review" e o valoare legitimă. Multe reguli reale sunt impuse de o persoană care observă. Golul nu e o valoare legitimă. Dacă nu poți numi ce ar prinde o încălcare, ai scris o opinie, și ar trebui marcată ca atare.
Severitatea e un enum ordonat, nu o etichetă. Cititorul nu trebuie să știe din ce categorie face parte un document; trebuie să știe dacă această regulă anume îl obligă. Severitatea spune asta direct.
Ce am lăsat deliberat afară
Trei câmpuri care par evident necesare lipsesc.
Nu există status. Statusul e metadata despre ciclul de viață al unei înregistrări și aparține de orice stochează înregistrări, nu de conținutul documentului. A-l pune în document înseamnă că fiecare cititor trebuie să deducă dacă se uită la ceva viu.
Nu există kind sau authority. Amândouă clasifică fără să informeze. A ști că un document e „un standard", nu „un ghid", nu-i spune cititorului aproape nimic acționabil; a ști că o regulă anume e blocantă îi spune totul.
Id-urile sunt create manual, nu derivate. Obișnuiau să fie calculate din numele fișierului și clasificare, ceea ce însemna că redenumirea unui fișier rupea fiecare referință către el. La fel și reclasificarea unui document, care e o decizie editorială ce ar trebui să nu coste nimic. Un id care se schimbă nu e un id.
Markdown e un export, nu o sursă
Generarea produce pagini markdown plate, pe care lumea le citește într-un browser sau un terminal. Sunt output. Editarea uneia n-are sens, pentru că următorul build o suprascrie.
Ceea ce ridică întrebarea evidentă: ce oprește pe cineva să editeze una oricum, în grabă, și editarea să supraviețuiască?
Build-ul regenerează fiecare pagină și o compară byte cu byte cu ce e comis. O pagină editată manual pică verificarea.
Ăsta e mecanismul portant al întregului design. Fără el, generarea e doar consultativă: o editare funcționează, nimeni nu regenerează o lună, iar fișierul generat devine tacit un al doilea autor al aceluiași fapt. Fără nicio modalitate de a spune care dintre cei doi are dreptate. Cu el, editarea pică imediat, cât timp persoana care a făcut-o e încă acolo să fie redirecționată spre JSON.
Fiecare pagină generată poartă și un banner care numește comanda care a produs-o. Un fișier care nu spune că e generat va fi editat până la urmă de cineva de bună-credință.
Jumătatea de regăsire
Markdown-ul generat rezolvă problema umană. Nu o rezolvă pe cea a mașinii, iar asta se dovedește a fi jumătatea mai interesantă.
A da unui agent întregul corpus e risipitor și, peste o anumită dimensiune, imposibil. A citi tot ce avem noi costă aproximativ șaizeci și șapte de mii de tokeni. Majoritatea task-urilor au nevoie de o fracțiune din asta, iar care fracțiune depinde de task.
Deci regăsirea e o parte de prim rang a bibliotecii, nu ceva improvizat de fiecare consumator:
- Ceri setul normativ și primești fiecare regulă. Câteva mii de tokeni, neordonate. Ordonarea aici ar fi o greșeală: a renunța la o regulă blocantă ca să economisești câteva sute de tokeni e un schimb prost la orice buget.
- Pui o întrebare și primești fundamentare ordonată, cu buget. Normalizată după lungime, ca cel mai lung document să nu câștige prin volum brut, cu rezumate injectate în loc de pagini întregi.
- Filtrezi după etichetă și setul se restrânge la ce obligă limbajul sau subsistemul în care ești de fapt.
O proprietate contează mai mult decât ordonarea: când bugetul forțează ceva afară, răspunsul spune ce a scos. Un context trunchiat tacit citește exact ca unul complet, iar un agent căruia i se dă un set parțial de reguli le va aplica cu încredere pe cele primite. A numi omisiunea e diferența dintre un buget și o minciună.
Regula de arhitectură
Biblioteca are o singură constrângere structurală: nucleul ei nu atinge niciodată stocarea. Fără căi de fișiere, fără apeluri open, fără bază de date.
Stocarea e o interfață cu patru metode, listă chei, citește, scrie, șterge, peste o cheie opacă. Implementarea pe fișiere e singura livrată, iar una în memorie are cam zece linii. Suita de teste implementează o a doua special ca să dovedească faptul că granița e reală, nu doar nominală.
Câștigul e că același corpus poate trăi într-un director, o bază de date sau un object store fără ca modelele să știe. Constrângerea care a produs asta a fost pur și simplu refuzul de a lăsa un Path să intre în nucleu.
Ce costă
Scrisul e mai lent. A scrie o regulă înseamnă a-i decide severitatea și a numi ce o impune, și amândouă sunt decizii pe care proza te lasă să le eviți. Frecarea asta e feature-ul, dar tot frecare e, iar un corpus cu două documente nu o amortizează.
Dimensiunea la care începe să merite e cam acolo unde un corpus devine ceva ce lumea citează unii altora, nu citește de la un capăt la altul. Unde întrebările devin „mă obligă asta" și „ce dovedește", care sunt exact întrebările la care structura poate răspunde, iar proza nu.
Am ajuns la acel punct la vreo douăzeci de documente. Sub zece, un director markdown bine ținut e probabil răspunsul corect, și n-am pretinde altceva.