mjolnir-qa 1.0.8 → 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/README.bs.md CHANGED
@@ -1,390 +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. Testovi vam govore šta je prošlo. Mjölnir vam govori čemu možete vjerovati." width="100%" />
4
4
 
5
- ### Tvoji testovi lažu. Mi to dokazujemo.
5
+ <br />
6
6
 
7
- **Verification Trust Engine za QA.** Mjölnir audita test suite-ove i CI
8
- pipeline-ove, izvještava ocjenjivački rezultat i pokazuje tačno gdje se
9
- povjerenje lomi.
7
+ Mjölnir pronalazi testove koji ne mogu pasti i pipelineove koji ne mogu postati crveni,<br />
8
+ a zatim ocjenjuje koliko se rezultatu može vjerovati, uz dokaz za svaki bod.
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.pl.md) | [Русский](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
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
- **Jesu li tvoji testovi dostojni povjerenja?**
24
+ [Pogledajte kako radi](#pogledajte-kako-radi) · [Brzi početak](#brzi-početak) · [Šta pronalazi](#šta-mjölnir-pronalazi) · [Ocjena](#ocjena-vrijednosti) · [Dokazi](#model-dokaza) · [Analiza pokretanja](#analiza-pokretanja-testova) · [CI](#integritet-ci-ja) · [Agenti](#ai-agenti) · [Sigurnost](#povjerenje-i-sigurnost) · [Ograničenja](#šta-vam-mjölnir-ne-može-reći) · [Dokumentacija](#dokumentacija)
25
+
26
+ <details>
27
+ <summary>Čitajte na drugom jeziku — 22 prijevoda</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.pl.md) | [Русский](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
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
- [Vidi ga na djelu](#-vidi-ga-na-djelu) ·
27
- [Brzi početak](#-brzi-početak) ·
28
- [Šta provjerava](#-šta-mjölnir-provjerava) ·
29
- [Bodovanje](#kako-radi-bodovanje) ·
30
- [CI](#-ci-integracija) · [Konfiguracija](#konfiguracija) ·
31
- [Dokumentacija](#-dokumentacija)
35
+ </details>
32
36
 
33
37
  </div>
34
38
 
35
- ---
39
+ <br />
40
+
41
+ ## Zelena kvačica je tvrdnja, a ne dokaz
42
+
43
+ Zelena kvačica znači da pipeline nije pao. Ne znači da su se testovi izvršili, niti da su mogli pasti. Svaki od ovih slučajeva prolazi zeleno:
44
+
45
+ - commitovani `.only` koji je pokrenuo 3 testa umjesto 900
46
+ - `continue-on-error: true` na jobu koji je trebao blokirati
47
+ - `|| true` nakon naredbe za testove
48
+ - test koji ništa ne provjerava ili ima prazno tijelo
49
+ - retry omotač koji pravi pad pretvara u sretan prolaz
50
+ - izvještaj koji workflow otprema, a nikad ga nije generisao
51
+ - fiksni sleep koji drži na okupu race condition
52
+
53
+ Nijedan od njih ne boji pipeline u crveno, a svaki na reviewu izgleda namjerno. Zato i opstaju. Evo kako Mjölnir čita stvaran primjer:
54
+
55
+ <p align="center">
56
+ <img src="assets/readme/scan.svg" alt="CI workflow demo repozitorija, pročitan red po red. Mjölnir označava svaki nalaz u redu u kojem ga je prijavio, s pravilom, onim što nije u redu, nivoom dokaza i izmjerenom stopom lažno pozitivnih rezultata." width="800" />
57
+ </p>
58
+
59
+ <sub>Svaki nalaz koji je demo skeniranje prijavilo za ovaj workflow, u redu u kojem je prijavljen. Generisano naredbom `npm run docs:readme-brand` iz [`demo-report.json`](assets/readme/demo-report.json) i zaključano protiv odstupanja u CI-ju.</sub>
60
+
61
+ **Strogi režim.** Najagresivnija otkrivanja — `.only`, `continue-on-error`, prazni testovi, zloupotreba ponavljanja — žive u karantinskom nivou. Rade samo pod `--strict` i ograničena su na `info` ozbiljnost: označavaju, ali nikada ne blokiraju. Podrazumijevano skeniranje (`npx mjolnir-qa@latest` bez `--strict`) pokriva samo osnovna i proširena pravila. Dodajte `--strict` kada želite i savjetodavni sloj.
62
+
63
+ Mjölnir čita skup testova, CI workflowe i, ako ga imate, izvještaj stvarnog pokretanja. Ne pokreće vaše testove, ne instalira vaše zavisnosti i ne izvršava kod koji skenira. A kada nema dokaza, to i kaže umjesto da izmišlja pouzdanost:
64
+
65
+ | Situacija | Šta Mjölnir prijavljuje |
66
+ | ------------------------------------------------------------ | ---------------------------------------------------------------- |
67
+ | Nisu pronađene deklaracije testova | Ocjena `null`, prikazana kao **UNKNOWN**. Nikad izmišljenih 100. |
68
+ | Nema baselinea ni uporedive revizije | **UNKNOWN**, uz naveden razlog. Nikad pretpostavljena 0. |
69
+ | Skeniranje prekinuto (vremenski budžet, nečitljive datoteke) | **PARTIAL**, izlaz `2`. Nikad se ne prikazuje kao čisto. |
70
+
71
+ <p align="center">
72
+ <img src="assets/readme/how-it-works.svg" alt="Kako Mjölnir radi. Statički čita skup testova i CI pipeline, kao i izvještaj stvarnog pokretanja kada postoji. Svaki nalaz vaga prema nivou dokaza i nivou povjerenja, pri čemu samo stvarno pokretanje može dosegnuti L3 do L5, i daje nalaze, ocjenu vrijednosti i CI kapiju sa zamrznutim izlaznim kodovima. U petlji agenta, AI piše ispravku, a Mjölnir ponovo skenira da je dokaže." width="880" />
73
+ </p>
74
+
75
+ <sub>Napravljeno za ovu stranicu i prikazano u omjeru 1:1. Generisano naredbom `npm run docs:readme-brand` i zaključano protiv odstupanja u CI-ju; ocjena, brojevi i ID pravila dolaze iz [`script.demo.json`](assets/video/script.demo.json), [`demo-report.json`](assets/readme/demo-report.json) i registra pravila, nikad se ne kucaju ručno. Ista slika kao poster: [`architecture.svg`](assets/readme/architecture.svg).</sub>
76
+
77
+ <br />
78
+
79
+ ## Pogledajte kako radi
36
80
 
37
- ## 🎬 Vidi ga na djelu
81
+ Stvarno skeniranje [`examples/demo-repo`](examples/demo-repo), malog Playwright skupa testova s CI workflowom. Evo gdje su otišli njegovi bodovi:
38
82
 
39
83
  <p align="center">
40
- <img src="assets/readme/demo.svg" alt="Kompletan --verbose izvještaj Mjölnira nad demo repoom: WORTHINESS 75/100 NEEDS WORK, dijagnostika po kategorijama, lista FIX THIS FIRST i svaki nalaz sa ID-om pravila i brojem linije kroz CI, Playwright, test higijenu i Python pravila" width="900" />
84
+ <img src="assets/readme/terminal-hero.svg" alt="Mjölnirov pregled odbitaka: WORTHINESS 75/100 NEEDS WORK, ocjena po kategoriji, okvir odbitaka po ozbiljnosti i lista FIX THIS FIRST" width="520" />
41
85
  </p>
42
86
 
43
- <sub>Cjelokupan izlaz `npx mjolnir-qa ./examples/demo-repo --verbose`,
44
- renderiran od pravog reportera — ništa skraćeno. Regenerira se preko
45
- `npm run docs:demo`;
46
- [`tests/demo-asset-reproducibility.spec.ts`](tests/demo-asset-reproducibility.spec.ts)
47
- obara CI ako artefakt odskoči od onoga što alat ispisuje.</sub>
87
+ <sub>Generisano naredbom `npm run docs:hero` iz stvarnog skeniranja i zaključano protiv odstupanja u CI-ju. Puni `--verbose` izvještaj istog skeniranja je [`demo.svg`](assets/readme/demo.svg) (`npm run docs:demo`).</sub>
48
88
 
49
- **Šta se upravo desilo:**
89
+ <details>
90
+ <summary><strong>Pogledajte</strong> — skeniranje, ispravka koju ispisuje i ponovno skeniranje koje je dokazuje</summary>
91
+
92
+ <br />
50
93
 
51
- 1. Mjölnir je pronašao Playwright specifikacije, svoju konfiguraciju,
52
- CI workflow i Python test fajl — četiri jezika/formata, jedan prolaz.
53
- 2. Pronašao je dokaze koji slabe povjerenje u suite — `continue-on-error`
54
- koji maskira job, `|| true` koji guta exit kod, tvrdi sleepovi,
55
- krhki selektor, ugrađene staging URL-ove, `networkidle` čekanje.
56
- 3. Svaki je pretvorio u konkretan nalaz s ID-om pravila, lokacijom i
57
- fixom — i u jedan rezultat na koji možeš gate-ovati PR.
94
+ <p align="center">
95
+ <a href="assets/video/mjolnir-demo.mp4">
96
+ <img src="assets/video/mjolnir-demo-poster.png" alt="Kadar demo snimka: npx mjolnir-qa@latest skenira demo repozitorij u prozoru terminala" width="900" />
97
+ </a>
98
+ </p>
99
+
100
+ <sub>Renderovano kadar po kadar iz stvarnog skeniranja naredbom `npm run docs:video`; nikad snimljeno sa ekrana. Odaberite kadar da otvorite [`mjolnir-demo.mp4`](assets/video/mjolnir-demo.mp4).</sub>
101
+
102
+ </details>
58
103
 
59
104
  ### Jedan nalaz izbliza
60
105
 
61
- Pokreni `mjolnir explain QA-CI-001` na prvom nalaženom iznad i dobiješ:
106
+ Svaki nalaz odgovara na četiri pitanja: gdje je, koliko je Mjölnir siguran, koliko često pravilo griješi i kako ga ispraviti.
107
+
108
+ <p align="center">
109
+ <img src="assets/readme/finding-anatomy.svg" alt="Prvi nalaz demo skeniranja, tačno onako kako ga terminal ispisuje, s označena četiri dijela: gdje, koliko sigurno, koliko često pravilo griješi, i ispravka." width="100%" />
110
+ </p>
111
+
112
+ `mjolnir explain QA-CI-001` ispisuje cijeli zapis povjerenja pravila, uključujući izmjerenu stopu lažno pozitivnih rezultata i nivo koji mu je ta stopa donijela:
62
113
 
63
114
  ```text
64
- ▚ QA-CI-001 — continue-on-error masks a failing verification gate
115
+ ▍ QA-CI-001 — continue-on-error masks a failing verification gate
65
116
 
66
117
  Severity: error
67
118
  Confidence: high
119
+ Tier: quarantine
68
120
  Evidence: E2
69
- 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
70
126
 
71
127
  WHAT WAS FOUND (real detector output, not a mockup)
72
128
  Job `security-scan` runs a verification gate under `continue-on-error: true`.
73
129
 
74
130
  WHY IT MATTERS
75
- This job can fail every day and CI will still show green. The checkmark
76
- 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.
77
133
 
78
134
  HOW TO FIX
79
135
  Remove continue-on-error, or scope it to individual non-blocking steps only.
80
- ```
81
136
 
82
- To je jedinica vrijednosti: ne sitnica stila, nego mjesto gdje ti CI
83
- poručuje da je nešto prošlo, a nije prošlo.
137
+ Example from this rule's own must-fire fixture: QA-CI-001/must-fire/masked.yml
84
138
 
85
- ---
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
86
146
 
87
- ## ⚡ Brzi početak
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.
88
150
 
89
- Pokreni ga nad repoom za kompletan izvještaj i ocjenjivački rezultat:
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.
154
+
155
+ Docs: mjolnir rules --md (full catalog, this rule included)
156
+ ```
157
+
158
+ To je jedinica vrijednosti: jedno mjesto na kojem CI prijavljuje prolaz koji nije zaslužio.
159
+
160
+ <br />
161
+
162
+ ## Brzi početak
90
163
 
91
164
  ```bash
92
165
  npx mjolnir-qa@latest
93
166
  ```
94
167
 
95
- **U CI je proizvod jedna komanda.** Skenira samo ono što je grana
96
- dotakla i izlazi s ne-nula kodom kod novih problema:
168
+ Skenira trenutni direktorij i ispisuje Trust Report: šta je pronašao, koliko mu možete vjerovati, zašto i šta dalje uraditi. Završava s `0` kada ništa na nivou kapije ili iznad nije pronađeno.
169
+
170
+ U CI-ju skenirajte samo ono što je grana uvela, kako stari skup testova ne bi potopio vaš prvi pull request:
97
171
 
98
172
  ```bash
99
173
  npx mjolnir-qa@latest --scope changed
100
174
  ```
101
175
 
102
- Ubaci to kao check u PR — `mjolnir ci install` piše workflow — i
103
- gotovo. Sve ostalo je opciono.
176
+ `mjolnir ci install` to zapisuje kao GitHub Actions workflow, koristeći [action](https://github.com/Sergey-Bar/Mjolnir#readme) prikovan za glavni tag `v1` (ili obični `npx` s `--no-action`). Ostaje savjetodavan dok ne odlučite da treba blokirati.
104
177
 
105
- | Komanda | Šta radi |
178
+ | Naredba | Šta radi |
106
179
  | ----------------------------------- | ------------------------------------------------------- |
107
- | `mjolnir` | Sken cijelog repoa + ocjenjivački rezultat |
108
- | `mjolnir --scope changed` | Samo ono što je tvoja grana unijela — CI oblik |
109
- | `mjolnir ci install` | Generiše savjetodavni PR workflow |
110
- | `mjolnir explain QA-CI-001` | Šta / zašto / fix + izmjerena FP stopa za jedno pravilo |
111
- | `mjolnir rules --unmeasured` | Pravila koja rade pretpostavkom, a ne mjerenjem |
112
- | `mjolnir --json` / `--format sarif` | Mašinski čitljivo / GitHub Code Scanning |
113
- | `mjolnir --strict` | Pokreće i pravila quarantine tier-a (veći rizik FP) |
180
+ | `mjolnir` | Trust Report: presuda, pouzdanost, sljedeći korak |
181
+ | `mjolnir --scope changed` | Samo ono što je vaša grana uvela (CI oblik) |
182
+ | `mjolnir ci install` | Generiše savjetodavni PR workflow (zasnovan na actionu) |
183
+ | `mjolnir explain QA-CI-001` | Šta, zašto i ispravka, plus izmjerena FP stopa |
184
+ | `mjolnir why src/a.spec.ts:42` | Zašto je baš ovaj red označen. Nikad ne blokira. |
185
+ | `mjolnir forensics ./test-results/` | Dokazi iz stvarnog pokretanja |
186
+ | `mjolnir trust-report` | Samostalni Trust Artifact (md + json) |
187
+ | `mjolnir handoff` | Plan sanacije za agenta za kodiranje |
188
+ | `mjolnir --json` / `--format sarif` | Mašinski čitljiv izlaz, GitHub Code Scanning |
189
+ | `mjolnir --format codequality` | GitLab Code Quality izvještaj (artefakt MR widgeta) |
190
+ | `mjolnir --strict` | Pokreće i pravila nivoa quarantine (veći FP rizik) |
114
191
 
115
192
  <details>
116
- <summary><strong>Kad je nešto flaky</strong></summary>
117
-
118
- | Komanda | Šta radi |
119
- | ----------------------------------- | -------------------------------------------------------- |
120
- | `mjolnir forensics ./test-results/` | Stvarni podaci runova → presude `TRUE-FLAKE`, `FLAKY.md` |
121
- | `mjolnir triage ./test-results/` | Prijedlog karantene iz historije izvršavanja |
122
- | `mjolnir pw-report ./test-results/` | Sažetak Playwright runa — retry / flake / najsporiji |
123
- | `mjolnir doctor:playwright` | Dubinski skan samo Playwright + Selector Health Score |
193
+ <summary><strong>Sve ostale naredbe</strong> — trijaža nestabilnih testova, izvještavanje, upravljanje</summary>
194
+
195
+ <br />
196
+
197
+ | Naredba | Šta radi |
198
+ | ----------------------------------- | ------------------------------------------------------------------------------ |
199
+ | `mjolnir --classic` | Baner ocjene iz vremena prije Trust Reporta |
200
+ | `mjolnir explain verdict` | Zašto je presuda sačuvanog skeniranja takva kakva jeste |
201
+ | `mjolnir triage ./test-results/` | Vođena trijaža. Svaki red završava sljedećim korakom. |
202
+ | `mjolnir pw-report ./test-results/` | Sažetak Playwright pokretanja: ponavljanja, nestabilni testovi, najsporiji |
203
+ | `mjolnir doctor:playwright` | Dubinsko skeniranje samo za Playwright plus Selector Health Score |
204
+ | `mjolnir fix --dry-run` / `fix` | Sigurne automatske ispravke, svaka ponovo skenirana da se dokaže da je uspjela |
205
+ | `mjolnir baseline` / `diff` | Snimak nalaza, a zatim prijava samo novih ili gorih |
206
+ | `mjolnir impact --since <ref>` | Šta je commit uveo i riješio |
207
+ | `mjolnir summary` | CI anotacije i sažetak koraka iz izvještaja |
208
+ | `mjolnir pr-comment` | Ciljani PR komentar, u Markdownu |
209
+ | `mjolnir debt` | Registar testnog duga s modelom troškova |
210
+ | `mjolnir handover` | Mapa skupa testova za novog QA inženjera |
211
+ | `mjolnir init` | Otkriva frameworke, ispisuje listu za podešavanje |
212
+ | `mjolnir suppressions` | Prikazuje utišane nalaze, radi upravljanja |
213
+ | `mjolnir rules --unmeasured` | Pravila koja rade na pretpostavci, a ne na mjerenju |
214
+ | `mjolnir rules --md` | Kompletan katalog pravila (JSON ili Markdown) |
215
+ | `mjolnir doctor` | Samorevizija Mjölnirove vlastite baze pravila |
216
+ | `mjolnir create-rule <ID>` | Pravi kostur novog pravila i njegovih fixturea |
217
+ | `mjolnir stats` | Lokalni brojači svih viđenih ispravki |
218
+ | `mjolnir badge` | JSON za shields.io endpoint i isječak koda |
219
+ | `mjolnir --cache` | Inkrementalna ponovna skeniranja preko lokalnog keša presuda |
220
+ | `mjolnir --format mermaid` | Dijagram arhitekture testova za PR komentar |
221
+
222
+ `mjolnir help <command>` ispisuje upotrebu, primjere i sljedeći korak za svaku od njih.
124
223
 
125
224
  </details>
126
225
 
127
- <details>
128
- <summary><strong>Povremeno / izvještaji</strong></summary>
129
-
130
- | Komanda | Šta radi |
131
- | ------------------------------- | ------------------------------------------------- |
132
- | `mjolnir fix --dry-run` / `fix` | Sigurne automatske popravke s dokazom |
133
- | `mjolnir baseline` / `diff` | Snimak nalaza, pa izvještaj samo novih/pogoršanih |
134
- | `mjolnir impact --since <ref>` | Šta se promijenilo od ranijeg commita |
135
- | `mjolnir debt` | Registarr testnog duga s modelom troška |
136
- | `mjolnir handover` | Karta onboardingu suite-a za novog QA |
137
- | `mjolnir stats` | Lokalni ukupni brojači viđenih fixova |
138
- | `mjolnir badge` | shields.io endpoint JSON + snippet |
139
- | `mjolnir rules --md` | Potpuni katalog pravila (JSON ili Markdown) |
140
- | `mjolnir doctor` | Samoaudit Mjölnirove vlastite baze pravila |
141
- | `mjolnir create-rule <ID>` | Scafholduje novo pravilo + fixture |
142
- | `mjolnir --format mermaid` | Dijagram test arhitekture za PR komentar |
226
+ Zahtijeva **Node.js ≥ 22.18** na Windowsu, macOS-u ili Linuxu. Više volite globalnu instalaciju? `npm i -g mjolnir-qa`. Minimum dolazi iz lanca alata za build (tsdown cilja na njega, a pipeline izdanja radi smoke testove na njemu); zavisnostima za izvršavanje ne treba više od toga.
143
227
 
144
- </details>
145
-
146
- Instaliraj globalno umjesto `npx` ako preferiraš: `npm i -g mjolnir-qa`.
147
- Zahtijeva Node.js ≥ 22.18. Radi na Windows, macOS i Linux.
148
-
149
- ---
150
-
151
- ## 👥 Za koga je ovo?
152
-
153
- - **QA / SDET** koji drže e2e ili integracioni suite i trebaju dokaz da
154
- suite stvarno zaslužuje zeleni check koji proizvodi.
155
- - **Platform / DevEx timovi** odgovorni za CI integritet i release
156
- gateove — ljudi kojima je stalo da `continue-on-error` nikad ne
157
- preboji crveni pipeline u zeleni u tišini.
158
- - **OSS maintaineri** koji žele jeftin, uvijek uključen verifikacioni
159
- gate koji radi lokalno i u CI bez mrežnih poziva.
160
-
161
- ---
162
-
163
- ## 🔨 Šta Mjölnir provjerava
164
-
165
- | | |
166
- | --- | --------------------------------------------------------------------------------------------------------------------- |
167
- | ⚖️ | **Ocjenjivački rezultat** — jedan broj, transparentna tabela odbitaka, bez crne kutije |
168
- | 🎭 | **Selector Health Score** — ocjenjuje tvoje Playwright locatore, ne samo prolaznost |
169
- | 🔬 | **Runtime forenzika** — čita stvarne Playwright/JUnit podatke runova i hvata `TRUE-FLAKE`, ne samo statičke nagađanja |
170
- | 🚨 | **Pravila CI integriteta** — hvata `continue-on-error`, `\|\| true` i druge trikove lažno zelenog |
171
- | 🐍 | **Sva četiri Playwright bindinga** — TypeScript, Python, Java, C#/.NET — plus pytest, JUnit/TestNG i CI workflowi |
172
- | 🔒 | **Local-first** — nula mrežnih poziva pri skeniranju, nula telemetrije, radi u sekundama |
228
+ <br />
173
229
 
174
- ### Pravila
230
+ ## Šta Mjölnir pronalazi
175
231
 
176
- Svako pravilo dolazi s must-fire **i** must-not-fire fixtureima.
177
- Pravilo koje okida na svojoj negativnoj fixture ne može se isporučiti —
178
- to je vatrozid lažnih pozitiva.
179
-
180
- <details>
181
- <summary><strong>Test higijena</strong></summary>
182
-
183
- | ID | Pravilo | Severity |
184
- | ----------- | ---------------------------------------------------- | -------- |
185
- | QA-TEST-001 | Commitiran fokusirani test (`.only`, `fit`) | error |
186
- | QA-TEST-002 | Preskočen test bez opravdanja | error |
187
- | QA-TEST-002 | Preskočen test s evidentiranim opravdanjem | warning |
188
- | QA-TEST-003 | Test bez asercija | error |
189
- | QA-TEST-004 | Tvrdi sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning |
190
- | QA-TEST-006 | Zloupotreba retrya koja krije flakiness | warning |
191
- | QA-TEST-010 | Prazno tijelo testa | error |
192
-
193
- </details>
232
+ <p align="center">
233
+ <img src="assets/readme/stack.svg" alt="Radi s vašim stackom: jezici, test frameworci i CI sistemi koje pokrivaju njegova pravila, prema registru pravila." width="100%" />
234
+ </p>
194
235
 
195
- <details>
196
- <summary><strong>Kvalitet testova</strong></summary>
236
+ **79 pravila** u četiri porodice — higijena testova, kvalitet testova, Playwright i integritet CI-ja — za TypeScript i JavaScript, Python, Javu, C# i GitHub Actions YAML. Pokrivaju Playwright u sva četiri bindinga, plus pytest, JUnit, TestNG, NUnit, xUnit, MSTest, Jest, Vitest i Mochu, s početnom pokrivenošću za Cypress i Selenium. Devet od njih, da se vidi oblik:
197
237
 
198
- | ID | Pravilo | Severity |
199
- | ------------ | ----------------------------- | -------- |
200
- | QA-TQUAL-002 | Tautološka asercija | error |
201
- | QA-TQUAL-009 | Asercija neawaitanog promisea | error |
202
- | QA-TQUAL-011 | Komentarisani testovi | warning |
238
+ | ID | Pravilo | Ozbiljnost | Nivo |
239
+ | ------------ | -------------------------------------------------------------------- | ---------- | ---------- |
240
+ | QA-CI-001 | `continue-on-error` maskira kapiju verifikacije koja pada | error | quarantine |
241
+ | QA-CI-009 | Izlazni kod testova se ne prosljeđuje (`\|` bez pipefail, `;` lanci) | error | extended |
242
+ | QA-TEST-001 | Commitovan fokusirani test (`.only`, `fit`) | error | quarantine |
243
+ | QA-TEST-003 | Test bez asercija | error | quarantine |
244
+ | QA-TQUAL-009 | Asercija na promise bez await | error | quarantine |
245
+ | QA-PW-002 | Asercija na lokatoru bez await | error | core |
246
+ | QA-PW-004 | Krhki CSS/XPath selektori | warning | quarantine |
247
+ | QA-PY-002 | Preskočen test (`skip`, nestriktni `xfail`) | warning | core |
248
+ | QA-CS-103 | Testna metoda bez asercija | error | core |
203
249
 
204
- </details>
250
+ Kompletan katalog se generiše iz registra, nikad se ne održava ručno: `mjolnir rules --md`, [`docs/rules/`](docs/rules/) ili [vodič o tome šta provjerava](https://sergey-bar.github.io/Mjolnir/guide/what-it-checks).
205
251
 
206
252
  <details>
207
- <summary><strong>Playwright 🎭</strong></summary>
208
-
209
- | ID | Pravilo | Severity |
210
- | --------- | ------------------------------------------ | -------- |
211
- | QA-PW-002 | Asercija lokatora bez awaita | error |
212
- | QA-PW-003 | `page.pause()` / `test.only()` commitirani | error |
213
- | QA-PW-004 | Krhki CSS/XPath selektori | warning |
214
- | QA-PW-123 | Ugrađeni URL-ovi okruženja | warning |
253
+ <summary><strong>Svako pravilo navedeno u ovom README-u</strong>, u jednoj tabeli</summary>
254
+
255
+ <br />
256
+
257
+ > Pravila `quarantine` se pokreću samo uz `--strict` i nikad ne blokiraju (ograničena su na info). Prikazana ozbiljnost je ona koju je odredio autor.
258
+
259
+ | ID | Porodica | Pravilo | Ozbiljnost | Nivo |
260
+ | ------------ | ---------- | ------------------------------------------------------------ | ---------- | ---------- |
261
+ | QA-TEST-001 | Higijena | Commitovan fokusirani test (`.only`, `fit`) | error | quarantine |
262
+ | QA-TEST-002 | Higijena | Preskočen test. Bez praćenog razloga eskalira na `error`. | warning | quarantine |
263
+ | QA-TEST-003 | Higijena | Test bez asercija | error | quarantine |
264
+ | QA-TEST-004 | Higijena | Fiksni sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning | extended |
265
+ | QA-TEST-006 | Higijena | Zloupotreba ponavljanja koja skriva nestabilnost | warning | quarantine |
266
+ | QA-TEST-010 | Higijena | Prazno tijelo testa | error | quarantine |
267
+ | QA-TQUAL-002 | Kvalitet | Tautološka asercija | error | quarantine |
268
+ | QA-TQUAL-009 | Kvalitet | Asercija na promise bez await | error | quarantine |
269
+ | QA-TQUAL-011 | Kvalitet | Zakomentarisani testovi | warning | extended |
270
+ | QA-PW-002 | Playwright | Asercija na lokatoru bez await | error | core |
271
+ | QA-PW-003 | Playwright | Commitovani `page.pause()` / `test.only()` | error | core |
272
+ | QA-PW-004 | Playwright | Krhki CSS/XPath selektori | warning | quarantine |
273
+ | QA-PW-123 | Playwright | Hardkodirani URL-ovi okruženja | warning | quarantine |
274
+ | QA-PW-140 | Playwright | Snimak ekrana bez `maxDiffPixelRatio` | warning | core |
275
+ | QA-CI-001 | CI | `continue-on-error` maskira kapiju koja pada | error | quarantine |
276
+ | QA-CI-002 | CI | `\|\| true` guta izlazne kodove | error | extended |
277
+ | QA-CI-005 | CI | Izvještaj se koristi, ali se nikad ne generiše | error | quarantine |
278
+ | QA-CI-007 | CI | Retry omotači oko testova | warning | extended |
279
+ | QA-CI-008 | CI | Korak koji uvijek uspijeva maskira padove | error | quarantine |
280
+ | QA-CI-009 | CI | Izlazni kod se ne prosljeđuje (`\|` bez pipefail, `;` lanci) | error | extended |
281
+ | QA-CI-010 | CI | Testovi preskočeni tamo gdje moraju blokirati | error | quarantine |
282
+ | QA-PY-002 | Python | Preskočen test (`skip`, nestriktni `xfail`) | warning | core |
283
+ | QA-PY-003 | Python | Testna funkcija bez asercija | error | quarantine |
284
+ | QA-PY-005 | Python | `time.sleep()` u testovima | warning | extended |
285
+ | QA-PY-012 | Python | Tautološka asercija | error | quarantine |
286
+ | QA-JV-101 | Java | Onemogućen test (`@Disabled`) | warning | core |
287
+ | QA-JV-102 | Java | Fiksni sleep (`Thread.sleep()`) | warning | extended |
288
+ | QA-JV-103 | Java | Testna metoda bez asercija | error | extended |
289
+ | QA-JV-105 | Java | Fiksni sleep preko Playwright `waitForTimeout()` | warning | core |
290
+ | QA-JV-106 | Java | Krhki selektor umjesto lokatora zasnovanog na ulozi | warning | quarantine |
291
+ | QA-CS-101 | C# | Preskočen test (`[Ignore]`, `[Fact(Skip=)]`) | warning | core |
292
+ | QA-CS-102 | C# | Fiksni sleep (`Thread.Sleep` / `Task.Delay`) | warning | core |
293
+ | QA-CS-103 | C# | Testna metoda bez asercija | error | core |
294
+ | QA-CS-105 | C# | Fiksni sleep preko `WaitForTimeoutAsync()` | warning | extended |
295
+ | QA-CS-106 | C# | Krhki selektor umjesto lokatora zasnovanog na ulozi | warning | quarantine |
296
+
297
+ Python dolazi i s pravilima QA-PY-001…012 (higijena pytesta) i QA-PY-101…108 (Playwright za Python). Cypress i Selenium imaju početne skupove od po tri pravila.
215
298
 
216
299
  </details>
217
300
 
218
- <details>
219
- <summary><strong>CI integritet</strong></summary>
220
-
221
- | ID | Pravilo | Severity |
222
- | --------- | --------------------------------------------------------------- | -------- |
223
- | QA-CI-001 | `continue-on-error` maskira padove | error |
224
- | QA-CI-002 | `\|\| true` guta exit kodove | error |
225
- | QA-CI-005 | Izvještaj se troši ali nikad ne generira | error |
226
- | QA-CI-007 | Retry omotači oko testova | warning |
227
- | QA-CI-008 | Uvijek uspješan step maskira padove | error |
228
- | QA-CI-009 | Exit kod testa se ne propagira (`\|` bez pipefail, `;` lanci) | error |
229
- | QA-CI-010 | Testovi preskaču se gdje moraju blokirati (skip-on-PR guardovi) | error |
230
-
231
- </details>
301
+ Svako pravilo se isporučuje s must-fire **i** must-not-fire fixtureom, a pravilo koje se okine na vlastitom negativnom fixtureu ne može biti isporučeno. To je zaštitni zid od lažno pozitivnih rezultata; `mjolnir doctor` ga provodi u vlastitom CI-ju ovog repozitorija.
232
302
 
233
- <details>
234
- <summary><strong>Python / pytest 🐍</strong></summary>
303
+ ### Selector Health Score
235
304
 
236
- | ID | Pravilo | Severity |
237
- | --------- | ----------------------------------------- | -------- |
238
- | QA-PY-002 | Preskočen test (`skip`, nestrogi `xfail`) | warning |
239
- | QA-PY-003 | Test funkcija bez asercija | error |
240
- | QA-PY-005 | `time.sleep()` u testovima | warning |
241
- | QA-PY-012 | Tautološka asercija | error |
305
+ `mjolnir doctor:playwright` ocjenjuje svaki lokator prema tome kako pronalazi element: onako kako bi to uradio korisnik (uloga, oznaka, tekst), preko eksplicitnog ugovora (`data-testid`) ili strukturnom slučajnošću (CSS lanci, XPath). Svaka datoteka dobija ocjenu od 0 do 100:
242
306
 
243
- Ukupno 20 Python pravila (QA-PY-001…012 pytest higijena + QA-PY-101…108 Playwright-Python).
307
+ ```text
308
+ ▍ SELECTOR HEALTH
244
309
 
245
- </details>
310
+ e2e/login.spec.ts
311
+ [█████████████░░░░░░░] 65 / 100
312
+ role/text: 1 · testid: 0 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
246
313
 
247
- <details>
248
- <summary><strong>Java / JUnit · TestNG ☕</strong></summary>
314
+ e2e/checkout.spec.ts
315
+ [█████████████████░░░] 86 / 100
316
+ role/text: 3 · testid: 1 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
317
+ ```
249
318
 
250
- | ID | Pravilo | Severity |
251
- | --------- | ----------------------------------------- | -------- |
252
- | QA-JV-101 | Onemogućen test (`@Disabled`) | warning |
253
- | QA-JV-102 | Tvrdi sleep (`Thread.sleep()`) | warning |
254
- | QA-JV-103 | Test metoda bez asercija | error |
255
- | QA-JV-105 | Tvrdi sleep Playwright `waitForTimeout()` | warning |
256
- | QA-JV-106 | Krhki selektor umjesto role lokatora | warning |
319
+ Ovo mjeri **otpornost, a ne ispravnost**. `.btn.btn-primary > div:nth-child(2)` prolazi danas i nastavlja prolaziti dok neko ne dirne markup. Niska ocjena nikad ne tvrdi da je test pokvaren, samo da zavisi od markupa koji niko nije obećao sačuvati.
257
320
 
258
- </details>
321
+ <br />
259
322
 
260
- <details>
261
- <summary><strong>C# / .NET — NUnit · xUnit · MSTest 🟣</strong></summary>
323
+ ## Ocjena vrijednosti
262
324
 
263
- | ID | Pravilo | Severity |
264
- | --------- | -------------------------------------------- | -------- |
265
- | QA-CS-101 | Preskočen test (`[Ignore]`, `[Fact(Skip=)]`) | warning |
266
- | QA-CS-102 | Tvrdi sleep (`Thread.Sleep` / `Task.Delay`) | warning |
267
- | QA-CS-103 | Test metoda bez asercija | error |
268
- | QA-CS-105 | Tvrdi sleep `WaitForTimeoutAsync()` | warning |
269
- | QA-CS-106 | Krhki selektor umjesto role lokatora | warning |
325
+ <p align="center">
326
+ <img src="assets/readme/score-gauge.svg" alt="Skala vrijednosti od 0 do 100, s markerom koji prelazi svaku ocjenu: UNWORTHY ispod 50, NEEDS WORK od 50 do 79, WORTHY od 80 do 99, FORGED na 100" width="720" />
327
+ </p>
270
328
 
271
- </details>
329
+ <sub>Svaka ocjena od 0 do 100, postavljena stvarnim `deriveScoreState`. Generisano naredbom `npm run docs:gauge` i zaključano protiv odstupanja u CI-ju.</sub>
272
330
 
273
- > Potpuni živi katalog — svako pravilo s tierom, confidence, rizikom
274
- > lažnih pozitiva i dostupnošću autofixa — generira se iz registra:
275
- >
276
- > ```bash
277
- > mjolnir rules --md
278
- > ```
279
- >
280
- > Stranice po pravilu žive u [`docs/rules/`](docs/rules/).
331
+ | Ocjena | Presuda |
332
+ | --------- | ----------------------------------------------- |
333
+ | `0 – 49` | **UNWORTHY** |
334
+ | `50 – 79` | **NEEDS WORK** |
335
+ | `80 – 99` | **WORTHY** |
336
+ | `100` | **FORGED** |
337
+ | `null` | **UNKNOWN**: nisu pronađene deklaracije testova |
281
338
 
282
- ### Koliko je od ovoga izmjereno
339
+ **Kako se računa.** Ozbiljnost određuje osnovni odbitak (`error −8`, `warning −3`, `info −1`), a nivo dokaza ga umanjuje: E2 se računa u potpunosti, E1 upola (zaokruženo nadolje), E0 nikako. Zbir se normalizuje prema izloženosti skupa testova, odnosno odbici po deklaraciji testa umjesto po datoteci. Terminal ispisuje iste umanjene brojeve koje je ocjena koristila; nema skrivenog drugog modela. Detalji: [docs/SCORING.md](docs/SCORING.md) i [vodič za ocjenjivanje](https://sergey-bar.github.io/Mjolnir/guide/scoring).
283
340
 
284
- **78 od 99 pravila nose stopu lažnih pozitiva izmjerenu nad stvarnim
285
- OSS kodom** (≥ 10 ručno klasificiranih nalaza svako; vidi
286
- [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). Ostalih 21 izlazi na autorovoj
287
- procjeni. Podnožje svakog skana kaže koliko od _okinutih_ pravila je
288
- izmjereno; `mjolnir rules --unmeasured` izlista neizmjerena; stranica
289
- `mjolnir explain` svakog pravila navodi njen status. Objavljujemo stopu
290
- toga. Rast tog broja je neprekidni rad projekta.
341
+ **Šta 100 ne znači.** Ne znači da je softver ispravan, da je skup testova dovoljan ili da je proizvod bez grešaka. Znači jednu stvar: **nijedno od pravila koja je Mjölnir procijenio nije proizvelo odbitak u ovom skeniranju i ovom modelu dokaza.**
291
342
 
292
- ### Tierovi pravila i jezična zrelost
343
+ <br />
293
344
 
294
- Svako pravilo je `core`, `extended` ili `quarantine`, dodijeljeno prema
295
- njegovoj **izmjerenij** stopi lažnih pozitiva:
345
+ ## Model dokaza
296
346
 
297
- | Tier | Značenje | Zadani skan | `--strict` |
298
- | ------------ | ---------------------------------------- | :---------: | :--------: |
299
- | `core` | ≤ 10 % izmjerena FP | ✅ | ✅ |
300
- | `extended` | ≤ 30 % izmjerena FP | ✅ | ✅ |
301
- | `quarantine` | iznad 30 %, ili još neizmjereno (n < 10) | ❌ | ✅ |
347
+ Svaki nalaz nosi dvije oznake: koliko je Mjölnir siguran i koliko je daleko nalaz provjeren. To je razlika između alata koji prijavljuje obrasce i alata od kojeg možete uslovljavati izdanje.
302
348
 
303
- | Jezik | Adapter | Pokrivenost danas |
304
- | --------------- | -------------- | --------------------------------------------------------- |
305
- | TypeScript / JS | AST kompajlera | najšira, najviše mjerena — pretežno `core`/`extended` |
306
- | Python / pytest | Regex sloj | široka, auditrana na korpusu — pretežno `core`/`extended` |
307
- | Java | Regex sloj | novija — pretežno `extended`/`quarantine` |
308
- | C# / .NET | Regex sloj | novija — pretežno `extended`/`quarantine` |
349
+ **Koliko sigurno — nivo dokaza.**
309
350
 
310
- TypeScript i Python imaju najširu izmjerenu pokrivenost. Java i C# su
311
- isporučeni, dokumentirani i ostaju izvan glavnog broja dok se prava
312
- korisnička suite (ne vlastiti testovi binding biblioteke) ne audita.
351
+ | Nivo | Naziv | Znači | Odbitak |
352
+ | ------ | --------------------- | -------------------------------------------------- | ------- |
353
+ | **E2** | Deterministički dokaz | Defekt je prisutan u kodu onakvom kakav je napisan | Pun |
354
+ | **E1** | Dokaz iz obrasca | Poklopio se obrazac usko povezan s defektom | Pola |
355
+ | **E0** | Zapažanje | Vrijedi znati. Nije tvrdnja da nešto nije u redu. | Nula |
313
356
 
314
- ---
357
+ Pouzdanost detekcije nije snaga dokaza. Pravilo može biti sigurno da je pronašlo ono što je tražilo, a ipak gledati heuristiku. E1 nalazi su tu da se čitaju i procjenjuju, nikad da se primjenjuju naslijepo, i ta granica je utisnuta na nalaz u terminalu, u JSON-u i u predaji agentu.
315
358
 
316
- ## Kako radi bodovanje
359
+ **Koliko daleko je provjereno — nivo povjerenja.** Većina nalaza dolazi iz čitanja vašeg koda. Dajte Mjölniru izvještaj stvarnog pokretanja testova i on može potvrditi da se kod zaista izvršio.
317
360
 
318
361
  <p align="center">
319
- <img src="assets/readme/terminal-hero.svg" alt="Terminalni izlaz Mjölnira — WORTHINESS 75/100 NEEDS WORK, dijagnostika po kategorijama i lista FIX THIS FIRST" width="820" />
362
+ <img src="assets/readme/trust-ladder.svg" alt="Ljestvica povjerenja od L0 do L5. L0 do L2 dolaze iz čitanja koda; L3 do L5 zahtijevaju izvještaj stvarnog pokretanja, što je označeno prekidom na ljestvici." width="100%" />
320
363
  </p>
321
364
 
322
- <sub>Regenerira se preko `npm run docs:hero`;
323
- [`tests/hero-asset-reproducibility.spec.ts`](tests/hero-asset-reproducibility.spec.ts)
324
- obara CI ako artefakt odskoči od onoga što reporter stvarno ispisuje.</sub>
365
+ | Nivo | Jednostavnim riječima | Šta je potrebno |
366
+ | ------ | --------------------- | ------------------------------------------------------------ |
367
+ | **L0** | Zabilježeno | Čitanje koda |
368
+ | **L1** | Liči na problem | Čitanje koda: poklopio se obrazac |
369
+ | **L2** | Dokazano u kodu | Čitanje koda: defekt je strukturni |
370
+ | **L3** | Datoteka se izvršila | Izvještaj pokretanja pokazuje da je datoteka nalaza izvršena |
371
+ | **L4** | Test se izvršio | Izvještaj pokretanja pokazuje da je test nalaza izvršen |
372
+ | **L5** | Pokretanje se slaže | Vlastiti rezultat pokretanja potvrđuje klasu defekta |
325
373
 
326
- Bodovanje je transparentno: **error −8, warning −3, info −1**, pa
327
- normalizirano izloženošću suite-a (odbitci po deklaraciji testa).
328
- Odbitci ponderirani dokazima znače da slabi signali koštaju manje.
329
- Terminal pokazuje iste popustljive brojeve koje koristi bodovanje —
330
- bez crne kutije. Puna metoda: [docs/SCORING.md](docs/SCORING.md).
374
+ Statičko skeniranje staje na L2. Samo izvještaj stvarnog pokretanja (Playwright JSON, Jest ili Vitest JSON, JUnit XML) može podići nalaz na L3 ili više, pa nalaz koji nikad nije viđen u izvršavanju nikad ne može tvrditi da jeste. Definicije: [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md).
331
375
 
332
- **Presude**
376
+ ### Koliko je od ovoga izmjereno
333
377
 
334
- | Score | Presuda |
335
- | ------- | ---------------- |
336
- | ≥ 80 | ✓ **WORTHY** |
337
- | 50 – 79 | ⚠ **NEEDS WORK** |
338
- | < 50 | ✖ **UNWORTHY** |
378
+ **74 od 79 pravila imaju stopu lažno pozitivnih rezultata izmjerenu na stvarnom OSS kodu** (najmanje 10 ručno klasifikovanih nalaza za svako; pogledajte [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). Ostalih 5 se isporučuje na autorovoj procjeni i to kaže, pravilo po pravilo, u `mjolnir explain`. `mjolnir rules --unmeasured` ih navodi, a podnožje svakog skeniranja prijavljuje koliko je izmjereno od pravila koja su se zaista _okinula_.
339
379
 
340
- **Nivoi dokaza** — svaki nalaz nosi jedan; on postavlja težinu nalaza u
341
- bodovanju:
380
+ Stope ostaju javne i kada su loše. QA-TEST-001 (commitovani `.only`) loše prolazi reviziju na stvarnim repozitorijima i zato je u quarantine. Aktuelni broj za svako pravilo, uključujući QA-PW-141, nalazi se u reviziji.
342
381
 
343
- | Nivo | Značenje | Utjecaj na bodovanje | Primjer |
344
- | ---- | ---------------------- | -------------------- | -------------------------------------------------- |
345
- | E2 | Deterministički defekt | Potpuni odbitak | Commitirani `.only` — strukturno dokazivo |
346
- | E1 | Heuristički obrazac | Polovina odbitka | Regexom pogođen `sleep()` — jak signal, nije dokaz |
347
- | E0 | Zapažanje | Nula (samo info) | Prijavljeno ali nikad ne gate-uje CI niti odbija |
382
+ ### Nivoi povjerenja pravila
348
383
 
349
- Većina pravila je **E1**. Slogan „we prove it" odnosi se na ovaj
350
- sistem: E2 nalazi su strukturni dokaz; E1 nalazi su ispravno
351
- pozicionirana upozorenja, ne formalni dokazi.
384
+ Nivoi prate izmjerenu stopu lažno pozitivnih rezultata, a ne mišljenje:
352
385
 
353
- Prazan repo boduje `null`, nikad lažnih 100 — vidi
354
- [Model povjerenja](#model-povjerenja).
386
+ | Nivo | Izmjereni FP | Ponašanje |
387
+ | -------------- | --------------------------------- | ----------------------------------------------------- |
388
+ | **core** | ≤ 10% | Zadani izvještaj, blokira |
389
+ | **extended** | ≤ 30% | Zadani izvještaj, niža pouzdanost |
390
+ | **quarantine** | > 30% ili eksplicitno deklarisano | Samo `--strict`, ograničeno na info, nikad ne blokira |
391
+ | _neizmjereno_ | n < 10 | Ne može se unaprijediti u core dok se ne izmjeri |
355
392
 
356
- ---
393
+ FP opsezi mogu samo degradirati nivo — nikad ne unapređuju pravilo iz `quarantine` ako je tamo eksplicitno deklarisano. Eksplicitno karantinirano pravilo ostaje u quarantine bez obzira na izmjerenu FP stopu.
357
394
 
358
- ## 🎭 Selector Health Score
395
+ Unapređenje, degradacija i zrelost po jeziku: [životni ciklus pravila](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle).
359
396
 
360
- Vodeća metrika za Playwright suiteove — koliko su otporni tvoji
361
- lokatori:
397
+ ### Zašto ovo nije linter
362
398
 
363
- ```text
364
- ▚ SELECTOR HEALTH — e2e/checkout.spec.ts
399
+ Linteri vam govore da li kod poštuje pravila. Mjölnir vam govori može li se vjerovati vašoj verifikaciji.
365
400
 
366
- [█████████████████░░░] 83 / 100
367
- role/text: 2 · testid: 1 · css-chains: 1 ⚠ · xpath: 0
368
- ```
401
+ | | Linteri (ESLint, SonarQube) | Alati za pokrivenost | AI pregled koda | **Mjölnir** |
402
+ | ---------------------------------------------------------------- | :-------------------------: | :------------------: | :-------------: | :----------------: |
403
+ | Ocjenjuje **sistem verifikacije**, a ne kod proizvoda | Ne | Ne | Ne | Da |
404
+ | Integritet CI workflowa (`continue-on-error`, `\|\| true`) | Ne | Ne | samo diff | Da |
405
+ | Ocjenjuje otpornost Playwright lokatora (Selector Health) | Ne | Ne | Ne | Da |
406
+ | Čita stvarne podatke pokretanja za `TRUE-FLAKE` presude | Ne | Ne | Ne | Da |
407
+ | Objavljuje izmjerenu stopu lažno pozitivnih rezultata po pravilu | Ne | Ne | Ne | Da |
408
+ | Označava testove bez asercija | Da\* | Ne | ponekad | Da |
409
+ | Hvata fiksne sleepove (`waitForTimeout`, `time.sleep`) | Da\* | Ne | ponekad | Da |
410
+ | Deterministički (isti ulaz, isti izlaz) | Da | Da | Ne | Da |
411
+ | Trošak po skeniranju | besplatno | besplatno | tokeni | **nula** (lokalno) |
412
+
413
+ <sub>\*Pokriveno s `eslint-plugin-jest` i `eslint-plugin-playwright` (`expect-expect`, `no-wait-for-timeout`) te vlastitim pravilima za asercije u SonarQubeu. Kolone opisuju zadano ponašanje za verifikaciju skupova testova; dodaci, plaćeni paketi i prilagođena pravila mijenjaju neke odgovore. Ovo je sažetak pozicioniranja, a ne benchmark.</sub>
369
414
 
370
- Role-bazirani lokatori osvajaju pun bodovni rezultat. CSS lanac klasa i
371
- XPath tone rezultat — lome se na svakom DOM refactoru ne govoreći ti
372
- koje ponašanje je regresiralo.
415
+ Koristite i AI pregled. Hvata nijanse, namjeru i greške u dizajnu koje nijedan obrazac ne može pronaći. Mjölnir hvata ono što AI pregled previdi jer izgleda namjerno: commitovani `.only`, progutan izlazni kod, `continue-on-error` na test jobu. Za to treba skeniranje, a ne rasuđivanje.
373
416
 
374
- ---
417
+ <br />
375
418
 
376
- ## 🔬 Runtime dokazi
419
+ ## Analiza pokretanja testova
377
420
 
378
- Statička detekcija flakinessa je nagađanje. Mjölnir čita **stvarne
379
- podatke izvršavanja** — Playwright JSON izvještaje i JUnit XML od
380
- bilo kojeg runnera:
421
+ Statička analiza rasuđuje o kodu koji se nikad nije izvršio. Analiza pokretanja čita šta se zaista dogodilo: Playwright JSON, Jest JSON, Vitest JSON i JUnit XML iz bilo kojeg runnera.
381
422
 
382
423
  ```bash
383
424
  mjolnir forensics ./test-results/
384
425
  ```
385
426
 
386
427
  ```text
387
- ▚ FLAKINESS LEADERBOARD
428
+ ▍ FLAKINESS LEADERBOARD
388
429
 
389
430
  3 tests · 1 failed · 1 flaky · 1 retried
390
431
 
@@ -394,294 +435,184 @@ FAILING declines an expired card (e2e/checkout.spec.ts)
394
435
  ████░░░░░░░░░░░░░░░░ 1.1s · 1 attempt
395
436
  ```
396
437
 
397
- Test koji prolazi tek od pokušaja ≥ 2 nije prolazni test — to je
398
- sretan test. Označava se kao `TRUE-FLAKE` bez obzira na konačni zeleni
399
- check.
438
+ `TRUE-FLAKE` ne znači da je test ponovljen. Znači da je test **pao barem u jednom pokušaju, a zatim završio zeleno**: sretan prolaz, označen bez obzira na to šta kaže konačna kvačica. `mjolnir triage` tu historiju pretvara u prijedlog karantina, a `mjolnir pw-report` sažima pokretanje. Upravo ti izvještaji pokretanja podižu nalaze na nivoe povjerenja L3 i više.
400
439
 
401
- ---
440
+ <br />
402
441
 
403
- ## ⚡ Mjölnir nije još jedan linter
442
+ ## Integritet CI-ja
404
443
 
405
- Linteri ti kažu prati li kod pravila. Mjölnir ti kaže može li se tvojoj
406
- verifikaciji vjerovati.
444
+ Test može prolaziti dok pipeline oko njega ne može pasti. Mjölnir čita i workflowe: `continue-on-error`, `|| true`, izlazne kodove koji se nikad ne prosljeđuju, korake koji uvijek uspijevaju, izvještaje koji se koriste, a nikad ne generišu, i kapije preskočene baš na događajima koji bi trebali blokirati. Svaki nalaz navodi job, korak i red, i nosi vlastiti nivo dokaza.
407
445
 
408
- | | ESLint / SonarQube | Coverage alati | Ručni review | **Mjölnir** |
409
- | --------------------------------------------------------- | :----------------: | :------------: | :----------: | :---------: |
410
- | CI workflow integritet (`continue-on-error`, `\|\| true`) | ❌ | ❌ | rijetko | ✅ |
411
- | Unakrsno-jezično (TS, Python, Java, C#) iz jednog alata | ❌ | ❌ | ❌ | ✅ |
412
- | Ocjenjuje otpornost Playwright lokatora (Selector Health) | ❌ | ❌ | rijetko | ✅ |
413
- | Označava testove bez pravih asercija | ✅ (plugin)\* | ❌ | ponekad | ✅ |
414
- | Hvata tvrde sleepove (`waitForTimeout`, `time.sleep`) | ✅ (plugin)\* | ❌ | ponekad | ✅ |
415
- | Radi u sekundama, nula mrežnih poziva pri skeniranju | ✅ | ✅ | — | ✅ |
446
+ Generišite PR workflow, zadano savjetodavan:
416
447
 
417
- \*`eslint-plugin-jest` (`expect-expect`) i `eslint-plugin-playwright`
418
- (`expect-expect`, `no-wait-for-timeout`) pokrivaju ovo za svoje
419
- frameworkove.
448
+ ```bash
449
+ mjolnir ci install
450
+ ```
420
451
 
421
- **Runtime analiza** je odvojena kategorija od statičkog lintanja:
452
+ Ili dodajte Marketplace action u workflow koji već imate:
422
453
 
423
- | | Playwright retry reporter | Allure / ReportPortal | **Mjölnir forensics** |
424
- | --------------------------------------------------- | :-----------------------: | :-------------------: | :-------------------: |
425
- | Čita stvarne podatke runova za presude `TRUE-FLAKE` | djelimično\* | djelimično (tag) | ✅ |
426
- | Izvještaj flaky triaže iz historije izvršavanja | ❌ | ✅ | ✅ |
427
- | Integrira se sa statičkim ocjenjivačkim rezultatom | ❌ | ❌ | ✅ |
454
+ ```yaml
455
+ - uses: Sergey-Bar/Mjolnir@v1
456
+ with:
457
+ scope: changed
458
+ fail-on: error
459
+ ```
428
460
 
429
- \*Playwright interno prati retryje ali ne proizvodi samostalan izvještaj
430
- flakinessa s oznakama presuda.
461
+ Prikujte `@v1` da pratite glavnu liniju, ili tačan tag (`@v0.5.32`) za ponovljivu kapiju. [docs/DISTRIBUTION-KIT.md](docs/DISTRIBUTION-KIT.md) pokriva Marketplace, Smithery i MCP registre.
431
462
 
432
- ---
463
+ Da nalaze stavite u GitHub Code Scanning, otpremite SARIF (potrebno `security-events: write` na nivou workflowa ili joba):
433
464
 
434
- ## 🤖 Zašto ne koristiti samo 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
+ ```
435
473
 
436
- Drugi problem, drugi sloj. AI review može primijetiti sumnjivu promjenu
437
- testa u diffu; ne dokazuje da je verifikacioni sistem kao cjelina
438
- dostojan povjerenja — i vidi samo diff koji mu pokažeš.
474
+ Na GitLabu, `--format codequality` zapisuje Code Quality izvještaj koji čitaju MR widget i diff anotacije ([docs/GITLAB-CI.md](docs/GITLAB-CI.md)). Podešavanje editora i pipelinea: [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
439
475
 
440
- | | AI code review (Copilot i sl.) | **Mjölnir** |
441
- | ---------------------------------------- | :------------------------------: | :-------------------------------------: |
442
- | Trošak po skanu | Tokeni (raste s veličinom diffa) | **Nula** (lokalno, instalirano) |
443
- | Vidi cijeli suite + sve CI konfiguracije | Samo PR diff koji pokažeš | **Sve, svaki put** |
444
- | Deterministički (isti ulaz → isti izlaz) | ❌ (nedeterministički) | **✅** |
445
- | Hvata obrasce dormantne mjesecima | Samo ako je u kontekstu | **✅** (skenira sve fajlove) |
446
- | Pamti nalaze između runova | ❌ (nema memorije između sesija) | **✅** (baseline + diff) |
447
- | Radi bez ljudskog okidača | Treba PR ili prompt | **✅** (CI hook, izvodi se u sekundama) |
476
+ ### Pripisivanje u opsegu promjena
448
477
 
449
- **Koristi oba.** AI hvata nijansu, namjeru i dizajnerske mane koje
450
- nijedan regex ne nađe. Mjölnir hvata strukturne obrasce koje AI
451
- zaobilazi jer izgledaju „namjerno" — commitirani `.only`, progutani
452
- exit kod, `continue-on-error` na test jobu. To nisu bugovi koji trebaju
453
- razmišljanje; to su činjenice koje trebaju skeniranje.
478
+ ```bash
479
+ npx mjolnir-qa@latest --scope changed
480
+ ```
454
481
 
455
- ---
482
+ Nalazi se pripisuju redovima koje je vaša grana dodala, mjereno u odnosu na **merge-base**. Opseg je isti skup datoteka koji otkriva puno skeniranje (TS/JS specifikacije i konfiguracije adaptera, `test_*.py`, `*Test.java`, `*Tests.cs`, `.github/workflows/*.yml`), plus necommitovane i nepraćene promjene, pa radi i prije commita. Baza se razrješava redom `main → master → origin/main → origin/master → origin/HEAD`; zamijenite je s `--base <ref>`.
456
483
 
457
- ## 🤖 CI integracija
484
+ Kada se merge-base ne može razriješiti (plitki klon, odvojeni HEAD, cilj izvan gita), nalazi se vraćaju na pripisivanje cijeloj datoteci **i izvještaj to kaže.** Tihi prelazak na rezervnu opciju bio bi upravo ona vrsta defekta zbog koje ovaj alat postoji.
458
485
 
459
- Jedna komanda generira PR workflow — po defaultu savjetodavan, nikad
460
- blokirajući:
486
+ <br />
461
487
 
462
- ```bash
463
- mjolnir ci install
464
- ```
488
+ ## AI agenti
465
489
 
466
- Ili ga poveži nativno u GitHub Code Scanning preko SARIF-a:
490
+ Nalazi vrijede samo ako nešto na osnovu njih djeluje.
467
491
 
468
- ```yaml
469
- - run: npx mjolnir-qa@latest --format sarif > mjolnir.sarif
470
- - uses: github/codeql-action/upload-sarif@v3
471
- with:
472
- sarif_file: mjolnir.sarif
492
+ ```text
493
+ SCAN → EVIDENCE → HANDOFF → AGENT → RE-SCAN → PROOF
473
494
  ```
474
495
 
475
- Editor i pipeline postavka za SARIF:
476
- [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
496
+ **AI piše ispravku. Mjölnir je verifikuje.** Dokaz dolazi iz ponovnog skeniranja, nikad iz agentovog vlastitog izvještaja o uspjehu.
477
497
 
478
- ### Pokrivenost promijenjenog opsega
498
+ | Naredba | Šta agent dobija |
499
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
500
+ | `mjolnir mcp` | [MCP](https://modelcontextprotocol.io) server preko stdio. `scan`, `explain` i `diff` postaju alati koji se mogu pozvati. |
501
+ | `mjolnir handoff` | Sačuvani `--json` izvještaj postaje deterministički Markdown plan: šta je otkriveno, granica dokaza za svaki nalaz, šta se **ne** smije promijeniti i kako verifikovati. |
502
+ | `mjolnir install` | Upisuje u agentske površine koje vaš repozitorij već ima (`.claude/`, `.cursor/`, `.kilo/`, `AGENTS.md`) kako bi agent ponovo skenirao prije nego što tvrdi da je gotov. |
479
503
 
480
- `--scope changed` pripisuje nalazima linije dodane u tvojoj grani naspram
481
- merge-base s `main`. Pokriva test fajlove (`*.spec.*`, `*.test.*`) plus
482
- GitHub workflow fajlove i Playwright konfiguracije u diffu. Kad se
483
- merge-base ne može razriješiti — shallow clone, detached HEAD, non-git
484
- cilj, drugi zadani branch — pošteno degradira: nalazi se vraćaju na
485
- atribuciju po cijelom fajlu i izvještaj to kaže. Prepiši baznu ref s
486
- `--base <ref>`.
504
+ Dodajte ga klijentu koji ima vlastiti CLI:
487
505
 
488
- ---
489
-
490
- ## Konfiguracija
491
-
492
- Mjölnir je zero-config. Opcioni `mjolnir.config.json` (ili
493
- `.mjolnir.json`) u korijenu repoa podešava severity, gating i opseg —
494
- nikad ne mijenja semantiku detekcije.
506
+ ```bash
507
+ claude mcp add mjolnir -- npx -y mjolnir-qa@latest mcp
508
+ ```
495
509
 
496
- | Key | Tip | Efekat |
497
- | ------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
498
- | `exclude` | `string[]` | Dodatni ignore globovi (gitignore podskup), preko ugrađenih defaulta |
499
- | `gate` | `"advisory" \| "error" \| "warning"` | Koji severity izlaze s ne-nula kodom (default `error`; `advisory` nikad ne blokira) |
500
- | `severityOverrides` | `{ "<RULE-ID>": severity }` | Prerangiraje nalaze pravila za tvoj repo |
501
- | `ignore` | `IgnoreEntry[]` | Potiskuje nalaze — **`reason` je obavezan**; unosi istječu nakon 90 dana (eksplicitni `expires` datum, ili vrijeme zadnje izmjene config fajla za unose bez njega) |
502
- | `plugins` | `string[]` | Paketi pravila trećih strana (vidi [Model povjerenja](#model-povjerenja)) |
510
+ Ili bilo kojem klijentu koji prima `mcpServers` blok:
503
511
 
504
512
  ```json
505
513
  {
506
- "gate": "error",
507
- "exclude": ["legacy/**"],
508
- "severityOverrides": { "QA-PW-141": "warning" },
509
- "ignore": [
510
- {
511
- "ruleId": "QA-TEST-004",
512
- "files": ["e2e/legacy-login.spec.ts"],
513
- "reason": "Third-party widget needs a settle delay; tracked in JIRA-4821",
514
- "expires": "2026-12-31"
515
- }
516
- ]
514
+ "mcpServers": {
515
+ "mjolnir": { "command": "npx", "args": ["-y", "mjolnir-qa@latest", "mcp"] }
516
+ }
517
517
  }
518
518
  ```
519
519
 
520
- - **`.mjolnirignore`** — jednostavna gitignore-slična datoteka za
521
- isključenja putanja, isti dijalekt kao `exclude`. Koristi je za
522
- mašinski šum; koristi `exclude` kad lista pripadne version kontroli,
523
- uz ostatak konfiguracije.
524
- - **CLI nadjačavanja** — `--strict` (uključi quarantine pravila),
525
- `--width <cols>` i `--ascii` / `--no-ascii` (terminalski render),
526
- `--tone blunt` (oštrije poruke), `--max-duration <sec>` (ograničen
527
- djelomični skan).
528
- - Potiskivanje pravila i životni ciklus deprecacije:
529
- [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md).
530
-
531
- `ignore` unosi hrane i samostalnu komandu `mjolnir suppressions`, koja
532
- izlista šta je trenutno potisnuto i kada ističe svaki unos.
533
-
534
- ---
535
-
536
- ## 📐 Exit kodovi i ugovori
537
-
538
- Zamrznuti — sigurni za gradnju CI logike:
539
-
540
- | Exit kod | Značenje |
541
- | -------- | ---------------------------------------------------------------------------------- |
542
- | `0` | Čisto — nema nalaza na ili iznad gatea |
543
- | `1` | Nalazi na ili iznad gatea |
544
- | `2` | Djelimičan skan (potrošen vremenski budžet, nečitljivi fajlovi) — nikad ne blokira |
545
- | `10` | Greška upotrebe (loš flag, nedostaje cilj) |
546
- | `20` | Interna greška |
547
-
548
- JSON/SARIF izvještaj je `schemaVersion: 1`. ID-jevi pravila
549
- (`QA-<FAMILY>-NNN`) su nepromjenjivi jednom isporučeni i nikad se ne
550
- ponovo koriste.
551
-
552
- ---
553
-
554
- ## Model povjerenja
555
-
556
- - **Local-first** — nula mrežnih poziva tokom skeniranja. Nikad. Nula
557
- telemetrije.
558
- - **Bez lažnih dokaza** — radije kažemo „nepoznato" nego „verifikovano".
559
- Prazan repo dobija `score: null`, nikad lažnih 100.
560
- - **Djelimična iskrenost** — ako je analiza prekinuta, izlaz to kaže.
561
- Nikad „complete" kad nije.
562
- - **FP vatrozid** — detekcija radi na pregledu koda bez komentara i
563
- stringova (TypeScript pravila koriste AST kompajlera): obrazac unutar
564
- prosačnog komentara ili doc-primjera-stringa je dokumentacija, ne
565
- nalaz.
566
- - **Izmjereno, ne tvrđeno** — u glavne tierove ulaze samo pravila sa
567
- stopom lažnih pozitiva iz stvarnog OSS koda (vidi
568
- [Koliko je od ovoga izmjereno](#koliko-je-od-ovoga-izmjereno));
569
- podnožje skana i `mjolnir rules --unmeasured` kažu koje su koje.
570
- - **Povjerenje u pluginove i kapija izvršavanja** — pluginovi su npm
571
- paketi deklarirani pod
572
- `"plugins"`; JS moduli žive u `mjolnir-rules/*.mjs`.
573
- **Nema sandboxa**: plugin kod radi s punim Node
574
- privilegijama, isti model povjerenja kao ESLint ili Vitest pluginovi.
575
- Zato je izvršavanje koda **opt-in pri svakom skanu**: proslijedite
576
- `--enable-plugins` (ili postavite `MJOLNIR_ENABLE_PLUGINS=1`), inače
577
- se izvori NE učitavaju — glasna stderr obavijesta izlista tačno što
578
- je preskočeno. Skeniranje nepouzdanog koda nikada ga ne izvršava.
579
- JSON pravila manifesti (`mjolnir-rules/*.json`) nisu pogođeni:
580
- deklariraju regex obrasce i po konstrukciji ne izvršavaju kod.
581
- Core prefiksi ID-jeva pravila su rezervirani i odbijaju se od
582
- pluginova i eksternih pravila radi sprečavanja spoofinga.
583
- - **Eksterna pravila lokalna workspaceu** (folder-bazirana, nula
584
- mreže) — `mjolnir-rules/` direktorij pored skan cilja učitava
585
- vlastita pravila: JSON fajlovi deklariraju regex obrasce (nikakav kod
586
- se ne izvršava), `.mjs`/`.js` moduli eksportuju `rules` (potpuno Node
587
- povjerenje, kao pluginovi). Eksterna pravila nose iste metadata
588
- povjerenja kao core; nikad ne mogu ući u core tier (core traži
589
- izmjerenu FP stopu iz corpus sidecara — deklarirani `tier: "core"`
590
- se stega na `extended`), poštuju tier limite i provjeravaju se na
591
- drift: `mjolnir rules --md --external` renderira katalog iz
592
- učitanih fajlova (provenijencija `external`), a generator matrice
593
- prima `--external <root>`.
594
-
595
- ---
596
-
597
- ## 🏗️ Arhitektura
520
+ **Zaštitna ograda je važnija od udobnosti.** Svaki nalaz u predaji nosi svoju granicu. **E2** kaže _deterministički: provjerite lokaciju i primijenite ispravku_. **E1** kaže _POTREBNA POTVRDA: samo zapažanje ne dokazuje defekt_. Agent koji naslijepo ispravlja E1, utišava pravilo ili mijenja pravilo da podigne ocjenu radi upravo ono zbog čega ovaj alat postoji, pa predaja to kaže u promptu, odmah pored nalaza.
598
521
 
599
- <details>
600
- <summary>Raširi stablo</summary>
522
+ <br />
601
523
 
602
- ```
603
- mjolnir/
604
- ├── src/
605
- │ ├── engine/ # LanguageAdapter interface + rule runner
606
- │ ├── adapters/ # typescript · python · java · csharp · github-actions
607
- │ ├── rules/ # rules across 8 families + the measured-FP table
608
- │ ├── playwright/ # Selector Health Score engine
609
- │ ├── discovery/ # workspace, frameworks, ignore resolution
610
- │ ├── scope/ # git merge-base changed-scope engine
611
- │ ├── scorer/ # transparent deduction table + prioritization
612
- │ ├── reporter/ # terminal · JSON · SARIF 2.1 · Mermaid
613
- │ ├── forensics/ # run-data ingestion · flake verdicts · triage
614
- │ ├── config/ # mjolnir.config.json + suppressions
615
- │ ├── plugins/ # third-party rule loading (no sandbox)
616
- │ └── commands/ # every subcommand
617
- └── tests/
618
- ├── fixtures/ # must-fire / must-not-fire per rule
619
- └── golden/ # frozen score regression locks
620
- ```
524
+ ## Povjerenje i sigurnost
621
525
 
622
- </details>
526
+ **Prvo lokalno, nula telemetrije.** Nijedan API sposoban za mrežu (`fetch`, `http`, `https`, `net`, `dns`, `dgram`, WebSocket) ne postoji nigdje u `src/`, a [`privacy-network-isolation.spec.ts`](tests/contract/privacy-network-isolation.spec.ts) obara build ako se neki pojavi. Zabranjuje i `eval` i `new Function`. Skeniranje nepouzdanog koda ga nikad ne izvršava: statička analiza čita izvorni tekst, a analiza pokretanja parsira datoteke izvještaja koje već postoje na disku.
527
+
528
+ Dvije napomene: sam `npx` preuzima paket prije nego što se išta pokrene, a garancija pokriva `src/`, ne dodatke trećih strana.
529
+
530
+ **Dodaci nisu u sandboxu.** JS dodaci (`mjolnir-rules/*.mjs` ili npm paketi navedeni pod `"plugins"`) rade s punim Node privilegijama, istim modelom povjerenja kao ESLint ili Vitest dodaci. Njihovo učitavanje je izričit izbor **po skeniranju**: bez `--enable-plugins` (ili `MJOLNIR_ENABLE_PLUGINS=1`) njihovi izvori se nikad ne učitavaju, a obavještenje na stderr navodi šta je preskočeno. JSON manifesti pravila ne izvršavaju kod, a prefiksi ID-jeva core pravila su rezervisani kako se nijedan dodatak ne bi mogao lažno predstaviti kao neko od njih. Ranjivosti prijavite preko [SECURITY.md](SECURITY.md).
531
+
532
+ **Radi na samom sebi.** Motor povjerenja u verifikaciju nema kredibilitet ako sam nije provjerljiv. Svako CI pokretanje skenira ovaj repozitorij buildom koji je proizvelo to isto pokretanje. Kapija pada na svakom nalazu ozbiljnosti error, kao i na **djelimičnom** skeniranju ili **pravilu koje se srušilo**, jer skraćeno samoskeniranje koje ništa ne prijavljuje jeste upravo lažna zelena boja zbog koje ovaj projekat postoji. `mjolnir doctor` u istom pokretanju ponovo revidira bazu pravila (zaštitni zid fixturea, poštenje nivoa, gornja granica nivoa core), a provjera s rezultatom INCONCLUSIVE pada potpuno isto kao neuspjela. Oba izvještaja se otpremaju kao artefakti builda.
533
+
534
+ ### Izlazni kodovi i mašinski ugovor
623
535
 
624
- - **Pravila su čiste funkcije** — `(SourceFileContext) → Finding[]`,
625
- bez I/O-a, bez globala. Novi ekosistem = jedan adapter + njegova
626
- pravila.
627
- - **TypeScript/Playwright koristi AST kompajlera** (ts-morph). Python,
628
- Java i C# rade na zajedničkom regex sloju s maskiranim komentarima i
629
- stringovima.
630
- - Tree-sitter WASM AST sloj za Javu i C# postoji i sljedeći je korak
631
- preciznosti — još nije povezan u sinhroni skan pipeline.
536
+ Zamrznuti, kako biste na njima mogli graditi CI logiku:
632
537
 
633
- ---
538
+ | Izlazni kod | Značenje |
539
+ | ----------- | ---------------------------------------------------------------------------------------- |
540
+ | `0` | Čisto: nema nalaza na nivou kapije ili iznad |
541
+ | `1` | Nalazi na nivou kapije ili iznad |
542
+ | `2` | Djelimično skeniranje (istekao vremenski budžet, nečitljive datoteke). Nikad ne blokira. |
543
+ | `10` | Greška u upotrebi (pogrešna zastavica, nedostaje cilj) |
544
+ | `20` | Interna greška |
634
545
 
635
- ## 📚 Dokumentacija
546
+ `2` se namjerno razlikuje od `0`: skeniranje koje nije završilo nije "ništa pronašlo". Samo nije završilo s traženjem.
636
547
 
637
- | Dokument | Šta je unutra |
638
- | ------------------------------------------------------ | ----------------------------------------------- |
639
- | [docs/SCORING.md](docs/SCORING.md) | Normalizacija rezultata + ponderiranje dokazima |
640
- | [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Izmjerene stope lažnih pozitiva + metodologija |
641
- | [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Stanja pravila, potiskivanje, deprecacija |
642
- | [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | SARIF izlaz + editor/CI postavka |
643
- | [docs/rules/](docs/rules/) | Generirani katalog po pravilu |
644
- | [CONTRIBUTING.md](CONTRIBUTING.md) | Dev postavka + workflow doprinosa |
645
- | [CHANGELOG.md](CHANGELOG.md) | Historija izdanja |
646
- | [SECURITY.md](SECURITY.md) | Prijavljivanje ranjivosti |
548
+ Sve što mašina troši (rezultati MCP alata, `--json`, SARIF 2.1) dolazi iz jednog kanonskog rezultata pod verzionisanom shemom koja se **samo proširuje** (`schemaVersion: 1`, `contractVersion: 1`), tako da nijedan potrošač ne mora rekonstruisati značenje iz renderovanog teksta. Pogledajte [mašinski ugovor](docs/machine-contract.md). ID-jevi pravila (`QA-<FAMILY>-NNN`) su nepromjenjivi nakon isporuke i nikad se ne koriste ponovo.
647
549
 
648
- ---
550
+ <br />
649
551
 
650
- ## 📈 Status
552
+ ## Šta vam Mjölnir ne može reći
651
553
 
652
- **v0.5.x · otvorena beta.** JSON shema i exit kodovi su zamrznuti
653
- ugovori. TypeScript i Python imaju najširu izmjerenu pokrivenost; Java
654
- i C# su noviji — čitaj ih kroz
655
- [tabelu tierova](#tierovi-pravila-i-jezična-zrelost).
554
+ - **Ne pokreće vaše testove.** Čisto skeniranje nije skup testova koji prolazi.
555
+ - **Ne može vam reći da je asercija _pogrešna_.** `expect(total).toBe(41)` izgleda zdravo. Mjölnir pronalazi testove koji _ne mogu pasti_ i pipelineove koji _ne mogu postati crveni_, a ne testove koji provjeravaju pogrešnu stvar.
556
+ - **Ne dokazuje poslovnu ispravnost.** Ništa ovdje ne kaže da vaš proizvod radi ono što je zahtjev tražio.
557
+ - **100 nije dokaz dobrog skupa testova.** Da li vaš skup pokriva vaš stvarni rizik je drugo pitanje, a ovaj alat na njega ne odgovara.
558
+ - **5 od 79 pravila se isporučuje na procjeni**, a ne na izmjerenoj stopi. Svako od njih to kaže na vlastitom nalazu.
559
+ - **E1 nije E2.** Heuristički nalazi vrijede čitanja, ali ne i primjene naslijepo.
560
+ - **Prazan repozitorij dobija `null`, nikad 100.**
561
+ - **Datoteka nazvana `*.spec.ts` bez deklaracija testova ne računa se kao pokrivenost.** Repozitorij čije jedine spec datoteke sadrže importe ili tipove (nula poziva `it`/`test`) dobija `null`, a ne 100.
656
562
 
657
- ---
563
+ <br />
658
564
 
659
- ## 🤝 Doprinos
565
+ ## Dokumentacija
660
566
 
661
- Nova pravila su najlakši prvi doprinos — jedna komanda scaffolduje
662
- pravilo plus njegove must-fire **i** must-not-fire fixture (generirano
663
- pravilo namjerno pada na fixtureima dok ne implementiraš stvarnu
664
- detekciju — stub se ne može isporučiti):
567
+ Kompletna stranica dokumentacije nalazi se na <https://sergey-bar.github.io/Mjolnir/>.
568
+
569
+ | Dokument | Šta sadrži |
570
+ | ------------------------------------------------------ | ------------------------------------------------------ |
571
+ | [docs/SCORING.md](docs/SCORING.md) | Normalizacija ocjene i ponderisanje dokaza |
572
+ | [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md) | Kanonski rječnik: jedna riječ po pojmu |
573
+ | [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Izmjerene stope lažno pozitivnih rezultata i metoda |
574
+ | [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Stanja pravila, nivoi, utišavanje, povlačenje |
575
+ | [docs/VERSIONING.md](docs/VERSIONING.md) | Semver politika, zamrznute površine, ciklus povlačenja |
576
+ | [docs/machine-contract.md](docs/machine-contract.md) | Kanonski mašinski čitljiv rezultat |
577
+ | [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | SARIF izlaz i podešavanje editora ili CI-ja |
578
+ | [docs/GITLAB-CI.md](docs/GITLAB-CI.md) | GitLab: Code Quality izvještaj, MR recept, kapija |
579
+ | [docs/rules/](docs/rules/) | Generisani katalog po pravilu |
580
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | Razvojno okruženje i tok doprinosa |
581
+ | [SUPPORT.md](SUPPORT.md) | Gdje pitati, prijaviti i dobiti pomoć |
582
+ | [SECURITY.md](SECURITY.md) | Prijava ranjivosti |
583
+ | [CHANGELOG.md](CHANGELOG.md) | Historija izdanja |
584
+
585
+ ### Status
586
+
587
+ **Verzija 1.** JSON shema i izlazni kodovi su zamrznuti ugovori. TypeScript i Python imaju najširu izmjerenu pokrivenost. Java i C# su noviji; čitajte ih kroz [tabelu zrelosti](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle). Šta slijedi, bez izmišljenih datuma: [javna mapa puta](https://sergey-bar.github.io/Mjolnir/reference/roadmap).
588
+
589
+ ### Doprinos
590
+
591
+ Nova pravila su najlakši prvi doprinos. Jedna naredba pravi kostur pravila s njegovim must-fire **i** must-not-fire fixtureima. Generisano pravilo namjerno pada na vlastitim fixtureima dok se ne napiše stvarna detekcija, jer isporučeni kostur jeste pravilo koje niko nije izmjerio:
665
592
 
666
593
  ```bash
667
594
  mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
668
595
  ```
669
596
 
670
- Potpuni dev setup, komande stalnog gatea i zakoni anti-creep / fixture
671
- vatrozida su u [CONTRIBUTING.md](CONTRIBUTING.md).
597
+ Razvojno okruženje, naredbe stalnih kapija te zakoni anti-creep i zaštitnog zida fixturea nalaze se u [CONTRIBUTING.md](CONTRIBUTING.md).
672
598
 
673
- ---
599
+ <br />
674
600
 
675
601
  <div align="center">
676
602
 
677
- **Prestani isporučivati testovima kojima ne možeš vjerovati.**
603
+ <img src="assets/readme/closing.svg" alt="Pokrenite ga na svom repozitoriju." width="100%" />
678
604
 
679
605
  ```bash
680
606
  npx mjolnir-qa@latest
681
607
  ```
682
608
 
683
- **Star ⭐ · Watch 👀 · Contribute 🤝**
609
+ [Pročitajte vodič](https://sergey-bar.github.io/Mjolnir/guide/getting-started) · [Stranica dokumentacije](https://sergey-bar.github.io/Mjolnir/) · [npm](https://www.npmjs.com/package/mjolnir-qa)
610
+
611
+ <br />
612
+
613
+ Ne pitajte jesu li testovi prošli.<br />
614
+ Pitajte dokazuju li dokazi da zaslužuju povjerenje.
684
615
 
685
- Izgradio [Sergey Bar](https://www.linkedin.com/in/sergeybar/)
616
+ <sub>Napravio [Sergey Bar](https://www.linkedin.com/in/sergeybar/) · MIT licenca</sub>
686
617
 
687
618
  </div>