mjolnir-qa 1.0.9 → 2.0.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.pl.md CHANGED
@@ -1,400 +1,431 @@
1
1
  <div align="center">
2
2
 
3
- <img src="assets/readme/logo.png" alt="Mjölnir — Verification Trust Engine" width="800" />
3
+ <img src="assets/readme/hero.svg" alt="Mjölnir. Testy mówią ci, co przeszło. Mjölnir mówi ci, czemu możesz zaufać." width="100%" />
4
4
 
5
- ### Twoje testy kłamią. My to dowodzimy.
5
+ <br />
6
6
 
7
- **Verification Trust Engine dla QA.** Mjölnir audytuje suite testowe i
8
- pipeline'y CI, raportuje wskaźnik wiarygodności i pokazuje dokładnie,
9
- gdzie zaufanie się łamie.
7
+ Mjölnir znajduje testy, które nie mogą zawieść, i pipeline'y, które nie mogą zrobić się czerwone,<br />
8
+ a potem ocenia, na ile można ufać wynikowi, podając dowód dla każdego punktu.
10
9
 
11
- [![npm](https://img.shields.io/npm/v/mjolnir-qa.svg?style=flat-square&color=C19A34&labelColor=0A1119)](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=0A1119)](https://github.com/Sergey-Bar/Mjolnir/actions/workflows/ci.yml)
13
- [![license](https://img.shields.io/badge/license-MIT-C19A34.svg?style=flat-square&labelColor=0A1119)](LICENSE)
14
- [![node](https://img.shields.io/badge/node-%E2%89%A5%2022.18-37ABBD.svg?style=flat-square&labelColor=0A1119)](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.ru.md) | [Norsk](README.no.md) | [Português (Brasil)](README.br.md) | [ไทย](README.th.md) | [Türkçe](README.tr.md) | [Українська](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)
10
+ <br />
17
11
 
18
- > 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-08.
12
+ [![npm](https://img.shields.io/npm/v/mjolnir-qa.svg?style=flat-square&color=1F6F7C&labelColor=0A1119)](https://www.npmjs.com/package/mjolnir-qa)
13
+ [![downloads](https://img.shields.io/npm/dm/mjolnir-qa.svg?style=flat-square&color=1F6F7C&labelColor=0A1119)](https://www.npmjs.com/package/mjolnir-qa)
14
+ [![ci](https://img.shields.io/github/actions/workflow/status/Sergey-Bar/Mjolnir/ci.yml?branch=main&style=flat-square&label=ci&labelColor=0A1119)](https://github.com/Sergey-Bar/Mjolnir/actions/workflows/ci.yml)
15
+ [![coverage](https://img.shields.io/codecov/c/github/Sergey-Bar/Mjolnir?style=flat-square&color=1F6F7C&labelColor=0A1119&label=coverage)](https://codecov.io/gh/Sergey-Bar/Mjolnir)
16
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/Sergey-Bar/Mjolnir/badge)](https://scorecard.dev/viewer/?uri=github.com/Sergey-Bar/Mjolnir)
17
+ [![license](https://img.shields.io/badge/license-MIT-1F6F7C.svg?style=flat-square&labelColor=0A1119)](LICENSE)
18
+ [![node](https://img.shields.io/badge/node-%E2%89%A5%2022.18-1F6F7C.svg?style=flat-square&labelColor=0A1119)](https://nodejs.org)
19
19
 
20
20
  ```bash
21
21
  npx mjolnir-qa@latest
22
22
  ```
23
23
 
24
- **Czy twoje testy zasługują na zaufanie?**
24
+ [Zobacz w działaniu](#zobacz-w-działaniu) · [Szybki start](#szybki-start) · [Co znajduje](#co-znajduje-mjölnir) · [Wynik](#wynik-wiarygodności) · [Dowody](#model-dowodów) · [Analiza przebiegów](#analiza-przebiegów-testów) · [CI](#integralność-ci) · [Agenci](#agenci-ai) · [Bezpieczeństwo](#zaufanie-i-bezpieczeństwo) · [Ograniczenia](#czego-mjölnir-nie-może-ci-powiedzieć) · [Dokumentacja](#dokumentacja)
25
+
26
+ <details>
27
+ <summary>Czytaj w innym języku — 22 tłumaczenia</summary>
28
+
29
+ [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.ru.md) | [Norsk](README.no.md) | [Português (Brasil)](README.br.md) | [ไทย](README.th.md) | [Türkçe](README.tr.md) | [Українська](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)
30
+
31
+ > 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-15.
32
+
33
+ <!-- Source hash: 3541b09e8d04 -->
25
34
 
26
- [Zobacz w akcji](#-zobacz-w-akcji) ·
27
- [Szybki start](#-szybki-start) ·
28
- [Co sprawdza](#-co-sprawdza-mjölnir) ·
29
- [Punktacja](#jak-działa-punktacja) ·
30
- [CI](#-integracja-ci) · [Konfiguracja](#konfiguracja) ·
31
- [Dokumentacja](#-dokumentacja)
35
+ </details>
32
36
 
33
37
  </div>
34
38
 
35
- ---
39
+ <br />
40
+
41
+ ## Zielony znacznik to deklaracja, a nie dowód
42
+
43
+ Zielony znacznik oznacza, że pipeline nie zawiódł. Nie oznacza, że testy się wykonały ani że mogły zawieść. Każdy z tych przypadków przechodzi na zielono:
44
+
45
+ - zacommitowane `.only`, które uruchomiło 3 testy zamiast 900
46
+ - `continue-on-error: true` na jobie, który miał blokować
47
+ - `|| true` po poleceniu uruchamiającym testy
48
+ - test, który niczego nie sprawdza albo ma puste ciało
49
+ - wrapper ponawiający, który zamienia prawdziwą porażkę w szczęśliwe przejście
50
+ - raport, który workflow wysyła, choć nigdy go nie wygenerował
51
+ - sztywny sleep, który podtrzymuje wyścig
52
+
53
+ Żaden z nich nie zmienia koloru pipeline'u na czerwony, a każdy w review wygląda na zamierzony. Właśnie dlatego przetrwają. Oto Mjölnir czytający prawdziwy przypadek:
54
+
55
+ <p align="center">
56
+ <img src="assets/readme/scan.svg" alt="Workflow CI repozytorium demonstracyjnego, czytany wiersz po wierszu. Mjölnir oznacza każde znalezisko w zgłoszonym wierszu, z jego regułą, opisem problemu, poziomem dowodu i zmierzonym odsetkiem fałszywych alarmów." width="800" />
57
+ </p>
58
+
59
+ <sub>Każde znalezisko, które skan demonstracyjny zgłosił dla tego workflow, w zgłoszonym wierszu. Wygenerowane przez `npm run docs:readme-brand` z [`demo-report.json`](assets/readme/demo-report.json) i zabezpieczone w CI przed rozjazdem.</sub>
60
+
61
+ **Tryb ścisły.** Najbardziej agresywne wykrycia — `.only`, `continue-on-error`, puste testy, nadużywanie ponownych prób — żyją w poziomie kwarantanny. Działają tylko z `--strict` i są ograniczone do ważności `info`: oznaczają, ale nigdy nie blokują. Domyślne skanowanie (`npx mjolnir-qa@latest` bez `--strict`) obejmuje tylko reguły rdzeniowe i rozszerzone. Dodaj `--strict`, gdy chcesz też warstwę doradczą.
62
+
63
+ Mjölnir czyta zestaw testów, workflow CI oraz, jeśli go masz, raport z prawdziwego przebiegu. Nie uruchamia twoich testów, nie instaluje zależności ani nie wykonuje skanowanego kodu. A gdy nie ma dowodów, mówi to wprost, zamiast wymyślać pewność:
64
+
65
+ | Sytuacja | Co zgłasza Mjölnir |
66
+ | ----------------------------------------------- | ------------------------------------------------------------------ |
67
+ | Nie znaleziono deklaracji testów | Wynik `null`, wyświetlany jako **UNKNOWN**. Nigdy zmyślone 100. |
68
+ | Brak baseline'u lub porównywalnej rewizji | **UNKNOWN**, z podanym powodem. Nigdy założone 0. |
69
+ | Skan przerwany (limit czasu, nieczytelne pliki) | **PARTIAL**, kod wyjścia `2`. Nigdy nie przedstawiany jako czysty. |
70
+
71
+ <p align="center">
72
+ <img src="assets/readme/how-it-works.svg" alt="Jak działa Mjölnir. Czyta statycznie zestaw testów i pipeline CI, a także raport z prawdziwego przebiegu, jeśli istnieje. Waży każde znalezisko według poziomu dowodu i poziomu zaufania, przy czym tylko prawdziwy przebieg może osiągnąć L3–L5, i zwraca znaleziska, wynik wiarygodności oraz bramkę CI z zamrożonymi kodami wyjścia. W pętli agenta AI pisze poprawkę, a Mjölnir skanuje ponownie, aby ją udowodnić." width="880" />
73
+ </p>
74
+
75
+ <sub>Przygotowane dla tej strony i pokazane w skali 1:1. Wygenerowane przez `npm run docs:readme-brand` i zabezpieczone w CI przed rozjazdem; wynik, liczby i ID reguły pochodzą z [`script.demo.json`](assets/video/script.demo.json), [`demo-report.json`](assets/readme/demo-report.json) i rejestru reguł, nigdy nie są wpisywane ręcznie. Ten sam obraz jako plakat: [`architecture.svg`](assets/readme/architecture.svg).</sub>
76
+
77
+ <br />
78
+
79
+ ## Zobacz w działaniu
36
80
 
37
- ## 🎬 Zobacz w akcji
81
+ Prawdziwy skan [`examples/demo-repo`](examples/demo-repo), małego zestawu Playwright z workflow CI. Oto, gdzie poszły jego punkty:
38
82
 
39
83
  <p align="center">
40
- <img src="assets/readme/demo.svg" alt="Pełny raport --verbose Mjölnir na demo repo: WORTHINESS 75/100 NEEDS WORK, rozbicie diagnostyki wg kategorii, lista FIX THIS FIRST i każde znalezisko z ID reguły i numerem linii — CI, Playwright, higiena testów i reguły Pythona" width="900" />
84
+ <img src="assets/readme/terminal-hero.svg" alt="Rozbicie potrąceń Mjölnira: WORTHINESS 80/100 WORTHY, wynik według kategorii, ramka potrąceń według ważności i lista FIX THIS FIRST" width="520" />
41
85
  </p>
42
86
 
43
- <sub>Kompletny wynik `npx mjolnir-qa ./examples/demo-repo --verbose`,
44
- wyrenderowany przez prawdziwy reporter — nic nie ucięto. Regenerowany
45
- przez `npm run docs:demo`;
46
- [`tests/demo-asset-reproducibility.spec.ts`](tests/demo-asset-reproducibility.spec.ts)
47
- wywala CI, jeśli artefakt odjechał od tego, co wypisuje narzędzie.</sub>
87
+ <sub>Wygenerowane przez `npm run docs:hero` z prawdziwego skanu i zabezpieczone w CI przed rozjazdem. Pełny raport `--verbose` z tego samego skanu to [`demo.svg`](assets/readme/demo.svg) (`npm run docs:demo`).</sub>
88
+
89
+ <details>
90
+ <summary><strong>Obejrzyj</strong> — skan, poprawka, którą wypisuje, i ponowny skan, który ją potwierdza</summary>
91
+
92
+ <br />
93
+
94
+ <p align="center">
95
+ <a href="assets/video/mjolnir-demo.mp4">
96
+ <img src="assets/video/mjolnir-demo-poster.png" alt="Klatka nagrania demonstracyjnego: npx mjolnir-qa@latest skanuje repozytorium demonstracyjne w oknie terminala" width="900" />
97
+ </a>
98
+ </p>
48
99
 
49
- **Co właśnie się stało:**
100
+ <sub>Wyrenderowane klatka po klatce z prawdziwego skanu przez `npm run docs:video`; nigdy nagrywane z ekranu. Wybierz klatkę, aby otworzyć [`mjolnir-demo.mp4`](assets/video/mjolnir-demo.mp4).</sub>
50
101
 
51
- 1. Mjölnir znalazł specyfikacje Playwright, swoją konfigurację,
52
- workflow CI i plik testowy Pythona — cztery języki/formaty, jeden
53
- przebieg.
54
- 2. Znalazł dowody osłabiające zaufanie do suity — `continue-on-error`
55
- maskujący job, `|| true` połykający kod wyjścia, twarde sleepy,
56
- kruchy selektor, zaszyte na sztywno URL-e stagingu, czekanie
57
- `networkidle`.
58
- 3. Każdy z nich zamienił w konkretne znalezisko z ID reguły, miejscem
59
- i fixem — oraz w jedną punktację, na której można gate'ować PR.
102
+ </details>
60
103
 
61
104
  ### Jedno znalezisko z bliska
62
105
 
63
- Uruchom `mjolnir explain QA-CI-001` na pierwszym znalezisku powyżej, a
64
- otrzymasz:
106
+ Każde znalezisko odpowiada na cztery pytania: gdzie jest, jak pewny jest Mjölnir, jak często reguła się myli i jak to naprawić.
107
+
108
+ <p align="center">
109
+ <img src="assets/readme/finding-anatomy.svg" alt="Pierwsze znalezisko ze skanu demonstracyjnego, dokładnie tak, jak wypisuje je terminal, z oznaczonymi czterema częściami: gdzie, jak pewne, jak często reguła się myli, oraz poprawka." width="100%" />
110
+ </p>
111
+
112
+ `mjolnir explain QA-CI-001` wypisuje całą kartotekę zaufania reguły, w tym zmierzony odsetek fałszywych alarmów i poziom, który ten odsetek jej zapewnił:
65
113
 
66
114
  ```text
67
- ▚ QA-CI-001 — continue-on-error masks a failing verification gate
115
+ ▍ QA-CI-001 — continue-on-error masks a failing verification gate
68
116
 
69
117
  Severity: error
70
118
  Confidence: high
119
+ Tier: quarantine
71
120
  Evidence: E2
72
- Measured FP: not yet measured — this rule ships on assumption (see docs/FP-AUDIT.md)
121
+ QA impact: False-green risk (FALSE-GREEN)
122
+ Measured FP: 11% (19 hand-classified corpus verdicts)
123
+ FP risk: low (author estimate)
124
+ Languages: yaml
125
+ Frameworks: github-actions, azure-pipelines
73
126
 
74
127
  WHAT WAS FOUND (real detector output, not a mockup)
75
128
  Job `security-scan` runs a verification gate under `continue-on-error: true`.
76
129
 
77
130
  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.
131
+ This job can fail every day and CI will still show green. The checkmark on
132
+ this workflow cannot be trusted.
80
133
 
81
134
  HOW TO FIX
82
135
  Remove continue-on-error, or scope it to individual non-blocking steps only.
83
- ```
84
136
 
85
- To jest jednostka wartości: nie czepialstwo stylistyczne, lecz miejsce,
86
- gdzie twój CI mówi ci, że coś przeszło, choć nie przeszło.
137
+ Example from this rule's own must-fire fixture: QA-CI-001/must-fire/masked.yml
87
138
 
88
- ---
139
+ WHAT WOULD CHANGE THE VERDICT
140
+ - a run report next to the scan target (mjolnir.report.json or test-results/)
141
+ corroborating this file lifts its findings to L3–L5
142
+ - a documented suppression (mjolnir.config.json) lowers the finding count
143
+ without claiming correctness
144
+ - quarantine findings run only under --strict and are advisory (E0) — they can
145
+ never gate CI
89
146
 
90
- ## ⚡ Szybki start
147
+ NEXT ACTION
148
+ Fix the first occurrence, then re-run: `mjolnir --scope changed`. Every
149
+ occurrence of this rule is listed in the scan output.
91
150
 
92
- Uruchom na repozytorium — dostaniesz pełny raport i wskaźnik
93
- wiarygodności:
151
+ HOW TO VERIFY THE FIX
152
+ Re-run `mjolnir` on the changed file(s) — this finding should no longer
153
+ appear. `mjolnir --scope changed` scopes the check to just what you touched.
94
154
 
95
- ```bash
96
- npx mjolnir-qa@latest
155
+ Docs: mjolnir rules --md (full catalog, this rule included)
97
156
  ```
98
157
 
99
- **W CI produktem jest jedna komenda.** Skanuje tylko to, czego dotknął
100
- branch, i kończy się kodem niezerowym przy nowych problemach:
158
+ To jest jednostka wartości: jedno miejsce, w którym CI zgłasza przejście, na które nie zasłużyło.
159
+
160
+ <br />
161
+
162
+ ## Szybki start
101
163
 
102
164
  ```bash
103
- npx mjolnir-qa@latest --scope changed
165
+ npx mjolnir-qa@latest
104
166
  ```
105
167
 
106
- Wrzuć to jako check w PR — `mjolnir ci install` pisze workflow — i
107
- gotowe. Wszystko inne jest opcjonalne.
168
+ Skanuje bieżący katalog i wypisuje Trust Report: co znalazł, na ile możesz temu ufać, dlaczego i co zrobić dalej. Kończy się kodem `0`, gdy nie znaleziono niczego na poziomie bramki lub powyżej.
108
169
 
109
- | Komenda | Co robi |
110
- | ----------------------------------- | -------------------------------------------------------- |
111
- | `mjolnir` | Skan całego repo + wskaźnik wiarygodności |
112
- | `mjolnir --scope changed` | Tylko to, co wprowadził twój branch — wariant CI |
113
- | `mjolnir ci install` | Generuje doradczy workflow PR |
114
- | `mjolnir explain QA-CI-001` | Co / dlaczego / fix + zmierzona stopa FP dla reguły |
115
- | `mjolnir rules --unmeasured` | Reguły działające na założeniu, nie na pomiarze |
116
- | `mjolnir --json` / `--format sarif` | Czytelne maszynowo / GitHub Code Scanning |
117
- | `mjolnir --strict` | Uruchamia też reguły tieru quarantine (wyższe ryzyko FP) |
118
-
119
- <details>
120
- <summary><strong>Gdy coś jest flaky</strong></summary>
170
+ W CI skanuj tylko to, co wprowadziła gałąź, aby stary zestaw testów nie zatopił twojego pierwszego pull requesta:
121
171
 
122
- | Komenda | Co robi |
123
- | ----------------------------------- | ----------------------------------------------------------------- |
124
- | `mjolnir forensics ./test-results/` | Prawdziwe dane przebiegów → werdykty `TRUE-FLAKE`, `FLAKY.md` |
125
- | `mjolnir triage ./test-results/` | Propozycja kwarantanny z historii wykonania |
126
- | `mjolnir pw-report ./test-results/` | Podsumowanie przebiegu Playwright — retry / flaki / najwolniejsze |
127
- | `mjolnir doctor:playwright` | Głęboki skan tylko Playwright + Selector Health Score |
172
+ ```bash
173
+ npx mjolnir-qa@latest --scope changed
174
+ ```
128
175
 
129
- </details>
176
+ `mjolnir ci install` zapisuje to jako workflow GitHub Actions, używając [akcji](https://github.com/Sergey-Bar/Mjolnir#readme) przypiętej do głównego tagu `v1` (albo zwykłego `npx` z `--no-action`). Pozostaje doradczy, dopóki nie zdecydujesz, że ma blokować.
177
+
178
+ | Polecenie | Co robi |
179
+ | ----------------------------------- | ----------------------------------------------------------- |
180
+ | `mjolnir` | Trust Report: werdykt, pewność, następny krok |
181
+ | `mjolnir --scope changed` | Tylko to, co wprowadziła twoja gałąź (forma dla CI) |
182
+ | `mjolnir ci install` | Generuje doradczy workflow dla PR (oparty na akcji) |
183
+ | `mjolnir explain QA-CI-001` | Co, dlaczego i jak naprawić, plus zmierzony odsetek FP |
184
+ | `mjolnir why src/a.spec.ts:42` | Dlaczego oznaczono dokładnie ten wiersz. Nigdy nie blokuje. |
185
+ | `mjolnir forensics ./test-results/` | Dowody z prawdziwego przebiegu |
186
+ | `mjolnir trust-report` | Samodzielny Trust Artifact (md + json) |
187
+ | `mjolnir handoff` | Plan naprawy dla agenta kodującego |
188
+ | `mjolnir --json` / `--format sarif` | Wyjście czytelne maszynowo, GitHub Code Scanning |
189
+ | `mjolnir --format codequality` | Raport GitLab Code Quality (artefakt widżetu MR) |
190
+ | `mjolnir --strict` | Uruchamia też reguły poziomu quarantine (wyższe ryzyko FP) |
130
191
 
131
192
  <details>
132
- <summary><strong>Okazjonalnie / raporty</strong></summary>
133
-
134
- | Komenda | Co robi |
135
- | ------------------------------- | --------------------------------------------------------- |
136
- | `mjolnir fix --dry-run` / `fix` | Bezpieczne autofiksy z dowodem |
137
- | `mjolnir baseline` / `diff` | Migawka znalezisk, potem raport tylko nowych/pogorszonych |
138
- | `mjolnir impact --since <ref>` | Co się zmieniło od wcześniejszego commita |
139
- | `mjolnir debt` | Rejestr długu testowego z modelem kosztów |
140
- | `mjolnir handover` | Mapa onboardingu suity dla nowego QA |
141
- | `mjolnir stats` | Lokalne liczniki wszystkich widzianych fixów |
142
- | `mjolnir badge` | JSON endpointu shields.io + snippet |
143
- | `mjolnir rules --md` | Pełny katalog reguł (JSON albo Markdown) |
144
- | `mjolnir doctor` | Samoaudyt własnej bazy reguł Mjölnir |
145
- | `mjolnir create-rule <ID>` | Szkielet nowej reguły + fixture |
146
- | `mjolnir --format mermaid` | Diagram architektury testów do komentarza PR |
193
+ <summary><strong>Wszystkie pozostałe polecenia</strong> — triaż niestabilnych testów, raportowanie, nadzór</summary>
194
+
195
+ <br />
196
+
197
+ | Polecenie | Co robi |
198
+ | ----------------------------------- | --------------------------------------------------------------------------------------- |
199
+ | `mjolnir --classic` | Baner wyniku sprzed Trust Reportu |
200
+ | `mjolnir explain verdict` | Dlaczego werdykt zapisanego skanu jest taki, a nie inny |
201
+ | `mjolnir triage ./test-results/` | Prowadzony triaż. Każdy wiersz kończy się następnym krokiem. |
202
+ | `mjolnir pw-report ./test-results/` | Podsumowanie przebiegu Playwright: ponowienia, niestabilne testy, najwolniejsze |
203
+ | `mjolnir doctor:playwright` | Głęboki skan tylko dla Playwright plus Selector Health Score |
204
+ | `mjolnir fix --dry-run` / `fix` | Bezpieczne automatyczne poprawki, każda ponownie skanowana, by udowodnić, że zadziałała |
205
+ | `mjolnir baseline` / `diff` | Zapisuje stan znalezisk, a potem zgłasza tylko nowe lub gorsze |
206
+ | `mjolnir impact --since <ref>` | Co commit wprowadził i rozwiązał |
207
+ | `mjolnir summary` | Adnotacje CI i podsumowanie kroku na podstawie raportu |
208
+ | `mjolnir pr-comment` | Komentarz do PR o ograniczonym zakresie, w Markdown |
209
+ | `mjolnir debt` | Rejestr długu testowego z modelem kosztów |
210
+ | `mjolnir handover` | Mapa wdrożeniowa zestawu dla nowego inżyniera QA |
211
+ | `mjolnir init` | Wykrywa frameworki, wypisuje listę kontrolną konfiguracji |
212
+ | `mjolnir suppressions` | Wyświetla wyciszone znaleziska, na potrzeby nadzoru |
213
+ | `mjolnir rules --unmeasured` | Reguły działające na założeniu, a nie na pomiarze |
214
+ | `mjolnir rules --md` | Pełny katalog reguł (JSON lub Markdown) |
215
+ | `mjolnir doctor` | Autoaudyt własnej bazy reguł Mjölnira |
216
+ | `mjolnir create-rule <ID>` | Tworzy szkielet nowej reguły i jej fixture'ów |
217
+ | `mjolnir stats` | Lokalne liczniki wszystkich widzianych poprawek |
218
+ | `mjolnir badge` | JSON endpointu shields.io i fragment kodu |
219
+ | `mjolnir --cache` | Przyrostowe ponowne skany dzięki lokalnej pamięci podręcznej werdyktów |
220
+ | `mjolnir --format mermaid` | Diagram architektury testów do komentarza w PR |
221
+
222
+ `mjolnir help <command>` wypisuje sposób użycia, przykłady i następny krok dla każdego z nich.
147
223
 
148
224
  </details>
149
225
 
150
- Zainstaluj globalnie zamiast `npx`, jeśli wolisz: `npm i -g mjolnir-qa`.
151
- Wymaga Node.js ≥ 22.18. Działa na Windows, macOS i Linux.
152
-
153
- ---
154
-
155
- ## 👥 Dla kogo to jest?
156
-
157
- - **QA / SDET** posiadający suitę e2e lub integracyjną, którzy
158
- potrzebują dowodów, że suita naprawdę zasługuje na zielony check,
159
- jaki wystawia.
160
- - **Zespoły Platform / DevEx** odpowiedzialne za integralność CI i
161
- release gate'y — ludzie, dla których `continue-on-error` nie może
162
- nigdy po cichu przemalować czerwonego pipeline'u na zielono.
163
- - **Maintainerzy OSS**, którzy chcą taniego, zawsze włączonego gate'a
164
- weryfikacyjnego, działającego lokalnie i w CI bez wywołań sieciowych.
165
-
166
- ---
226
+ Wymaga **Node.js ≥ 22.18** w systemie Windows, macOS lub Linux. Wolisz instalację globalną? `npm i -g mjolnir-qa`. Minimalna wersja wynika z łańcucha budowania (tsdown ją obsługuje, a pipeline wydań wykonuje na niej testy dymne); zależności uruchomieniowe nie potrzebują nic więcej.
167
227
 
168
- ## 🔨 Co sprawdza Mjölnir
228
+ <br />
169
229
 
170
- | | |
171
- | --- | ------------------------------------------------------------------------------------------------------------------------------------- |
172
- | ⚖️ | **Wskaźnik wiarygodności** — jedna liczba, przejrzysta tabela potrąceń, żadna czarna skrzynka |
173
- | 🎭 | **Selector Health Score** — ocenia twoje lokatory Playwright, a nie tylko pass rate |
174
- | 🔬 | **Kryminalistyka runtime** — czyta prawdziwe dane przebiegów Playwright/JUnit, by złapać `TRUE-FLAKE`, nie tylko statyczne zgadywanki |
175
- | 🚨 | **Reguły integralności CI** — łapie `continue-on-error`, `\|\| true` i inne triki na fałszywą zieleń |
176
- | 🐍 | **Wszystkie cztery bindingi Playwright** — TypeScript, Python, Java, C#/.NET — plus pytest, JUnit/TestNG i workflow CI |
177
- | 🔒 | **Local-first** — zero wywołań sieciowych podczas skanu, zero telemetrii, działa w sekundy |
230
+ ## Co znajduje Mjölnir
178
231
 
179
- ### Reguły
232
+ <p align="center">
233
+ <img src="assets/readme/stack.svg" alt="Działa z twoim stosem: języki, frameworki testowe i systemy CI objęte jego regułami, według rejestru reguł." width="100%" />
234
+ </p>
180
235
 
181
- Każda reguła jest dostarczana z fixture'ami must-fire **i**
182
- must-not-fire. Reguła, która odpala na własnej negatywnej fixture,
183
- nie może się wydać — to zapora na fałszywe pozytywy.
236
+ **79 reguł** w czterech rodzinach — higiena testów, jakość testów, Playwright i integralność CI — dla TypeScript i JavaScript, Pythona, Javy, C# oraz YAML GitHub Actions. Obejmują Playwright we wszystkich czterech bindingach, a także pytest, JUnit, TestNG, NUnit, xUnit, MSTest, Jest, Vitest i Mocha, z początkowym wsparciem dla Cypress i Selenium. Dziewięć z nich, aby pokazać, jak to wygląda:
184
237
 
185
- <details>
186
- <summary><strong>Higiena testów</strong></summary>
187
-
188
- | ID | Reguła | Severity |
189
- | ----------- | ----------------------------------------------------- | -------- |
190
- | QA-TEST-001 | Committowany test z fokusem (`.only`, `fit`) | error |
191
- | QA-TEST-002 | Pominięty test bez uzasadnienia | error |
192
- | QA-TEST-002 | Pominięty test z zarejestrowanym uzasadnieniem | warning |
193
- | QA-TEST-003 | Test bez asercji | error |
194
- | QA-TEST-004 | Twardy sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning |
195
- | QA-TEST-006 | Nadużywanie retry, ukrywające flakiness | warning |
196
- | QA-TEST-010 | Puste ciało testu | error |
238
+ | ID | Reguła | Ważność | Poziom |
239
+ | ------------ | ------------------------------------------------------------------ | ------- | ---------- |
240
+ | QA-CI-001 | `continue-on-error` maskuje zawodzącą bramkę weryfikacji | error | quarantine |
241
+ | QA-CI-009 | Kod wyjścia testów nieprzekazany (`\|` bez pipefail, łańcuchy `;`) | error | extended |
242
+ | QA-TEST-001 | Zacommitowany test z fokusem (`.only`, `fit`) | error | quarantine |
243
+ | QA-TEST-003 | Test bez asercji | error | quarantine |
244
+ | QA-TQUAL-009 | Asercja na promise bez await | error | quarantine |
245
+ | QA-PW-002 | Asercja na lokatorze bez await | error | core |
246
+ | QA-PW-004 | Kruche selektory CSS/XPath | warning | quarantine |
247
+ | QA-PY-002 | Pominięty test (`skip`, nieścisły `xfail`) | warning | core |
248
+ | QA-CS-103 | Metoda testowa bez asercji | error | core |
197
249
 
198
- </details>
250
+ Pełny katalog jest generowany z rejestru, nigdy nie jest utrzymywany ręcznie: `mjolnir rules --md`, [`docs/rules/`](docs/rules/) albo [przewodnik po tym, co sprawdza](https://sergey-bar.github.io/Mjolnir/guide/what-it-checks).
199
251
 
200
252
  <details>
201
- <summary><strong>Jakość testów</strong></summary>
202
-
203
- | ID | Reguła | Severity |
204
- | ------------ | ------------------------- | -------- |
205
- | QA-TQUAL-002 | Asercja tautologiczna | error |
206
- | QA-TQUAL-009 | Asercja promise bez await | error |
207
- | QA-TQUAL-011 | Zakomentowane testy | warning |
253
+ <summary><strong>Każda reguła wymieniona w tym README</strong>, w jednej tabeli</summary>
254
+
255
+ <br />
256
+
257
+ > Reguły `quarantine` działają tylko z `--strict` i nigdy nie blokują (są ograniczone do info). Pokazana ważność to ważność nadana przez autora.
258
+
259
+ | ID | Rodzina | Reguła | Ważność | Poziom |
260
+ | ------------ | ---------- | ----------------------------------------------------------- | ------- | ---------- |
261
+ | QA-TEST-001 | Higiena | Zacommitowany test z fokusem (`.only`, `fit`) | error | quarantine |
262
+ | QA-TEST-002 | Higiena | Pominięty test. Bez śledzonego powodu eskaluje do `error`. | warning | quarantine |
263
+ | QA-TEST-003 | Higiena | Test bez asercji | error | quarantine |
264
+ | QA-TEST-004 | Higiena | Sztywny sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning | extended |
265
+ | QA-TEST-006 | Higiena | Nadużywanie ponowień, które ukrywa niestabilność | warning | quarantine |
266
+ | QA-TEST-010 | Higiena | Puste ciało testu | error | quarantine |
267
+ | QA-TQUAL-002 | Jakość | Asercja tautologiczna | error | quarantine |
268
+ | QA-TQUAL-009 | Jakość | Asercja na promise bez await | error | quarantine |
269
+ | QA-TQUAL-011 | Jakość | Zakomentowane testy | warning | extended |
270
+ | QA-PW-002 | Playwright | Asercja na lokatorze bez await | error | core |
271
+ | QA-PW-003 | Playwright | Zacommitowane `page.pause()` / `test.only()` | error | core |
272
+ | QA-PW-004 | Playwright | Kruche selektory CSS/XPath | warning | quarantine |
273
+ | QA-PW-123 | Playwright | Zakodowane na sztywno adresy URL środowisk | warning | quarantine |
274
+ | QA-PW-140 | Playwright | Zrzut ekranu bez `maxDiffPixelRatio` | warning | core |
275
+ | QA-CI-001 | CI | `continue-on-error` maskuje zawodzącą bramkę | error | quarantine |
276
+ | QA-CI-002 | CI | `\|\| true` połyka kody wyjścia | error | extended |
277
+ | QA-CI-005 | CI | Raport używany, ale nigdy niegenerowany | error | quarantine |
278
+ | QA-CI-007 | CI | Wrappery ponawiające wokół testów | warning | extended |
279
+ | QA-CI-008 | CI | Krok, który zawsze się udaje, maskuje porażki | error | quarantine |
280
+ | QA-CI-009 | CI | Kod wyjścia nieprzekazany (`\|` bez pipefail, łańcuchy `;`) | error | extended |
281
+ | QA-CI-010 | CI | Testy pomijane tam, gdzie muszą blokować | error | quarantine |
282
+ | QA-PY-002 | Python | Pominięty test (`skip`, nieścisły `xfail`) | warning | core |
283
+ | QA-PY-003 | Python | Funkcja testowa bez asercji | error | quarantine |
284
+ | QA-PY-005 | Python | `time.sleep()` w testach | warning | extended |
285
+ | QA-PY-012 | Python | Asercja tautologiczna | error | quarantine |
286
+ | QA-JV-101 | Java | Wyłączony test (`@Disabled`) | warning | core |
287
+ | QA-JV-102 | Java | Sztywny sleep (`Thread.sleep()`) | warning | extended |
288
+ | QA-JV-103 | Java | Metoda testowa bez asercji | error | extended |
289
+ | QA-JV-105 | Java | Sztywny sleep przez `waitForTimeout()` w Playwright | warning | core |
290
+ | QA-JV-106 | Java | Kruchy selektor zamiast lokatora opartego na roli | warning | quarantine |
291
+ | QA-CS-101 | C# | Pominięty test (`[Ignore]`, `[Fact(Skip=)]`) | warning | core |
292
+ | QA-CS-102 | C# | Sztywny sleep (`Thread.Sleep` / `Task.Delay`) | warning | core |
293
+ | QA-CS-103 | C# | Metoda testowa bez asercji | error | core |
294
+ | QA-CS-105 | C# | Sztywny sleep przez `WaitForTimeoutAsync()` | warning | extended |
295
+ | QA-CS-106 | C# | Kruchy selektor zamiast lokatora opartego na roli | warning | quarantine |
296
+
297
+ Python ma też reguły QA-PY-001…012 (higiena pytest) i QA-PY-101…108 (Playwright dla Pythona). Cypress i Selenium mają zestawy startowe po trzy reguły.
208
298
 
209
299
  </details>
210
300
 
211
- <details>
212
- <summary><strong>Playwright 🎭</strong></summary>
301
+ Każda reguła trafia do wydania z fixture'em must-fire **i** must-not-fire, a reguła, która odpala na własnym negatywnym fixture'ze, nie może zostać wydana. To zapora przed fałszywymi alarmami; `mjolnir doctor` egzekwuje ją we własnym CI tego repozytorium.
213
302
 
214
- | ID | Reguła | Severity |
215
- | --------- | ------------------------------------------- | -------- |
216
- | QA-PW-002 | Asercja lokatora bez await | error |
217
- | QA-PW-003 | `page.pause()` / `test.only()` committowane | error |
218
- | QA-PW-004 | Kruche selektory CSS/XPath | warning |
219
- | QA-PW-123 | Zaszyte na sztywno URL-e środowisk | warning |
303
+ ### Selector Health Score
220
304
 
221
- </details>
305
+ `mjolnir doctor:playwright` ocenia każdy lokator według tego, jak znajduje element: tak jak zrobiłby to użytkownik (rola, etykieta, tekst), przez jawny kontrakt (`data-testid`) lub przez przypadek strukturalny (łańcuchy CSS, XPath). Każdy plik dostaje wynik od 0 do 100:
222
306
 
223
- <details>
224
- <summary><strong>Integralność CI</strong></summary>
225
-
226
- | ID | Reguła | Severity |
227
- | --------- | ------------------------------------------------------------------ | -------- |
228
- | QA-CI-001 | `continue-on-error` maskuje porażki | error |
229
- | QA-CI-002 | `\|\| true` połyka kody wyjścia | error |
230
- | QA-CI-005 | Raport konsumowany, ale nigdy nie generowany | error |
231
- | QA-CI-007 | Wrapper'y retry wokół testów | warning |
232
- | QA-CI-008 | Zawsze udany step maskuje porażki | error |
233
- | QA-CI-009 | Kod wyjścia testu niepropagowany (`\|` bez pipefail, łańcuchy `;`) | error |
234
- | QA-CI-010 | Testy pomijane tam, gdzie muszą blokować (strażniki skip-on-PR) | error |
235
-
236
- </details>
237
-
238
- <details>
239
- <summary><strong>Python / pytest 🐍</strong></summary>
240
-
241
- | ID | Reguła | Severity |
242
- | --------- | ------------------------------------------ | -------- |
243
- | QA-PY-002 | Pominięty test (`skip`, niestrykt `xfail`) | warning |
244
- | QA-PY-003 | Funkcja testowa bez asercji | error |
245
- | QA-PY-005 | `time.sleep()` w testach | warning |
246
- | QA-PY-012 | Asercja tautologiczna | error |
247
-
248
- Łącznie 20 reguł Pythona (QA-PY-001…012 higiena pytest + QA-PY-101…108 Playwright-Python).
307
+ ```text
308
+ ▍ SELECTOR HEALTH
249
309
 
250
- </details>
310
+ e2e/login.spec.ts
311
+ [█████████████░░░░░░░] 65 / 100
312
+ role/text: 1 · testid: 0 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
251
313
 
252
- <details>
253
- <summary><strong>Java / JUnit · TestNG ☕</strong></summary>
314
+ e2e/checkout.spec.ts
315
+ [██████████████████░░] 88 / 100
316
+ role/text: 4 · testid: 1 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
317
+ ```
254
318
 
255
- | ID | Reguła | Severity |
256
- | --------- | ------------------------------------------ | -------- |
257
- | QA-JV-101 | Wyłączony test (`@Disabled`) | warning |
258
- | QA-JV-102 | Twardy sleep (`Thread.sleep()`) | warning |
259
- | QA-JV-103 | Metoda testowa bez asercji | error |
260
- | QA-JV-105 | Twardy sleep Playwright `waitForTimeout()` | warning |
261
- | QA-JV-106 | Kruchy selektor zamiast role lokatora | warning |
319
+ To mierzy **odporność, a nie poprawność**. `.btn.btn-primary > div:nth-child(2)` przechodzi dziś i będzie przechodzić, dopóki ktoś nie ruszy znaczników. Niski wynik nigdy nie twierdzi, że test jest zepsuty, tylko że zależy od znaczników, których nikt nie obiecał zachować.
262
320
 
263
- </details>
321
+ <br />
264
322
 
265
- <details>
266
- <summary><strong>C# / .NET — NUnit · xUnit · MSTest 🟣</strong></summary>
323
+ ## Wynik wiarygodności
267
324
 
268
- | ID | Reguła | Severity |
269
- | --------- | -------------------------------------------- | -------- |
270
- | QA-CS-101 | Pominięty test (`[Ignore]`, `[Fact(Skip=)]`) | warning |
271
- | QA-CS-102 | Twardy sleep (`Thread.Sleep` / `Task.Delay`) | warning |
272
- | QA-CS-103 | Metoda testowa bez asercji | error |
273
- | QA-CS-105 | Twardy sleep `WaitForTimeoutAsync()` | warning |
274
- | QA-CS-106 | Kruchy selektor zamiast role lokatora | warning |
325
+ <p align="center">
326
+ <img src="assets/readme/score-gauge.svg" alt="Skala wiarygodności od 0 do 100, ze znacznikiem przechodzącym przez każdy wynik: UNWORTHY poniżej 50, NEEDS WORK od 50 do 79, WORTHY od 80 do 99, FORGED przy 100" width="720" />
327
+ </p>
275
328
 
276
- </details>
329
+ <sub>Każdy wynik od 0 do 100, umieszczony przez prawdziwe `deriveScoreState`. Wygenerowane przez `npm run docs:gauge` i zabezpieczone w CI przed rozjazdem.</sub>
277
330
 
278
- > Pełny, żywy katalog — każda reguła z tierem, confidence, ryzykiem
279
- > fałszywych pozytywów i dostępnością autofixa — jest generowany z
280
- > rejestru:
281
- >
282
- > ```bash
283
- > mjolnir rules --md
284
- > ```
285
- >
286
- > Strony pojedynczych reguł mieszkają w [`docs/rules/`](docs/rules/).
331
+ | Wynik | Werdykt |
332
+ | --------- | --------------------------------------------- |
333
+ | `0 – 49` | **UNWORTHY** |
334
+ | `50 – 79` | **NEEDS WORK** |
335
+ | `80 – 99` | **WORTHY** |
336
+ | `100` | **FORGED** |
337
+ | `null` | **UNKNOWN**: nie znaleziono deklaracji testów |
287
338
 
288
- ### Ile z tego jest zmierzone
339
+ **Jak jest liczony.** Ważność ustala potrącenie bazowe (`error −8`, `warning −3`, `info −1`), a poziom dowodu je obniża: E2 liczy się w całości, E1 w połowie (zaokrąglając w dół), E0 wcale. Suma jest normalizowana względem ekspozycji zestawu, czyli potrąceń na deklarację testu, a nie na plik. Terminal wypisuje te same obniżone liczby, których użył wynik; nie ma ukrytego drugiego modelu. Szczegóły: [docs/SCORING.md](docs/SCORING.md) i [przewodnik po wyniku](https://sergey-bar.github.io/Mjolnir/guide/scoring).
289
340
 
290
- **78 z 99 reguł niesie stopę fałszywych pozytywów zmierzoną na
291
- prawdziwym kodzie OSS** (≥ 10 ręcznie zaklasyfikowanych znalezisk każda;
292
- zob. [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). Pozostałe 21 wychodzi na
293
- oszacowaniu autora. Stopka każdego skanu mówi, ile z _odpalonych_
294
- reguł jest zmierzonych; `mjolnir rules --unmeasured` wypisuje
295
- niezmierzone; strona `mjolnir explain` każdej reguły deklaruje jej
296
- się na 95 % i za to trafia do kwarantanny. Powiększanie tej liczby to
297
- stale trwająca praca projektu.
341
+ **Czego 100 nie oznacza.** Nie oznacza, że oprogramowanie jest poprawne, zestaw testów wystarczający, a produkt wolny od defektów. Oznacza jedno: **żadna z reguł ocenionych przez Mjölnira nie dała potrącenia w tym skanie i przy tym modelu dowodów.**
298
342
 
299
- ### Tiery reguł i dojrzałość językowa
343
+ <br />
300
344
 
301
- Każda reguła to `core`, `extended` albo `quarantine`, przypisane z jej
302
- **zmierzoną** stopą fałszywych pozytywów:
345
+ ## Model dowodów
303
346
 
304
- | Tier | Znaczenie | Skan domyślny | `--strict` |
305
- | ------------ | ------------------------------------------------ | :-----------: | :--------: |
306
- | `core` | ≤ 10 % zmierzonych FP | ✅ | ✅ |
307
- | `extended` | ≤ 30 % zmierzonych FP | ✅ | ✅ |
308
- | `quarantine` | powyżej 30 %, albo jeszcze niezmierzone (n < 10) | ❌ | ✅ |
347
+ Każde znalezisko ma dwie etykiety: jak pewny jest Mjölnir i jak daleko znalezisko zostało sprawdzone. To różnica między narzędziem, które zgłasza wzorce, a narzędziem, od którego możesz uzależnić wydanie.
309
348
 
310
- | Język | Adapter | Pokrycie dziś |
311
- | --------------- | --------------- | ------------------------------------------------------------ |
312
- | TypeScript / JS | AST kompilatora | najszersze, najmocniej mierzone — głównie `core`/`extended` |
313
- | Python / pytest | Warstwa regex | szerokie, audytowane na korpusie — głównie `core`/`extended` |
314
- | Java | Warstwa regex | nowsze — głównie `extended`/`quarantine` |
315
- | C# / .NET | Warstwa regex | nowsze — głównie `extended`/`quarantine` |
349
+ **Jak pewne — poziom dowodu.**
316
350
 
317
- TypeScript i Python mają najszersze zmierzone pokrycie. Java i C#
318
- się wydały, są udokumentowane i pozostają poza nagłówkową liczbą,
319
- aż prawdziwa konsumująca suita (nie własne testy biblioteki bindingu)
320
- zostanie audytowana.
351
+ | Poziom | Nazwa | Znaczenie | Potrącenie |
352
+ | ------ | ---------------------- | -------------------------------------------------- | ---------- |
353
+ | **E2** | Dowód deterministyczny | Defekt jest obecny w kodzie w obecnej postaci | Pełne |
354
+ | **E1** | Dowód ze wzorca | Dopasował się wzorzec silnie związany z defektem | Połowa |
355
+ | **E0** | Obserwacja | Warto wiedzieć. Nie twierdzi, że coś jest nie tak. | Zero |
321
356
 
322
- ---
357
+ Pewność wykrycia to nie siła dowodu. Reguła może być pewna, że dopasowała to, czego szukała, a mimo to patrzeć na heurystykę. Znaleziska E1 są po to, by je czytać i oceniać, nigdy stosować na ślepo, a ta granica jest odciśnięta na znalezisku w terminalu, w JSON i w przekazaniu dla agenta.
323
358
 
324
- ## Jak działa punktacja
359
+ **Jak daleko sprawdzone — poziom zaufania.** Większość znalezisk pochodzi z czytania twojego kodu. Daj Mjölnirowi raport z prawdziwego przebiegu testów, a potwierdzi, że kod naprawdę się wykonał.
325
360
 
326
361
  <p align="center">
327
- <img src="assets/readme/terminal-hero.svg" alt="Wynik terminala Mjölnir — WORTHINESS 75/100 NEEDS WORK, rozbicie diagnostyki wg kategorii i lista FIX THIS FIRST" width="820" />
362
+ <img src="assets/readme/trust-ladder.svg" alt="Drabina zaufania od L0 do L5. L0–L2 pochodzą z czytania kodu; L3–L5 wymagają raportu z prawdziwego przebiegu, co zaznacza przerwa w drabinie." width="100%" />
328
363
  </p>
329
364
 
330
- <sub>Regenerowany przez `npm run docs:hero`;
331
- [`tests/hero-asset-reproducibility.spec.ts`](tests/hero-asset-reproducibility.spec.ts)
332
- wywala CI, jeśli artefakt odjechał od tego, co reporter naprawdę
333
- wypisuje.</sub>
365
+ | Poziom | Po ludzku | Czego wymaga |
366
+ | ------ | -------------------- | --------------------------------------------------------------- |
367
+ | **L0** | Odnotowane | Czytanie kodu |
368
+ | **L1** | Wygląda na problem | Czytanie kodu: dopasował się wzorzec |
369
+ | **L2** | Udowodnione w kodzie | Czytanie kodu: defekt jest strukturalny |
370
+ | **L3** | Plik się wykonał | Raport z przebiegu pokazuje, że plik znaleziska został wykonany |
371
+ | **L4** | Test się wykonał | Raport z przebiegu pokazuje, że test znaleziska został wykonany |
372
+ | **L5** | Przebieg się zgadza | Sam wynik przebiegu potwierdza klasę defektu |
334
373
 
335
- Punktacja jest przejrzysta: **error −8, warning −3, info −1**, potem
336
- normalizacja o ekspozycję suity (potrącenia na deklarację testu).
337
- Potrącenia ważone dowodami znaczą, że słabe sygnały kosztują mniej.
338
- Terminal pokazuje te same zdyskontowane liczby, których używa
339
- punktacja — żadnej czarnej skrzynki. Pełna metoda:
340
- [docs/SCORING.md](docs/SCORING.md).
374
+ Skan statyczny kończy się na L2. Tylko raport z prawdziwego przebiegu (Playwright JSON, Jest lub Vitest JSON, JUnit XML) może podnieść znalezisko do L3 lub wyżej, więc znalezisko, którego nigdy nie widziano w działaniu, nigdy nie może twierdzić, że działało. Definicje: [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md).
341
375
 
342
- **Werdykty**
376
+ ### Ile z tego jest zmierzone
343
377
 
344
- | Score | Werdykt |
345
- | ------- | ---------------- |
346
- | ≥ 80 | ✓ **WORTHY** |
347
- | 50 – 79 | ⚠ **NEEDS WORK** |
348
- | < 50 | ✖ **UNWORTHY** |
378
+ **74 z 79 reguł ma odsetek fałszywych alarmów zmierzony na prawdziwym kodzie OSS** (co najmniej 10 ręcznie sklasyfikowanych znalezisk każda; zobacz [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). Pozostałe 5 opiera się na szacunku autora i mówi to, reguła po regule, w `mjolnir explain`. `mjolnir rules --unmeasured` je wypisuje, a stopka każdego skanu podaje, ile z reguł, które faktycznie _odpaliły_, jest zmierzonych.
349
379
 
350
- **Poziomy dowodów** — każde znalezisko niesie jeden; ustawia wagę
351
- znaleziska w punktacji:
380
+ Odsetki pozostają publiczne, także gdy są złe. QA-TEST-001 (zacommitowane `.only`) wypada słabo w audycie na prawdziwych repozytoriach i dlatego siedzi w quarantine. Aktualna liczba dla każdej reguły, łącznie z QA-PW-141, jest w audycie.
352
381
 
353
- | Poziom | Znaczenie | Wpływ na punktację | Przykład |
354
- | ------ | --------------------- | ------------------ | ------------------------------------------------------ |
355
- | E2 | Deterministyczna wada | Pełne potrącenie | Committowany `.only` — dowodliwe strukturalnie |
356
- | E1 | Heurystyczny wzorzec | Połowa potrącenia | Regex-owo trafiony `sleep()` — mocny sygnał, nie dowód |
357
- | E0 | Obserwacja | Zero (tylko info) | Raportowane, ale nigdy nie gate'uje CI i nie potrąca |
382
+ ### Poziomy zaufania reguł
358
383
 
359
- Większość reguł to **E1**. Slogan „we prove it" odnosi się do tego
360
- systemu: znaleziska E2 to dowód strukturalny; znaleziska E1 to
361
- poprawnie pozycjonowane ostrzeżenia, nie formalne dowody.
384
+ Poziomy wynikają ze zmierzonego odsetka fałszywych alarmów, nie z opinii:
362
385
 
363
- Puste repo punktuje `null`, nigdy fałszywą setkę — zob.
364
- [Model zaufania](#model-zaufania).
386
+ | Poziom | Zmierzone FP | Zachowanie |
387
+ | -------------- | ------------------------------ | --------------------------------------------------------- |
388
+ | **core** | ≤ 10% | Raport domyślny, blokuje |
389
+ | **extended** | ≤ 30% | Raport domyślny, niższa pewność |
390
+ | **quarantine** | > 30% lub jawnie zadeklarowane | Tylko `--strict`, ograniczone do info, nigdy nie blokuje |
391
+ | _niezmierzona_ | n < 10 | Nie może awansować do core, dopóki nie zostanie zmierzona |
365
392
 
366
- ---
393
+ Pasma FP mogą tylko obniżyć poziom — nigdy nie promują reguły z `quarantine`, jeśli została tam jawnie zadeklarowana. Jawna reguła w quarantine pozostaje w quarantine niezależnie od zmierzonego wskaźnika FP.
367
394
 
368
- ## 🎭 Selector Health Score
395
+ Awans, degradacja i dojrzałość według języka: [cykl życia reguł](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle).
369
396
 
370
- Flagowa metryka dla suite'ów Playwright — jak odporne są twoje
371
- lokatory:
397
+ ### Dlaczego to nie jest linter
372
398
 
373
- ```text
374
- ▚ SELECTOR HEALTH — e2e/checkout.spec.ts
399
+ Lintery mówią ci, czy kod przestrzega reguł. Mjölnir mówi ci, czy twojej weryfikacji można ufać.
375
400
 
376
- [█████████████████░░░] 83 / 100
377
- role/text: 2 · testid: 1 · css-chains: 1 ⚠ · xpath: 0
378
- ```
401
+ | | Lintery (ESLint, SonarQube) | Narzędzia pokrycia | Code review z AI | **Mjölnir** |
402
+ | ---------------------------------------------------------------- | :-------------------------: | :----------------: | :--------------: | :-----------------: |
403
+ | Ocenia **system weryfikacji**, a nie kod produktu | Nie | Nie | Nie | Tak |
404
+ | Integralność workflow CI (`continue-on-error`, `\|\| true`) | Nie | Nie | tylko diff | Tak |
405
+ | Ocenia odporność lokatorów Playwright (Selector Health) | Nie | Nie | Nie | Tak |
406
+ | Czyta prawdziwe dane z przebiegów dla werdyktów `TRUE-FLAKE` | Nie | Nie | Nie | Tak |
407
+ | Publikuje zmierzony odsetek fałszywych alarmów dla każdej reguły | Nie | Nie | Nie | Tak |
408
+ | Oznacza testy bez asercji | Tak\* | Nie | czasem | Tak |
409
+ | Wyłapuje sztywne sleepy (`waitForTimeout`, `time.sleep`) | Tak\* | Nie | czasem | Tak |
410
+ | Deterministyczny (to samo wejście, to samo wyjście) | Tak | Tak | Nie | Tak |
411
+ | Koszt skanu | za darmo | za darmo | tokeny | **zero** (lokalnie) |
412
+
413
+ <sub>\*Pokryte przez `eslint-plugin-jest` i `eslint-plugin-playwright` (`expect-expect`, `no-wait-for-timeout`) oraz przez własne reguły asercji SonarQube. Kolumny opisują domyślne zachowanie przy weryfikacji zestawów testów; wtyczki, płatne plany i własne reguły zmieniają niektóre odpowiedzi. To podsumowanie pozycjonowania, a nie benchmark.</sub>
379
414
 
380
- Lokatory oparte na rolach dostają pełną punktację. Łańcuchy klas CSS i
381
- XPath toną w punktacji — łamią się przy każdym refactorze DOM, nie
382
- mówiąc, które zachowanie zregresowało.
415
+ Korzystaj też z review z AI. Wychwytuje niuanse, intencje i wady projektowe, których żaden wzorzec nie znajdzie. Mjölnir wychwytuje to, co review z AI przeoczy, bo wygląda na zamierzone: zacommitowane `.only`, połknięty kod wyjścia, `continue-on-error` na jobie testowym. To wymaga skanowania, nie rozumowania.
383
416
 
384
- ---
417
+ <br />
385
418
 
386
- ## 🔬 Dowody z runtime
419
+ ## Analiza przebiegów testów
387
420
 
388
- Statyczna detekcja flakiness to zgadywanie. Mjölnir czyta **prawdziwe
389
- dane wykonania** — raporty JSON Playwright i XML JUnit z dowolnego
390
- runnera:
421
+ Analiza statyczna rozumuje o kodzie, który nigdy się nie wykonał. Analiza przebiegów czyta to, co faktycznie się stało: Playwright JSON, Jest JSON, Vitest JSON i JUnit XML z dowolnego runnera.
391
422
 
392
423
  ```bash
393
424
  mjolnir forensics ./test-results/
394
425
  ```
395
426
 
396
427
  ```text
397
- ▚ FLAKINESS LEADERBOARD
428
+ ▍ FLAKINESS LEADERBOARD
398
429
 
399
430
  3 tests · 1 failed · 1 flaky · 1 retried
400
431
 
@@ -404,293 +435,184 @@ FAILING declines an expired card (e2e/checkout.spec.ts)
404
435
  ████░░░░░░░░░░░░░░░░ 1.1s · 1 attempt
405
436
  ```
406
437
 
407
- Test, który przechodzi dopiero od próby ≥ 2, nie jest testem
408
- przechodzącym — to szczęśliwy test. Zostaje oznaczony `TRUE-FLAKE`
409
- niezależnie od finalnego zielonego checka.
438
+ `TRUE-FLAKE` nie oznacza, że test był ponawiany. Oznacza, że test **zawiódł przynajmniej jedną próbę, a potem zakończył się na zielono**: szczęśliwe przejście, oznaczone bez względu na to, co mówi końcowy znacznik. `mjolnir triage` zamienia tę historię w propozycję kwarantanny, a `mjolnir pw-report` podsumowuje przebieg. To te same raporty z przebiegów podnoszą znaleziska do poziomów zaufania L3 i wyżej.
410
439
 
411
- ---
440
+ <br />
412
441
 
413
- ## ⚡ Mjölnir nie jest kolejnym linterem
442
+ ## Integralność CI
414
443
 
415
- Lintery mówią ci, czy kod trzyma się reguł. Mjölnir mówi ci, czy twoja
416
- weryfikacja da się uznać za wiarygodną.
444
+ Test może przechodzić, podczas gdy pipeline wokół niego nie może zawieść. Mjölnir czyta też workflow: `continue-on-error`, `|| true`, kody wyjścia, które nigdy się nie propagują, kroki zawsze kończące się sukcesem, raporty używane, ale nigdy niegenerowane, oraz bramki pomijane przy zdarzeniach, które powinny blokować. Każde znalezisko wskazuje job, krok i wiersz oraz ma własny poziom dowodu.
417
445
 
418
- | | ESLint / SonarQube | Narzędzia coverage | Ręczny review | **Mjölnir** |
419
- | ----------------------------------------------------------- | :----------------: | :----------------: | :-----------: | :---------: |
420
- | Integralność workflow CI (`continue-on-error`, `\|\| true`) | ❌ | ❌ | rzadko | ✅ |
421
- | Cross-językowo (TS, Python, Java, C#) z jednego narzędzia | ❌ | ❌ | ❌ | ✅ |
422
- | Ocenia odporność lokatorów Playwright (Selector Health) | ❌ | ❌ | rzadko | ✅ |
423
- | Wyłapuje testy bez prawdziwych asercji | ✅ (plugin)\* | ❌ | czasem | ✅ |
424
- | Łapie twarde sleepy (`waitForTimeout`, `time.sleep`) | ✅ (plugin)\* | ❌ | czasem | ✅ |
425
- | Działa w sekundy, zero wywołań sieciowych podczas skanu | ✅ | ✅ | — | ✅ |
446
+ Wygeneruj workflow dla PR, domyślnie doradczy:
426
447
 
427
- \*`eslint-plugin-jest` (`expect-expect`) i `eslint-plugin-playwright`
428
- (`expect-expect`, `no-wait-for-timeout`) pokrywają to dla swoich
429
- frameworków.
448
+ ```bash
449
+ mjolnir ci install
450
+ ```
430
451
 
431
- **Analiza runtime** to osobna kategoria obok statycznego lintowania:
452
+ Albo dodaj akcję z Marketplace do workflow, który już masz:
432
453
 
433
- | | Playwright retry reporter | Allure / ReportPortal | **Mjölnir forensics** |
434
- | ---------------------------------------------------------- | :-----------------------: | :-------------------: | :-------------------: |
435
- | Czyta prawdziwe dane przebiegów dla werdyktów `TRUE-FLAKE` | częściowo\* | częściowo (tag) | ✅ |
436
- | Raport triażu flakiness z historii wykonania | ❌ | ✅ | ✅ |
437
- | Integruje się ze statycznym wskaźnikiem wiarygodności | ❌ | ❌ | ✅ |
454
+ ```yaml
455
+ - uses: Sergey-Bar/Mjolnir@v1
456
+ with:
457
+ scope: changed
458
+ fail-on: error
459
+ ```
438
460
 
439
- \*Playwright śledzi retry wewnętrznie, ale nie produkuje samodzielnego
440
- raportu flakiness z etykietami werdyktów.
461
+ Przypnij `@v1`, aby podążać za główną linią, albo dokładny tag (`@v0.5.32`) dla powtarzalnej bramki. [docs/DISTRIBUTION-KIT.md](docs/DISTRIBUTION-KIT.md) opisuje Marketplace, Smithery i rejestry MCP.
441
462
 
442
- ---
463
+ Aby umieścić znaleziska w GitHub Code Scanning, wyślij SARIF (wymaga `security-events: write` na poziomie workflow lub job):
443
464
 
444
- ## 🤖 Czemu nie użyć po prostu AI code review?
465
+ ```yaml
466
+ - run: npx mjolnir-qa@latest --format sarif > mjolnir.sarif
467
+ continue-on-error: true
468
+ - uses: github/codeql-action/upload-sarif@v3
469
+ if: ${{ !cancelled() }}
470
+ with:
471
+ sarif_file: mjolnir.sarif
472
+ ```
445
473
 
446
- Inny problem, inna warstwa. AI review może dostrzec podejrzaną zmianę
447
- testu w diffie; nie dowodzi, że system weryfikacji jako całość jest
448
- godny zaufania — i widzi tylko diff, który mu pokażesz.
474
+ W GitLab `--format codequality` zapisuje raport Code Quality, który czytają widżet MR i adnotacje diffu ([docs/GITLAB-CI.md](docs/GITLAB-CI.md)). Konfiguracja edytora i pipeline'u: [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
449
475
 
450
- | | AI code review (Copilot i in.) | **Mjölnir** |
451
- | ------------------------------------------------- | :-------------------------------: | :-------------------------------: |
452
- | Koszt na skan | Tokeny (rośnie z rozmiarem diffа) | **Zero** (lokalny, zainstalowany) |
453
- | Widzi całą suitę + wszystkie configi CI | Tylko diff PR, który mu pokażesz | **Wszystko, za każdym razem** |
454
- | Deterministyczny (ten sam input → ten sam output) | ❌ (niedeterministyczny) | **✅** |
455
- | Łapie wzorce śpiące miesiącami | Tylko jeśli jest w kontekście | **✅** (skanuje wszystkie pliki) |
456
- | Pamięta znaleziska między przebiegami | ❌ (brak pamięci między sesjami) | **✅** (baseline + diff) |
457
- | Działa bez ludzkiego wyzwalacza | Potrzebuje PR-a albo promptu | **✅** (hak CI, działa sekundy) |
476
+ ### Przypisanie w zakresie zmian
458
477
 
459
- **Używaj obu.** AI łapie niuans, intencję i wady projektowe, których
460
- żaden regex nie znajdzie. Mjölnir łapie strukturalne wzorce, które AI
461
- pomija, bo wyglądają „intencjonalnie" — committowany `.only`,
462
- połknięty kod wyjścia, `continue-on-error` na jobie testowym. To nie
463
- są bugi wymagające rozumowania; to fakty wymagające skanowania.
478
+ ```bash
479
+ npx mjolnir-qa@latest --scope changed
480
+ ```
464
481
 
465
- ---
482
+ Znaleziska są przypisywane do wierszy dodanych przez twoją gałąź, liczonych względem **merge-base**. Zakres to ten sam zbiór plików, który odkrywa pełny skan (specyfikacje TS/JS i konfiguracje adapterów, `test_*.py`, `*Test.java`, `*Tests.cs`, `.github/workflows/*.yml`), plus niezacommitowane i nieśledzone zmiany, więc działa jeszcze przed commitem. Baza jest rozwiązywana w kolejności `main → master → origin/main → origin/master → origin/HEAD`; możesz ją nadpisać przez `--base <ref>`.
466
483
 
467
- ## 🤖 Integracja CI
484
+ Gdy merge-base nie da się rozwiązać (płytki klon, odłączony HEAD, cel poza git), znaleziska wracają do przypisania do całego pliku **i raport to mówi.** Ciche przejście na tryb awaryjny byłoby dokładnie tym rodzajem defektu, dla którego wykrywania istnieje to narzędzie.
468
485
 
469
- Jedna komenda generuje workflow PR — domyślnie doradczy, nigdy
470
- blokujący:
486
+ <br />
471
487
 
472
- ```bash
473
- mjolnir ci install
474
- ```
488
+ ## Agenci AI
475
489
 
476
- Albo podepnij go natywnie pod GitHub Code Scanning przez SARIF:
490
+ Znaleziska są coś warte tylko wtedy, gdy coś na nie reaguje.
477
491
 
478
- ```yaml
479
- - run: npx mjolnir-qa@latest --format sarif > mjolnir.sarif
480
- - uses: github/codeql-action/upload-sarif@v3
481
- with:
482
- sarif_file: mjolnir.sarif
492
+ ```text
493
+ SCAN → EVIDENCE → HANDOFF → AGENT → RE-SCAN → PROOF
483
494
  ```
484
495
 
485
- Konfiguracja edytora i pipeline'u dla SARIF:
486
- [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
496
+ **AI pisze poprawkę. Mjölnir ją weryfikuje.** Dowód pochodzi z ponownego skanu, nigdy z własnego raportu agenta o sukcesie.
487
497
 
488
- ### Pokrycie changed-scope
498
+ | Polecenie | Co dostaje agent |
499
+ | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
500
+ | `mjolnir mcp` | Serwer [MCP](https://modelcontextprotocol.io) przez stdio. `scan`, `explain` i `diff` stają się narzędziami do wywołania. |
501
+ | `mjolnir handoff` | Zapisany raport `--json` staje się deterministycznym planem w Markdown: co wykryto, granica dowodu dla każdego znaleziska, co **nie** może się zmienić, jak to zweryfikować. |
502
+ | `mjolnir install` | Zapisuje w miejscach dla agentów, które twoje repo już ma (`.claude/`, `.cursor/`, `.kilo/`, `AGENTS.md`), aby agent skanował ponownie, zanim oświadczy, że skończył. |
489
503
 
490
- `--scope changed` przypisuje znaleziska liniom dodanym w twoim branchu
491
- względem merge-base z `main`. Pokrywa pliki testowe (`*.spec.*`,
492
- `*.test.*`) plus pliki workflow GitHub i konfiguracje Playwright w
493
- diffie. Gdy merge-base nie da się rozwiązać — shallow clone, detached
494
- HEAD, cel spoza git, inny domyślny branch — degraduje się uczciwie:
495
- znaleziska wracają do atrybucji na cały plik, a raport mówi o tym.
496
- Nadpisz bazową ref przez `--base <ref>`.
504
+ Dodaj go do klienta, który ma własne CLI:
497
505
 
498
- ---
499
-
500
- ## Konfiguracja
501
-
502
- Mjölnir jest zero-config. Opcjonalny `mjolnir.config.json` (lub
503
- `.mjolnir.json`) w korzeniu repo dostraja severity, gating i scope —
504
- nigdy nie zmienia semantyki detekcji.
506
+ ```bash
507
+ claude mcp add mjolnir -- npx -y mjolnir-qa@latest mcp
508
+ ```
505
509
 
506
- | Key | Typ | Działanie |
507
- | ------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
508
- | `exclude` | `string[]` | Dodatkowe globy ignorowania (podzbiór gitignore), na wierzchu wbudowanych domyślnych |
509
- | `gate` | `"advisory" \| "error" \| "warning"` | Które severity kończą się kodem niezerowym (domyślnie `error`; `advisory` nigdy nie blokuje) |
510
- | `severityOverrides` | `{ "<RULE-ID>": severity }` | Przerankowuje znaleziska reguły dla twojego repo |
511
- | `ignore` | `IgnoreEntry[]` | Wycisza znaleziska — **`reason` jest wymagany**; wpisy wygasają po 90 dniach (jawna data `expires`, albo czas ostatniej modyfikacji pliku konfiga dla wpisów bez niej) |
512
- | `plugins` | `string[]` | Zewnętrzne pakiety reguł (zob. [Model zaufania](#model-zaufania)) |
510
+ Albo do dowolnego klienta, który przyjmuje blok `mcpServers`:
513
511
 
514
512
  ```json
515
513
  {
516
- "gate": "error",
517
- "exclude": ["legacy/**"],
518
- "severityOverrides": { "QA-PW-141": "warning" },
519
- "ignore": [
520
- {
521
- "ruleId": "QA-TEST-004",
522
- "files": ["e2e/legacy-login.spec.ts"],
523
- "reason": "Third-party widget needs a settle delay; tracked in JIRA-4821",
524
- "expires": "2026-12-31"
525
- }
526
- ]
514
+ "mcpServers": {
515
+ "mjolnir": { "command": "npx", "args": ["-y", "mjolnir-qa@latest", "mcp"] }
516
+ }
527
517
  }
528
518
  ```
529
519
 
530
- - **`.mjolnirignore`** — prosty plik w stylu gitignore dla wykluczeń
531
- ścieżek, ten sam dialekt co `exclude`. Użyj go na szum maszynowy; użyj
532
- `exclude`, gdy lista należy do kontroli wersji, obok reszty configa.
533
- - **Override'y CLI** — `--strict` (dołącz reguły kwarantanny),
534
- `--width <cols>` i `--ascii` / `--no-ascii` (render terminala),
535
- `--tone blunt` (ostrejsze komunikaty), `--max-duration <sec>`
536
- (ograniczony skan częściowy).
537
- - Wyciszanie reguł i cykl życia deprecacji:
538
- [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md).
539
-
540
- Wpisy `ignore` zasilają też samodzielną komendę `mjolnir suppressions`,
541
- która wypisuje, co jest aktualnie wyciszone i kiedy wygasa każdy wpis.
542
-
543
- ---
544
-
545
- ## 📐 Kody wyjścia i kontrakty
546
-
547
- Zamrożone — bezpieczna baza do budowania logiki CI:
548
-
549
- | Kod wyjścia | Znaczenie |
550
- | ----------- | ------------------------------------------------------------------------------- |
551
- | `0` | Czysto — brak znalezisk na poziomie gate'a lub wyżej |
552
- | `1` | Znaleziska na poziomie gate'a lub wyżej |
553
- | `2` | Skan częściowy (wyczerpany budżet czasu, nieczytelne pliki) — nigdy nie blokuje |
554
- | `10` | Błąd użycia (zły flag, brakujący cel) |
555
- | `20` | Błąd wewnętrzny |
556
-
557
- Raport JSON/SARIF to `schemaVersion: 1`. ID reguł (`QA-<FAMILY>-NNN`)
558
- są niezmienne po wydaniu i nigdy nie są używane ponownie.
559
-
560
- ---
561
-
562
- ## Model zaufania
563
-
564
- - **Local-first** — zero wywołań sieciowych podczas skanowania. Nigdy.
565
- Zero telemetrii.
566
- - **Żadnych fałszywych dowodów** — wolimy powiedzieć „nieznane" niż
567
- „zweryfikowane". Puste repo dostaje `score: null`, nigdy fałszywej
568
- setki.
569
- - **Częściowa uczciwość** — jeśli analizę ucięto, wynik to mówi. Nigdy
570
- „complete", gdy to nieprawda.
571
- - **Zapora FP** — detekcja działa na widoku kodu wolnym od komentarzy i
572
- stringów (reguły TypeScript używają AST kompilatora): wzorzec w
573
- komentarzu prozatorskim czy doc- przykładzie-stringu to dokumentacja,
574
- nie znalezisko.
575
- - **Zmierzone, nie założone** — do tierów nagłówkowych trafiają tylko
576
- reguły ze stopą fałszywych pozytywów z prawdziwego kodu OSS (zob.
577
- [Ile z tego jest zmierzone](#ile-z-tego-jest-zmierzone)); stopka
578
- skanu i `mjolnir rules --unmeasured` powiedzą ci, które które.
579
- - **Zaufanie do pluginów i brama wykonania** — pluginy to pakiety npm
580
- deklarowane pod
581
- `"plugins"`; moduły JS żyją w `mjolnir-rules/*.mjs`.
582
- **Nie ma sandboxa**: kod pluginu działa z pełnymi
583
- uprawnieniami Node, ten sam model zaufania co pluginy ESLint czy
584
- Vitest. Dlatego wykonanie kodu jest **opt-in przy każdym skanie**:
585
- przekaż `--enable-plugins` (albo ustaw `MJOLNIR_ENABLE_PLUGINS=1`),
586
- inaczej źródła NIE są ładowane — głośny komunikat na stderr wylicza
587
- dokładnie, co pominięto. Skanowanie niezaufanego kodu nigdy go nie
588
- wykonuje. Manifesty reguł JSON (`mjolnir-rules/*.json`) nie są
589
- dotknięte: deklarują wzorce regex i z założenia nie wykonują kodu.
590
- Prefiksy ID reguł core są zarezerwowane i odrzucane od
591
- pluginów i zewnętrznych reguł przeciw spoofingowi.
592
- - **Zewnętrzne reguły lokalne wobec workspace'u** (folderowe, zero
593
- sieci) — katalog `mjolnir-rules/` obok celu skanu ładuje własne
594
- reguły: pliki JSON deklarują wzorce regex (żaden kod nie jest
595
- wykonywany), moduły `.mjs`/`.js` eksportują `rules` (pełne zaufanie
596
- Node, jak pluginy). Zewnętrzne reguły niosą te same metadane zaufania
597
- co core; nie mogą nigdy wyjść w tierze core (core wymaga zmierzonej
598
- stopy FP z sidecara korpusu — deklarowane `tier: "core"` jest
599
- ściągane do `extended`), przestrzegają limitów tierów i są
600
- sprawdzane na dryft: `mjolnir rules --md --external` renderuje
601
- katalog z załadowanych plików (pochodzenie `external`), a generator
602
- macierzy przyjmuje `--external <root>`.
603
-
604
- ---
605
-
606
- ## 🏗️ Architektura
520
+ **Zabezpieczenie jest ważniejsze niż wygoda.** Każde znalezisko w przekazaniu niesie swoją granicę. **E2** mówi _deterministyczne: sprawdź lokalizację i zastosuj poprawkę_. **E1** mówi _WYMAGA POTWIERDZENIA: sama obserwacja nie dowodzi defektu_. Agent, który na ślepo naprawia E1, wycisza regułę albo edytuje regułę, by podnieść wynik, robi dokładnie to, dla czego wykrywania istnieje to narzędzie, więc przekazanie mówi to w prompcie, obok znaleziska.
607
521
 
608
- <details>
609
- <summary>Rozwiń drzewo</summary>
522
+ <br />
610
523
 
611
- ```
612
- mjolnir/
613
- ├── src/
614
- │ ├── engine/ # LanguageAdapter interface + rule runner
615
- │ ├── adapters/ # typescript · python · java · csharp · github-actions
616
- │ ├── rules/ # rules across 8 families + the measured-FP table
617
- │ ├── playwright/ # Selector Health Score engine
618
- │ ├── discovery/ # workspace, frameworks, ignore resolution
619
- │ ├── scope/ # git merge-base changed-scope engine
620
- │ ├── scorer/ # transparent deduction table + prioritization
621
- │ ├── reporter/ # terminal · JSON · SARIF 2.1 · Mermaid
622
- │ ├── forensics/ # run-data ingestion · flake verdicts · triage
623
- │ ├── config/ # mjolnir.config.json + suppressions
624
- │ ├── plugins/ # third-party rule loading (no sandbox)
625
- │ └── commands/ # every subcommand
626
- └── tests/
627
- ├── fixtures/ # must-fire / must-not-fire per rule
628
- └── golden/ # frozen score regression locks
629
- ```
524
+ ## Zaufanie i bezpieczeństwo
630
525
 
631
- </details>
526
+ **Najpierw lokalnie, zero telemetrii.** W `src/` nie ma nigdzie żadnego API zdolnego do komunikacji sieciowej (`fetch`, `http`, `https`, `net`, `dns`, `dgram`, WebSocket), a [`privacy-network-isolation.spec.ts`](tests/contract/privacy-network-isolation.spec.ts) przerywa build, jeśli któreś się pojawi. Zakazuje też `eval` i `new Function`. Skanowanie niezaufanego kodu nigdy go nie wykonuje: analiza statyczna czyta tekst źródłowy, a analiza przebiegów parsuje pliki raportów, które już są na dysku.
527
+
528
+ Dwa zastrzeżenia: samo `npx` pobiera pakiet, zanim cokolwiek się uruchomi, a gwarancja obejmuje `src/`, nie wtyczki firm trzecich.
529
+
530
+ **Wtyczki nie działają w piaskownicy.** Wtyczki JS (`mjolnir-rules/*.mjs` lub pakiety npm wymienione w `"plugins"`) działają z pełnymi uprawnieniami Node, w tym samym modelu zaufania co wtyczki ESLint czy Vitest. Ich ładowanie wymaga świadomej zgody **dla każdego skanu**: bez `--enable-plugins` (lub `MJOLNIR_ENABLE_PLUGINS=1`) ich źródła nigdy nie są ładowane, a komunikat na stderr wymienia, co pominięto. Manifesty reguł w JSON nie wykonują kodu, a prefiksy ID reguł core są zarezerwowane, aby żadna wtyczka nie mogła się pod nie podszyć. Zgłaszaj podatności przez [SECURITY.md](SECURITY.md).
531
+
532
+ **Działa na sobie samym.** Silnik zaufania do weryfikacji nie ma wiarygodności, jeśli sam nie jest weryfikowalny. Każdy przebieg CI skanuje to repozytorium buildem wytworzonym w tym samym przebiegu. Bramka zawodzi przy każdym znalezisku o ważności error, a także przy **częściowym** skanie lub **regule, która się wysypała**, bo ucięty autoskan, który niczego nie zgłasza, to właśnie fałszywa zieleń, dla której wykrywania istnieje ten projekt. `mjolnir doctor` w tym samym przebiegu ponownie audytuje bazę reguł (zapora fixture'ów, uczciwość poziomów, limit poziomu core), a kontrola z wynikiem INCONCLUSIVE zawodzi dokładnie tak jak nieudana. Oba raporty są wysyłane jako artefakty buildu.
533
+
534
+ ### Kody wyjścia i kontrakt maszynowy
632
535
 
633
- - **Reguły to czyste funkcje** — `(SourceFileContext) → Finding[]`,
634
- bez I/O, bez globali. Nowy ekosystem = jeden adapter + jego reguły.
635
- - **TypeScript/Playwright używa AST kompilatora** (ts-morph). Python,
636
- Java i C# działają na wspólnej warstwie regex z maskowaniem
637
- komentarzy i stringów.
638
- - Warstwa AST tree-sitter WASM dla Javy i C# istnieje i jest
639
- następnym krokiem precyzji — nie jest jeszcze podpięta do
640
- synchronicznego pipeline'u skanu.
536
+ Zamrożone, więc możesz budować na nich logikę CI:
641
537
 
642
- ---
538
+ | Kod wyjścia | Znaczenie |
539
+ | ----------- | -------------------------------------------------------------------------------- |
540
+ | `0` | Czysto: brak znalezisk na poziomie bramki lub powyżej |
541
+ | `1` | Znaleziska na poziomie bramki lub powyżej |
542
+ | `2` | Częściowy skan (przekroczony limit czasu, nieczytelne pliki). Nigdy nie blokuje. |
543
+ | `10` | Błąd użycia (zła flaga, brak celu) |
544
+ | `20` | Błąd wewnętrzny |
643
545
 
644
- ## 📚 Dokumentacja
546
+ `2` celowo różni się od `0`: skan, który się nie zakończył, nie znalazł „niczego”. On po prostu nie skończył szukać.
645
547
 
646
- | Dokument | Co zawiera |
647
- | ------------------------------------------------------ | ----------------------------------------------- |
648
- | [docs/SCORING.md](docs/SCORING.md) | Normalizacja punktacji + ważenie dowodami |
649
- | [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Zmierzone stopy fałszywych pozytywów + metodyka |
650
- | [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Stany reguł, wyciszanie, deprecacja |
651
- | [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | Wyjście SARIF + konfiguracja edytora/CI |
652
- | [docs/rules/](docs/rules/) | Generowany katalog per reguła |
653
- | [CONTRIBUTING.md](CONTRIBUTING.md) | Setup dev + workflow kontrybucji |
654
- | [CHANGELOG.md](CHANGELOG.md) | Historia wydań |
655
- | [SECURITY.md](SECURITY.md) | Zgłaszanie podatności |
548
+ Wszystko, co konsumuje maszyna (wyniki narzędzi MCP, `--json`, SARIF 2.1), pochodzi z jednego kanonicznego wyniku w wersjonowanym schemacie, **rozszerzanym wyłącznie addytywnie** (`schemaVersion: 1`, `contractVersion: 1`), więc żaden konsument nie musi odtwarzać znaczenia z wyrenderowanego tekstu. Zobacz [kontrakt maszynowy](docs/machine-contract.md). ID reguł (`QA-<FAMILY>-NNN`) są niezmienne po wydaniu i nigdy nie są używane ponownie.
656
549
 
657
- ---
550
+ <br />
658
551
 
659
- ## 📈 Status
552
+ ## Czego Mjölnir nie może ci powiedzieć
660
553
 
661
- **v0.5.x · otwarta beta.** Schemat JSON i kody wyjścia to zamrożone
662
- kontrakty. TypeScript i Python mają najszersze zmierzone pokrycie; Java
663
- i C# są nowsze — czytaj o nich przez
664
- [tabelę tierów](#tiery-reguł-i-dojrzałość-językowa).
554
+ - **Nie uruchamia twoich testów.** Czysty skan to nie przechodzący zestaw testów.
555
+ - **Nie powie ci, że asercja jest _błędna_.** `expect(total).toBe(41)` wygląda zdrowo. Mjölnir znajduje testy, które _nie mogą zawieść_, i pipeline'y, które _nie mogą zrobić się czerwone_, a nie testy, które sprawdzają niewłaściwą rzecz.
556
+ - **Nie dowodzi poprawności biznesowej.** Nic tutaj nie mówi, że twój produkt robi to, czego wymagało wymaganie.
557
+ - **100 nie jest dowodem dobrego zestawu testów.** To, czy twój zestaw pokrywa realne ryzyko, to inne pytanie, a to narzędzie na nie nie odpowiada.
558
+ - **5 z 79 reguł opiera się na szacunku**, a nie na zmierzonym odsetku. Każda z nich mówi to na własnym znalezisku.
559
+ - **E1 to nie E2.** Znaleziska heurystyczne warto czytać, ale nie warto stosować na ślepo.
560
+ - **Puste repo dostaje `null`, nigdy 100.**
561
+ - **Plik o nazwie `*.spec.ts` bez deklaracji testów nie liczy się jako pokrycie.** Repo, którego jedyne pliki spec zawierają importy lub typy (zero wywołań `it`/`test`), dostaje `null`, a nie 100.
665
562
 
666
- ---
563
+ <br />
667
564
 
668
- ## 🤝 Kontrybucja
565
+ ## Dokumentacja
669
566
 
670
- Nowe reguły to najłatwiejszy pierwszy wkład — jedna komenda wystawia
671
- szkielet reguły plus jej fixture must-fire **i** must-not-fire
672
- (wygenerowana reguła celowo wypada na fixture'ach, dopóki nie
673
- zaimplementujesz prawdziwej detekcji — stub nie może się wydać):
567
+ Pełna strona dokumentacji jest pod adresem <https://sergey-bar.github.io/Mjolnir/>.
568
+
569
+ | Dokument | Co zawiera |
570
+ | ------------------------------------------------------ | ----------------------------------------------------- |
571
+ | [docs/SCORING.md](docs/SCORING.md) | Normalizacja wyniku i ważenie dowodów |
572
+ | [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md) | Kanoniczne słownictwo: jedno słowo na pojęcie |
573
+ | [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Zmierzone odsetki fałszywych alarmów i metoda |
574
+ | [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Stany reguł, poziomy, wyciszanie, wycofywanie |
575
+ | [docs/VERSIONING.md](docs/VERSIONING.md) | Zasady semver, zamrożone interfejsy, cykl wycofywania |
576
+ | [docs/machine-contract.md](docs/machine-contract.md) | Kanoniczny wynik czytelny maszynowo |
577
+ | [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | Wyjście SARIF i konfiguracja edytora lub CI |
578
+ | [docs/GITLAB-CI.md](docs/GITLAB-CI.md) | GitLab: raport Code Quality, przepis na MR, bramka |
579
+ | [docs/rules/](docs/rules/) | Generowany katalog reguł |
580
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | Środowisko deweloperskie i proces kontrybucji |
581
+ | [SUPPORT.md](SUPPORT.md) | Gdzie pytać, zgłaszać i szukać pomocy |
582
+ | [SECURITY.md](SECURITY.md) | Zgłaszanie podatności |
583
+ | [CHANGELOG.md](CHANGELOG.md) | Historia wydań |
584
+
585
+ ### Status
586
+
587
+ **Wersja 1.** Schemat JSON i kody wyjścia są zamrożonymi kontraktami. TypeScript i Python mają najszersze zmierzone pokrycie. Java i C# są nowsze; czytaj je przez [tabelę dojrzałości](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle). Co dalej, bez wymyślonych dat: [publiczna mapa drogowa](https://sergey-bar.github.io/Mjolnir/reference/roadmap).
588
+
589
+ ### Współtworzenie
590
+
591
+ Nowe reguły to najłatwiejszy pierwszy wkład. Jedno polecenie tworzy szkielet reguły z jej fixture'ami must-fire **i** must-not-fire. Wygenerowana reguła celowo nie przechodzi własnych fixture'ów, dopóki nie zostanie napisane prawdziwe wykrywanie, bo wydany szkielet to reguła, której nikt nie zmierzył:
674
592
 
675
593
  ```bash
676
594
  mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
677
595
  ```
678
596
 
679
- Pełny setup dev, komendy stałego gate'a oraz prawa anti-creep /
680
- zapory fixture'owej są w [CONTRIBUTING.md](CONTRIBUTING.md).
597
+ Środowisko deweloperskie, polecenia stałych bramek oraz prawa anti-creep i zapory fixture'ów są opisane w [CONTRIBUTING.md](CONTRIBUTING.md).
681
598
 
682
- ---
599
+ <br />
683
600
 
684
601
  <div align="center">
685
602
 
686
- **Przestań wydawać testy, którym nie możesz ufać.**
603
+ <img src="assets/readme/closing.svg" alt="Uruchom go na swoim repo." width="100%" />
687
604
 
688
605
  ```bash
689
606
  npx mjolnir-qa@latest
690
607
  ```
691
608
 
692
- **Star ⭐ · Watch 👀 · Contribute 🤝**
609
+ [Przeczytaj przewodnik](https://sergey-bar.github.io/Mjolnir/guide/getting-started) · [Strona dokumentacji](https://sergey-bar.github.io/Mjolnir/) · [npm](https://www.npmjs.com/package/mjolnir-qa)
610
+
611
+ <br />
612
+
613
+ Nie pytaj, czy testy przeszły.<br />
614
+ Zapytaj, czy dowody potwierdzają, że zasługują na zaufanie.
693
615
 
694
- Zbudowane przez [Sergeya Bara](https://www.linkedin.com/in/sergeybar/)
616
+ <sub>Stworzone przez [Sergey Bar](https://www.linkedin.com/in/sergeybar/) · Licencja MIT</sub>
695
617
 
696
618
  </div>