mjolnir-qa 0.4.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.tr.md ADDED
@@ -0,0 +1,699 @@
1
+ <div align="center">
2
+
3
+ <img src="assets/readme/logo.png" alt="Mjölnir — Verification Trust Engine" width="800" />
4
+
5
+ ### Testlerin sana yalan söylüyor. Biz kanıtlıyoruz.
6
+
7
+ **QA için Verification Trust Engine.** Mjölnir test takımlarını ve CI
8
+ boru hatlarını denetler, güvenilirlik puanı bildirir ve güvenin tam
9
+ olarak nerede kırıldığını gösterir.
10
+
11
+ [![npm](https://img.shields.io/npm/v/mjolnir-qa.svg?style=flat-square&color=C9A227&labelColor=0B0F17)](https://www.npmjs.com/package/mjolnir-qa)
12
+ [![ci](https://img.shields.io/github/actions/workflow/status/Sergey-Bar/Mjolnir/ci.yml?branch=main&style=flat-square&label=ci&labelColor=0B0F17)](https://github.com/Sergey-Bar/Mjolnir/actions/workflows/ci.yml)
13
+ [![license](https://img.shields.io/badge/license-MIT-C9A227.svg?style=flat-square&labelColor=0B0F17)](LICENSE)
14
+ [![node](https://img.shields.io/badge/node-%E2%89%A5%2022.18-2E8C7F.svg?style=flat-square&labelColor=0B0F17)](https://nodejs.org)
15
+
16
+ [English](README.md) | [简体中文](README.zh.md) | [繁體中文](README.zht.md) | [한국어](README.ko.md) | [Deutsch](README.de.md) | [Español](README.es.md) | [Français](README.fr.md) | [Italiano](README.it.md) | [Dansk](README.da.md) | [日本語](README.ja.md) | [Polski](README.pl.md) | [Русский](README.ru.md) | [Norsk](README.no.md) | [Português (Brasil)](README.br.md) | [ไทย](README.th.md) | Türkçe | [Українська](README.uk.md) | [বাংলা](README.bn.md) | [Ελληνικά](README.gr.md) | [Tiếng Việt](README.vi.md) | [עברית](README.he.md) | [العربية](README.ar.md) | [Bosanski](README.bs.md)
17
+
18
+ > 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-04.
19
+
20
+ ```bash
21
+ npx mjolnir-qa@latest
22
+ ```
23
+
24
+ **Testleriniz güvenilmeye değer mi?**
25
+
26
+ [Nasıl çalıştığını gör](#-nasıl-çalıştığını-gör) ·
27
+ [Hızlı başlangıç](#-hızlı-başlangıç) ·
28
+ [Neleri kontrol eder](#-mjölnir-neleri-kontrol-eder) ·
29
+ [Puanlama](#puanlama-nasıl-çalışır) ·
30
+ [CI](#-ci-entegrasyonu) · [Yapılandırma](#yapılandırma) ·
31
+ [Belgelendirme](#-belgelendirme)
32
+
33
+ </div>
34
+
35
+ ---
36
+
37
+ ## 🎬 Nasıl çalıştığını gör
38
+
39
+ <p align="center">
40
+ <img src="assets/readme/demo.svg" alt="Mjölnir'in demo bir repo üzerindeki eksiksiz --verbose raporu: WORTHINESS 75/100 NEEDS WORK, kategori bazında teşhis dökümü, FIX THIS FIRST listesi ve her bulgu için kural kimliği ile satır numarası — CI, Playwright, test hijyeni ve Python kuralları boyunca" width="900" />
41
+ </p>
42
+
43
+ <sub>`npx mjolnir-qa ./examples/demo-repo --verbose` çıktısının tam hali,
44
+ gerçek reporterdan render edildi — hiçbir şey kırpılmadı.
45
+ `npm run docs:demo` ile yeniden üretilir;
46
+ [`tests/demo-asset-reproducibility.spec.ts`](tests/demo-asset-reproducibility.spec.ts)
47
+ dosyası, çıktı aracın bastığından saptarsa CI'ı düşürür.</sub>
48
+
49
+ **Az önce olanlar:**
50
+
51
+ 1. Mjölnir, Playwright spesifikasyonlarını, kendi yapılandırmasını, CI
52
+ workflow'unu ve bir Python test dosyasını keşfetti — dört
53
+ dil/format, tek geçiş.
54
+ 2. Takımın güvenini zayıflatan kanıtlar buldu — bir işi maskeden
55
+ geçiren `continue-on-error`, bir exit kodunu yutan `|| true`, katı
56
+ sleep'ler, kırılgan bir seçici, sabitlenmiş staging URL'leri, bir
57
+ `networkidle` beklemesi.
58
+ 3. Her birini kural kimliği, konum ve düzeltme içeren somut bir bulguya
59
+ — ve bir PR'ı gate'leyebileceğin tek bir puana dönüştürdü.
60
+
61
+ ### Yakın plandan bir bulgu
62
+
63
+ Yukarıdaki ilk bulgu için `mjolnir explain QA-CI-001` komutunu çalıştırın,
64
+ elde edeceğiniz:
65
+
66
+ ```text
67
+ ▚▞ QA-CI-001 — continue-on-error masks a failing verification gate
68
+
69
+ Severity: error
70
+ Confidence: high
71
+ Evidence: E2
72
+ Measured FP: not yet measured — this rule ships on assumption (see docs/FP-AUDIT.md)
73
+
74
+ WHAT WAS FOUND (real detector output, not a mockup)
75
+ Job `security-scan` runs a verification gate under `continue-on-error: true`.
76
+
77
+ WHY IT MATTERS
78
+ This job can fail every day and CI will still show green. The checkmark
79
+ on this workflow cannot be trusted.
80
+
81
+ HOW TO FIX
82
+ Remove continue-on-error, or scope it to individual non-blocking steps only.
83
+ ```
84
+
85
+ İşte değer birimi: stil özürü değil, CI'ınızın bir şeyin geçtiğini
86
+ söylediği — oysa geçmediği — bir yer.
87
+
88
+ ---
89
+
90
+ ## ⚡ Hızlı başlangıç
91
+
92
+ Tam rapor ve güvenilirlik puanı için bir repoda çalıştırın:
93
+
94
+ ```bash
95
+ npx mjolnir-qa@latest
96
+ ```
97
+
98
+ **CI'da ürün tek komuttur.** Yalnızca branch'in dokunduğu şeyi tarar ve
99
+ yeni sorunlarda sıfır olmayan kodla çıkar:
100
+
101
+ ```bash
102
+ npx mjolnir-qa@latest --scope changed
103
+ ```
104
+
105
+ Bunu bir PR kontrolüne koyun — `mjolnir ci install` workflow'u yazar —
106
+ ve bitti. Gerisi opsiyoneldir.
107
+
108
+ | Komut | Ne yapar |
109
+ | ----------------------------------- | ------------------------------------------------------------------- |
110
+ | `mjolnir` | Tüm repo taraması + güvenilirlik puanı |
111
+ | `mjolnir --scope changed` | Yalnızca branch'inin getirdikleri — CI biçimi |
112
+ | `mjolnir ci install` | Danışmanlık PR workflow'unu üretir |
113
+ | `mjolnir explain QA-CI-001` | Ne / neden / düzeltme + bir kural için ölçülmüş FP oranı |
114
+ | `mjolnir rules --unmeasured` | Ölçümle değil varsayımla çalışan kurallar |
115
+ | `mjolnir --json` / `--format sarif` | Makine okunur / GitHub Code Scanning |
116
+ | `mjolnir --strict` | Quarantine katmanı kurallarını da çalıştırır (daha yüksek FP riski) |
117
+
118
+ <details>
119
+ <summary><strong>Bir şey flaky olduğunda</strong></summary>
120
+
121
+ | Komut | Ne yapar |
122
+ | ----------------------------------- | --------------------------------------------------------------- |
123
+ | `mjolnir forensics ./test-results/` | Gerçek çalıştırma verileri → `TRUE-FLAKE` hükümleri, `FLAKY.md` |
124
+ | `mjolnir triage ./test-results/` | Yürütme geçmişinden karantina önerisi |
125
+ | `mjolnir pw-report ./test-results/` | Playwright çalıştırma özeti — retry / flake / en yavaşlar |
126
+ | `mjolnir doctor:playwright` | Yalnızca Playwright derin tarama + Selector Health Score |
127
+
128
+ </details>
129
+
130
+ <details>
131
+ <summary><strong>Nadiren / raporlar</strong></summary>
132
+
133
+ | Komut | Ne yapar |
134
+ | ------------------------------- | ---------------------------------------------------------------- |
135
+ | `mjolnir fix --dry-run` / `fix` | Kanıtlı, güvenli otomatik düzeltmeler |
136
+ | `mjolnir baseline` / `diff` | Bulguların anlık görüntüsü, sonra yalnızca yeni/kötüleşen raporu |
137
+ | `mjolnir impact --since <ref>` | Önceki bir commit'ten bu yana ne değişti |
138
+ | `mjolnir debt` | Maliyet modeliyle test borcu defteri |
139
+ | `mjolnir handover` | Yeni QA için takım devralma haritası |
140
+ | `mjolnir stats` | Görülen düzeltmelerin yerel, tüm-zaman sayaçları |
141
+ | `mjolnir badge` | shields.io endpoint JSON'u + snippet |
142
+ | `mjolnir rules --md` | Tam kural kataloğu (JSON veya Markdown) |
143
+ | `mjolnir doctor` | Mjölnir'in kendi kural tabanının iç denetimi |
144
+ | `mjolnir create-rule <ID>` | Yeni kural + fixture iskeleti |
145
+ | `mjolnir --format mermaid` | PR yorumu için test mimarisi diyagramı |
146
+
147
+ </details>
148
+
149
+ Tercih ediyorsanız `npx` yerine global kurun: `npm i -g mjolnir-qa`.
150
+ Node.js ≥ 22.18 gerekir. Windows, macOS ve Linux'ta çalışır.
151
+
152
+ ---
153
+
154
+ ## 👥 Kimin için?
155
+
156
+ - **QA / SDET** — e2e veya entegrasyon takımına sahip, takımın ürettiği
157
+ yeşil onayın gerçekten hak edildiğine dair kanıt gerektiren kişiler.
158
+ - **Platform / DevEx ekipleri** — CI bütünlüğünden ve release
159
+ kapılarından sorumlu; bir `continue-on-error`'ın kırmızı hattı sessizce
160
+ yeşile boyamasını istemeyenler.
161
+ - **OSS bakıcıları** — yerel ve CI'da, sıfır ağ çağrısıyla çalışan ucuz,
162
+ her zaman açık bir doğrulama kapısı isteyenler.
163
+
164
+ ---
165
+
166
+ ## 🔨 Mjölnir neleri kontrol eder
167
+
168
+ | | |
169
+ | --- | ------------------------------------------------------------------------------------------------------------------------------- |
170
+ | ⚖️ | **Güvenilirlik puanı** — tek sayı, şeffaf kesinti tablosu, kara kutu yok |
171
+ | 🎭 | **Selector Health Score** — yalnızca geçiş oranınızı değil, Playwright locator'larınızı not eder |
172
+ | 🔬 | **Çalışma zamanı adli analizi** — gerçek Playwright/JUnit verilerini okur ve `TRUE-FLAKE` yakalar, yalnızca statik tahmin değil |
173
+ | 🚨 | **CI bütünlüğü kuralları** — `continue-on-error`, `\|\| true` ve diğer yanlış-yeşil hilelerini yakalar |
174
+ | 🐍 | **Dört Playwright bağlamasının hepsi** — TypeScript, Python, Java, C#/.NET — artı pytest, JUnit/TestNG ve CI workflow'ları |
175
+ | 🔒 | **Local-first** — tarama sırasında sıfır ağ çağrısı, sıfır telemetri, saniyeler içinde çalışır |
176
+
177
+ ### Kurallar
178
+
179
+ Her kural, must-fire **ve** must-not-fire fixture'larıyla gelir.
180
+ Kendi negatif fixture'ında tetiklenen bir kural sevk edilemez — bu,
181
+ yanlış pozitif duvarıdır.
182
+
183
+ <details>
184
+ <summary><strong>Test hijyeni</strong></summary>
185
+
186
+ | ID | Kural | Severity |
187
+ | ----------- | --------------------------------------------------- | -------- |
188
+ | QA-TEST-001 | Commit edilmiş odaklı test (`.only`, `fit`) | error |
189
+ | QA-TEST-002 | Gerekçesiz atlanan test | error |
190
+ | QA-TEST-002 | Kayıtlı gerekçeyle atlanan test | warning |
191
+ | QA-TEST-003 | Assertion içermeyen test | error |
192
+ | QA-TEST-004 | Katı sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning |
193
+ | QA-TEST-006 | Flakiness'i gizleyen retry istismarı | warning |
194
+ | QA-TEST-010 | Boş test gövdesi | error |
195
+
196
+ </details>
197
+
198
+ <details>
199
+ <summary><strong>Test kalitesi</strong></summary>
200
+
201
+ | ID | Kural | Severity |
202
+ | ------------ | ----------------------------------- | -------- |
203
+ | QA-TQUAL-001 | Yalnızca mock ile doğrulama | info |
204
+ | QA-TQUAL-002 | Totolojik assertion | error |
205
+ | QA-TQUAL-009 | Await edilmemiş promise assertion'ı | error |
206
+ | QA-TQUAL-011 | Yorum satırına çevrilmiş testler | warning |
207
+
208
+ </details>
209
+
210
+ <details>
211
+ <summary><strong>Playwright 🎭</strong></summary>
212
+
213
+ | ID | Kural | Severity |
214
+ | --------- | --------------------------------------------- | -------- |
215
+ | QA-PW-002 | Await edilmemiş locator assertion'ı | error |
216
+ | QA-PW-003 | Commit edilmiş `page.pause()` / `test.only()` | error |
217
+ | QA-PW-004 | Kırılgan CSS/XPath seçicileri | warning |
218
+ | QA-PW-005 | `page.evaluate()` içinde iş mantığı | info |
219
+ | QA-PW-114 | Eski element handle'ları (`page.$`) | info |
220
+ | QA-PW-118 | `networkidle` beklemeleri (flaky by design) | info |
221
+ | QA-PW-123 | Sabitlenmiş ortam URL'leri | warning |
222
+
223
+ </details>
224
+
225
+ <details>
226
+ <summary><strong>CI bütünlüğü</strong></summary>
227
+
228
+ | ID | Kural | Severity |
229
+ | --------- | --------------------------------------------------------------------- | -------- |
230
+ | QA-CI-001 | `continue-on-error` başarısızlıkları maskeler | error |
231
+ | QA-CI-002 | `\|\| true` exit kodlarını yutar | error |
232
+ | QA-CI-005 | Rapor tüketilir ama asla üretilmez | error |
233
+ | QA-CI-007 | Testleri saran retry sarmalayıcıları | warning |
234
+ | QA-CI-008 | Hepsi-başarılı adım başarısızlıkları maskeler | error |
235
+ | QA-CI-009 | Test exit kodu iletilmez (`\|` pipefail'sız, `;` zincirleri) | error |
236
+ | QA-CI-010 | Testler, bloklaması gereken yerlerde atlanıyor (skip-on-PR bekçileri) | error |
237
+
238
+ </details>
239
+
240
+ <details>
241
+ <summary><strong>Python / pytest 🐍</strong></summary>
242
+
243
+ | ID | Kural | Severity |
244
+ | --------- | -------------------------------------------- | -------- |
245
+ | QA-PY-002 | Atlanan test (`skip`, katı olmayan `xfail`) | warning |
246
+ | QA-PY-003 | Assertion içermeyen test fonksiyonu | error |
247
+ | QA-PY-005 | Testlerde `time.sleep()` | warning |
248
+ | QA-PY-006 | Boş test gövdesi (`pass`) | info |
249
+ | QA-PY-010 | Freeze olmadan rastgelelik/zaman bağımlılığı | info |
250
+ | QA-PY-012 | Totolojik assertion | error |
251
+
252
+ Toplam 20 Python kuralı (QA-PY-001…012 pytest hijyeni + QA-PY-101…108 Playwright-Python).
253
+
254
+ </details>
255
+
256
+ <details>
257
+ <summary><strong>Java / JUnit · TestNG ☕</strong></summary>
258
+
259
+ | ID | Kural | Severity |
260
+ | --------- | ---------------------------------------- | -------- |
261
+ | QA-JV-101 | Devre dışı test (`@Disabled`) | warning |
262
+ | QA-JV-102 | Katı sleep (`Thread.sleep()`) | warning |
263
+ | QA-JV-103 | Assertion içermeyen test yöntemi | error |
264
+ | QA-JV-105 | Playwright katı sleep `waitForTimeout()` | warning |
265
+ | QA-JV-106 | Role locator yerine kırılgan seçici | warning |
266
+ | QA-JV-108 | Testte sabitlenmiş ortam URL'si | info |
267
+ | QA-JV-111 | Kapsayıcı mock `page.route("**")` | info |
268
+
269
+ </details>
270
+
271
+ <details>
272
+ <summary><strong>C# / .NET — NUnit · xUnit · MSTest 🟣</strong></summary>
273
+
274
+ | ID | Kural | Severity |
275
+ | --------- | ------------------------------------------ | -------- |
276
+ | QA-CS-101 | Atlanan test (`[Ignore]`, `[Fact(Skip=)]`) | warning |
277
+ | QA-CS-102 | Katı sleep (`Thread.Sleep` / `Task.Delay`) | warning |
278
+ | QA-CS-103 | Assertion içermeyen test yöntemi | error |
279
+ | QA-CS-105 | Katı sleep `WaitForTimeoutAsync()` | warning |
280
+ | QA-CS-106 | Role locator yerine kırılgan seçici | warning |
281
+ | QA-CS-108 | Testte sabitlenmiş ortam URL'si | info |
282
+ | QA-CS-111 | Kapsayıcı mock `page.RouteAsync("**")` | info |
283
+
284
+ </details>
285
+
286
+ > Tam canlı katalog — her kuralın tier'i, güveni, yanlış pozitif riski ve
287
+ > autofix kullanılabilirliğiyle — kayıt defterinden üretilir:
288
+ >
289
+ > ```bash
290
+ > mjolnir rules --md
291
+ > ```
292
+ >
293
+ > Kural başına sayfalar [`docs/rules/`](docs/rules/) altındadır.
294
+
295
+ ### Ne kadarı ölçülmüş
296
+
297
+ **99 kuraldan 74'ü, gerçek OSS koduna karşı ölçülmüş bir yanlış pozitif
298
+ oranı taşıyor** (her biri için ≥ 10 elle sınıflandırılmış bulgu; bkz.
299
+ [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). Diğer 19'u yazarın tahminine göre
300
+ yayına giriyor. Her tarama alt bilgisi, _tetiklenen_ kuralların kaçının
301
+ ölçüldüğünü söyler; `mjolnir rules --unmeasured` ölçülmeyenleri listeler;
302
+ her kuralın `mjolnir explain` sayfası durumunu belirtir. Oranı çirkin
303
+ olduğunda bile yayımlarız — QA-CS-103 %95 ile denetleniyor ve bu yüzden
304
+ karantinada. O 78'i büyütmek, projenin süregelen işidir.
305
+
306
+ ### Kural katmanları ve dil olgunluğu
307
+
308
+ Her kural, **ölçülmüş** yanlış pozitif oranına göre atanmış `core`,
309
+ `extended` veya `quarantine` olur:
310
+
311
+ | Tier | Anlamı | Varsayılan tarama | `--strict` |
312
+ | ------------ | ------------------------------------------- | :---------------: | :--------: |
313
+ | `core` | ≤ %10 ölçülmüş FP | ✅ | ✅ |
314
+ | `extended` | ≤ %30 ölçülmüş FP | ✅ | ✅ |
315
+ | `quarantine` | %30 üzerinde veya henüz ölçülmemiş (n < 10) | ❌ | ✅ |
316
+
317
+ | Dil | Adaptör | Bugünkü kapsam |
318
+ | --------------- | ------------- | -------------------------------------------------------- |
319
+ | TypeScript / JS | Derleyici AST | en geniş, en çok ölçülmüş — çoğunlukla `core`/`extended` |
320
+ | Python / pytest | Regex katmanı | geniş, corpus denetimli — çoğunlukla `core`/`extended` |
321
+ | Java | Regex katmanı | daha yeni — çoğunlukla `extended`/`quarantine` |
322
+ | C# / .NET | Regex katmanı | daha yeni — çoğunlukla `extended`/`quarantine` |
323
+
324
+ TypeScript ve Python en geniş ölçülmüş kapsama sahiptir. Java ve C#
325
+ sevk edildi, belgelendi ve gerçek bir tüketici takımı (bir bağlama
326
+ kütüphanesinin kendi testleri değil) denetlenene kadar başlık sayısının
327
+ dışında kalır.
328
+
329
+ ---
330
+
331
+ ## Puanlama nasıl çalışır
332
+
333
+ <p align="center">
334
+ <img src="assets/readme/terminal-hero.svg" alt="Mjölnir terminal çıktısı — WORTHINESS 75/100 NEEDS WORK, kategori bazında teşhis dökümü ve FIX THIS FIRST listesi" width="820" />
335
+ </p>
336
+
337
+ <sub>`npm run docs:hero` ile yeniden üretilir;
338
+ [`tests/hero-asset-reproducibility.spec.ts`](tests/hero-asset-reproducibility.spec.ts)
339
+ dosyası, çıktı reporter'ın gerçekten bastığından saptarsa CI'ı düşürür.</sub>
340
+
341
+ Puan şeffaftır: **error −8, warning −3, info −1**, ardından takım
342
+ maruziyetine göre normalizasyon (test bildirimi başına kesinti).
343
+ Kanıtla ağırlıklandırılan kesintiler, zayıf sinyallerin daha az pahalı
344
+ olduğu anlamına gelir. Terminal, puanın kullandığı aynı iskontolu
345
+ sayıları gösterir — kara kutu yok. Tam yöntem:
346
+ [docs/SCORING.md](docs/SCORING.md).
347
+
348
+ **Hükümler**
349
+
350
+ | Score | Hüküm |
351
+ | ------- | ---------------- |
352
+ | ≥ 80 | ✓ **WORTHY** |
353
+ | 50 – 79 | ⚠ **NEEDS WORK** |
354
+ | < 50 | ✖ **UNWORTHY** |
355
+
356
+ **Kanıt düzeyleri** — her bulgu bir tane taşır; bulgunun puan içindeki
357
+ ağırlığını belirler:
358
+
359
+ | Düzey | Anlamı | Puana etkisi | Örnek |
360
+ | ----- | ----------------- | --------------------- | --------------------------------------------------------- |
361
+ | E2 | Belirleyici kusur | Tam kesinti | Commit edilmiş `.only` — yapısal olarak kanıtlanabilir |
362
+ | E1 | Sezgisel örüntü | Yarım kesinti | Regex ile yakalanan `sleep()` — güçlü sinyal, kanıt değil |
363
+ | E0 | Gözlem | Sıfır (yalnızca info) | Bildirilir ama asla CI'ı gate'lemez ve kesinti yapmaz |
364
+
365
+ Kuralların çoğu **E1**'dir. «we prove it» sloganı bu sisteme işaret
366
+ eder: E2 bulguları yapısal kanıttır; E1 bulguları doğru konumlanmış
367
+ uyarılarıdır, resmî kanıt değildir.
368
+
369
+ Boş bir repo `null` puanlar — sahte 100 asla; bkz.
370
+ [Güven modeli](#güven-modeli).
371
+
372
+ ---
373
+
374
+ ## 🎭 Selector Health Score
375
+
376
+ Playwright takımları için başlık metriği — locator'larınız ne kadar
377
+ dayanıklı:
378
+
379
+ ```text
380
+ ▚▞ SELECTOR HEALTH — e2e/checkout.spec.ts
381
+
382
+ [█████████████████░░░] 83 / 100
383
+ role/text: 2 · testid: 1 · css-chains: 1 ⚠ · xpath: 0
384
+ ```
385
+
386
+ Rol tabanlı locator'lar tam puan alır. CSS sınıf zincirleri ve XPath
387
+ puanı batırır — herhangi bir DOM yeniden düzenlemesinde, hangi davranışın
388
+ gerilediğini söylemeden kırılırlar.
389
+
390
+ ---
391
+
392
+ ## 🔬 Çalışma zamanı kanıtı
393
+
394
+ Statik flakiness tespiti tahminidir. Mjölnir **gerçek yürütme
395
+ verilerini** okur — herhangi bir koşucudan Playwright JSON raporları ve
396
+ JUnit XML:
397
+
398
+ ```bash
399
+ mjolnir forensics ./test-results/
400
+ ```
401
+
402
+ ```text
403
+ ▚▞ FLAKINESS LEADERBOARD
404
+
405
+ 3 tests · 1 failed · 1 flaky · 1 retried
406
+
407
+ TRUE-FLAKE completes checkout with saved card (e2e/checkout.spec.ts)
408
+ ████████████████████ 6.0s · 2 attempts
409
+ FAILING declines an expired card (e2e/checkout.spec.ts)
410
+ ████░░░░░░░░░░░░░░░░ 1.1s · 1 attempt
411
+ ```
412
+
413
+ 2. denemeden itibaren geçen test, geçen test değildir — şanslı bir
414
+ testtir. Son yeşil onaydan bağımsız olarak `TRUE-FLAKE` olarak
415
+ işaretlenir.
416
+
417
+ ---
418
+
419
+ ## ⚡ Mjölnir bir linter daha değildir
420
+
421
+ Linter'lar kodun kurallara uyup uymadığını söyler. Mjölnir, doğrulamanıza
422
+ güvenilip güvenilemeyeceğini söyler.
423
+
424
+ | | ESLint / SonarQube | Coverage araçları | Manuel inceleme | **Mjölnir** |
425
+ | ------------------------------------------------------------- | :----------------: | :---------------: | :-------------: | :---------: |
426
+ | CI workflow bütünlüğü (`continue-on-error`, `\|\| true`) | ❌ | ❌ | nadiren | ✅ |
427
+ | Tek araçla çapraz dil (TS, Python, Java, C#) | ❌ | ❌ | ❌ | ✅ |
428
+ | Playwright locator dayanıklılığını not eder (Selector Health) | ❌ | ❌ | nadiren | ✅ |
429
+ | Gerçek assertion'ı olmayan testleri işaretler | ✅ (eklenti)\* | ❌ | bazen | ✅ |
430
+ | Katı sleep'leri yakalar (`waitForTimeout`, `time.sleep`) | ✅ (eklenti)\* | ❌ | bazen | ✅ |
431
+ | Saniyeler içinde çalışır, tarama sırasında sıfır ağ çağrısı | ✅ | ✅ | — | ✅ |
432
+
433
+ \*`eslint-plugin-jest` (`expect-expect`) ve `eslint-plugin-playwright`
434
+ (`expect-expect`, `no-wait-for-timeout`) bunları ilgili çerçeveler için
435
+ karşılar.
436
+
437
+ **Çalışma zamanı analizi**, statik linting'in yanı sıra ayrı bir
438
+ kategoridir:
439
+
440
+ | | Playwright retry reporter | Allure / ReportPortal | **Mjölnir forensics** |
441
+ | --------------------------------------------------------- | :-----------------------: | :-------------------: | :-------------------: |
442
+ | `TRUE-FLAKE` hükümleri için gerçek çalıştırma verisi okur | kısmen\* | kısmen (tag) | ✅ |
443
+ | Yürütme geçmişinden flaky triyaj raporu | ❌ | ✅ | ✅ |
444
+ | Statik güvenilirlik puanıyla bütünleşir | ❌ | ❌ | ✅ |
445
+
446
+ \*Playwright retry'ları içeriden izler ama hüküm etiketli bağımsız bir
447
+ flakiness raporu üretmez.
448
+
449
+ ---
450
+
451
+ ## 🤖 Neden yalnızca AI kod incelemesi kullanmayasınız?
452
+
453
+ Farklı sorun, farklı katman. AI incelemesi bir diff'teki şüpheli test
454
+ değişikliğini fark edebilir; doğrulama sisteminin bütünüyle güvenilir
455
+ olduğunu kanıtlamaz — ve yalnızca ona gösterdiğiniz diff'i görür.
456
+
457
+ | | AI kod incelemesi (Copilot vb.) | **Mjölnir** |
458
+ | -------------------------------------------- | :-------------------------------: | :---------------------------: |
459
+ | Tarama başına maliyet | Token (diff boyutuyla ölçeklenir) | **Sıfır** (yerel, kurulu) |
460
+ | Tüm takımı + tüm CI yapılandırmalarını görür | Yalnızca gösterdiğiniz PR diff'i | **Her şey, her seferinde** |
461
+ | Belirleyici (aynı girdi → aynı çıktı) | ❌ (belirsiz) | **✅** |
462
+ | Aylardır uyuyan örüntüleri yakalar | Yalnızca bağlamdaysa | **✅** (tüm dosyaları tarar) |
463
+ | Çalıştırmalar arasında bulguları hatırlar | ❌ (oturumlar arası bellek yok) | **✅** (baseline + diff) |
464
+ | İnsan tetiklemesi olmadan çalışır | PR veya prompt gerekir | **✅** (CI kancası, 3 saniye) |
465
+
466
+ **İkisini de kullanın.** AI, hiçbir regex'in bulamayacağı nüansı, niyeti
467
+ ve tasarım kusurlarını yakalar. Mjölnir, AI'nın «kasıtlı» göründükleri
468
+ için gözden kaçırdığı yapısal örüntüleri yakalar — commit edilmiş bir
469
+ `.only`, yutulmuş bir exit kodu, test işindeki bir `continue-on-error`.
470
+ Bunlar akıl gerektiren hatalar değil; tarama gerektiren olgulardır.
471
+
472
+ ---
473
+
474
+ ## 🤖 CI entegrasyonu
475
+
476
+ Tek komut bir PR workflow'u üretir — varsayılan olarak danışmanlık,
477
+ asla engellemeyen:
478
+
479
+ ```bash
480
+ mjolnir ci install
481
+ ```
482
+
483
+ Ya da SARIF üzerinden GitHub Code Scanning'e yerel olarak bağlayın:
484
+
485
+ ```yaml
486
+ - run: npx mjolnir-qa@latest --format sarif > mjolnir.sarif
487
+ - uses: github/codeql-action/upload-sarif@v3
488
+ with:
489
+ sarif_file: mjolnir.sarif
490
+ ```
491
+
492
+ SARIF için düzenleyici ve hattan kurulumu:
493
+ [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
494
+
495
+ ### Değişen kapsam kapsamı
496
+
497
+ `--scope changed`, bulguları branch'inizin `main` ile birleştirme
498
+ tabanına (merge-base) göre eklediği satırlara atfeder. Test dosyalarını
499
+ (`*.spec.*`, `*.test.*`) ve diff'teki GitHub workflow dosyalarını ve
500
+ Playwright yapılandırmalarını kapsar. Merge-base çözülemediğinde —
501
+ shallow clone, detached HEAD, git dışı hedef, farklı varsayılan branch —
502
+ dürüstçe geriler: bulgular tüm dosya atfına döner ve rapor bunu söyler.
503
+ Taban referansını `--base <ref>` ile geçersiz kılın.
504
+
505
+ ---
506
+
507
+ ## Yapılandırma
508
+
509
+ Mjölnir sıfır-yapılandırmadır. Repo kökündeki isteğe bağlı bir
510
+ `mjolnir.config.json` (veya `.mjolnir.json`) şiddeti, kapıyı ve kapsamı
511
+ ayarlar — algılama anlamını asla değiştirmez.
512
+
513
+ | Key | Tür | Etki |
514
+ | ------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
515
+ | `exclude` | `string[]` | Ek ignore glob'ları (gitignore alt kümesi), yerleşik varsayılanların üzerine |
516
+ | `gate` | `"advisory" \| "error" \| "warning"` | Hangi şiddetlerin sıfır olmayan kodla çıkacağı (varsayılan `error`; `advisory` asla engellemez) |
517
+ | `severityOverrides` | `{ "<RULE-ID>": severity }` | Bir kuralın bulgularını deponuz için yeniden sıralar |
518
+ | `ignore` | `IgnoreEntry[]` | Bulguları bastırır — **`reason` zorunludur**; girdiler 90 gün sonra sona erer (açık bir `expires` tarihi, ya da tarihi olmayan girdiler için yapılandırma dosyasının son değişiklik zamanı) |
519
+ | `plugins` | `string[]` | Üçüncü taraf kural paketleri (bkz. [Güven modeli](#güven-modeli)) |
520
+
521
+ ```json
522
+ {
523
+ "gate": "error",
524
+ "exclude": ["legacy/**"],
525
+ "severityOverrides": { "QA-PW-118": "warning" },
526
+ "ignore": [
527
+ {
528
+ "ruleId": "QA-TEST-004",
529
+ "files": ["e2e/legacy-login.spec.ts"],
530
+ "reason": "Third-party widget needs a settle delay; tracked in JIRA-4821",
531
+ "expires": "2026-12-31"
532
+ }
533
+ ]
534
+ }
535
+ ```
536
+
537
+ - **`.mjolnirignore`** — yol dışlamaları için düz gitignore tarzı bir
538
+ dosya, `exclude` ile aynı diyalekt. Makinaya özgü gürültü için onu
539
+ kullanın; liste sürüm denetimine, diğer yapılandırmanın yanına
540
+ girecekse `exclude` kullanın.
541
+ - **CLI geçersiz kılmaları** — `--strict` (karantina kurallarını dahil
542
+ et), `--width <cols>` ve `--ascii` / `--no-ascii` (terminal
543
+ görüntüsü), `--tone blunt` (daha sert mesajlar),
544
+ `--max-duration <sec>` (sınırlı kısmi tarama).
545
+ - Kural bastırma ve kullanımdan kaldırma yaşam döngüsü:
546
+ [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md).
547
+
548
+ `ignore` girdileri ayrıca bağımsız `mjolnir suppressions` komutunu besler;
549
+ bu komut şu anda bastırılanları ve her girdinin ne zaman sona ereceğini
550
+ listeler.
551
+
552
+ ---
553
+
554
+ ## 📐 Çıkış kodları ve sözleşmeler
555
+
556
+ Donmuş — üstüne CI mantığı kurmak güvenli:
557
+
558
+ | Çıkış kodu | Anlamı |
559
+ | ---------- | ------------------------------------------------------------------------- |
560
+ | `0` | Temiz — kapı düzeyinde veya üzerinde bulgu yok |
561
+ | `1` | Kapı düzeyinde veya üzerinde bulgular |
562
+ | `2` | Kısmi tarama (zaman bütçesi doldu, okunamayan dosyalar) — asla engellemez |
563
+ | `10` | Kullanım hatası (hatalı bayrak, hedef eksik) |
564
+ | `20` | İç hata |
565
+
566
+ JSON/SARIF raporu `schemaVersion: 1`'dir. Kural kimlikleri
567
+ (`QA-<FAMILY>-NNN`) sevk edildikten sonra değişmez ve asla yeniden
568
+ kullanılmaz.
569
+
570
+ ---
571
+
572
+ ## Güven modeli
573
+
574
+ - **Local-first** — tarama sırasında sıfır ağ çağrısı. Asla. Sıfır
575
+ telemetri.
576
+ - **Yanlış kanıt yok** — «doğrulandı» demek yerine «bilinmiyor» demeyi
577
+ tercih ederiz. Boş repo `score: null` alır, sahte 100 asla.
578
+ - **Kısmi dürüstlük** — analiz yarıda kesildiyse çıktı bunu söyler.
579
+ Öyle olmadığında asla «complete» demez.
580
+ - **FP duvarı** — algılama, yorumlardan/dizelerden arınmış kod
581
+ görünümü üzerinde çalışır (TypeScript kuralları derleyici AST'sini
582
+ kullanır): düz yazı yorumu içindeki veya doküman örnek dizesindeki bir
583
+ örüntü, dokümantasyondur — bulgu değildir.
584
+ - **Ölçülmüş, iddia edilmiş değil** — yalnızca gerçek OSS kodundan
585
+ yanlış pozitif oranı olan kurallar başlık katmanlarına girer (bkz.
586
+ [Ne kadarı ölçülmüş](#ne-kadarı-ölçülmüş)); tarama alt bilgisi ve
587
+ `mjolnir rules --unmeasured` hangisinin ne olduğunu söyler.
588
+ - **Eklenti güveni** — eklentiler `"plugins"` altında bildirilen npm
589
+ paketleridir. **Sandbox yok**: eklenti kodu tam Node ayrıcalıklarıyla
590
+ çalışır; ESLint veya Vitest eklentileriyle aynı güven modeli. Çekirdek
591
+ kural kimliği önekleri rezerve edilmiştir ve kimlik taklidini önlemek
592
+ için eklentilerden reddedilir.
593
+ - **Workspace-yerel dış kurallar** (klasör tabanlı, sıfır ağ) — tarama
594
+ hedefinin yanındaki bir `mjolnir-rules/` dizini özel kurallar yükler:
595
+ JSON dosyaları regex örüntüleri bildirir (kod yürütülmez),
596
+ `.mjs`/`.js` modülleri `rules` dışa aktarır (tam Node güveni,
597
+ eklentiler gibi). Dış kurallar çekirdekle aynı güven üstverilerini
598
+ taşır; asla çekirdek katmanına giremezler (çekirdek, corpus yan
599
+ dosyasından ölçülmüş bir FP oranı gerektirir — bildirilen
600
+ `tier: "core"`, `extended`'a sıkıştırılır), katman üst sınırlarına
601
+ uyar ve sapma için denetlenir: `mjolnir rules --md --external`,
602
+ kataloğu yüklenen dosyalardan görüntüler (kaynak `external`);
603
+ matris üreteci `--external <root>` kabul eder.
604
+
605
+ ---
606
+
607
+ ## 🏗️ Mimari
608
+
609
+ <details>
610
+ <summary>Ağacı genişlet</summary>
611
+
612
+ ```
613
+ mjolnir/
614
+ ├── src/
615
+ │ ├── engine/ # LanguageAdapter interface + rule runner
616
+ │ ├── adapters/ # typescript · python · java · csharp · github-actions
617
+ │ ├── rules/ # rules across 8 families + the measured-FP table
618
+ │ ├── playwright/ # Selector Health Score engine
619
+ │ ├── discovery/ # workspace, frameworks, ignore resolution
620
+ │ ├── scope/ # git merge-base changed-scope engine
621
+ │ ├── scorer/ # transparent deduction table + prioritization
622
+ │ ├── reporter/ # terminal · JSON · SARIF 2.1 · Mermaid
623
+ │ ├── forensics/ # run-data ingestion · flake verdicts · triage
624
+ │ ├── config/ # mjolnir.config.json + suppressions
625
+ │ ├── plugins/ # third-party rule loading (no sandbox)
626
+ │ └── commands/ # every subcommand
627
+ └── tests/
628
+ ├── fixtures/ # must-fire / must-not-fire per rule
629
+ └── golden/ # frozen score regression locks
630
+ ```
631
+
632
+ </details>
633
+
634
+ - **Kurallar saf fonksiyonlardır** — `(SourceFileContext) → Finding[]`,
635
+ I/O yok, global yok. Yeni bir ekosistem = bir adaptör + onun
636
+ kuralları.
637
+ - **TypeScript/Playwright derleyici AST'sini kullanır** (ts-morph).
638
+ Python, Java ve C#, maskeli yorum/dizeli paylaşılan bir regex
639
+ katmanında çalışır.
640
+ - Java ve C# için bir tree-sitter WASM AST katmanı mevcuttur ve bir
641
+ sonraki hassasiyet adımıdır — henüz senkron tarama hattına bağlı
642
+ değildir.
643
+
644
+ ---
645
+
646
+ ## 📚 Belgelendirme
647
+
648
+ | Belge | İçinde ne var |
649
+ | ------------------------------------------------------ | ----------------------------------------------- |
650
+ | [docs/SCORING.md](docs/SCORING.md) | Puan normalizasyonu + kanıt ağırlıklandırma |
651
+ | [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Ölçülmüş yanlış pozitif oranları + yöntem |
652
+ | [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Kural durumları, bastırma, kullanımdan kaldırma |
653
+ | [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | SARIF çıktısı + düzenleyici/CI kurulumu |
654
+ | [docs/rules/](docs/rules/) | Üretilmiş kural başına katalog |
655
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | Geliştirme kurulumu + katkı akışı |
656
+ | [CHANGELOG.md](CHANGELOG.md) | Sürüm geçmişi |
657
+ | [SECURITY.md](SECURITY.md) | Güvenlik açığı bildirimi |
658
+
659
+ ---
660
+
661
+ ## 📈 Durum
662
+
663
+ **v0.5.x · açık beta.** JSON şeması ve çıkış kodları donmuş
664
+ sözleşmelerdir. TypeScript ve Python en geniş ölçülmüş kapsama sahiptir;
665
+ Java ve C# daha yenidir —
666
+ [katman tablosu](#kural-katmanları-ve-dil-olgunluğu) üzerinden okuyun.
667
+
668
+ ---
669
+
670
+ ## 🤝 Katkıda bulunma
671
+
672
+ Yeni kurallar en kolay ilk katkıdır — tek komut, kuralı plus must-fire
673
+ **ve** must-not-fire fixture'larıyla iskeletler (üretilen kural, gerçek
674
+ algılama uygulayana dek fixture'larında kasıtlı olarak başarısız olur —
675
+ bir stub sevk edilemez):
676
+
677
+ ```bash
678
+ mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
679
+ ```
680
+
681
+ Tam geliştirme kurulumu, sürekli kapı komutları ve anti-creep /
682
+ fixture duvarı yasaları [CONTRIBUTING.md](CONTRIBUTING.md) içindedir.
683
+
684
+ ---
685
+
686
+ <div align="center">
687
+
688
+ **Güvenemediğiniz testleri sevk etmeyi bırakın.**
689
+
690
+ ```bash
691
+ npx mjolnir-qa@latest
692
+ ```
693
+
694
+ **Star ⭐ · Watch 👀 · Contribute 🤝**
695
+
696
+ [Sergey Bar](https://www.linkedin.com/in/sergeybar/) tarafından
697
+ oluşturuldu
698
+
699
+ </div>