strategia de teste voost-control · 4 variante măsurate · 12 iul 2026

Toate testele împart o singură bază de date. Până când?

Fiecare flake din ultimele luni — inclusiv perechea de azi-noapte — are aceeași rădăcină: vitest rulează fișierele în paralel, dar toate scriu în aceeași bază Postgres. Am cartografiat tot sistemul (2 workflow-uri, 16 agenți, Codex gpt-5.6-sol inclus), am construit 3 prototipuri reale și le-am măsurat. Nimic de mai jos nu e estimare — totul a rulat pe mașina ta.

58,1s
lana unit azi (413 fișiere, 2 workeri, CI chiar mai rău: 1 worker)
22,5s
aceeași lană, prototipurile A+B compuse, toate 3016 testele verzi
10 / 10
perechea istoric flaky, FĂRĂ mock-uri, pe baze private (controlul: 2/2 pică)
0
linii schimbate în src/ — totul e infrastructură de teste
ACTUL 1

Boala și cicatricile ei

Nu am doar o părere că baza partajată e problema — am inventarul cicatricilor. Fiecare mecanism de mai jos există doar ca să gestioneze consecințele bazei comune. Apasă pe fiecare.

Mecanismele-cicatrice (apasă)
suite-lock (21 fișiere) SERIAL_FIRST_FILES vi.mock pe switch-uri cleanup registry (463 linii) ~130 linii de reguli în TESTING.md cap 25% workeri + CI la 1 404 forkuri de guard = 24s
Chip-urile tăiate cu ✕ verde (după ce activezi varianta B în Actul 3) sunt mecanismele care se pot șterge, nu doar îmblânzi.
ACTUL 2

Ideea centrală: fiecare worker cu baza lui

Fix-ul structural e aproape jenant de ieftin: o bază-template migrată o dată (~1s), clonată per worker cu createdb -T în 0,14s. Joacă-te cu simulatorul — e aritmetica reală, măsurată.

Simulator — cine ce bază vede
2
voost_control_test_<ticket> — a tuturor
conexiuni (max): 42 / buget <60 din 300 partajate provizionare: 0s disc: 0 MB
Măsurat în prototipul B: clona 0,14s / 12 MB; la 6 workeri cu connection_limit=3, peak-ul real de conexiuni a fost 14 — mai puțin decât cele ~42 de azi la doar 2 workeri. Iar după kill -9 în mijlocul rulării, janitorul a curățat singur cele 6 clone orfane la următorul run.
ACTUL 3

Ce au arătat prototipurile (rulate, nu promise)

Trei prototipuri pe branch-uri separate, măsurate câte 3 rulări, apoi atacate de un review Codex gpt-5.6-sol și un sceptic care a re-rulat el însuși testele de aur. Toate cele 6 verdicte: solide.

Lana unit, cap la cap (413 fișiere / 3016 teste, aceeași mașină)
Azi2 workeri · bază partajată
58,1s
A: lane split + guard o datăfără schimbare de model
32,3–33,6s
B: clone per worker, 6 workeriizolare structurală
38,5–42,1s
A+B, lane suprapuseizolare + viteză
22,5–25,8s
Bonusul nevizibil aici: CI rulează azi cu 1 worker — câștigul acolo e mai mare decât local. Iar lana de integrare (build Next de câteva minute la fiecare rulare) are prototipul F: build-ul se sare când amprenta surselor nu s-a schimbat — logică implementată și testată, cu un fix cerut de Codex înainte de ship (variabilele NEXT_PUBLIC_* trebuie incluse în amprentă).
Testul de aur — flake-ul real, fără mock-uri

Perechea pipeline-pause × pipeline-watchdog (+ automations-health-panel), cu band-aid-ul de mock-uri scos, rulată de 10 ori pe clone per worker:

10 / 10
verde cu VOOST_DB_PER_WORKER=1 — citiri REALE de switch-uri, zero vi.mock
2 / 2
picate în modul de azi, aceiași workeri — boala e vie, clona o elimină
×2
scepticul independent a re-rulat ambele serii și a reprodus exact rezultatul
Asta e inversul drift-ului: în loc să adăugăm mock-uri ca să ținem testele verzi (stratul care poate minți în timp), ștergem mock-urile și testele citesc din nou codul real, pe o bază pe care n-o mai calcă nimeni. Template-ul e legat criptografic de migrațiile din repo (hash), deci nu poate rămâne în urmă în tăcere — spre deosebire de template-ul ad-hoc pe care l-am găsit azi pe mașină, deja stale cu o migrare.
ACTUL 4

Variantele tale, cu pro și contra

Toate cele patru sunt viabile — de-asta alegi tu. Apasă „detalii" pentru contra-argumentele complete și fix-urile cerute de review înainte de merge.

V0 · a nu se face

Rămânem cum e

58s · flakes gestionate manual
  • Zero efort acum
  • Fiecare flake nou = încă o convenție, încă un mock, încă o lecție în doc (banda de alergat de la #743 încoace)
  • #1282 rămâne deschis; CI rămâne la 1 worker
  • Fiecare agent nou re-învață ~130 de linii de reguli
de ce e respinsăAzi-noapte a demonstrat costul: un flake de vecinătate a mâncat o seară de diagnoză. Sistemul actual FUNCȚIONEAZĂ, dar prin disciplină documentată, nu prin construcție — iar disciplina documentată e exact ce uită agenții.
V1 · doar viteza

Prototipul A singur

~33s (×1,75) · risc minim
  • 311 linii, 5 fișiere, zero schimbare de model — poate intra azi
  • Șterge taxa de 24s (404 forkuri de guard → 1 per mediu), guard-ul rămâne intact (verificat cu env otrăvit)
  • Livrează promisiunea deja scrisă în ci.yml și vitest.config
  • Nu vindecă nimic: toate cicatricile și #1282 rămân
  • Lana cu DB rămâne la 2 workeri (25%)
fix-uri pre-merge (din review)Amprenta env să includă și conținutul fișierelor dotenv (fereastră îngustă, semnalată de sceptic); docs/TESTING.md actualizat în același branch; test:ci mutat pe noul runner. Toate mici.
V2 · recomandarea

A + B: split + clone per worker

~23s (×2,5) · boala eliminată
  • Flake-class-ul dispare prin construcție — dovada: 10/10 fără mock-uri
  • Se ȘTERG: suite-lock, SERIAL_FIRST, vi.mock pinning, mare parte din cleanup + regulile din doc — mai puțin de învățat pentru agenți, nu mai mult
  • Anti-drift dublu: mock-urile pleacă, template-ul e hash-uit pe migrații (nu poate rămâne stale în tăcere)
  • Buget de conexiuni MAI MIC ca azi (peak 14 vs ~42); janitor auto după crash (kill -9 verificat)
  • 0 linii în src/; flag-gated (oprit = comportamentul de azi, byte-identic)
  • 267 linii de infrastructură nouă de întreținut (un modul cu invariante clare)
  • Fișierele din ACELAȘI worker împart clona secvențial — regula „scope-your-counts" rămâne pentru cazul ăla (sau escaladezi la V3)
  • Lana integration-api rămâne pe modelul vechi (server unic) — pas separat
fix-uri pre-merge (din review)Numele clonelor să includă un token de rulare (două rulări simultane pe ACELAȘI ticket nu trebuie să-și șteargă clonele una alteia — P2 de la Codex); păstrarea query-params din URL la rescriere; sweep de fișiere media per clonă înainte de drop. Definition of done: ștergerea mecanismelor retirate + rescrierea lecției din TESTING.md + un ADR.
V3 · parcat deocamdată

Bază per FIȘIER (nu doar per worker)

~+8s peste V2 · izolare absolută
  • Mental model perfect pentru agenți: „fișierul tău = baza ta, fă orice"
  • Ar șterge și restul disciplinei de cleanup
  • ~0,3s clonă+drop × 153 fișiere DB — plătești mereu, câștigi doar dacă leakage-ul secvențial intra-worker chiar mușcă
  • Ambii ideatori (Codex și Fable) au zis: doar dacă V2 se dovedește insuficient
criteriu de dezghețareDacă după V2 mai apare vreun flake din rânduri acumulate secvențial în același worker — adoptezi per-file întâi pe lana cli-only (fișiere puține și lungi, overhead-ul se amortizează).
Scorecard — pe criteriile tale
CriteriuV0 aziV1 doar AV2 A+B ★V3 per-file
Flaky?clase vii, gestionate manualla fel ca V0clasa DB eliminată structuralidem + intra-worker
Viteză (lana unit)58s · CI 1 worker~33s~23s · CI deblocat~31s (est.)
Risc de driftmock-urile se înmulțescneschimbatmock-uri șterse + template hash-uitidem
De învățat pentru agenți~130 linii de regulila felo frază: „workerul tău are baza lui"„fișierul tău are baza lui"
Mentenanțăconvenții în creștereminimăun modul de 267 linii ÎN LOC de 4 sisteme de convenții+ janitor per-file
Cod de producție atins000
ACTUL 5

Dacă alegi, ce se întâmplă concret

mantra

Izolarea care ține e cea construită, nu cea documentată: o clonă de 0,14s bate o pagină de reguli.