mjolnir-qa 1.0.9 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +204 -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 +453 -438
- 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 +716 -110
- package/dist/cli.mjs +9815 -22027
- package/dist/mcp/stdio.mjs +2164 -886
- package/dist/rolldown-runtime-8H4AJuhK.mjs +14 -0
- package/dist/scan-pipeline-C0ka-RmX.mjs +2 -0
- package/dist/scan-pipeline-D3Yk2cef.mjs +15309 -0
- package/package.json +14 -8
package/README.no.md
CHANGED
|
@@ -1,396 +1,431 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
<img src="assets/readme/
|
|
3
|
+
<img src="assets/readme/hero.svg" alt="Mjölnir. Tester forteller deg hva som besto. Mjölnir forteller deg hva du kan stole på." width="100%" />
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<br />
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
tilliten bryter sammen.
|
|
7
|
+
Mjölnir finner tester som ikke kan feile og pipelines som ikke kan bli røde,<br />
|
|
8
|
+
og vurderer deretter hvor langt resultatet er til å stole på, med beviset for hvert poeng.
|
|
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.pl.md) | [Русский](README.ru.md) | Norsk | [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
|
+
[Se det i aksjon](#se-det-i-aksjon) · [Kom raskt i gang](#kom-raskt-i-gang) · [Hva det finner](#hva-mjölnir-finner) · [Score](#worthiness-scoren) · [Evidens](#evidensmodellen) · [Kjøringsanalyse](#kjøringsanalyse) · [CI](#ci-integritet) · [Agenter](#ai-agenter) · [Sikkerhet](#tillit-og-sikkerhet) · [Begrensninger](#hva-mjölnir-ikke-kan-fortelle-deg) · [Dokumentasjon](#dokumentasjon)
|
|
25
|
+
|
|
26
|
+
<details>
|
|
27
|
+
<summary>Les på et annet språk — 22 oversettelser</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 | [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)
|
|
25
30
|
|
|
26
|
-
[
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
[Dokumentasjon](#-dokumentasjon)
|
|
31
|
+
> 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-15.
|
|
32
|
+
|
|
33
|
+
<!-- Source hash: 3541b09e8d04 -->
|
|
34
|
+
|
|
35
|
+
</details>
|
|
32
36
|
|
|
33
37
|
</div>
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
<br />
|
|
40
|
+
|
|
41
|
+
## En grønn hake er en påstand, ikke et bevis
|
|
42
|
+
|
|
43
|
+
En grønn hake betyr at pipelinen ikke feilet. Den betyr ikke at testene kjørte, eller at de kunne ha feilet. Hver eneste av disse går grønt gjennom:
|
|
44
|
+
|
|
45
|
+
- en committet `.only` som kjørte 3 tester i stedet for 900
|
|
46
|
+
- `continue-on-error: true` på jobben som skulle ha blokkert
|
|
47
|
+
- `|| true` etter testkommandoen
|
|
48
|
+
- en test som ikke sjekker noe, eller som har en tom kropp
|
|
49
|
+
- en retry-wrapper som gjør en reell feil om til en heldig bestått
|
|
50
|
+
- en rapport som workflowen laster opp, men aldri har generert
|
|
51
|
+
- en fast sleep som holder sammen en race condition
|
|
52
|
+
|
|
53
|
+
Ingen av dem gjør pipelinen rød, og hver av dem ser tilsiktet ut i review. Derfor overlever de. Her leser Mjölnir et ekte eksempel:
|
|
36
54
|
|
|
37
|
-
|
|
55
|
+
<p align="center">
|
|
56
|
+
<img src="assets/readme/scan.svg" alt="Demo-repositoriets CI-workflow, lest linje for linje. Mjölnir markerer hvert funn på linjen det ble rapportert, med regelen, hva som er galt, evidensnivået og den målte falsk-positiv-raten." width="800" />
|
|
57
|
+
</p>
|
|
58
|
+
|
|
59
|
+
<sub>Hvert funn demoskanningen rapporterte for denne workflowen, på linjen det ble rapportert. Generert av `npm run docs:readme-brand` fra [`demo-report.json`](assets/readme/demo-report.json) og låst mot avvik i CI.</sub>
|
|
60
|
+
|
|
61
|
+
**Streng modus.** De mest aggressive deteksjonene — `.only`, `continue-on-error`, tomme tester, misbruk av omkjøringer — lever i karantenenivået. De kjører bare under `--strict` og er begrenset til `info`-alvorlighetsgrad: de flagger, de blokkerer aldri. Standardskanningen (`npx mjolnir-qa@latest` uten `--strict`) dekker bare kjerne- og utvidede regler. Legg til `--strict` når du også vil ha rådgivningslaget.
|
|
62
|
+
|
|
63
|
+
Mjölnir leser testsuiten, CI-workflowene og, hvis du har en, rapporten fra en ekte kjøring. Det kjører ikke testene dine, installerer ikke avhengighetene dine og kjører ikke koden det skanner. Og når det mangler evidens, sier det det i stedet for å finne på tillit:
|
|
64
|
+
|
|
65
|
+
| Situasjon | Hva Mjölnir rapporterer |
|
|
66
|
+
| ------------------------------------------------ | ----------------------------------------------------------- |
|
|
67
|
+
| Ingen testdeklarasjoner funnet | Score `null`, vist som **UNKNOWN**. Aldri en oppdiktet 100. |
|
|
68
|
+
| Ingen baseline eller sammenlignbar revisjon | **UNKNOWN**, med årsaken oppgitt. Aldri en antatt 0. |
|
|
69
|
+
| Skanning avbrutt (tidsbudsjett, uleselige filer) | **PARTIAL**, exit `2`. Aldri presentert som ren. |
|
|
38
70
|
|
|
39
71
|
<p align="center">
|
|
40
|
-
<img src="assets/readme/
|
|
72
|
+
<img src="assets/readme/how-it-works.svg" alt="Slik fungerer Mjölnir. Det leser testsuiten og CI-pipelinen statisk, og rapporten fra en ekte kjøring når det finnes en. Det vekter hvert funn etter evidensnivå og tillitsnivå, der bare en ekte kjøring kan nå L3 til L5, og gir funn, en worthiness-score og en CI-gate med fryste exitkoder. I agentløkken skriver AI rettelsen, og Mjölnir skanner på nytt for å bevise den." width="880" />
|
|
41
73
|
</p>
|
|
42
74
|
|
|
43
|
-
<sub>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
75
|
+
<sub>Komponert for denne siden og vist i 1:1. Generert av `npm run docs:readme-brand` og låst mot avvik i CI; score, antall og regel-ID kommer fra [`script.demo.json`](assets/video/script.demo.json), [`demo-report.json`](assets/readme/demo-report.json) og regelregisteret, aldri skrevet inn for hånd. Samme bilde som plakat: [`architecture.svg`](assets/readme/architecture.svg).</sub>
|
|
76
|
+
|
|
77
|
+
<br />
|
|
78
|
+
|
|
79
|
+
## Se det i aksjon
|
|
80
|
+
|
|
81
|
+
En ekte skanning av [`examples/demo-repo`](examples/demo-repo), en liten Playwright-suite med en CI-workflow. Her er hvor poengene ble av:
|
|
82
|
+
|
|
83
|
+
<p align="center">
|
|
84
|
+
<img src="assets/readme/terminal-hero.svg" alt="Mjölnirs oversikt over trekk: WORTHINESS 80/100 WORTHY, scoren per kategori, trekkboksen per alvorlighetsgrad og en FIX THIS FIRST-liste" width="520" />
|
|
85
|
+
</p>
|
|
86
|
+
|
|
87
|
+
<sub>Generert av `npm run docs:hero` fra en ekte skanning og låst mot avvik i CI. Den fullstendige `--verbose`-rapporten fra samme skanning er [`demo.svg`](assets/readme/demo.svg) (`npm run docs:demo`).</sub>
|
|
88
|
+
|
|
89
|
+
<details>
|
|
90
|
+
<summary><strong>Se det</strong> — en skanning, rettelsen den skriver ut, og den nye skanningen som beviser den</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="Et bilde fra demoopptaket: npx mjolnir-qa@latest skanner demo-repositoriet i et terminalvindu" width="900" />
|
|
97
|
+
</a>
|
|
98
|
+
</p>
|
|
49
99
|
|
|
50
|
-
|
|
100
|
+
<sub>Rendret bilde for bilde fra en ekte skanning av `npm run docs:video`; aldri tatt opp fra skjermen. Velg bildet for å åpne [`mjolnir-demo.mp4`](assets/video/mjolnir-demo.mp4).</sub>
|
|
51
101
|
|
|
52
|
-
|
|
53
|
-
en Python-testfil — fire språk/formater, ett gjennomløp.
|
|
54
|
-
2. Den fant beviser som svekker tilliten til suiten — en
|
|
55
|
-
`continue-on-error` som maskerer en jobb, en `|| true` som svelger en
|
|
56
|
-
exit-kode, harde sleeps, en skjør selector, hardkodede staging-URLer,
|
|
57
|
-
en `networkidle`-ventetid.
|
|
58
|
-
3. Den gjorde hvert av dem til et konkret funn med regel-ID, plassering
|
|
59
|
-
og fiks — og til én score du kan gate en PR på.
|
|
102
|
+
</details>
|
|
60
103
|
|
|
61
104
|
### Ett funn på nært hold
|
|
62
105
|
|
|
63
|
-
|
|
106
|
+
Hvert funn svarer på fire spørsmål: hvor det er, hvor sikker Mjölnir er, hvor ofte regelen tar feil, og hvordan det rettes.
|
|
107
|
+
|
|
108
|
+
<p align="center">
|
|
109
|
+
<img src="assets/readme/finding-anatomy.svg" alt="Det første funnet fra demoskanningen, nøyaktig slik terminalen skriver det ut, med de fire delene markert: hvor, hvor sikkert, hvor ofte regelen tar feil, og rettelsen." width="100%" />
|
|
110
|
+
</p>
|
|
111
|
+
|
|
112
|
+
`mjolnir explain QA-CI-001` skriver ut en regels fullstendige tillitsprofil, inkludert den målte falsk-positiv-raten og nivået den raten har gitt den:
|
|
64
113
|
|
|
65
114
|
```text
|
|
66
|
-
|
|
115
|
+
▍ QA-CI-001 — continue-on-error masks a failing verification gate
|
|
67
116
|
|
|
68
117
|
Severity: error
|
|
69
118
|
Confidence: high
|
|
119
|
+
Tier: quarantine
|
|
70
120
|
Evidence: E2
|
|
71
|
-
|
|
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
|
|
72
126
|
|
|
73
127
|
WHAT WAS FOUND (real detector output, not a mockup)
|
|
74
128
|
Job `security-scan` runs a verification gate under `continue-on-error: true`.
|
|
75
129
|
|
|
76
130
|
WHY IT MATTERS
|
|
77
|
-
This job can fail every day and CI will still show green. The checkmark
|
|
78
|
-
|
|
131
|
+
This job can fail every day and CI will still show green. The checkmark on
|
|
132
|
+
this workflow cannot be trusted.
|
|
79
133
|
|
|
80
134
|
HOW TO FIX
|
|
81
135
|
Remove continue-on-error, or scope it to individual non-blocking steps only.
|
|
82
|
-
```
|
|
83
136
|
|
|
84
|
-
|
|
85
|
-
forteller deg at noe besto, selv om det ikke gjorde det.
|
|
137
|
+
Example from this rule's own must-fire fixture: QA-CI-001/must-fire/masked.yml
|
|
86
138
|
|
|
87
|
-
|
|
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
|
|
88
146
|
|
|
89
|
-
|
|
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.
|
|
90
150
|
|
|
91
|
-
|
|
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.
|
|
92
154
|
|
|
93
|
-
|
|
94
|
-
npx mjolnir-qa@latest
|
|
155
|
+
Docs: mjolnir rules --md (full catalog, this rule included)
|
|
95
156
|
```
|
|
96
157
|
|
|
97
|
-
|
|
98
|
-
|
|
158
|
+
Det er verdienheten: ett sted der CI rapporterer en bestått den ikke har gjort seg fortjent til.
|
|
159
|
+
|
|
160
|
+
<br />
|
|
161
|
+
|
|
162
|
+
## Kom raskt i gang
|
|
99
163
|
|
|
100
164
|
```bash
|
|
101
|
-
npx mjolnir-qa@latest
|
|
165
|
+
npx mjolnir-qa@latest
|
|
102
166
|
```
|
|
103
167
|
|
|
104
|
-
|
|
105
|
-
og du er ferdig. Alt annet er valgfritt.
|
|
106
|
-
|
|
107
|
-
| Kommando | Hva den gjør |
|
|
108
|
-
| ----------------------------------- | --------------------------------------------------- |
|
|
109
|
-
| `mjolnir` | Skann av hele repoet + verdighetsscore |
|
|
110
|
-
| `mjolnir --scope changed` | Bare det branchen din innførte — CI-formen |
|
|
111
|
-
| `mjolnir ci install` | Genererer den rådgivende PR-workflowen |
|
|
112
|
-
| `mjolnir explain QA-CI-001` | Hva / hvorfor / fiks + målt FP-rate for én regel |
|
|
113
|
-
| `mjolnir rules --unmeasured` | Reglene som kjører på antagelse, ikke måling |
|
|
114
|
-
| `mjolnir --json` / `--format sarif` | Maskinlesbart / GitHub Code Scanning |
|
|
115
|
-
| `mjolnir --strict` | Kjør også quarantine-tier-regler (høyere FP-risiko) |
|
|
168
|
+
Det skanner gjeldende mappe og skriver ut Trust Report: hva det fant, hvor langt du kan stole på det, hvorfor, og hva du bør gjøre videre. Det avslutter med `0` når ingenting på eller over gaten ble funnet.
|
|
116
169
|
|
|
117
|
-
|
|
118
|
-
<summary><strong>Når noe er flaky</strong></summary>
|
|
170
|
+
I CI bør du bare skanne det grenen har introdusert, så en eldre testsuite ikke drukner din første pull request:
|
|
119
171
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
| `mjolnir triage ./test-results/` | Karanteneforslag fra utførelseshistorikken |
|
|
124
|
-
| `mjolnir pw-report ./test-results/` | Playwright-runoversikt — retries / flakes / de tregeste |
|
|
125
|
-
| `mjolnir doctor:playwright` | Dypskann kun Playwright + Selector Health Score |
|
|
172
|
+
```bash
|
|
173
|
+
npx mjolnir-qa@latest --scope changed
|
|
174
|
+
```
|
|
126
175
|
|
|
127
|
-
|
|
176
|
+
`mjolnir ci install` skriver det som en GitHub Actions-workflow med [action-en](https://github.com/Sergey-Bar/Mjolnir#readme) festet til major-taggen `v1` (eller vanlig `npx` med `--no-action`). Den forblir rådgivende til du bestemmer at den skal blokkere.
|
|
177
|
+
|
|
178
|
+
| Kommando | Hva den gjør |
|
|
179
|
+
| ----------------------------------- | ---------------------------------------------------------- |
|
|
180
|
+
| `mjolnir` | Trust Report: dom, sikkerhet, neste handling |
|
|
181
|
+
| `mjolnir --scope changed` | Bare det grenen din har introdusert (CI-formen) |
|
|
182
|
+
| `mjolnir ci install` | Generer den rådgivende PR-workflowen (action-basert) |
|
|
183
|
+
| `mjolnir explain QA-CI-001` | Hva, hvorfor og rettelse, pluss den målte FP-raten |
|
|
184
|
+
| `mjolnir why src/a.spec.ts:42` | Hvorfor akkurat denne linjen ble markert. Blokkerer aldri. |
|
|
185
|
+
| `mjolnir forensics ./test-results/` | Kjøringsevidens fra en ekte kjøring |
|
|
186
|
+
| `mjolnir trust-report` | Selvstendig Trust-artefakt (md + json) |
|
|
187
|
+
| `mjolnir handoff` | Utbedringsplan for en kodeagent |
|
|
188
|
+
| `mjolnir --json` / `--format sarif` | Maskinlesbar utdata, GitHub Code Scanning |
|
|
189
|
+
| `mjolnir --format codequality` | GitLab Code Quality-rapport (MR-widget-artefakt) |
|
|
190
|
+
| `mjolnir --strict` | Kjør også regler på quarantine-nivå (høyere FP-risiko) |
|
|
128
191
|
|
|
129
192
|
<details>
|
|
130
|
-
<summary><strong>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
|
135
|
-
|
|
|
136
|
-
| `mjolnir
|
|
137
|
-
| `mjolnir
|
|
138
|
-
| `mjolnir
|
|
139
|
-
| `mjolnir
|
|
140
|
-
| `mjolnir
|
|
141
|
-
| `mjolnir
|
|
142
|
-
| `mjolnir
|
|
143
|
-
| `mjolnir
|
|
144
|
-
| `mjolnir
|
|
193
|
+
<summary><strong>Alle andre kommandoer</strong> — triage av ustabile tester, rapportering, styring</summary>
|
|
194
|
+
|
|
195
|
+
<br />
|
|
196
|
+
|
|
197
|
+
| Kommando | Hva den gjør |
|
|
198
|
+
| ----------------------------------- | ------------------------------------------------------------------------- |
|
|
199
|
+
| `mjolnir --classic` | Scorebanneret fra før Trust Report |
|
|
200
|
+
| `mjolnir explain verdict` | Hvorfor dommen for den lagrede skanningen er som den er |
|
|
201
|
+
| `mjolnir triage ./test-results/` | Veiledet triage. Hver rad slutter med en neste handling. |
|
|
202
|
+
| `mjolnir pw-report ./test-results/` | Oppsummering av Playwright-kjøring: retries, ustabile tester, de tregeste |
|
|
203
|
+
| `mjolnir doctor:playwright` | Dypskanning bare for Playwright pluss Selector Health Score |
|
|
204
|
+
| `mjolnir fix --dry-run` / `fix` | Trygge autorettelser, hver skannet på nytt for å bevise at den virket |
|
|
205
|
+
| `mjolnir baseline` / `diff` | Ta et øyeblikksbilde av funn, og rapporter deretter bare nye eller verre |
|
|
206
|
+
| `mjolnir impact --since <ref>` | Hva en commit introduserte og løste |
|
|
207
|
+
| `mjolnir summary` | CI-annotasjoner og en step-oppsummering fra en rapport |
|
|
208
|
+
| `mjolnir pr-comment` | En avgrenset PR-kommentar, som Markdown |
|
|
209
|
+
| `mjolnir debt` | Register over testgjeld med en kostnadsmodell |
|
|
210
|
+
| `mjolnir handover` | Introduksjonskart over suiten for en ny QA-ingeniør |
|
|
211
|
+
| `mjolnir init` | Oppdag rammeverk, skriv ut en sjekkliste for oppsett |
|
|
212
|
+
| `mjolnir suppressions` | List undertrykte funn, for styring |
|
|
213
|
+
| `mjolnir rules --unmeasured` | Reglene som kjører på antakelser, ikke målinger |
|
|
214
|
+
| `mjolnir rules --md` | Fullstendig regelkatalog (JSON eller Markdown) |
|
|
215
|
+
| `mjolnir doctor` | Selvrevisjon av Mjölnirs egen regelbase |
|
|
216
|
+
| `mjolnir create-rule <ID>` | Lag skjelettet til en ny regel og dens fixtures |
|
|
217
|
+
| `mjolnir stats` | Lokale tellere over alle rettelser som noen gang er sett |
|
|
218
|
+
| `mjolnir badge` | shields.io-endepunkt-JSON og snutt |
|
|
219
|
+
| `mjolnir --cache` | Inkrementelle nye skanninger via en lokal hurtigbuffer for dommer |
|
|
220
|
+
| `mjolnir --format mermaid` | Diagram over testarkitekturen for en PR-kommentar |
|
|
221
|
+
|
|
222
|
+
`mjolnir help <command>` skriver ut bruk, eksempler og neste steg for hver av dem.
|
|
145
223
|
|
|
146
224
|
</details>
|
|
147
225
|
|
|
148
|
-
|
|
149
|
-
`npm i -g mjolnir-qa`. Krever Node.js ≥ 22.18. Fungerer på Windows,
|
|
150
|
-
macOS og Linux.
|
|
151
|
-
|
|
152
|
-
---
|
|
226
|
+
Krever **Node.js ≥ 22.18** på Windows, macOS eller Linux. Foretrekker du en global installasjon? `npm i -g mjolnir-qa`. Minstekravet kommer fra byggeverktøykjeden (tsdown sikter mot det, og release-pipelinen røyktester mot det); kjøretidsavhengighetene trenger ikke mer enn det.
|
|
153
227
|
|
|
154
|
-
|
|
228
|
+
<br />
|
|
155
229
|
|
|
156
|
-
|
|
157
|
-
bevis for at suiten faktisk fortjener den grønne haken den
|
|
158
|
-
produserer.
|
|
159
|
-
- **Plattform-/DevEx-team** som har ansvar for CI-integritet og
|
|
160
|
-
release gates — folket som bryr seg om at en `continue-on-error`
|
|
161
|
-
aldri stille maler en rød pipeline grønn.
|
|
162
|
-
- **OSS-maintainere** som vil ha en billig, alltid på verifikasjonsgate
|
|
163
|
-
som kjører lokalt og i CI uten nettverkskall.
|
|
230
|
+
## Hva Mjölnir finner
|
|
164
231
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
232
|
+
<p align="center">
|
|
233
|
+
<img src="assets/readme/stack.svg" alt="Fungerer med stacken din: språkene, testrammeverkene og CI-systemene reglene dekker, fra regelregisteret." width="100%" />
|
|
234
|
+
</p>
|
|
168
235
|
|
|
169
|
-
|
|
170
|
-
| --- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
171
|
-
| ⚖️ | **Verdighetsscore** — ett tall, transparent fradragstabell, ingen black box |
|
|
172
|
-
| 🎭 | **Selector Health Score** — vurderer Playwright-locatorene dine, ikke bare pass rate |
|
|
173
|
-
| 🔬 | **Runtime-forundersøkelse** — leser ekte Playwright/JUnit-kjøringsdata og fanger `TRUE-FLAKE`, ikke bare statiske gjetninger |
|
|
174
|
-
| 🚨 | **CI-integritetsregler** — fanger `continue-on-error`, `\|\| true` og andre falskgrønne triks |
|
|
175
|
-
| 🐍 | **Alle fire Playwright-bindings** — TypeScript, Python, Java, C#/.NET — pluss pytest, JUnit/TestNG og CI-workflows |
|
|
176
|
-
| 🔒 | **Local-first** — null nettverkskall under skanning, null telemetri, kjører på sekunder |
|
|
236
|
+
**79 regler** i fire familier — testhygiene, testkvalitet, Playwright og CI-integritet — på tvers av TypeScript og JavaScript, Python, Java, C# og GitHub Actions-YAML. De dekker Playwright i alle fire bindings, pluss pytest, JUnit, TestNG, NUnit, xUnit, MSTest, Jest, Vitest og Mocha, med startdekning for Cypress og Selenium. Ni av dem, for å vise formen:
|
|
177
237
|
|
|
178
|
-
|
|
238
|
+
| ID | Regel | Alvorlighetsgrad | Nivå |
|
|
239
|
+
| ------------ | ---------------------------------------------------------------------- | ---------------- | ---------- |
|
|
240
|
+
| QA-CI-001 | `continue-on-error` skjuler en feilende verifiseringsgate | error | quarantine |
|
|
241
|
+
| QA-CI-009 | Testens exitkode videreformidles ikke (`\|` uten pipefail, `;`-kjeder) | error | extended |
|
|
242
|
+
| QA-TEST-001 | Fokusert test committet (`.only`, `fit`) | error | quarantine |
|
|
243
|
+
| QA-TEST-003 | Test uten assertions | error | quarantine |
|
|
244
|
+
| QA-TQUAL-009 | Promise-assertion uten await | error | quarantine |
|
|
245
|
+
| QA-PW-002 | Locator-assertion uten await | error | core |
|
|
246
|
+
| QA-PW-004 | Skjøre CSS/XPath-selektorer | warning | quarantine |
|
|
247
|
+
| QA-PY-002 | Hoppet over test (`skip`, ikke-streng `xfail`) | warning | core |
|
|
248
|
+
| QA-CS-103 | Testmetode uten assertions | error | core |
|
|
179
249
|
|
|
180
|
-
|
|
181
|
-
En regel som utløses på sin egen negative fixture, kan ikke skipes —
|
|
182
|
-
det er false-positive-brannmuren.
|
|
250
|
+
Den fullstendige katalogen genereres fra registeret, aldri vedlikeholdt for hånd: `mjolnir rules --md`, [`docs/rules/`](docs/rules/) eller [veiledningen om hva det sjekker](https://sergey-bar.github.io/Mjolnir/guide/what-it-checks).
|
|
183
251
|
|
|
184
252
|
<details>
|
|
185
|
-
<summary><strong>
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
|
192
|
-
|
|
|
193
|
-
| QA-TEST-
|
|
194
|
-
| QA-TEST-
|
|
195
|
-
| QA-TEST-
|
|
253
|
+
<summary><strong>Alle regler nevnt i denne README-en</strong>, i én tabell</summary>
|
|
254
|
+
|
|
255
|
+
<br />
|
|
256
|
+
|
|
257
|
+
> `quarantine`-regler kjører bare under `--strict` og blokkerer aldri (de er begrenset til info). Alvorlighetsgraden som vises, er forfatterens.
|
|
258
|
+
|
|
259
|
+
| ID | Familie | Regel | Alvorlighetsgrad | Nivå |
|
|
260
|
+
| ------------ | ---------- | ------------------------------------------------------------------- | ---------------- | ---------- |
|
|
261
|
+
| QA-TEST-001 | Hygiene | Fokusert test committet (`.only`, `fit`) | error | quarantine |
|
|
262
|
+
| QA-TEST-002 | Hygiene | Hoppet over test. Eskalerer til `error` uten en sporet begrunnelse. | warning | quarantine |
|
|
263
|
+
| QA-TEST-003 | Hygiene | Test uten assertions | error | quarantine |
|
|
264
|
+
| QA-TEST-004 | Hygiene | Fast sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning | extended |
|
|
265
|
+
| QA-TEST-006 | Hygiene | Misbruk av retries som skjuler ustabilitet | warning | quarantine |
|
|
266
|
+
| QA-TEST-010 | Hygiene | Tom testkropp | error | quarantine |
|
|
267
|
+
| QA-TQUAL-002 | Kvalitet | Tautologisk assertion | error | quarantine |
|
|
268
|
+
| QA-TQUAL-009 | Kvalitet | Promise-assertion uten await | error | quarantine |
|
|
269
|
+
| QA-TQUAL-011 | Kvalitet | Utkommenterte tester | warning | extended |
|
|
270
|
+
| QA-PW-002 | Playwright | Locator-assertion uten await | error | core |
|
|
271
|
+
| QA-PW-003 | Playwright | `page.pause()` / `test.only()` committet | error | core |
|
|
272
|
+
| QA-PW-004 | Playwright | Skjøre CSS/XPath-selektorer | warning | quarantine |
|
|
273
|
+
| QA-PW-123 | Playwright | Hardkodede miljø-URL-er | warning | quarantine |
|
|
274
|
+
| QA-PW-140 | Playwright | Skjermbilde uten `maxDiffPixelRatio` | warning | core |
|
|
275
|
+
| QA-CI-001 | CI | `continue-on-error` skjuler en feilende gate | error | quarantine |
|
|
276
|
+
| QA-CI-002 | CI | `\|\| true` svelger exitkoder | error | extended |
|
|
277
|
+
| QA-CI-005 | CI | Rapport brukt, men aldri generert | error | quarantine |
|
|
278
|
+
| QA-CI-007 | CI | Retry-wrappere rundt tester | warning | extended |
|
|
279
|
+
| QA-CI-008 | CI | Step som alltid lykkes, skjuler feil | error | quarantine |
|
|
280
|
+
| QA-CI-009 | CI | Exitkode videreformidles ikke (`\|` uten pipefail, `;`-kjeder) | error | extended |
|
|
281
|
+
| QA-CI-010 | CI | Tester hoppet over der de må blokkere | error | quarantine |
|
|
282
|
+
| QA-PY-002 | Python | Hoppet over test (`skip`, ikke-streng `xfail`) | warning | core |
|
|
283
|
+
| QA-PY-003 | Python | Testfunksjon uten assertions | error | quarantine |
|
|
284
|
+
| QA-PY-005 | Python | `time.sleep()` i tester | warning | extended |
|
|
285
|
+
| QA-PY-012 | Python | Tautologisk assertion | error | quarantine |
|
|
286
|
+
| QA-JV-101 | Java | Deaktivert test (`@Disabled`) | warning | core |
|
|
287
|
+
| QA-JV-102 | Java | Fast sleep (`Thread.sleep()`) | warning | extended |
|
|
288
|
+
| QA-JV-103 | Java | Testmetode uten assertions | error | extended |
|
|
289
|
+
| QA-JV-105 | Java | Fast sleep med Playwright `waitForTimeout()` | warning | core |
|
|
290
|
+
| QA-JV-106 | Java | Skjør selektor i stedet for rollebasert locator | warning | quarantine |
|
|
291
|
+
| QA-CS-101 | C# | Hoppet over test (`[Ignore]`, `[Fact(Skip=)]`) | warning | core |
|
|
292
|
+
| QA-CS-102 | C# | Fast sleep (`Thread.Sleep` / `Task.Delay`) | warning | core |
|
|
293
|
+
| QA-CS-103 | C# | Testmetode uten assertions | error | core |
|
|
294
|
+
| QA-CS-105 | C# | Fast sleep med `WaitForTimeoutAsync()` | warning | extended |
|
|
295
|
+
| QA-CS-106 | C# | Skjør selektor i stedet for rollebasert locator | warning | quarantine |
|
|
296
|
+
|
|
297
|
+
Python har i tillegg QA-PY-001…012 (pytest-hygiene) og QA-PY-101…108 (Playwright for Python). Cypress og Selenium har startsett på tre regler hver.
|
|
196
298
|
|
|
197
299
|
</details>
|
|
198
300
|
|
|
199
|
-
|
|
200
|
-
<summary><strong>Testkvalitet</strong></summary>
|
|
301
|
+
Hver regel leveres med en must-fire- **og** en must-not-fire-fixture, og en regel som slår ut på sin egen negative fixture, kan ikke leveres. Det er brannmuren mot falske positiver; `mjolnir doctor` håndhever den i dette repositoriets egen CI.
|
|
201
302
|
|
|
202
|
-
|
|
203
|
-
| ------------ | ------------------------------- | -------- |
|
|
204
|
-
| QA-TQUAL-002 | Tautologisk assertion | error |
|
|
205
|
-
| QA-TQUAL-009 | Assertion på promise uten await | error |
|
|
206
|
-
| QA-TQUAL-011 | Utkommenterte tester | warning |
|
|
303
|
+
### Selector Health Score
|
|
207
304
|
|
|
208
|
-
|
|
305
|
+
`mjolnir doctor:playwright` vurderer hver locator etter hvordan den finner et element: slik en bruker ville gjort (rolle, etikett, tekst), via en eksplisitt kontrakt (`data-testid`), eller ved et strukturelt tilfelle (CSS-kjeder, XPath). Hver fil får en score fra 0 til 100:
|
|
209
306
|
|
|
210
|
-
|
|
211
|
-
|
|
307
|
+
```text
|
|
308
|
+
▍ SELECTOR HEALTH
|
|
212
309
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
| QA-PW-003 | `page.pause()` / `test.only()` commitet | error |
|
|
217
|
-
| QA-PW-004 | Skjøre CSS/XPath-selektorer | warning |
|
|
218
|
-
| QA-PW-123 | Hardkodede miljø-URLer | warning |
|
|
310
|
+
e2e/login.spec.ts
|
|
311
|
+
[█████████████░░░░░░░] 65 / 100
|
|
312
|
+
role/text: 1 · testid: 0 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
|
|
219
313
|
|
|
220
|
-
|
|
314
|
+
e2e/checkout.spec.ts
|
|
315
|
+
[██████████████████░░] 88 / 100
|
|
316
|
+
role/text: 4 · testid: 1 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
|
|
317
|
+
```
|
|
221
318
|
|
|
222
|
-
|
|
223
|
-
<summary><strong>CI-integritet</strong></summary>
|
|
224
|
-
|
|
225
|
-
| ID | Regel | Severity |
|
|
226
|
-
| --------- | ------------------------------------------------------------------ | -------- |
|
|
227
|
-
| QA-CI-001 | `continue-on-error` maskerer feil | error |
|
|
228
|
-
| QA-CI-002 | `\|\| true` svelger exit-koder | error |
|
|
229
|
-
| QA-CI-005 | Rapport forbrukes, men genereres aldri | error |
|
|
230
|
-
| QA-CI-007 | Retry-wrappers rundt tester | warning |
|
|
231
|
-
| QA-CI-008 | Alltid-vellykket step maskerer feil | error |
|
|
232
|
-
| QA-CI-009 | Testens exit-kode propageres ikke (`\|` uten pipefail, `;`-kjeder) | error |
|
|
233
|
-
| QA-CI-010 | Tester hoppes over der de må blokkere (skip-on-PR-guards) | error |
|
|
319
|
+
Dette måler **robusthet, ikke korrekthet**. `.btn.btn-primary > div:nth-child(2)` består i dag og fortsetter å bestå til noen rører markupen. En lav score påstår aldri at testen er ødelagt, bare at den avhenger av markup ingen har lovet å beholde.
|
|
234
320
|
|
|
235
|
-
|
|
321
|
+
<br />
|
|
236
322
|
|
|
237
|
-
|
|
238
|
-
<summary><strong>Python / pytest 🐍</strong></summary>
|
|
323
|
+
## Worthiness-scoren
|
|
239
324
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
| QA-PY-003 | Testfunksjon uten assertions | error |
|
|
244
|
-
| QA-PY-005 | `time.sleep()` i tester | warning |
|
|
245
|
-
| QA-PY-012 | Tautologisk assertion | error |
|
|
325
|
+
<p align="center">
|
|
326
|
+
<img src="assets/readme/score-gauge.svg" alt="Worthiness-skalaen fra 0 til 100, med en markør som går gjennom hver score: UNWORTHY under 50, NEEDS WORK fra 50 til 79, WORTHY fra 80 til 99, FORGED ved 100" width="720" />
|
|
327
|
+
</p>
|
|
246
328
|
|
|
247
|
-
|
|
329
|
+
<sub>Hver score fra 0 til 100, plassert av den ekte `deriveScoreState`. Generert av `npm run docs:gauge` og låst mot avvik i CI.</sub>
|
|
248
330
|
|
|
249
|
-
|
|
331
|
+
| Score | Dom |
|
|
332
|
+
| --------- | ------------------------------------------- |
|
|
333
|
+
| `0 – 49` | **UNWORTHY** |
|
|
334
|
+
| `50 – 79` | **NEEDS WORK** |
|
|
335
|
+
| `80 – 99` | **WORTHY** |
|
|
336
|
+
| `100` | **FORGED** |
|
|
337
|
+
| `null` | **UNKNOWN**: ingen testdeklarasjoner funnet |
|
|
250
338
|
|
|
251
|
-
|
|
252
|
-
<summary><strong>Java / JUnit · TestNG ☕</strong></summary>
|
|
339
|
+
**Slik beregnes den.** Alvorlighetsgraden setter et grunntrekk (`error −8`, `warning −3`, `info −1`), og evidensnivået reduserer det: E2 teller fullt, E1 halvt (rundet ned), E0 ingenting. Summen normaliseres etter suitens eksponering, altså trekk per testdeklarasjon i stedet for per fil. Terminalen skriver ut de samme reduserte tallene som scoren brukte; det finnes ingen skjult modell nummer to. Detaljer: [docs/SCORING.md](docs/SCORING.md) og [scoringsveiledningen](https://sergey-bar.github.io/Mjolnir/guide/scoring).
|
|
253
340
|
|
|
254
|
-
|
|
255
|
-
| --------- | ----------------------------------------- | -------- |
|
|
256
|
-
| QA-JV-101 | Deaktivert test (`@Disabled`) | warning |
|
|
257
|
-
| QA-JV-102 | Hardt sleep (`Thread.sleep()`) | warning |
|
|
258
|
-
| QA-JV-103 | Testmetode uten assertions | error |
|
|
259
|
-
| QA-JV-105 | Playwright hardt sleep `waitForTimeout()` | warning |
|
|
260
|
-
| QA-JV-106 | Skjør selector i stedet for role-locator | warning |
|
|
341
|
+
**Hva 100 ikke betyr.** Det betyr ikke at programvaren er korrekt, at suiten er tilstrekkelig, eller at produktet er feilfritt. Det betyr én ting: **ingen av Mjölnirs evaluerte regler ga et trekk under denne skanningen og denne evidensmodellen.**
|
|
261
342
|
|
|
262
|
-
|
|
343
|
+
<br />
|
|
263
344
|
|
|
264
|
-
|
|
265
|
-
<summary><strong>C# / .NET — NUnit · xUnit · MSTest 🟣</strong></summary>
|
|
345
|
+
## Evidensmodellen
|
|
266
346
|
|
|
267
|
-
|
|
268
|
-
| --------- | ---------------------------------------------- | -------- |
|
|
269
|
-
| QA-CS-101 | Hoppet over test (`[Ignore]`, `[Fact(Skip=)]`) | warning |
|
|
270
|
-
| QA-CS-102 | Hardt sleep (`Thread.Sleep` / `Task.Delay`) | warning |
|
|
271
|
-
| QA-CS-103 | Testmetode uten assertions | error |
|
|
272
|
-
| QA-CS-105 | Hardt sleep `WaitForTimeoutAsync()` | warning |
|
|
273
|
-
| QA-CS-106 | Skjør selector i stedet for role-locator | warning |
|
|
347
|
+
Hvert funn har to etiketter: hvor sikker Mjölnir er, og hvor langt funnet er sjekket. Det er forskjellen mellom et verktøy som rapporterer mønstre og et verktøy du kan la en release avhenge av.
|
|
274
348
|
|
|
275
|
-
|
|
349
|
+
**Hvor sikkert — evidensnivået.**
|
|
276
350
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
### Hvor mye er målt
|
|
288
|
-
|
|
289
|
-
**78 av 99 regler bærer en false-positive-rate målt mot ekte OSS-kode**
|
|
290
|
-
(≥ 10 håndklassifiserte funn hver; se
|
|
291
|
-
[docs/FP-AUDIT.md](docs/FP-AUDIT.md)). De andre 21 skiper på
|
|
292
|
-
forfatterens estimat. Hver skann-fotnote forteller hvor mange av de
|
|
293
|
-
_utløste_ reglene som er målt; `mjolnir rules --unmeasured` lister de
|
|
294
|
-
umålte; hver regels `mjolnir explain`-side angir statusen. Vi publiserer
|
|
295
|
-
karantene for det. Å få det tallet til å vokse er prosjektets fortsatte
|
|
296
|
-
arbeid.
|
|
297
|
-
|
|
298
|
-
### Regel-tiers og språkmodenhet
|
|
299
|
-
|
|
300
|
-
Hver regel er `core`, `extended` eller `quarantine`, tildelt ut fra sin
|
|
301
|
-
**målte** false-positive-rate:
|
|
302
|
-
|
|
303
|
-
| Tier | Betydning | Standardskann | `--strict` |
|
|
304
|
-
| ------------ | ---------------------------------------- | :-----------: | :--------: |
|
|
305
|
-
| `core` | ≤ 10 % målt FP | ✅ | ✅ |
|
|
306
|
-
| `extended` | ≤ 30 % målt FP | ✅ | ✅ |
|
|
307
|
-
| `quarantine` | over 30 %, eller ennå ikke målt (n < 10) | ❌ | ✅ |
|
|
308
|
-
|
|
309
|
-
| Språk | Adapter | Dekning i dag |
|
|
310
|
-
| --------------- | -------------- | ------------------------------------------------ |
|
|
311
|
-
| TypeScript / JS | Kompilator-AST | bredeste, mest målte — mest `core`/`extended` |
|
|
312
|
-
| Python / pytest | Regex-lag | bredt, corpus-auditeret — mest `core`/`extended` |
|
|
313
|
-
| Java | Regex-lag | nyere — mest `extended`/`quarantine` |
|
|
314
|
-
| C# / .NET | Regex-lag | nyere — mest `extended`/`quarantine` |
|
|
315
|
-
|
|
316
|
-
TypeScript og Python har den bredeste målte dekningen. Java og C# er
|
|
317
|
-
skipet, dokumentert og holdes utenfor overskriftstallet til en ekte
|
|
318
|
-
forbrukersuite (ikke et binding-biblioteks egne tester) er auditeret.
|
|
319
|
-
|
|
320
|
-
---
|
|
321
|
-
|
|
322
|
-
## Slik fungerer scoren
|
|
351
|
+
| Nivå | Navn | Betyr | Trekk |
|
|
352
|
+
| ------ | -------------------- | ---------------------------------------------------- | ----- |
|
|
353
|
+
| **E2** | Deterministisk bevis | Defekten finnes i koden slik den er skrevet | Fullt |
|
|
354
|
+
| **E1** | Mønsterevidens | Et mønster som er sterkt knyttet til defekten, traff | Halvt |
|
|
355
|
+
| **E0** | Observasjon | Verdt å vite. Ikke en påstand om at noe er galt. | Null |
|
|
356
|
+
|
|
357
|
+
Sikkerhet i en deteksjon er ikke styrken i beviset. En regel kan være sikker på at den fant det den lette etter, og likevel se på en heuristikk. E1-funn er der for å bli lest og vurdert, aldri brukt i blinde, og den grensen står på funnet i terminalen, i JSON-en og i overleveringen til agenten.
|
|
358
|
+
|
|
359
|
+
**Hvor langt det er sjekket — tillitsnivået.** De fleste funn kommer fra å lese koden din. Gi Mjölnir rapporten fra en ekte testkjøring, så kan det bekrefte at koden faktisk kjørte.
|
|
323
360
|
|
|
324
361
|
<p align="center">
|
|
325
|
-
<img src="assets/readme/
|
|
362
|
+
<img src="assets/readme/trust-ladder.svg" alt="Tillitsstigen fra L0 til L5. L0 til L2 kommer fra å lese koden; L3 til L5 krever en ekte kjøringsrapport, markert med et brudd i stigen." width="100%" />
|
|
326
363
|
</p>
|
|
327
364
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
365
|
+
| Nivå | Med vanlige ord | Hva det krever |
|
|
366
|
+
| ------ | -------------------- | -------------------------------------------------- |
|
|
367
|
+
| **L0** | Notert | Å lese koden |
|
|
368
|
+
| **L1** | Ser ut som problemet | Å lese koden: et mønster traff |
|
|
369
|
+
| **L2** | Bevist i koden | Å lese koden: defekten er strukturell |
|
|
370
|
+
| **L3** | Filen kjørte | En kjøringsrapport viser at funnets fil ble kjørt |
|
|
371
|
+
| **L4** | Testen kjørte | En kjøringsrapport viser at funnets test ble kjørt |
|
|
372
|
+
| **L5** | Kjøringen er enig | Kjøringens eget resultat bekrefter defektklassen |
|
|
332
373
|
|
|
333
|
-
|
|
334
|
-
normalisert etter suitens eksponering (fradrag per testdeklarasjon).
|
|
335
|
-
Bevisvektede fradrag betyr at svake signaler koster mindre. Terminalen
|
|
336
|
-
viser de samme diskonterte tallene scoren bruker — ingen black box.
|
|
337
|
-
Full metode: [docs/SCORING.md](docs/SCORING.md).
|
|
374
|
+
En statisk skanning stopper ved L2. Bare en ekte kjøringsrapport (Playwright JSON, Jest eller Vitest JSON, JUnit XML) kan løfte et funn til L3 eller høyere, så et funn som aldri er sett kjøre, kan aldri påstå at det gjorde det. Definisjoner: [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md).
|
|
338
375
|
|
|
339
|
-
|
|
376
|
+
### Hvor mye av dette som er målt
|
|
340
377
|
|
|
341
|
-
|
|
342
|
-
| ------- | ---------------- |
|
|
343
|
-
| ≥ 80 | ✓ **WORTHY** |
|
|
344
|
-
| 50 – 79 | ⚠ **NEEDS WORK** |
|
|
345
|
-
| < 50 | ✖ **UNWORTHY** |
|
|
378
|
+
**74 av 79 regler har en falsk-positiv-rate målt mot ekte OSS-kode** (minst 10 håndklassifiserte funn hver; se [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). De andre 5 bygger på forfatterens anslag og sier det, regel for regel, i `mjolnir explain`. `mjolnir rules --unmeasured` lister dem, og bunnteksten i hver skanning oppgir hvor mange av reglene som faktisk _slo ut_, som er målt.
|
|
346
379
|
|
|
347
|
-
|
|
348
|
-
scoren:
|
|
380
|
+
Ratene forblir offentlige også når de er dårlige. QA-TEST-001 (en committet `.only`) kommer dårlig ut av revisjonen på ekte repositorier og sitter derfor i quarantine. Det aktuelle tallet for hver regel, inkludert QA-PW-141, står i revisjonen.
|
|
349
381
|
|
|
350
|
-
|
|
351
|
-
| ---- | --------------------- | --------------- | --------------------------------------------------- |
|
|
352
|
-
| E2 | Deterministisk defekt | Fullt fradrag | Commitet `.only` — strukturelt bevisbart |
|
|
353
|
-
| E1 | Heuristisk mønster | Halvt fradrag | Regex-truffet `sleep()` — sterkt signal, ikke bevis |
|
|
354
|
-
| E0 | Observasjon | Null (kun info) | Rapportert, men gater aldri CI eller trekker fra |
|
|
382
|
+
### Tillitsnivåer
|
|
355
383
|
|
|
356
|
-
|
|
357
|
-
systemet: E2-funn er strukturelt bevis; E1-funn er korrekt plasserte
|
|
358
|
-
advarsler, ikke formelle beviser.
|
|
384
|
+
Nivåene følger den målte falsk-positiv-raten, ikke meninger:
|
|
359
385
|
|
|
360
|
-
|
|
361
|
-
|
|
386
|
+
| Nivå | Målt FP | Oppførsel |
|
|
387
|
+
| -------------- | ------------------------------ | ---------------------------------------------------- |
|
|
388
|
+
| **core** | ≤ 10% | Standardrapport, blokkerer |
|
|
389
|
+
| **extended** | ≤ 30% | Standardrapport, lavere sikkerhet |
|
|
390
|
+
| **quarantine** | > 30% eller eksplisitt erklært | Bare `--strict`, begrenset til info, blokkerer aldri |
|
|
391
|
+
| _ikke målt_ | n < 10 | Kan ikke forfremmes til core før den er målt |
|
|
362
392
|
|
|
363
|
-
|
|
393
|
+
FP-bånd kan bare degradere et nivå — de forfremmer aldri en regel ut av `quarantine` hvis den var eksplisitt erklært der. En eksplisitt karantenesatt regel forblir i quarantine uavhengig av dens målte FP-rate.
|
|
364
394
|
|
|
365
|
-
|
|
395
|
+
Forfremmelse, degradering og modenhet per språk: [reglenes livssyklus](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle).
|
|
366
396
|
|
|
367
|
-
|
|
397
|
+
### Hvorfor dette ikke er en linter
|
|
368
398
|
|
|
369
|
-
|
|
370
|
-
▚ SELECTOR HEALTH — e2e/checkout.spec.ts
|
|
399
|
+
Lintere forteller deg om koden følger regler. Mjölnir forteller deg om verifiseringen din er til å stole på.
|
|
371
400
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
401
|
+
| | Lintere (ESLint, SonarQube) | Dekningsverktøy | AI-kodegjennomgang | **Mjölnir** |
|
|
402
|
+
| -------------------------------------------------------------- | :-------------------------: | :-------------: | :----------------: | :---------------: |
|
|
403
|
+
| Scorer **verifiseringssystemet**, ikke produktkoden | Nei | Nei | Nei | Ja |
|
|
404
|
+
| Integritet i CI-workflows (`continue-on-error`, `\|\| true`) | Nei | Nei | bare diffen | Ja |
|
|
405
|
+
| Vurderer robustheten til Playwright-locators (Selector Health) | Nei | Nei | Nei | Ja |
|
|
406
|
+
| Leser ekte kjøringsdata for `TRUE-FLAKE`-dommer | Nei | Nei | Nei | Ja |
|
|
407
|
+
| Publiserer en målt falsk-positiv-rate per regel | Nei | Nei | Nei | Ja |
|
|
408
|
+
| Markerer tester uten assertions | Ja\* | Nei | noen ganger | Ja |
|
|
409
|
+
| Fanger faste sleeps (`waitForTimeout`, `time.sleep`) | Ja\* | Nei | noen ganger | Ja |
|
|
410
|
+
| Deterministisk (samme input, samme output) | Ja | Ja | Nei | Ja |
|
|
411
|
+
| Kostnad per skanning | gratis | gratis | tokens | **null** (lokalt) |
|
|
412
|
+
|
|
413
|
+
<sub>\*Dekket av `eslint-plugin-jest` og `eslint-plugin-playwright` (`expect-expect`, `no-wait-for-timeout`) og av SonarQubes egne assertion-regler. Kolonnene beskriver standardoppførselen for verifisering av testsuiter; plugins, betalte planer og egne regler endrer noen svar. Dette er en posisjoneringsoversikt, ikke en benchmark.</sub>
|
|
375
414
|
|
|
376
|
-
|
|
377
|
-
scoren — de brekker ved enhver DOM-refaktor uten å fortelle deg hvilken
|
|
378
|
-
atferd som har regressert.
|
|
415
|
+
Bruk AI-gjennomgang også. Den fanger nyanser, intensjon og designfeil som ingen mønstre kan finne. Mjölnir fanger det AI-gjennomgangen overser fordi det ser tilsiktet ut: en committet `.only`, en svelget exitkode, en `continue-on-error` på en testjobb. Slikt krever skanning, ikke resonnering.
|
|
379
416
|
|
|
380
|
-
|
|
417
|
+
<br />
|
|
381
418
|
|
|
382
|
-
##
|
|
419
|
+
## Kjøringsanalyse
|
|
383
420
|
|
|
384
|
-
Statisk
|
|
385
|
-
kjøringsdata** — Playwright JSON-rapporter og JUnit-XML fra enhver
|
|
386
|
-
runner:
|
|
421
|
+
Statisk analyse resonnerer om kode som aldri har kjørt. Kjøringsanalysen leser hva som faktisk skjedde: Playwright JSON, Jest JSON, Vitest JSON og JUnit XML fra hvilken som helst runner.
|
|
387
422
|
|
|
388
423
|
```bash
|
|
389
424
|
mjolnir forensics ./test-results/
|
|
390
425
|
```
|
|
391
426
|
|
|
392
427
|
```text
|
|
393
|
-
|
|
428
|
+
▍ FLAKINESS LEADERBOARD
|
|
394
429
|
|
|
395
430
|
3 tests · 1 failed · 1 flaky · 1 retried
|
|
396
431
|
|
|
@@ -400,293 +435,184 @@ FAILING declines an expired card (e2e/checkout.spec.ts)
|
|
|
400
435
|
████░░░░░░░░░░░░░░░░ 1.1s · 1 attempt
|
|
401
436
|
```
|
|
402
437
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
438
|
+
`TRUE-FLAKE` betyr ikke at testen ble kjørt på nytt. Det betyr at testen **feilet minst ett forsøk og deretter endte grønt**: en heldig bestått, markert uansett hva den endelige haken sier. `mjolnir triage` gjør den historikken om til et karanteneforslag, og `mjolnir pw-report` oppsummerer en kjøring. Det er de samme kjøringsrapportene som løfter funn til tillitsnivå L3 og høyere.
|
|
439
|
+
|
|
440
|
+
<br />
|
|
441
|
+
|
|
442
|
+
## CI-integritet
|
|
406
443
|
|
|
407
|
-
|
|
444
|
+
En test kan bestå mens pipelinen rundt den ikke kan feile. Mjölnir leser også workflowene: `continue-on-error`, `|| true`, exitkoder som aldri videreformidles, steps som alltid lykkes, rapporter som brukes, men aldri genereres, og gates som hoppes over ved nettopp de hendelsene som burde blokkere. Hvert funn oppgir jobb, step og linje, og har sitt eget evidensnivå.
|
|
408
445
|
|
|
409
|
-
|
|
446
|
+
Generer PR-workflowen, rådgivende som standard:
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
mjolnir ci install
|
|
450
|
+
```
|
|
410
451
|
|
|
411
|
-
|
|
412
|
-
verifiseringen din kan stoles på.
|
|
452
|
+
Eller legg Marketplace-action-en til en workflow du allerede har:
|
|
413
453
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
454
|
+
```yaml
|
|
455
|
+
- uses: Sergey-Bar/Mjolnir@v1
|
|
456
|
+
with:
|
|
457
|
+
scope: changed
|
|
458
|
+
fail-on: error
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
Fest `@v1` for å følge major-linjen, eller en eksakt tagg (`@v0.5.32`) for en reproduserbar gate. [docs/DISTRIBUTION-KIT.md](docs/DISTRIBUTION-KIT.md) dekker Marketplace, Smithery og MCP-registrene.
|
|
462
|
+
|
|
463
|
+
For å få funn inn i GitHub Code Scanning, last opp SARIF (krever `security-events: write` på workflow- eller job-nivå):
|
|
464
|
+
|
|
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
|
+
```
|
|
422
473
|
|
|
423
|
-
|
|
424
|
-
(`expect-expect`, `no-wait-for-timeout`) dekker dette for sine
|
|
425
|
-
respektive rammeverk.
|
|
474
|
+
På GitLab skriver `--format codequality` Code Quality-rapporten som MR-widgeten og diff-annotasjonene leser ([docs/GITLAB-CI.md](docs/GITLAB-CI.md)). Oppsett av editor og pipeline: [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
|
|
426
475
|
|
|
427
|
-
|
|
476
|
+
### Tilordning i endret omfang
|
|
428
477
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
| Flaky-triage-rapport fra utførelseshistorikken | ❌ | ✅ | ✅ |
|
|
433
|
-
| Integrerer med den statiske verdighetsscoren | ❌ | ❌ | ✅ |
|
|
478
|
+
```bash
|
|
479
|
+
npx mjolnir-qa@latest --scope changed
|
|
480
|
+
```
|
|
434
481
|
|
|
435
|
-
|
|
436
|
-
flakiness-rapport med dommeetiketter.
|
|
482
|
+
Funn tilordnes linjene grenen din har lagt til, målt mot **merge-base**. Omfanget er det samme filsettet en full skanning finner (TS/JS-specs og adapterkonfigurasjoner, `test_*.py`, `*Test.java`, `*Tests.cs`, `.github/workflows/*.yml`), pluss ikke-committede og usporede endringer, så det fungerer før du committer. Basen løses i rekkefølgen `main → master → origin/main → origin/master → origin/HEAD`; overstyr den med `--base <ref>`.
|
|
437
483
|
|
|
438
|
-
|
|
484
|
+
Når merge-base ikke kan løses (en shallow clone, et detached HEAD, et mål utenfor git), faller funnene tilbake til tilordning for hele filen, **og rapporten sier det.** En stille fallback ville vært nøyaktig den typen defekt dette verktøyet finnes for å fange.
|
|
439
485
|
|
|
440
|
-
|
|
486
|
+
<br />
|
|
441
487
|
|
|
442
|
-
|
|
443
|
-
testendring i en diff; det beviser ikke at verifiseringssystemet som
|
|
444
|
-
helhet er troverdig — og det ser bare diffen du viser det.
|
|
488
|
+
## AI-agenter
|
|
445
489
|
|
|
446
|
-
|
|
447
|
-
| ------------------------------------------- | :-------------------------------------: | :----------------------------------: |
|
|
448
|
-
| Kostnad per skann | Tokens (skalerer med diffstørrelsen) | **Null** (lokal, installert) |
|
|
449
|
-
| Ser hele suiten + alle CI-konfigs | Bare PR-diffen du viser | **Alt, hver gang** |
|
|
450
|
-
| Deterministisk (samme input → samme output) | ❌ (ikke-deterministisk) | **✅** |
|
|
451
|
-
| Fanger mønstre som har sovet i måneder | Bare hvis det er i konteksten | **✅** (skanner alle filer) |
|
|
452
|
-
| Husker funn mellom kjøringer | ❌ (ingen hukommelse på tvers av økter) | **✅** (baseline + diff) |
|
|
453
|
-
| Kjører uten menneskelig utløser | Krever en PR eller prompt | **✅** (CI-hook, kjører på sekunder) |
|
|
490
|
+
Funn er bare verdt noe hvis noe handler på dem.
|
|
454
491
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
`continue-on-error` på et testjobb. Det er ikke bugs som krever
|
|
459
|
-
resonnering; det er fakta som krever skanning.
|
|
492
|
+
```text
|
|
493
|
+
SCAN → EVIDENCE → HANDOFF → AGENT → RE-SCAN → PROOF
|
|
494
|
+
```
|
|
460
495
|
|
|
461
|
-
|
|
496
|
+
**AI skriver rettelsen. Mjölnir verifiserer den.** Beviset kommer fra den nye skanningen, aldri fra agentens egen melding om suksess.
|
|
462
497
|
|
|
463
|
-
|
|
498
|
+
| Kommando | Hva agenten får |
|
|
499
|
+
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
500
|
+
| `mjolnir mcp` | En [MCP](https://modelcontextprotocol.io)-server over stdio. `scan`, `explain` og `diff` blir kallbare verktøy. |
|
|
501
|
+
| `mjolnir handoff` | En lagret `--json`-rapport blir en deterministisk Markdown-plan: hva som ble oppdaget, evidensgrensen for hvert funn, hva som **ikke** må endres, og hvordan det verifiseres. |
|
|
502
|
+
| `mjolnir install` | Skriver inn i agentflatene repoet ditt allerede har (`.claude/`, `.cursor/`, `.kilo/`, `AGENTS.md`), slik at agenten skanner på nytt før den påstår at den er ferdig. |
|
|
464
503
|
|
|
465
|
-
|
|
466
|
-
blokkerende:
|
|
504
|
+
Legg det til i en klient som har sin egen CLI:
|
|
467
505
|
|
|
468
506
|
```bash
|
|
469
|
-
mjolnir
|
|
507
|
+
claude mcp add mjolnir -- npx -y mjolnir-qa@latest mcp
|
|
470
508
|
```
|
|
471
509
|
|
|
472
|
-
Eller
|
|
510
|
+
Eller i en hvilken som helst klient som tar en `mcpServers`-blokk:
|
|
473
511
|
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
512
|
+
```json
|
|
513
|
+
{
|
|
514
|
+
"mcpServers": {
|
|
515
|
+
"mjolnir": { "command": "npx", "args": ["-y", "mjolnir-qa@latest", "mcp"] }
|
|
516
|
+
}
|
|
517
|
+
}
|
|
479
518
|
```
|
|
480
519
|
|
|
481
|
-
|
|
482
|
-
[docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
|
|
520
|
+
**Rekkverket betyr mer enn bekvemmeligheten.** Hvert funn i en overlevering bærer sin grense. **E2** sier _deterministisk: sjekk plasseringen og bruk rettelsen_. **E1** sier _KREVER BEKREFTELSE: observasjonen alene beviser ikke defekten_. En agent som retter E1 i blinde, undertrykker en regel eller redigerer en regel for å heve scoren, gjør nøyaktig det dette verktøyet finnes for å fange, så overleveringen sier det i prompten, rett ved siden av funnet.
|
|
483
521
|
|
|
484
|
-
|
|
522
|
+
<br />
|
|
485
523
|
|
|
486
|
-
|
|
487
|
-
i forhold til merge-base med `main`. Den dekker testfiler (`*.spec.*`,
|
|
488
|
-
`*.test.*`) pluss GitHub-workflowfiler og Playwright-konfigurasjoner i
|
|
489
|
-
diffen. Når merge-base ikke kan resolve — shallow clone, detached HEAD,
|
|
490
|
-
ikke-git-mål, annen default-branch — degraderer den ærlig: funn faller
|
|
491
|
-
tilbake til hel-fil-attribuering, og rapporten sier det. Overskriv
|
|
492
|
-
base-ref med `--base <ref>`.
|
|
524
|
+
## Tillit og sikkerhet
|
|
493
525
|
|
|
494
|
-
|
|
526
|
+
**Local-first, null telemetri.** Det finnes ingen nettverkskapabel API (`fetch`, `http`, `https`, `net`, `dns`, `dgram`, WebSocket) noe sted i `src/`, og [`privacy-network-isolation.spec.ts`](tests/contract/privacy-network-isolation.spec.ts) får bygget til å feile hvis en dukker opp. Den forbyr også `eval` og `new Function`. Å skanne kode du ikke stoler på, kjører den aldri: statisk analyse leser kildetekst, og kjøringsanalysen parser rapportfiler som allerede ligger på disken.
|
|
495
527
|
|
|
496
|
-
|
|
528
|
+
To forbehold: `npx` henter selv pakken før noe kjører, og garantien dekker `src/`, ikke tredjeparts plugins.
|
|
497
529
|
|
|
498
|
-
|
|
499
|
-
`.mjolnir.json`) i roten av repoet fininnstiller severity, gating og
|
|
500
|
-
scope — den endrer aldri deteksjonssemantikken.
|
|
530
|
+
**Plugins kjører ikke i en sandkasse.** JS-plugins (`mjolnir-rules/*.mjs`, eller npm-pakker oppført under `"plugins"`) kjører med fulle Node-rettigheter, samme tillitsmodell som ESLint- eller Vitest-plugins. Å laste dem er et aktivt valg **per skanning**: uten `--enable-plugins` (eller `MJOLNIR_ENABLE_PLUGINS=1`) lastes kildene deres aldri, og en melding på stderr lister hva som ble hoppet over. JSON-regelmanifester kjører ingen kode, og prefiksene for core-regel-ID-er er reservert, slik at et plugin ikke kan utgi seg for å være en av dem. Rapporter sårbarheter via [SECURITY.md](SECURITY.md).
|
|
501
531
|
|
|
502
|
-
|
|
503
|
-
| ------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
504
|
-
| `exclude` | `string[]` | Ekstra ignore-globs (gitignore-delmengde), oppå de innebygde defaultene |
|
|
505
|
-
| `gate` | `"advisory" \| "error" \| "warning"` | Hvilke severities som avslutter med ikke-null (default `error`; `advisory` blokkerer aldri) |
|
|
506
|
-
| `severityOverrides` | `{ "<RULE-ID>": severity }` | Omrangerer en regels funn for repoet ditt |
|
|
507
|
-
| `ignore` | `IgnoreEntry[]` | Undertrykker funn — **`reason` er påkrevd**; oppføringer utløper etter 90 dager (en eksplisitt `expires`-dato, eller config-filens last-modified-tid for oppføringer uten) |
|
|
508
|
-
| `plugins` | `string[]` | Regelpakker fra tredjepart (se [Tillitsmodellen](#tillitsmodellen)) |
|
|
532
|
+
**Det kjører på seg selv.** En verification trust engine har ingen troverdighet med mindre den selv kan verifiseres. Hver CI-kjøring skanner dette repositoriet med bygget den samme kjøringen produserte. Gaten feiler ved ethvert funn med alvorlighetsgrad error, og også ved en **delvis** skanning eller en **regel som krasjet**, fordi en avkortet selvskanning som ikke rapporterer noe, er nøyaktig det falske grønne dette prosjektet finnes for å fange. `mjolnir doctor` reviderer regelbasen på nytt i samme kjøring (fixture-brannmur, ærlige nivåer, taket for core-nivået), og en INCONCLUSIVE-sjekk feiler akkurat som en feilende sjekk. Begge rapportene lastes opp som byggeartefakter.
|
|
509
533
|
|
|
510
|
-
|
|
511
|
-
{
|
|
512
|
-
"gate": "error",
|
|
513
|
-
"exclude": ["legacy/**"],
|
|
514
|
-
"severityOverrides": { "QA-PW-141": "warning" },
|
|
515
|
-
"ignore": [
|
|
516
|
-
{
|
|
517
|
-
"ruleId": "QA-TEST-004",
|
|
518
|
-
"files": ["e2e/legacy-login.spec.ts"],
|
|
519
|
-
"reason": "Third-party widget needs a settle delay; tracked in JIRA-4821",
|
|
520
|
-
"expires": "2026-12-31"
|
|
521
|
-
}
|
|
522
|
-
]
|
|
523
|
-
}
|
|
524
|
-
```
|
|
534
|
+
### Exitkoder og maskinkontrakten
|
|
525
535
|
|
|
526
|
-
|
|
527
|
-
sti-ekskluderinger, samme dialekt som `exclude`. Bruk den for
|
|
528
|
-
maskinspesifikk støy; bruk `exclude` når listen hører hjemme i
|
|
529
|
-
versjonskontroll sammen med resten av konfigurasjonen.
|
|
530
|
-
- **CLI-overrides** — `--strict` (inkluder karantèneregler),
|
|
531
|
-
`--width <cols>` og `--ascii` / `--no-ascii` (terminalrendering),
|
|
532
|
-
`--tone blunt` (hardere meldinger), `--max-duration <sec>`
|
|
533
|
-
(begrenset delvis skanning).
|
|
534
|
-
- Regelundertrykkelse og deprecation-levetid:
|
|
535
|
-
[docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md).
|
|
536
|
-
|
|
537
|
-
`ignore`-oppføringer driver også den selvstendige kommandoen
|
|
538
|
-
`mjolnir suppressions`, som lister hva som er undertrykket nå, og når
|
|
539
|
-
hver oppføring utløper.
|
|
540
|
-
|
|
541
|
-
---
|
|
542
|
-
|
|
543
|
-
## 📐 Exit-koder & kontrakter
|
|
544
|
-
|
|
545
|
-
Frosne — trygge å bygge CI-logikk på:
|
|
546
|
-
|
|
547
|
-
| Exit-kode | Betydning |
|
|
548
|
-
| --------- | --------------------------------------------------------------------------- |
|
|
549
|
-
| `0` | Rent — ingen funn på eller over gaten |
|
|
550
|
-
| `1` | Funn på eller over gaten |
|
|
551
|
-
| `2` | Delvis skanning (tidsbudsjett brukt opp, ulesebare filer) — blokkerer aldri |
|
|
552
|
-
| `10` | Bruksfeil (ugyldig flagg, manglende mål) |
|
|
553
|
-
| `20` | Intern feil |
|
|
554
|
-
|
|
555
|
-
JSON/SARIF-rapporten er `schemaVersion: 1`. Regel-IDer
|
|
556
|
-
(`QA-<FAMILY>-NNN`) er uforanderlige én gang skipet og gjenbrukes
|
|
557
|
-
aldri.
|
|
558
|
-
|
|
559
|
-
---
|
|
560
|
-
|
|
561
|
-
## Tillitsmodellen
|
|
562
|
-
|
|
563
|
-
- **Local-first** — null nettverkskall under skanning. Ever. Null
|
|
564
|
-
telemetri.
|
|
565
|
-
- **Ingen falsk bevis** — vi sier heller «ukjent» enn «verifisert». Et
|
|
566
|
-
tomt repo får `score: null`, aldri en falsk 100.
|
|
567
|
-
- **Delvis ærlighet** — hvis analysen ble avkortet, sier utdataene det.
|
|
568
|
-
Aldri «complete» når det ikke er tilfelle.
|
|
569
|
-
- **FP-brannmur** — deteksjon kjører på et kommentar-/streng-fritt view
|
|
570
|
-
av koden (TypeScript-regler bruker kompilator-AST): et mønster inne i
|
|
571
|
-
en prosakommentar eller en doc-eksempelstreng er dokumentasjon, ikke
|
|
572
|
-
et funn.
|
|
573
|
-
- **Målt, ikke påstått** — bare regler med en false-positive-rate fra
|
|
574
|
-
ekte OSS-kode skiper i overskriftstierne (se
|
|
575
|
-
[Hvor mye er målt](#hvor-mye-er-målt)); skann-fotnoten og
|
|
576
|
-
`mjolnir rules --unmeasured` forteller deg hvilke som er hva.
|
|
577
|
-
- **Plugin-tillit og kjøringsport** — plugins er npm-pakker deklarert under
|
|
578
|
-
`"plugins"`; JS-moduler bor i `mjolnir-rules/*.mjs`.
|
|
579
|
-
Det er **ingen sandbox**: plugin-kode kjører med fulle
|
|
580
|
-
Node-privilegier, samme tillitsmodell som ESLint- eller
|
|
581
|
-
Vitest-plugins. Derfor er kodekjøring **opt-in ved hver skann**: gi
|
|
582
|
-
`--enable-plugins` (eller sett `MJOLNIR_ENABLE_PLUGINS=1`), ellers
|
|
583
|
-
lastes kildene IKKE — et høylig stderr-varsel lister nøyaktig hva som
|
|
584
|
-
ble hoppet over. Å skanne ukjent kode kjører den aldri. JSON-regelmanifest
|
|
585
|
-
(`mjolnir-rules/*.json`) berøres ikke: de deklarerer regex-mønstre og
|
|
586
|
-
kjører ingen kode av konstruksjon. Core regel-ID-prefiks er reservert
|
|
587
|
-
og avvises fra
|
|
588
|
-
plugins og eksterne regler mot spoofing.
|
|
589
|
-
- **Workspace-lokale eksterne regler** (mappebaserte, null nettverk) —
|
|
590
|
-
en `mjolnir-rules/`-mappe ved siden av skannemålet loader
|
|
591
|
-
tilpassede regler: JSON-filer deklarerer regex-mønstre (ingen kode
|
|
592
|
-
eksekveres), `.mjs`/`.js`-moduler eksporterer `rules` (full
|
|
593
|
-
Node-tillit, som plugins). Eksterne regler bærer samme
|
|
594
|
-
trust-metadata som core; de kan aldri skipe i core-tieren (core
|
|
595
|
-
krever en målt FP-rate fra corpus-sidecaren — en deklarert
|
|
596
|
-
`tier: "core"` klemmes til `extended`), adlyder tier-grenser og
|
|
597
|
-
sjekkes for drift: `mjolnir rules --md --external` renderer
|
|
598
|
-
katalogen fra de lastede filene (proveniens `external`), og
|
|
599
|
-
matrisegeneratoren aksepterer `--external <root>`.
|
|
600
|
-
|
|
601
|
-
---
|
|
602
|
-
|
|
603
|
-
## 🏗️ Arkitektur
|
|
536
|
+
Fryst, så du kan bygge CI-logikk på dem:
|
|
604
537
|
|
|
605
|
-
|
|
606
|
-
|
|
538
|
+
| Exitkode | Betydning |
|
|
539
|
+
| -------- | --------------------------------------------------------------------------- |
|
|
540
|
+
| `0` | Ren: ingen funn på eller over gaten |
|
|
541
|
+
| `1` | Funn på eller over gaten |
|
|
542
|
+
| `2` | Delvis skanning (tidsbudsjett brukt opp, uleselige filer). Blokkerer aldri. |
|
|
543
|
+
| `10` | Brukerfeil (feil flagg, manglende mål) |
|
|
544
|
+
| `20` | Intern feil |
|
|
607
545
|
|
|
608
|
-
|
|
609
|
-
mjolnir/
|
|
610
|
-
├── src/
|
|
611
|
-
│ ├── engine/ # LanguageAdapter interface + rule runner
|
|
612
|
-
│ ├── adapters/ # typescript · python · java · csharp · github-actions
|
|
613
|
-
│ ├── rules/ # rules across 8 families + the measured-FP table
|
|
614
|
-
│ ├── playwright/ # Selector Health Score engine
|
|
615
|
-
│ ├── discovery/ # workspace, frameworks, ignore resolution
|
|
616
|
-
│ ├── scope/ # git merge-base changed-scope engine
|
|
617
|
-
│ ├── scorer/ # transparent deduction table + prioritization
|
|
618
|
-
│ ├── reporter/ # terminal · JSON · SARIF 2.1 · Mermaid
|
|
619
|
-
│ ├── forensics/ # run-data ingestion · flake verdicts · triage
|
|
620
|
-
│ ├── config/ # mjolnir.config.json + suppressions
|
|
621
|
-
│ ├── plugins/ # third-party rule loading (no sandbox)
|
|
622
|
-
│ └── commands/ # every subcommand
|
|
623
|
-
└── tests/
|
|
624
|
-
├── fixtures/ # must-fire / must-not-fire per rule
|
|
625
|
-
└── golden/ # frozen score regression locks
|
|
626
|
-
```
|
|
546
|
+
`2` er bevisst forskjellig fra `0`: en skanning som ikke ble ferdig, har ikke funnet ingenting. Den er bare ikke ferdig med å lete.
|
|
627
547
|
|
|
628
|
-
|
|
548
|
+
Alt en maskin bruker (MCP-verktøyresultater, `--json`, SARIF 2.1), kommer fra ett kanonisk resultat under et versjonert, **bare additivt** skjema (`schemaVersion: 1`, `contractVersion: 1`), så ingen forbruker trenger å gjenskape betydningen fra rendret tekst. Se [maskinkontrakten](docs/machine-contract.md). Regel-ID-er (`QA-<FAMILY>-NNN`) kan ikke endres etter at de er levert, og gjenbrukes aldri.
|
|
629
549
|
|
|
630
|
-
|
|
631
|
-
ingen I/O, ingen globals. Nye økosystem = én adapter + dens regler.
|
|
632
|
-
- **TypeScript/Playwright bruker kompilator-AST** (ts-morph). Python,
|
|
633
|
-
Java og C# kjører på et delt regex-lag med maskerte kommentar/strenger.
|
|
634
|
-
- Et tree-sitter WASM AST-lag for Java og C# finnes og er neste
|
|
635
|
-
presisjonssteg — det er ennå ikke koblet på den synkrone
|
|
636
|
-
skanne-pipelinen.
|
|
550
|
+
<br />
|
|
637
551
|
|
|
638
|
-
|
|
552
|
+
## Hva Mjölnir ikke kan fortelle deg
|
|
639
553
|
|
|
640
|
-
|
|
554
|
+
- **Det kjører ikke testene dine.** En ren skanning er ikke en bestått suite.
|
|
555
|
+
- **Det kan ikke fortelle deg at en assertion er _feil_.** `expect(total).toBe(41)` ser sunn ut. Mjölnir finner tester som _ikke kan feile_ og pipelines som _ikke kan bli røde_, ikke tester som sjekker feil ting.
|
|
556
|
+
- **Det beviser ikke forretningsmessig korrekthet.** Ingenting her sier at produktet ditt gjør det kravet ba om.
|
|
557
|
+
- **100 er ikke bevis på en god suite.** Om suiten din dekker den reelle risikoen din, er et annet spørsmål, og det svarer ikke dette verktøyet på.
|
|
558
|
+
- **5 av 79 regler bygger på et anslag**, ikke en målt rate. Hver av dem sier det på sitt eget funn.
|
|
559
|
+
- **E1 er ikke E2.** Heuristiske funn er verdt å lese, ikke verdt å bruke i blinde.
|
|
560
|
+
- **Et tomt repo får `null`, aldri 100.**
|
|
561
|
+
- **En fil som heter `*.spec.ts` uten testdeklarasjoner, teller ikke som dekning.** Et repo der de eneste spec-filene inneholder imports eller typer (null `it`/`test`-kall), får `null`, ikke 100.
|
|
641
562
|
|
|
642
|
-
|
|
643
|
-
| ------------------------------------------------------ | ------------------------------------------- |
|
|
644
|
-
| [docs/SCORING.md](docs/SCORING.md) | Score-normalisering + bevisvektning |
|
|
645
|
-
| [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Målte false-positive-rater + metode |
|
|
646
|
-
| [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Regeltilstander, undertrykking, deprecation |
|
|
647
|
-
| [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | SARIF-utdata + editor/CI-oppsett |
|
|
648
|
-
| [docs/rules/](docs/rules/) | Generert katalog per regel |
|
|
649
|
-
| [CONTRIBUTING.md](CONTRIBUTING.md) | Dev-oppsett + bidragsflyt |
|
|
650
|
-
| [CHANGELOG.md](CHANGELOG.md) | Utgivelseshistorikk |
|
|
651
|
-
| [SECURITY.md](SECURITY.md) | Sårbarhetsrapportering |
|
|
563
|
+
<br />
|
|
652
564
|
|
|
653
|
-
|
|
565
|
+
## Dokumentasjon
|
|
654
566
|
|
|
655
|
-
|
|
567
|
+
Det fullstendige dokumentasjonsnettstedet finner du på <https://sergey-bar.github.io/Mjolnir/>.
|
|
656
568
|
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
[
|
|
569
|
+
| Dokument | Hva det inneholder |
|
|
570
|
+
| ------------------------------------------------------ | ------------------------------------------------ |
|
|
571
|
+
| [docs/SCORING.md](docs/SCORING.md) | Normalisering av scoren og vekting av evidens |
|
|
572
|
+
| [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md) | Kanonisk ordforråd: ett ord per begrep |
|
|
573
|
+
| [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Målte falsk-positiv-rater og metoden |
|
|
574
|
+
| [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Regeltilstander, nivåer, undertrykking, utfasing |
|
|
575
|
+
| [docs/VERSIONING.md](docs/VERSIONING.md) | Semver-policy, fryste flater, utfasingssyklus |
|
|
576
|
+
| [docs/machine-contract.md](docs/machine-contract.md) | Det kanoniske maskinlesbare resultatet |
|
|
577
|
+
| [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | SARIF-utdata og oppsett av editor eller CI |
|
|
578
|
+
| [docs/GITLAB-CI.md](docs/GITLAB-CI.md) | GitLab: Code Quality-rapport, MR-oppskrift, gate |
|
|
579
|
+
| [docs/rules/](docs/rules/) | Generert katalog per regel |
|
|
580
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | Utviklingsmiljø og bidragsflyt |
|
|
581
|
+
| [SUPPORT.md](SUPPORT.md) | Hvor du kan spørre, rapportere og få hjelp |
|
|
582
|
+
| [SECURITY.md](SECURITY.md) | Rapportering av sårbarheter |
|
|
583
|
+
| [CHANGELOG.md](CHANGELOG.md) | Versjonshistorikk |
|
|
661
584
|
|
|
662
|
-
|
|
585
|
+
### Status
|
|
663
586
|
|
|
664
|
-
|
|
587
|
+
**Versjon 1.** JSON-skjemaet og exitkodene er fryste kontrakter. TypeScript og Python har den bredeste målte dekningen. Java og C# er nyere; les dem gjennom [modenhetstabellen](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle). Hva som kommer videre, uten oppdiktede datoer: [det offentlige veikartet](https://sergey-bar.github.io/Mjolnir/reference/roadmap).
|
|
665
588
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
genererte regelen feiler bevisst
|
|
669
|
-
ekte deteksjon — en stub kan ikke skipes):
|
|
589
|
+
### Bidra
|
|
590
|
+
|
|
591
|
+
Nye regler er det enkleste første bidraget. Én kommando lager skjelettet til regelen med must-fire- **og** must-not-fire-fixtures. Den genererte regelen feiler bevisst sine egne fixtures til ekte deteksjon er skrevet, fordi en stubb som blir levert, er en regel ingen har målt:
|
|
670
592
|
|
|
671
593
|
```bash
|
|
672
594
|
mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
|
|
673
595
|
```
|
|
674
596
|
|
|
675
|
-
|
|
676
|
-
fixture-brannmur-lovene er i [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
597
|
+
Utviklingsmiljøet, kommandoene for de faste gatene og anti-creep- og fixture-brannmur-lovene står i [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
677
598
|
|
|
678
|
-
|
|
599
|
+
<br />
|
|
679
600
|
|
|
680
601
|
<div align="center">
|
|
681
602
|
|
|
682
|
-
|
|
603
|
+
<img src="assets/readme/closing.svg" alt="Kjør det på repoet ditt." width="100%" />
|
|
683
604
|
|
|
684
605
|
```bash
|
|
685
606
|
npx mjolnir-qa@latest
|
|
686
607
|
```
|
|
687
608
|
|
|
688
|
-
|
|
609
|
+
[Les veiledningen](https://sergey-bar.github.io/Mjolnir/guide/getting-started) · [Dokumentasjonsnettsted](https://sergey-bar.github.io/Mjolnir/) · [npm](https://www.npmjs.com/package/mjolnir-qa)
|
|
610
|
+
|
|
611
|
+
<br />
|
|
612
|
+
|
|
613
|
+
Ikke spør om testene besto.<br />
|
|
614
|
+
Spør om evidensen beviser at de fortjener tillit.
|
|
689
615
|
|
|
690
|
-
|
|
616
|
+
<sub>Laget av [Sergey Bar](https://www.linkedin.com/in/sergeybar/) · MIT-lisens</sub>
|
|
691
617
|
|
|
692
618
|
</div>
|