mjolnir-qa 1.0.9 → 2.0.0
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/CHANGELOG.md +194 -0
- package/README.ar.md +434 -478
- package/README.bn.md +434 -491
- package/README.br.md +434 -520
- package/README.bs.md +431 -500
- package/README.da.md +433 -509
- package/README.de.md +432 -522
- package/README.es.md +428 -517
- package/README.fr.md +426 -520
- package/README.gr.md +433 -517
- package/README.he.md +433 -475
- package/README.it.md +436 -525
- package/README.ja.md +436 -506
- package/README.ko.md +434 -494
- package/README.md +416 -426
- package/README.no.md +435 -509
- package/README.pl.md +433 -511
- package/README.ru.md +434 -515
- package/README.th.md +434 -484
- package/README.tr.md +427 -504
- package/README.uk.md +433 -505
- package/README.vi.md +436 -494
- package/README.zh.md +433 -462
- package/README.zht.md +433 -462
- package/dist/cli.d.mts +590 -111
- package/dist/cli.mjs +9937 -8951
- package/dist/mcp/stdio.mjs +1904 -816
- package/dist/rolldown-runtime-8H4AJuhK.mjs +14 -0
- package/package.json +6 -4
package/README.pl.md
CHANGED
|
@@ -1,400 +1,431 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
<img src="assets/readme/
|
|
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
|
-
|
|
5
|
+
<br />
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
12
|
-
[](https://github.com/Sergey-Bar/Mjolnir/actions/workflows/ci.yml)
|
|
13
|
-
[](LICENSE)
|
|
14
|
-
[](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
|
-
|
|
12
|
+
[](https://www.npmjs.com/package/mjolnir-qa)
|
|
13
|
+
[](https://www.npmjs.com/package/mjolnir-qa)
|
|
14
|
+
[](https://github.com/Sergey-Bar/Mjolnir/actions/workflows/ci.yml)
|
|
15
|
+
[](https://codecov.io/gh/Sergey-Bar/Mjolnir)
|
|
16
|
+
[](https://scorecard.dev/viewer/?uri=github.com/Sergey-Bar/Mjolnir)
|
|
17
|
+
[](LICENSE)
|
|
18
|
+
[](https://nodejs.org)
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
npx mjolnir-qa@latest
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
84
|
+
<img src="assets/readme/terminal-hero.svg" alt="Rozbicie potrąceń Mjölnira: WORTHINESS 75/100 NEEDS WORK, 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>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
64
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
93
|
-
|
|
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
|
-
|
|
96
|
-
npx mjolnir-qa@latest
|
|
155
|
+
Docs: mjolnir rules --md (full catalog, this rule included)
|
|
97
156
|
```
|
|
98
157
|
|
|
99
|
-
|
|
100
|
-
|
|
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
|
|
165
|
+
npx mjolnir-qa@latest
|
|
104
166
|
```
|
|
105
167
|
|
|
106
|
-
|
|
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
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
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>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
| `mjolnir
|
|
139
|
-
| `mjolnir
|
|
140
|
-
| `mjolnir
|
|
141
|
-
| `mjolnir
|
|
142
|
-
| `mjolnir
|
|
143
|
-
| `mjolnir
|
|
144
|
-
| `mjolnir
|
|
145
|
-
| `mjolnir
|
|
146
|
-
| `mjolnir
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
|
189
|
-
|
|
|
190
|
-
| QA-TEST-
|
|
191
|
-
| QA-
|
|
192
|
-
| QA-
|
|
193
|
-
| QA-
|
|
194
|
-
| QA-
|
|
195
|
-
| QA-
|
|
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
|
-
|
|
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>
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
224
|
-
|
|
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
|
-
|
|
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
|
-
|
|
253
|
-
|
|
314
|
+
e2e/checkout.spec.ts
|
|
315
|
+
[█████████████████░░░] 86 / 100
|
|
316
|
+
role/text: 3 · testid: 1 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
|
|
317
|
+
```
|
|
254
318
|
|
|
255
|
-
|
|
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
|
-
|
|
321
|
+
<br />
|
|
264
322
|
|
|
265
|
-
|
|
266
|
-
<summary><strong>C# / .NET — NUnit · xUnit · MSTest 🟣</strong></summary>
|
|
323
|
+
## Wynik wiarygodności
|
|
267
324
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
-
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
343
|
+
<br />
|
|
300
344
|
|
|
301
|
-
|
|
302
|
-
**zmierzoną** stopą fałszywych pozytywów:
|
|
345
|
+
## Model dowodów
|
|
303
346
|
|
|
304
|
-
|
|
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
|
-
|
|
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
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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
|
-
|
|
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/
|
|
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
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
-
|
|
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
|
-
|
|
376
|
+
### Ile z tego jest zmierzone
|
|
343
377
|
|
|
344
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
364
|
-
|
|
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
|
-
|
|
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
|
-
|
|
371
|
-
lokatory:
|
|
397
|
+
### Dlaczego to nie jest linter
|
|
372
398
|
|
|
373
|
-
|
|
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
|
-
|
|
377
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
419
|
+
## Analiza przebiegów testów
|
|
387
420
|
|
|
388
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
442
|
+
## Integralność CI
|
|
414
443
|
|
|
415
|
-
|
|
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
|
-
|
|
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
|
-
|
|
428
|
-
|
|
429
|
-
|
|
448
|
+
```bash
|
|
449
|
+
mjolnir ci install
|
|
450
|
+
```
|
|
430
451
|
|
|
431
|
-
|
|
452
|
+
Albo dodaj akcję z Marketplace do workflow, który już masz:
|
|
432
453
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
454
|
+
```yaml
|
|
455
|
+
- uses: Sergey-Bar/Mjolnir@v1
|
|
456
|
+
with:
|
|
457
|
+
scope: changed
|
|
458
|
+
fail-on: error
|
|
459
|
+
```
|
|
438
460
|
|
|
439
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
460
|
-
|
|
461
|
-
|
|
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
|
-
|
|
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
|
-
|
|
470
|
-
blokujący:
|
|
486
|
+
<br />
|
|
471
487
|
|
|
472
|
-
|
|
473
|
-
mjolnir ci install
|
|
474
|
-
```
|
|
488
|
+
## Agenci AI
|
|
475
489
|
|
|
476
|
-
|
|
490
|
+
Znaleziska są coś warte tylko wtedy, gdy coś na nie reaguje.
|
|
477
491
|
|
|
478
|
-
```
|
|
479
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
517
|
-
|
|
518
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
552
|
+
## Czego Mjölnir nie może ci powiedzieć
|
|
660
553
|
|
|
661
|
-
**
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
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
|
-
##
|
|
565
|
+
## Dokumentacja
|
|
669
566
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
616
|
+
<sub>Stworzone przez [Sergey Bar](https://www.linkedin.com/in/sergeybar/) · Licencja MIT</sub>
|
|
695
617
|
|
|
696
618
|
</div>
|