Două teste care trec singure, dar pică împreună. Merge?
pipeline-pause.test.ts și pipeline-watchdog.test.ts trec fiecare
separat. Rulate în aceeași comandă, 3 teste ale watchdog-ului pică de fiecare dată —
inclusiv pe main curat. PR #1280 repară izolarea, nu regulile. Pagina asta îți arată
mecanismul, îl lasă să-l declanșezi tu, și pune pro și contra pe masă.
3 / 3
rulări în pereche picate, înainte de fix (pe main curat, fce08ed7)
18 / 18
rulări-stres verzi după fix (ambele ordini + combo cu 3 fișiere)
2 910
teste unit verzi local, de două ori; CI verde în 2m41s
0
linii de cod de producție atinse — doar tests/ și docs/
ACTUL 1
Trei piese, o singură bază de date
Nu e un bug în watchdog și nu e un rând uitat necurățat. E o coliziune de vecinătate: vitest rulează fișierele de test în paralel, iar toate împart aceeași bază de test.
Distribuția — apasă pe chip-uri
pipeline-pause.test.ts
Scriitorul. Testează pauza pipeline-ului: oprește și repornește comutatoare globale, la fiecare test.
Terenul comun. O singură bază Postgres pentru toate fișierele care rulează în paralel. Comutatoarele sunt rânduri în tabela automation_settings — vizibile pentru toți, instantaneu.
--fileParallelism
pipeline-watchdog.test.ts
Cititorul. Testează câinele de pază al pipeline-ului. Nu scrie niciodată comutatoarele — dar sweep-ul lui le citește, ca să nu alerteze pe o etapă oprită intenționat.
isPipelineStagePaused()apel „stuck” de 11 min
Scriitorulsuita care deține comutatoarele și le flutură
Terenul comunbaza de test partajată între procese
Cititorulsuita care doar citește și suferă
Fix-ulcitirile cititorului, țintuite la default
ACTUL 2
Declanșează flake-ul cu mâna ta
Simularea de mai jos e mecanismul real, pas cu pas. Alege modul de rulare, apoi apasă Rulează. Apoi pornește fix-ul și rulează din nou.
Simulator — perechea de teste pe aceeași bază
fix #1280: oprit
pipeline-pause.test.ts — scriitorul
așteaptă…
automation_settingstranscription_auto: — (default: pornit)cititorul e țintuit la default (vi.mock) — nu mai citește rândul ăsta
pipeline-watchdog.test.ts — cititorul
așteaptă…
Poanta: în paralel, fereastra „false” a scriitorului cade fix peste citirea sweep-ului. Nu e ordine greșită, nu e curățenie lipsă — e simultaneitate. De-asta perechea pica 100% din rulări, iar suita întreagă doar „de obicei trecea”.
ACTUL 3
Bonus găsit la diagnoză: furtul de markere
Fiecare sweep începe cu un pas de siguranță: reia din coadă toate apelurile parcate cu marker de pauză — din toată baza. Sub paralelism, sweep-ul unui vecin poate „fura” fixture-ul altcuiva.
Fixture-ul suitei pause, marker la vedere
vitest-pipeline-pause-transcription-…
automationPause: transcription
Markerul spune: „sunt parcat intenționat, reia-mă când repornește etapa.”
fix #1280: oprit
Cu fix-ul pornit, sweep-urile suitei watchdog au pasul de resume anulat (no-op) — nu testează nimeni fallback-ul acolo, iar acoperirea lui reală rămâne în pipeline-pause.test.ts. Vecinul nu mai poate fura.
ACTUL 4
Pro și contra, cinstit
Contra-urile vin din review-ul independent gpt-5.6-sol (Codex, effort ultra) pe branch — patru constatări, toate verificate în cod înainte să ajungă aici. Apasă pe fiecare contra ca să vezi răspunsul.
Pro
Zero risc de producție.
Diff-ul atinge doar două fișiere de test și TESTING.md. Niciun byte din src/. Nu cere deploy, nu poate strica runtime-ul.
Flake-ul reproductibil 100% dispare.
Înainte: 3/3 rulări-pereche picate. După: 18/18 verzi (ambele ordini + combo cu al treilea fișier expus, automations-health-panel).
Verificat pe toate porțile tale.
2 910 teste unit verzi local de două ori, lint + typecheck curate, CI verde pe runner-ul self-hosted. CI e singura poartă — și e trecută.
Review independent, pozitiv pe fix.
Codex: mock-urile sunt corect hoisted, păstrează restul exporturilor, întorc forma validă de raport; acoperirea reală rămâne unde trebuie.
Convenția e scrisă, nu doar aplicată.
TESTING.md primește regula în lecția existentă „parallel unit files share ONE database” — următorul agent nu mai redescoperă mecanismul.
Contra
Watchdog-ul nu mai exercită citirea reală a comutatoarelor.
Suita citește acum prin mock — un strat de realitate în minus.
RăspunsAdevărat, și e o mutare, nu o ștergere: integrarea reală pauză↔watchdog e testată explicit în pipeline-pause.test.ts („Pipeline Watchdog awareness of paused stages”), care rămâne pe citiri reale și e singurul scriitor al cheilor lui. Plus E2E-ul built-server acoperă resume-ul pe ambele etape.
Mock parțial = risc de drift dacă se schimbă registry-ul.
Dacă defaulturile comutatoarelor se schimbă, minte mock-ul?
RăspunsNu: mock-ul nu hardcodează valori — derivă din AUTOMATION_SWITCH_REGISTRY-ul real (importOriginal), deci un default schimbat se propagă singur. O schimbare de semnătură o prinde typecheck-ul din pre-commit și CI.
Nu rezolvă toată clasa de probleme.
Alte suite încă citesc real comutatoarele (canary, intake ClickPhone) și pot flake-ui la fel.
RăspunsCorect — și e documentat, nu ascuns: issue #1282 listează exact hazardurile reziduale, cu fișier și linie, verificate. PR-ul rezolvă perechea care pica garantat și scrie regula pentru restul. Perfectul nu blochează binele aici.
Codex a găsit și un bug de producție (nu din PR).
Claim-ul din resumePausedCallArtifacts nu e atomic: două resume-uri suprapuse pot dubla dispatch-ul.
RăspunsPre-existent — pe main de dinainte de PR, doar că review-ul l-a scos la lumină. E punctul 3 din #1282, cu direcție de fix (claim condițional atomic + test concurent). Nu e un motiv să ții pe loc un fix de teste; e un motiv să deschizi #1282 curând.
ACTUL 5
Verdictul, pe criteriile tale
Regulile casei: „testele sunt singurul code review care există — nu slăbi un test ca să treacă” și „complexitate minimă”. Aplicate:
Criteriu
Fără merge
Cu merge (#1280)
Perechea de teste, rulată împreună
pică mereu
verde, 18/18
Suita întreagă sub paralelism
„de obicei trece” = noroc
perechea eliminată din ecuație
Slăbește vreun test ca să treacă?
—
nu — mută acoperirea la proprietar, n-o șterge
Cod de producție atins
nimic
nimic
Hazarduri reziduale
necunoscute, nescrise
cunoscute, trasate în #1282
Complexitate adăugată
zero
2 mock-uri comentate + o regulă în doc
alegerea · merge
Merge #1280. Fix țintit, test-only, verificat pe toate porțile, cu review independent și cu partea nerezolvată documentată la vedere.
parcat · #1282
Restul clasei. Citirile reale din canary/intake + claim-ul neatomic din producție. Trasate cu fișier:linie și direcții de fix. Punctul 3 merită prioritate.
respins · a nu se face
„Lasă-l așa, suita mare trece oricum.” Adică: păstrezi un test care pică în funcție de vecini. Un review process care depinde de noroc nu e review process.
Merge PR #1280 — CI e deja verde; branch-ul claude/serene-boyd-6bb0e0 se închide odată cu el.
Nu cere deploy — schimbarea nu atinge runtime-ul; intră natural la următorul pnpm run deploy.
#1282 rămâne deschis — când ai o fereastră, punctul 3 (dublu-dispatch în resume) e singurul cu miză de producție.
mantra
Un test care depinde de vecini nu păzește codul — păzește norocul.