mjolnir-qa 1.0.9 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.gr.md CHANGED
@@ -1,399 +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. Τα τεστ σού λένε τι πέρασε. Το Mjölnir σού λέει τι μπορείς να εμπιστευτείς." width="100%" />
4
4
 
5
- ### Τα τεστ σου λένε ψέματα. Το αποδεικνύουμε.
5
+ <br />
6
6
 
7
- **Verification Trust Engine για QA.** Το Mjölnir ελέγχει suites τεστ και
8
- CI pipelines, αναφέρει δείκτη αξιοπιστίας και δείχνει ακριβώς πού
9
- σπάει η εμπιστοσύνη.
7
+ Το Mjölnir βρίσκει τεστ που δεν μπορούν να αποτύχουν και pipelines που δεν μπορούν να γίνουν κόκκινα,<br />
8
+ και στη συνέχεια βαθμολογεί πόσο μπορεί να εμπιστευτεί κανείς το αποτέλεσμα, με το τεκμήριο για κάθε πόντο.
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) | Ελληνικά | [Tiếng Việt](README.vi.md) | [עברית](README.he.md) | [العربية](README.ar.md) | [Bosanski](README.bs.md)
10
+ <br />
17
11
 
18
- > 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-08.
12
+ [![npm](https://img.shields.io/npm/v/mjolnir-qa.svg?style=flat-square&color=1F6F7C&labelColor=0A1119)](https://www.npmjs.com/package/mjolnir-qa)
13
+ [![downloads](https://img.shields.io/npm/dm/mjolnir-qa.svg?style=flat-square&color=1F6F7C&labelColor=0A1119)](https://www.npmjs.com/package/mjolnir-qa)
14
+ [![ci](https://img.shields.io/github/actions/workflow/status/Sergey-Bar/Mjolnir/ci.yml?branch=main&style=flat-square&label=ci&labelColor=0A1119)](https://github.com/Sergey-Bar/Mjolnir/actions/workflows/ci.yml)
15
+ [![coverage](https://img.shields.io/codecov/c/github/Sergey-Bar/Mjolnir?style=flat-square&color=1F6F7C&labelColor=0A1119&label=coverage)](https://codecov.io/gh/Sergey-Bar/Mjolnir)
16
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/Sergey-Bar/Mjolnir/badge)](https://scorecard.dev/viewer/?uri=github.com/Sergey-Bar/Mjolnir)
17
+ [![license](https://img.shields.io/badge/license-MIT-1F6F7C.svg?style=flat-square&labelColor=0A1119)](LICENSE)
18
+ [![node](https://img.shields.io/badge/node-%E2%89%A5%2022.18-1F6F7C.svg?style=flat-square&labelColor=0A1119)](https://nodejs.org)
19
19
 
20
20
  ```bash
21
21
  npx mjolnir-qa@latest
22
22
  ```
23
23
 
24
- **Είναι τα τεστ σου άξια εμπιστοσύνης;**
24
+ [Δείτε το σε δράση](#δείτε-το-σε-δράση) · [Γρήγορη εκκίνηση](#γρήγορη-εκκίνηση) · [Τι βρίσκει](#τι-βρίσκει-το-mjölnir) · [Βαθμολογία](#η-βαθμολογία-αξιοπιστίας) · [Τεκμήρια](#το-μοντέλο-τεκμηρίωσης) · [Ανάλυση εκτελέσεων](#ανάλυση-εκτελέσεων-τεστ) · [CI](#ακεραιότητα-ci) · [Πράκτορες](#πράκτορες-τν) · [Ασφάλεια](#εμπιστοσύνη-και-ασφάλεια) · [Όρια](#τι-δεν-μπορεί-να-σας-πει-το-mjölnir) · [Τεκμηρίωση](#τεκμηρίωση)
25
+
26
+ <details>
27
+ <summary>Διαβάστε σε άλλη γλώσσα — 22 μεταφράσεις</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) | Ελληνικά | [Tiếng Việt](README.vi.md) | [עברית](README.he.md) | [العربية](README.ar.md) | [Bosanski](README.bs.md)
30
+
31
+ > 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-15.
32
+
33
+ <!-- Source hash: 3541b09e8d04 -->
25
34
 
26
- [Δες το σε δράση](#-δες-το-σε-δράση) ·
27
- [Γρήγορη εκκίνηση](#-γρήγορη-εκκίνηση) ·
28
- [Τι ελέγχει](#-τι-ελέγχει-το-mjölnir) ·
29
- [Σκόρ](#πώς-λειτουργεί-το-σκόρ) ·
30
- [CI](#-ενσωμάτωση-ci) · [Διαμόρφωση](#διαμόρφωση) ·
31
- [Τεκμηρίωση](#-τεκμηρίωση)
35
+ </details>
32
36
 
33
37
  </div>
34
38
 
35
- ---
39
+ <br />
40
+
41
+ ## Ένα πράσινο τικ είναι ισχυρισμός, όχι απόδειξη
42
+
43
+ Ένα πράσινο τικ σημαίνει ότι το pipeline δεν απέτυχε. Δεν σημαίνει ότι τα τεστ εκτελέστηκαν ή ότι θα μπορούσαν να αποτύχουν. Κάθε ένα από αυτά περνά πράσινο:
44
+
45
+ - ένα `.only` σε commit που εκτέλεσε 3 τεστ αντί για 900
46
+ - `continue-on-error: true` στο job που έπρεπε να μπλοκάρει
47
+ - `|| true` μετά την εντολή των τεστ
48
+ - ένα τεστ που δεν ελέγχει τίποτα ή έχει άδειο σώμα
49
+ - ένα wrapper επαναλήψεων που μετατρέπει μια πραγματική αποτυχία σε τυχερή επιτυχία
50
+ - μια αναφορά που το workflow ανεβάζει αλλά δεν δημιούργησε ποτέ
51
+ - ένα σταθερό sleep που κρατά όρθια μια συνθήκη ανταγωνισμού
52
+
53
+ Κανένα δεν κάνει το pipeline κόκκινο, και το καθένα φαίνεται σκόπιμο στο review. Γι' αυτό επιβιώνουν. Ιδού το Mjölnir να διαβάζει ένα πραγματικό:
54
+
55
+ <p align="center">
56
+ <img src="assets/readme/scan.svg" alt="Το CI workflow του αποθετηρίου επίδειξης, διαβασμένο γραμμή προς γραμμή. Το Mjölnir σημειώνει κάθε εύρημα στη γραμμή που ανέφερε, με τον κανόνα του, τι είναι λάθος, το επίπεδο τεκμηρίωσης και το μετρημένο ποσοστό ψευδώς θετικών." width="800" />
57
+ </p>
58
+
59
+ <sub>Κάθε εύρημα που ανέφερε η σάρωση επίδειξης για αυτό το workflow, στη γραμμή που ανέφερε. Δημιουργείται με `npm run docs:readme-brand` από το [`demo-report.json`](assets/readme/demo-report.json) και κλειδώνεται έναντι αποκλίσεων στο CI.</sub>
60
+
61
+ **Αυστηρή λειτουργία.** Οι πιο επιθετικές ανιχνεύσεις — `.only`, `continue-on-error`, κενά τεστ, κατάχρηση επανάληψης — ζουν στο επίπεδο καραντίνας. Τρέχουν μόνο με `--strict` και περιορίζονται σε σοβαρότητα `info`: ειδοποιούν, δεν μπλοκάρουν ποτέ. Η προεπιλεγμένη σάρωση (`npx mjolnir-qa@latest` χωρίς `--strict`) καλύπτει μόνο βασικούς και εκτεταμένους κανόνες. Προσθέστε `--strict` όταν θέλετε και το επίπεδο συμβουλών.
62
+
63
+ Το Mjölnir διαβάζει τη σουίτα, τα CI workflows και, αν υπάρχει, την αναφορά μιας πραγματικής εκτέλεσης. Δεν εκτελεί τα τεστ σας, δεν εγκαθιστά τις εξαρτήσεις σας και δεν εκτελεί τον κώδικα που σαρώνει. Κι όταν δεν έχει τεκμήρια, το λέει αντί να επινοεί βεβαιότητα:
64
+
65
+ | Κατάσταση | Τι αναφέρει το Mjölnir |
66
+ | ------------------------------------------------------- | ----------------------------------------------------------------------- |
67
+ | Δεν βρέθηκαν δηλώσεις τεστ | Βαθμολογία `null`, εμφανίζεται ως **UNKNOWN**. Ποτέ ένα επινοημένο 100. |
68
+ | Χωρίς baseline ή συγκρίσιμη αναθεώρηση | **UNKNOWN**, με ρητή αιτία. Ποτέ ένα υποτιθέμενο 0. |
69
+ | Η σάρωση διακόπηκε (χρονικό όριο, μη αναγνώσιμα αρχεία) | **PARTIAL**, έξοδος `2`. Ποτέ δεν παρουσιάζεται ως καθαρή. |
70
+
71
+ <p align="center">
72
+ <img src="assets/readme/how-it-works.svg" alt="Πώς λειτουργεί το Mjölnir. Διαβάζει στατικά τη σουίτα τεστ και το CI pipeline, καθώς και την αναφορά μιας πραγματικής εκτέλεσης όταν υπάρχει. Σταθμίζει κάθε εύρημα με βάση το επίπεδο τεκμηρίωσης και το επίπεδο εμπιστοσύνης του, όπου μόνο μια πραγματική εκτέλεση φτάνει τα L3 έως L5, και παράγει ευρήματα, μια βαθμολογία αξιοπιστίας και μια πύλη CI με παγωμένους κωδικούς εξόδου. Στον βρόχο του πράκτορα, η τεχνητή νοημοσύνη γράφει τη διόρθωση και το Mjölnir σαρώνει ξανά για να την αποδείξει." width="880" />
73
+ </p>
74
+
75
+ <sub>Σχεδιασμένο για αυτή τη σελίδα και εμφανίζεται σε κλίμακα 1:1. Δημιουργείται με `npm run docs:readme-brand` και κλειδώνεται έναντι αποκλίσεων στο CI· η βαθμολογία, οι μετρήσεις και το ID του κανόνα προέρχονται από τα [`script.demo.json`](assets/video/script.demo.json), [`demo-report.json`](assets/readme/demo-report.json) και το μητρώο κανόνων, ποτέ δεν πληκτρολογούνται με το χέρι. Η ίδια εικόνα ως αφίσα: [`architecture.svg`](assets/readme/architecture.svg).</sub>
76
+
77
+ <br />
78
+
79
+ ## Δείτε το σε δράση
36
80
 
37
- ## 🎬 Δες το σε δράση
81
+ Μια πραγματική σάρωση του [`examples/demo-repo`](examples/demo-repo), μιας μικρής σουίτας Playwright με CI workflow. Εδώ πήγαν οι πόντοι της:
38
82
 
39
83
  <p align="center">
40
- <img src="assets/readme/demo.svg" alt="Η πλήρης αναφορά --verbose του Mjölnir σε ένα demo repo: WORTHINESS 75/100 NEEDS WORK, ανάλυση διαγνώσεων ανά κατηγορία, λίστα FIX THIS FIRST και κάθε εύρημα με ID κανόνα και αριθμό γραμμής σε CI, Playwright, υγιεινή τεστ και κανόνες Python" width="900" />
84
+ <img src="assets/readme/terminal-hero.svg" alt="Η ανάλυση αφαιρέσεων του Mjölnir: WORTHINESS 80/100 WORTHY, η βαθμολογία ανά κατηγορία, το πλαίσιο αφαιρέσεων ανά σοβαρότητα και μια λίστα FIX THIS FIRST" width="520" />
41
85
  </p>
42
86
 
43
- <sub>Η πλήρης έξοδος του `npx mjolnir-qa ./examples/demo-repo --verbose`,
44
- αποδομένη από τον πραγματικό reporter — τίποτα περικομμένο.
45
- Αναδημιουργείται με `npm run docs:demo`;
46
- [`tests/demo-asset-reproducibility.spec.ts`](tests/demo-asset-reproducibility.spec.ts)
47
- ρίχνει το CI αν ο artifact αποκλίνει από ό,τι τυπώνει το εργαλείο.</sub>
87
+ <sub>Δημιουργείται με `npm run docs:hero` από πραγματική σάρωση και κλειδώνεται έναντι αποκλίσεων στο CI. Η πλήρης αναφορά `--verbose` της ίδιας σάρωσης είναι το [`demo.svg`](assets/readme/demo.svg) (`npm run docs:demo`).</sub>
88
+
89
+ <details>
90
+ <summary><strong>Δείτε το</strong> — μια σάρωση, η διόρθωση που τυπώνει και η νέα σάρωση που την αποδεικνύει</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="Ένα καρέ της εγγραφής επίδειξης: το npx mjolnir-qa@latest σαρώνει το αποθετήριο επίδειξης σε ένα παράθυρο τερματικού" width="900" />
97
+ </a>
98
+ </p>
48
99
 
49
- **Τι μόλις συνέβη:**
100
+ <sub>Αποδόθηκε καρέ προς καρέ από πραγματική σάρωση με `npm run docs:video`· ποτέ δεν καταγράφηκε από την οθόνη. Επιλέξτε το καρέ για να ανοίξετε το [`mjolnir-demo.mp4`](assets/video/mjolnir-demo.mp4).</sub>
50
101
 
51
- 1. Το Mjölnir ανακάλυψε τα Playwright specs, τη διαμόρφωσή του, το CI
52
- workflow και ένα αρχείο τεστ Python — τέσσερις γλώσσες/μορφές, ένα
53
- πέρασμα.
54
- 2. Βρήκε στοιχεία που εξασθενούν την εμπιστοσύνη στη σουίτα — ένα
55
- `continue-on-error` που κρύβει job, ένα `|| true` που καταπίνει exit
56
- code, σκληρά sleeps, εύθραυστο selector, σκληρά staging URL,
57
- αναμονή `networkidle`.
58
- 3. Μετέτρεψε το καθένα σε συγκεκριμένο εύρημα με ID κανόνα, τοποθεσία
59
- και fix — και σε ένα σκόρ με το οποίο μπορείς να gated ένα PR.
102
+ </details>
60
103
 
61
104
  ### Ένα εύρημα από κοντά
62
105
 
63
- Τρέξε `mjolnir explain QA-CI-001` στο πρώτο εύρημα παραπάνω και θα
64
- πάρεις:
106
+ Κάθε εύρημα απαντά σε τέσσερα ερωτήματα: πού βρίσκεται, πόσο σίγουρο είναι το Mjölnir, πόσο συχνά κάνει λάθος ο κανόνας και πώς διορθώνεται.
107
+
108
+ <p align="center">
109
+ <img src="assets/readme/finding-anatomy.svg" alt="Το πρώτο εύρημα της σάρωσης επίδειξης, ακριβώς όπως το τυπώνει το τερματικό, με τα τέσσερα μέρη του σημειωμένα: πού, πόσο σίγουρο, πόσο συχνά κάνει λάθος ο κανόνας, και η διόρθωση." width="100%" />
110
+ </p>
111
+
112
+ Το `mjolnir explain QA-CI-001` τυπώνει ολόκληρο το ιστορικό εμπιστοσύνης ενός κανόνα, μαζί με το μετρημένο ποσοστό ψευδώς θετικών και το επίπεδο που του εξασφάλισε αυτό το ποσοστό:
65
113
 
66
114
  ```text
67
- ▚ QA-CI-001 — continue-on-error masks a failing verification gate
115
+ ▍ QA-CI-001 — continue-on-error masks a failing verification gate
68
116
 
69
117
  Severity: error
70
118
  Confidence: high
119
+ Tier: quarantine
71
120
  Evidence: E2
72
- Measured FP: not yet measured — this rule ships on assumption (see docs/FP-AUDIT.md)
121
+ QA impact: False-green risk (FALSE-GREEN)
122
+ Measured FP: 11% (19 hand-classified corpus verdicts)
123
+ FP risk: low (author estimate)
124
+ Languages: yaml
125
+ Frameworks: github-actions, azure-pipelines
73
126
 
74
127
  WHAT WAS FOUND (real detector output, not a mockup)
75
128
  Job `security-scan` runs a verification gate under `continue-on-error: true`.
76
129
 
77
130
  WHY IT MATTERS
78
- This job can fail every day and CI will still show green. The checkmark
79
- on this workflow cannot be trusted.
131
+ This job can fail every day and CI will still show green. The checkmark on
132
+ this workflow cannot be trusted.
80
133
 
81
134
  HOW TO FIX
82
135
  Remove continue-on-error, or scope it to individual non-blocking steps only.
83
- ```
84
136
 
85
- Αυτή είναι η μονάδα αξίας: όχι νίττα στυλ, αλλά ένα σημείο όπου το CI
86
- σου σου λέει ότι κάτι πέρασε ενώ δεν πέρασε.
137
+ Example from this rule's own must-fire fixture: QA-CI-001/must-fire/masked.yml
87
138
 
88
- ---
139
+ WHAT WOULD CHANGE THE VERDICT
140
+ - a run report next to the scan target (mjolnir.report.json or test-results/)
141
+ corroborating this file lifts its findings to L3–L5
142
+ - a documented suppression (mjolnir.config.json) lowers the finding count
143
+ without claiming correctness
144
+ - quarantine findings run only under --strict and are advisory (E0) — they can
145
+ never gate CI
89
146
 
90
- ## ⚡ Γρήγορη εκκίνηση
147
+ NEXT ACTION
148
+ Fix the first occurrence, then re-run: `mjolnir --scope changed`. Every
149
+ occurrence of this rule is listed in the scan output.
91
150
 
92
- Τρέξ' το σε ένα repo για πλήρη αναφορά και δείκτη αξιοπιστίας:
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.
93
154
 
94
- ```bash
95
- npx mjolnir-qa@latest
155
+ Docs: mjolnir rules --md (full catalog, this rule included)
96
156
  ```
97
157
 
98
- **Στο CI το προϊόν είναι μία εντολή.** Σκανάρει μόνο ό,τι άγγιξε το
99
- branch και βγαίνει μη μηδενικά σε νέα προβλήματα:
158
+ Αυτή είναι η μονάδα αξίας: ένα σημείο όπου το CI αναφέρει μια επιτυχία που δεν κέρδισε.
159
+
160
+ <br />
161
+
162
+ ## Γρήγορη εκκίνηση
100
163
 
101
164
  ```bash
102
- npx mjolnir-qa@latest --scope changed
165
+ npx mjolnir-qa@latest
103
166
  ```
104
167
 
105
- Ρίξε αυτό σε ένα PR check — το `mjolnir ci install` γράφει το workflow —
106
- και τελείωσες. Όλα τα άλλα είναι προαιρετικά.
168
+ Σαρώνει τον τρέχοντα κατάλογο και τυπώνει το Trust Report: τι βρήκε, πόσο μπορείτε να το εμπιστευτείτε, γιατί και τι να κάνετε μετά. Τερματίζει με `0` όταν δεν βρέθηκε τίποτα στο επίπεδο της πύλης ή πάνω από αυτό.
107
169
 
108
- | Εντολή | Τι κάνει |
109
- | ----------------------------------- | ------------------------------------------------------------ |
110
- | `mjolnir` | Πλήρες σκαν repo + δείκτης αξιοπιστίας |
111
- | `mjolnir --scope changed` | Μόνο ό,τι引入ε το branch σου — η μορφή CI |
112
- | `mjolnir ci install` | Δημιουργεί το συμβουλευτικό PR workflow |
113
- | `mjolnir explain QA-CI-001` | Τι / γιατί / fix + μετρημένο ποσοστό FP για έναν κανόνα |
114
- | `mjolnir rules --unmeasured` | Οι κανόνες που τρέχουν με υπόθεση, όχι με μέτρημα |
115
- | `mjolnir --json` / `--format sarif` | Μηχανικά αναγνώσιμο / GitHub Code Scanning |
116
- | `mjolnir --strict` | Εκτελεί και κανόνες tier quarantine (υψηλότερος κίνδυνος FP) |
117
-
118
- <details>
119
- <summary><strong>Όταν κάτι είναι flaky</strong></summary>
170
+ Στο CI, σαρώστε μόνο ό,τι εισήγαγε το branch, ώστε μια παλιά σουίτα να μη πνίξει το πρώτο σας pull request:
120
171
 
121
- | Εντολή | Τι κάνει |
122
- | ----------------------------------- | --------------------------------------------------------------- |
123
- | `mjolnir forensics ./test-results/` | Πραγματικά δεδομένα runs → ετυμηγορίες `TRUE-FLAKE`, `FLAKY.md` |
124
- | `mjolnir triage ./test-results/` | Πρόταση καραντίνας από ιστορικό εκτέλεσης |
125
- | `mjolnir pw-report ./test-results/` | Σύνοψη run Playwright — retries / flakes / τα πιο αργά |
126
- | `mjolnir doctor:playwright` | Βαθύ σκαν μόνο Playwright + Selector Health Score |
172
+ ```bash
173
+ npx mjolnir-qa@latest --scope changed
174
+ ```
127
175
 
128
- </details>
176
+ Το `mjolnir ci install` το γράφει ως GitHub Actions workflow, χρησιμοποιώντας το [action](https://github.com/Sergey-Bar/Mjolnir#readme) καρφιτσωμένο στο κύριο tag `v1` (ή απλό `npx` με `--no-action`). Παραμένει συμβουλευτικό μέχρι να αποφασίσετε ότι πρέπει να μπλοκάρει.
177
+
178
+ | Εντολή | Τι κάνει |
179
+ | ----------------------------------- | ------------------------------------------------------------------- |
180
+ | `mjolnir` | Trust Report: ετυμηγορία, βεβαιότητα, επόμενη ενέργεια |
181
+ | `mjolnir --scope changed` | Μόνο ό,τι εισήγαγε το branch σας (η μορφή για CI) |
182
+ | `mjolnir ci install` | Δημιουργεί το συμβουλευτικό workflow για PR (βασισμένο στο action) |
183
+ | `mjolnir explain QA-CI-001` | Τι, γιατί και διόρθωση, συν το μετρημένο ποσοστό FP |
184
+ | `mjolnir why src/a.spec.ts:42` | Γιατί σημειώθηκε ακριβώς αυτή η γραμμή. Δεν μπλοκάρει ποτέ. |
185
+ | `mjolnir forensics ./test-results/` | Τεκμήρια χρόνου εκτέλεσης από πραγματική εκτέλεση |
186
+ | `mjolnir trust-report` | Αυτόνομο Trust Artifact (md + json) |
187
+ | `mjolnir handoff` | Σχέδιο αποκατάστασης για πράκτορα κώδικα |
188
+ | `mjolnir --json` / `--format sarif` | Έξοδος αναγνώσιμη από μηχανές, GitHub Code Scanning |
189
+ | `mjolnir --format codequality` | Αναφορά GitLab Code Quality (artifact του widget του MR) |
190
+ | `mjolnir --strict` | Εκτελεί επίσης κανόνες επιπέδου quarantine (υψηλότερος κίνδυνος FP) |
129
191
 
130
192
  <details>
131
- <summary><strong>Σπάνια / αναφορές</strong></summary>
132
-
133
- | Εντολή | Τι κάνει |
134
- | ------------------------------- | ------------------------------------------------------- |
135
- | `mjolnir fix --dry-run` / `fix` | Ασφαλή αυτόματα fix με απόδειξη |
136
- | `mjolnir baseline` / `diff` | Στιγμιότυπο ευρημάτων, μετά αναφορά μόνο νέων/χειρότερα |
137
- | `mjolnir impact --since <ref>` | Τι άλλαξε από προηγούμενο commit |
138
- | `mjolnir debt` | Μητρώο τεχνολογικού χρέους τεστ με μοντέλο κόστους |
139
- | `mjolnir handover` | Χάρτης onboarding της σουίτας για νέο QA |
140
- | `mjolnir stats` | Τοπικοί σωρευτικοί μετρητές όλων των fix που είδε |
141
- | `mjolnir badge` | shields.io endpoint JSON + snippet |
142
- | `mjolnir rules --md` | Πλήρης κατάλογος κανόνων (JSON ή Markdown) |
143
- | `mjolnir doctor` | Αυτοέλεγχος της ίδιας της βάσης κανόνων του Mjölnir |
144
- | `mjolnir create-rule <ID>` | Σκαφφάρει νέο κανόνα + fixtures |
145
- | `mjolnir --format mermaid` | Διάγραμμα αρχιτεκτονικής τεστ για σχόλιο PR |
193
+ <summary><strong>Όλες οι υπόλοιπες εντολές</strong> — διαλογή ασταθών τεστ, αναφορές, διακυβέρνηση</summary>
194
+
195
+ <br />
196
+
197
+ | Εντολή | Τι κάνει |
198
+ | ----------------------------------- | ------------------------------------------------------------------------------------- |
199
+ | `mjolnir --classic` | Το banner βαθμολογίας πριν από το Trust Report |
200
+ | `mjolnir explain verdict` | Γιατί η ετυμηγορία της αποθηκευμένης σάρωσης είναι αυτή που είναι |
201
+ | `mjolnir triage ./test-results/` | Καθοδηγούμενη διαλογή. Κάθε γραμμή τελειώνει με μια επόμενη ενέργεια. |
202
+ | `mjolnir pw-report ./test-results/` | Σύνοψη εκτέλεσης Playwright: επαναλήψεις, ασταθή τεστ, τα πιο αργά |
203
+ | `mjolnir doctor:playwright` | Βαθιά σάρωση μόνο για Playwright συν Selector Health Score |
204
+ | `mjolnir fix --dry-run` / `fix` | Ασφαλείς αυτόματες διορθώσεις, καθεμία ξανασαρωμένη για να αποδειχθεί ότι εφαρμόστηκε |
205
+ | `mjolnir baseline` / `diff` | Στιγμιότυπο των ευρημάτων, και μετά αναφορά μόνο των νέων ή χειρότερων |
206
+ | `mjolnir impact --since <ref>` | Τι εισήγαγε και τι επέλυσε ένα commit |
207
+ | `mjolnir summary` | Σημειώσεις CI και σύνοψη step από μια αναφορά |
208
+ | `mjolnir pr-comment` | Ένα στοχευμένο σχόλιο PR, σε Markdown |
209
+ | `mjolnir debt` | Μητρώο τεχνικού χρέους τεστ με μοντέλο κόστους |
210
+ | `mjolnir handover` | Χάρτης γνωριμίας με τη σουίτα για νέο μηχανικό QA |
211
+ | `mjolnir init` | Ανιχνεύει frameworks, τυπώνει λίστα ελέγχου ρύθμισης |
212
+ | `mjolnir suppressions` | Εμφανίζει τα κατασταλμένα ευρήματα, για διακυβέρνηση |
213
+ | `mjolnir rules --unmeasured` | Οι κανόνες που λειτουργούν με υπόθεση, όχι με μέτρηση |
214
+ | `mjolnir rules --md` | Πλήρης κατάλογος κανόνων (JSON ή Markdown) |
215
+ | `mjolnir doctor` | Αυτοέλεγχος της βάσης κανόνων του ίδιου του Mjölnir |
216
+ | `mjolnir create-rule <ID>` | Δημιουργεί σκελετό για νέο κανόνα και τα fixtures του |
217
+ | `mjolnir stats` | Τοπικοί μετρητές όλων των διορθώσεων που έχουν εμφανιστεί |
218
+ | `mjolnir badge` | JSON endpoint του shields.io και απόσπασμα κώδικα |
219
+ | `mjolnir --cache` | Επαυξητικές νέες σαρώσεις μέσω τοπικής cache ετυμηγοριών |
220
+ | `mjolnir --format mermaid` | Διάγραμμα αρχιτεκτονικής τεστ για σχόλιο PR |
221
+
222
+ Το `mjolnir help <command>` τυπώνει τη χρήση, παραδείγματα και το επόμενο βήμα για οποιαδήποτε από αυτές.
146
223
 
147
224
  </details>
148
225
 
149
- Εγκατάσταση globally αντί για `npx` αν προτιμάς: `npm i -g mjolnir-qa`.
150
- Απαιτεί Node.js ≥ 22.18. Λειτουργεί σε Windows, macOS και Linux.
151
-
152
- ---
153
-
154
- ## 👥 Για ποιον είναι;
155
-
156
- - **QA / SDET** που έχουν e2e ή integration σουίτα και χρειάζονται
157
- αποδείξεις ότι η σουίτα αξίζει πραγματικά το πράσινο τσεκ που
158
- παράγει.
159
- - **Ομάδες Platform / DevEx** υπεύθυνες για ακεραιότητα CI και release
160
- gates — οι άνθρωποι που νοιάζονται να μην μετατρέψει ποτέ ένα
161
- `continue-on-error` βουβά κόκκινο pipeline σε πράσινο.
162
- - **Maintainers OSS** που θέλουν φτηνή, πάντα ενεργή πύλη επαλήθευσης
163
- που τρέχει τοπικά και σε CI χωρίς κλήσεις δικτύου.
164
-
165
- ---
226
+ Απαιτεί **Node.js ≥ 22.18** σε Windows, macOS ή Linux. Προτιμάτε καθολική εγκατάσταση; `npm i -g mjolnir-qa`. Το ελάχιστο όριο προέρχεται από την αλυσίδα εργαλείων build (το tsdown το στοχεύει και το pipeline κυκλοφορίας κάνει smoke tests σε αυτό)· οι εξαρτήσεις χρόνου εκτέλεσης δεν χρειάζονται τίποτα περισσότερο.
166
227
 
167
- ## 🔨 Τι ελέγχει το Mjölnir
228
+ <br />
168
229
 
169
- | | |
170
- | --- | ------------------------------------------------------------------------------------------------------------------------------------ |
171
- | ⚖️ | **Δείκτης αξιοπιστίας** — ένας αριθμός, διαφανής πίνακας αφαιρέσεων, καμία μαύρη κάψουλα |
172
- | 🎭 | **Selector Health Score** — βαθμολογεί τα Playwright locators σου, όχι μόνο το pass rate |
173
- | 🔬 | **Δικαστική ανάλυση runtime** — διαβάζει πραγματικά δεδομένα Playwright/JUnit για να πιάσει `TRUE-FLAKE`, όχι μόνο στατικές εικασίες |
174
- | 🚨 | **Κανόνες ακεραιότητας CI** — πιάνει `continue-on-error`, `\|\| true` και άλλα κόλπα ψεύτικου πράσινου |
175
- | 🐍 | **Και τα τέσσερα Playwright bindings** — TypeScript, Python, Java, C#/.NET — plus pytest, JUnit/TestNG και CI workflows |
176
- | 🔒 | **Local-first** — μηδενικές κλήσεις δικτύου κατά το σκαν, μηδενική τηλεμετρία, τρέχει σε δευτερόλεπτα |
230
+ ## Τι βρίσκει το Mjölnir
177
231
 
178
- ### Οι κανόνες
232
+ <p align="center">
233
+ <img src="assets/readme/stack.svg" alt="Λειτουργεί με τη στοίβα σας: οι γλώσσες, τα frameworks τεστ και τα συστήματα CI που καλύπτουν οι κανόνες του, από το μητρώο κανόνων." width="100%" />
234
+ </p>
179
235
 
180
- Κάθε κανόνας έρχεται με fixtures must-fire **και** must-not-fire.
181
- Κανόνας που ενεργοποιείται στη δική του αρνητική fixture δεν μπορεί να
182
- να κυκλοφορήσει — αυτός είναι ο τείχος των false positives.
236
+ **79 κανόνες** σε τέσσερις οικογένειες — υγιεινή τεστ, ποιότητα τεστ, Playwright και ακεραιότητα CI — για TypeScript και JavaScript, Python, Java, C# και YAML του GitHub Actions. Καλύπτουν το Playwright και στα τέσσερα bindings, καθώς και pytest, JUnit, TestNG, NUnit, xUnit, MSTest, Jest, Vitest και Mocha, με αρχική κάλυψη για Cypress και Selenium. Εννέα από αυτούς, για να φανεί η μορφή:
183
237
 
184
- <details>
185
- <summary><strong>Υγιεινή τεστ</strong></summary>
186
-
187
- | ID | Κανόνας | Severity |
188
- | ----------- | ----------------------------------------------------- | -------- |
189
- | QA-TEST-001 | Commitμένος focused τεστ (`.only`, `fit`) | error |
190
- | QA-TEST-002 | Παραλειμένο τεστ χωρίς δικαιολογία | error |
191
- | QA-TEST-002 | Παραλειμένο τεστ με καταγεγραμμένη δικαιολογία | warning |
192
- | QA-TEST-003 | Τεστ χωρίς assertions | error |
193
- | QA-TEST-004 | Σκληρό sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning |
194
- | QA-TEST-006 | Κατάχρηση retry που κρύβει flakiness | warning |
195
- | QA-TEST-010 | Κενό σώμα τεστ | error |
238
+ | ID | Κανόνας | Σοβαρότητα | Επίπεδο |
239
+ | ------------ | ----------------------------------------------------------------------------- | ---------- | ---------- |
240
+ | QA-CI-001 | Το `continue-on-error` κρύβει μια αποτυχημένη πύλη επαλήθευσης | error | quarantine |
241
+ | QA-CI-009 | Ο κωδικός εξόδου των τεστ δεν μεταφέρεται (`\|` χωρίς pipefail, αλυσίδες `;`) | error | extended |
242
+ | QA-TEST-001 | Εστιασμένο τεστ σε commit (`.only`, `fit`) | error | quarantine |
243
+ | QA-TEST-003 | Τεστ χωρίς ισχυρισμούς | error | quarantine |
244
+ | QA-TQUAL-009 | Ισχυρισμός σε promise χωρίς await | error | quarantine |
245
+ | QA-PW-002 | Ισχυρισμός σε locator χωρίς await | error | core |
246
+ | QA-PW-004 | Εύθραυστοι επιλογείς CSS/XPath | warning | quarantine |
247
+ | QA-PY-002 | Παραλειπόμενο τεστ (`skip`, μη αυστηρό `xfail`) | warning | core |
248
+ | QA-CS-103 | Μέθοδος τεστ χωρίς ισχυρισμούς | error | core |
196
249
 
197
- </details>
250
+ Ο πλήρης κατάλογος δημιουργείται από το μητρώο, ποτέ δεν συντηρείται με το χέρι: `mjolnir rules --md`, [`docs/rules/`](docs/rules/) ή ο [οδηγός για το τι ελέγχει](https://sergey-bar.github.io/Mjolnir/guide/what-it-checks).
198
251
 
199
252
  <details>
200
- <summary><strong>Ποιότητα τεστ</strong></summary>
201
-
202
- | ID | Κανόνας | Severity |
203
- | ------------ | ----------------------------- | -------- |
204
- | QA-TQUAL-002 | Ταυτολογική assertion | error |
205
- | QA-TQUAL-009 | Assertion promise χωρίς await | error |
206
- | QA-TQUAL-011 | Σχολιασμένα τεστ | warning |
253
+ <summary><strong>Κάθε κανόνας που αναφέρεται σε αυτό το README</strong>, σε έναν πίνακα</summary>
254
+
255
+ <br />
256
+
257
+ > Οι κανόνες `quarantine` εκτελούνται μόνο με `--strict` και δεν μπλοκάρουν ποτέ (περιορίζονται σε info). Η σοβαρότητα που εμφανίζεται είναι αυτή που όρισε ο δημιουργός.
258
+
259
+ | ID | Οικογένεια | Κανόνας | Σοβαρότητα | Επίπεδο |
260
+ | ------------ | ---------- | ----------------------------------------------------------------------- | ---------- | ---------- |
261
+ | QA-TEST-001 | Υγιεινή | Εστιασμένο τεστ σε commit (`.only`, `fit`) | error | quarantine |
262
+ | QA-TEST-002 | Υγιεινή | Παραλειπόμενο τεστ. Κλιμακώνεται σε `error` χωρίς καταγεγραμμένη αιτία. | warning | quarantine |
263
+ | QA-TEST-003 | Υγιεινή | Τεστ χωρίς ισχυρισμούς | error | quarantine |
264
+ | QA-TEST-004 | Υγιεινή | Σταθερό sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning | extended |
265
+ | QA-TEST-006 | Υγιεινή | Κατάχρηση επαναλήψεων που κρύβει την αστάθεια | warning | quarantine |
266
+ | QA-TEST-010 | Υγιεινή | Άδειο σώμα τεστ | error | quarantine |
267
+ | QA-TQUAL-002 | Ποιότητα | Ταυτολογικός ισχυρισμός | error | quarantine |
268
+ | QA-TQUAL-009 | Ποιότητα | Ισχυρισμός σε promise χωρίς await | error | quarantine |
269
+ | QA-TQUAL-011 | Ποιότητα | Τεστ σε σχόλια | warning | extended |
270
+ | QA-PW-002 | Playwright | Ισχυρισμός σε locator χωρίς await | error | core |
271
+ | QA-PW-003 | Playwright | `page.pause()` / `test.only()` σε commit | error | core |
272
+ | QA-PW-004 | Playwright | Εύθραυστοι επιλογείς CSS/XPath | warning | quarantine |
273
+ | QA-PW-123 | Playwright | Σκληροκωδικοποιημένα URL περιβαλλόντων | warning | quarantine |
274
+ | QA-PW-140 | Playwright | Στιγμιότυπο οθόνης χωρίς `maxDiffPixelRatio` | warning | core |
275
+ | QA-CI-001 | CI | Το `continue-on-error` κρύβει μια αποτυχημένη πύλη | error | quarantine |
276
+ | QA-CI-002 | CI | Το `\|\| true` καταπίνει κωδικούς εξόδου | error | extended |
277
+ | QA-CI-005 | CI | Αναφορά που καταναλώνεται αλλά δεν δημιουργείται ποτέ | error | quarantine |
278
+ | QA-CI-007 | CI | Wrappers επαναλήψεων γύρω από τα τεστ | warning | extended |
279
+ | QA-CI-008 | CI | Step που πετυχαίνει πάντα κρύβει αποτυχίες | error | quarantine |
280
+ | QA-CI-009 | CI | Ο κωδικός εξόδου δεν μεταφέρεται (`\|` χωρίς pipefail, αλυσίδες `;`) | error | extended |
281
+ | QA-CI-010 | CI | Τεστ που παραλείπονται εκεί όπου πρέπει να μπλοκάρουν | error | quarantine |
282
+ | QA-PY-002 | Python | Παραλειπόμενο τεστ (`skip`, μη αυστηρό `xfail`) | warning | core |
283
+ | QA-PY-003 | Python | Συνάρτηση τεστ χωρίς ισχυρισμούς | error | quarantine |
284
+ | QA-PY-005 | Python | `time.sleep()` στα τεστ | warning | extended |
285
+ | QA-PY-012 | Python | Ταυτολογικός ισχυρισμός | error | quarantine |
286
+ | QA-JV-101 | Java | Απενεργοποιημένο τεστ (`@Disabled`) | warning | core |
287
+ | QA-JV-102 | Java | Σταθερό sleep (`Thread.sleep()`) | warning | extended |
288
+ | QA-JV-103 | Java | Μέθοδος τεστ χωρίς ισχυρισμούς | error | extended |
289
+ | QA-JV-105 | Java | Σταθερό sleep με `waitForTimeout()` του Playwright | warning | core |
290
+ | QA-JV-106 | Java | Εύθραυστος επιλογέας αντί για locator βάσει ρόλου | warning | quarantine |
291
+ | QA-CS-101 | C# | Παραλειπόμενο τεστ (`[Ignore]`, `[Fact(Skip=)]`) | warning | core |
292
+ | QA-CS-102 | C# | Σταθερό sleep (`Thread.Sleep` / `Task.Delay`) | warning | core |
293
+ | QA-CS-103 | C# | Μέθοδος τεστ χωρίς ισχυρισμούς | error | core |
294
+ | QA-CS-105 | C# | Σταθερό sleep με `WaitForTimeoutAsync()` | warning | extended |
295
+ | QA-CS-106 | C# | Εύθραυστος επιλογέας αντί για locator βάσει ρόλου | warning | quarantine |
296
+
297
+ Η Python περιλαμβάνει επίσης τους QA-PY-001…012 (υγιεινή pytest) και QA-PY-101…108 (Playwright για Python). Τα Cypress και Selenium έχουν αρχικά σύνολα τριών κανόνων το καθένα.
207
298
 
208
299
  </details>
209
300
 
210
- <details>
211
- <summary><strong>Playwright 🎭</strong></summary>
301
+ Κάθε κανόνας κυκλοφορεί με ένα fixture must-fire **και** ένα must-not-fire, και ένας κανόνας που ενεργοποιείται στο δικό του αρνητικό fixture δεν μπορεί να κυκλοφορήσει. Αυτό είναι το τείχος προστασίας από ψευδώς θετικά· το `mjolnir doctor` το επιβάλλει στο CI αυτού του αποθετηρίου.
212
302
 
213
- | ID | Κανόνας | Severity |
214
- | --------- | ----------------------------------------- | -------- |
215
- | QA-PW-002 | Assertion locator χωρίς await | error |
216
- | QA-PW-003 | `page.pause()` / `test.only()` στο commit | error |
217
- | QA-PW-004 | Εύθραυστοι CSS/XPath selectors | warning |
218
- | QA-PW-123 | Σκληρά URL περιβάλλοντος | warning |
303
+ ### Selector Health Score
219
304
 
220
- </details>
305
+ Το `mjolnir doctor:playwright` βαθμολογεί κάθε locator ανάλογα με το πώς βρίσκει ένα στοιχείο: όπως θα το έκανε ένας χρήστης (ρόλος, ετικέτα, κείμενο), μέσω ρητού συμβολαίου (`data-testid`) ή από δομική σύμπτωση (αλυσίδες CSS, XPath). Κάθε αρχείο παίρνει βαθμολογία από 0 έως 100:
221
306
 
222
- <details>
223
- <summary><strong>Ακεραιότητα CI</strong></summary>
224
-
225
- | ID | Κανόνας | Severity |
226
- | --------- | --------------------------------------------------------------------- | -------- |
227
- | QA-CI-001 | Το `continue-on-error` κρύβει αποτυχίες | error |
228
- | QA-CI-002 | Το `\|\| true` καταπίνει exit codes | error |
229
- | QA-CI-005 | Αναφορά καταναλώνεται αλλά ποτέ δεν παράγεται | error |
230
- | QA-CI-007 | Περιτύλιξη retry γύρω από τεστ | warning |
231
- | QA-CI-008 | Step πάντα επιτυχές κρύβει αποτυχίες | error |
232
- | QA-CI-009 | Exit code του τεστ δεν προωθείται (`\|` χωρίς pipefail, αλυσίδες `;`) | error |
233
- | QA-CI-010 | Τεστ παραλείπονται εκεί που πρέπει να μπλοκάρουν (skip-on-PR guards) | error |
234
-
235
- </details>
236
-
237
- <details>
238
- <summary><strong>Python / pytest 🐍</strong></summary>
239
-
240
- | ID | Κανόνας | Severity |
241
- | --------- | --------------------------------------------- | -------- |
242
- | QA-PY-002 | Παραλειμένο τεστ (`skip`, μη αυστηρό `xfail`) | warning |
243
- | QA-PY-003 | Συνάρτηση τεστ χωρίς assertions | error |
244
- | QA-PY-005 | `time.sleep()` σε τεστ | warning |
245
- | QA-PY-012 | Ταυτολογική assertion | error |
246
-
247
- Συνολικά 20 κανόνες Python (QA-PY-001…012 υγιεινή pytest + QA-PY-101…108 Playwright-Python).
307
+ ```text
308
+ ▍ SELECTOR HEALTH
248
309
 
249
- </details>
310
+ e2e/login.spec.ts
311
+ [█████████████░░░░░░░] 65 / 100
312
+ role/text: 1 · testid: 0 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
250
313
 
251
- <details>
252
- <summary><strong>Java / JUnit · TestNG ☕</strong></summary>
314
+ e2e/checkout.spec.ts
315
+ [██████████████████░░] 88 / 100
316
+ role/text: 4 · testid: 1 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
317
+ ```
253
318
 
254
- | ID | Κανόνας | Severity |
255
- | --------- | ------------------------------------------ | -------- |
256
- | QA-JV-101 | Απενεργοποιημένο τεστ (`@Disabled`) | warning |
257
- | QA-JV-102 | Σκληρό sleep (`Thread.sleep()`) | warning |
258
- | QA-JV-103 | Μέθοδος τεστ χωρίς assertions | error |
259
- | QA-JV-105 | Σκληρό sleep Playwright `waitForTimeout()` | warning |
260
- | QA-JV-106 | Εύθραυστος selector αντί για role locator | warning |
319
+ Αυτό μετρά **ανθεκτικότητα, όχι ορθότητα**. Το `.btn.btn-primary > div:nth-child(2)` περνά σήμερα και θα συνεχίσει να περνά μέχρι κάποιος να αγγίξει το markup. Μια χαμηλή βαθμολογία δεν ισχυρίζεται ποτέ ότι το τεστ είναι χαλασμένο, μόνο ότι εξαρτάται από markup που κανείς δεν υποσχέθηκε να διατηρήσει.
261
320
 
262
- </details>
321
+ <br />
263
322
 
264
- <details>
265
- <summary><strong>C# / .NET — NUnit · xUnit · MSTest 🟣</strong></summary>
323
+ ## Η βαθμολογία αξιοπιστίας
266
324
 
267
- | ID | Κανόνας | Severity |
268
- | --------- | ---------------------------------------------- | -------- |
269
- | QA-CS-101 | Παραλειμένο τεστ (`[Ignore]`, `[Fact(Skip=)]`) | warning |
270
- | QA-CS-102 | Σκληρό sleep (`Thread.Sleep` / `Task.Delay`) | warning |
271
- | QA-CS-103 | Μέθοδος τεστ χωρίς assertions | error |
272
- | QA-CS-105 | Σκληρό sleep `WaitForTimeoutAsync()` | warning |
273
- | QA-CS-106 | Εύθραυστος selector αντί για role locator | warning |
325
+ <p align="center">
326
+ <img src="assets/readme/score-gauge.svg" alt="Η κλίμακα αξιοπιστίας από 0 έως 100, με έναν δείκτη που διατρέχει κάθε βαθμολογία: UNWORTHY κάτω από 50, NEEDS WORK από 50 έως 79, WORTHY από 80 έως 99, FORGED στο 100" width="720" />
327
+ </p>
274
328
 
275
- </details>
329
+ <sub>Κάθε βαθμολογία από 0 έως 100, τοποθετημένη από το πραγματικό `deriveScoreState`. Δημιουργείται με `npm run docs:gauge` και κλειδώνεται έναντι αποκλίσεων στο CI.</sub>
276
330
 
277
- > Ο πλήρης ζωντανός κατάλογος — κάθε κανόνας με tier, confidence,
278
- > κίνδυνο false positive και διαθεσιμότητα autofix — παράγεται από το
279
- > μητρώο:
280
- >
281
- > ```bash
282
- > mjolnir rules --md
283
- > ```
284
- >
285
- > Οι σελίδες ανά κανόνα ζουν στο [`docs/rules/`](docs/rules/).
331
+ | Βαθμολογία | Ετυμηγορία |
332
+ | ---------- | --------------------------------------- |
333
+ | `0 – 49` | **UNWORTHY** |
334
+ | `50 – 79` | **NEEDS WORK** |
335
+ | `80 – 99` | **WORTHY** |
336
+ | `100` | **FORGED** |
337
+ | `null` | **UNKNOWN**: δεν βρέθηκαν δηλώσεις τεστ |
286
338
 
287
- ### Πόσο από αυτό είναι μετρημένο
339
+ **Πώς υπολογίζεται.** Η σοβαρότητα ορίζει μια βασική αφαίρεση (`error −8`, `warning −3`, `info −1`) και το επίπεδο τεκμηρίωσης τη μειώνει: το E2 μετρά πλήρως, το E1 κατά το ήμισυ (με στρογγυλοποίηση προς τα κάτω), το E0 καθόλου. Το σύνολο κανονικοποιείται με βάση την έκθεση της σουίτας, δηλαδή αφαιρέσεις ανά δήλωση τεστ αντί ανά αρχείο. Το τερματικό τυπώνει τους ίδιους μειωμένους αριθμούς που χρησιμοποίησε η βαθμολογία· δεν υπάρχει κρυφό δεύτερο μοντέλο. Λεπτομέρειες: [docs/SCORING.md](docs/SCORING.md) και ο [οδηγός βαθμολόγησης](https://sergey-bar.github.io/Mjolnir/guide/scoring).
288
340
 
289
- **78 από 99 κανόνες φέρουν ποσοστό false positive μετρημένο σε πραγματικό
290
- κώδικα OSS** (≥ 10 χειροκίνητα ταξινομημένα ευρήματα ο καθένας· βλ.
291
- [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). Οι άλλοι 21 κυκλοφορούν πάνω στην
292
- εκτίμηση του συγγραφέα. Το υποσέλιδο κάθε σκαν σου λέει πόσοι από τους
293
- _ενεργούς_ κανόνες είναι μετρημένοι· `mjolnir rules --unmeasured`
294
- παραθέτει τους άμετρητους· η σελίδα `mjolnir explain` κάθε κανόνα
295
- δηλώνει την κατάστασή του. Δημοσιεύουμε το ποσοστό ακόμα κι όταν είναι
296
- αυτό. Να μεγαλώσει αυτός ο αριθμός είναι η συνεχιζόμενη δουλειά του έργου.
341
+ **Τι δεν σημαίνει το 100.** Δεν σημαίνει ότι το λογισμικό είναι σωστό, ότι η σουίτα επαρκεί ή ότι το προϊόν είναι απαλλαγμένο από ελαττώματα. Σημαίνει ένα πράγμα: **κανένας από τους κανόνες που αξιολόγησε το Mjölnir δεν παρήγαγε αφαίρεση σε αυτή τη σάρωση και με αυτό το μοντέλο τεκμηρίωσης.**
297
342
 
298
- ### Tiers κανόνων και ωριμότητα γλωσσών
343
+ <br />
299
344
 
300
- Κάθε κανόνας είναι `core`, `extended` ή `quarantine`, ανατεθειμένος από
301
- το **μετρημένο** ποσοστό false positive του:
345
+ ## Το μοντέλο τεκμηρίωσης
302
346
 
303
- | Tier | Σημασία | Προεπιλεγμένο σκαν | `--strict` |
304
- | ------------ | -------------------------------------- | :----------------: | :--------: |
305
- | `core` | ≤ 10 % μετρημένο FP | ✅ | ✅ |
306
- | `extended` | ≤ 30 % μετρημένο FP | ✅ | ✅ |
307
- | `quarantine` | πάνω από 30 %, ή ακόμα άμετρο (n < 10) | ❌ | ✅ |
347
+ Κάθε εύρημα φέρει δύο ετικέτες: πόσο σίγουρο είναι το Mjölnir και πόσο έχει ελεγχθεί το εύρημα. Αυτή είναι η διαφορά ανάμεσα σε ένα εργαλείο που αναφέρει μοτίβα και σε ένα εργαλείο στο οποίο μπορείτε να εξαρτήσετε μια κυκλοφορία.
308
348
 
309
- | Γλώσσα | Adapter | Κάλυψη σήμερα |
310
- | --------------- | ----------------- | ------------------------------------------------------------------ |
311
- | TypeScript / JS | AST μεταγλωττιστή | η ευρύτερη, η πιο μετρημένη — ως επί το πλείστον `core`/`extended` |
312
- | Python / pytest | Στρώμα regex | ευρεία, ελεγμένη σε corpus — ως επί το πλείστον `core`/`extended` |
313
- | Java | Στρώμα regex | νεότερη — ως επί το πλείστον `extended`/`quarantine` |
314
- | C# / .NET | Στρώμα regex | νεότερη — ως επί το πλείστον `extended`/`quarantine` |
349
+ **Πόσο σίγουρο — το επίπεδο τεκμηρίωσης.**
315
350
 
316
- TypeScript και Python έχουν την ευρύτερη μετρημένη κάλυψη. Η Java και η
317
- C# κυκλοφορούν, είναι τεκμηριωμένες και μένουν εκτός του headline αριθμού
318
- μέχρι μια πραγματική σουίτα καταναλωτή (όχι τα ίδια τα τεστ μιας
319
- βιβλιοθήκης binding) να ελεγχθεί.
351
+ | Επίπεδο | Όνομα | Σημαίνει | Αφαίρεση |
352
+ | ------- | ------------------------ | --------------------------------------------------------- | -------- |
353
+ | **E2** | Ντετερμινιστική απόδειξη | Το ελάττωμα υπάρχει στον κώδικα όπως είναι γραμμένος | Πλήρης |
354
+ | **E1** | Τεκμήριο μοτίβου | Ταίριαξε ένα μοτίβο στενά συνδεδεμένο με το ελάττωμα | Μισή |
355
+ | **E0** | Παρατήρηση | Αξίζει να το ξέρετε. Όχι ισχυρισμός ότι κάτι είναι λάθος. | Μηδέν |
320
356
 
321
- ---
357
+ Η βεβαιότητα μιας ανίχνευσης δεν είναι η ισχύς της απόδειξης. Ένας κανόνας μπορεί να είναι βέβαιος ότι βρήκε αυτό που έψαχνε και παρ' όλα αυτά να κοιτάζει μια ευρετική. Τα ευρήματα E1 υπάρχουν για να διαβάζονται και να κρίνονται, ποτέ για να εφαρμόζονται στα τυφλά, και αυτό το όριο είναι αποτυπωμένο στο εύρημα στο τερματικό, στο JSON και στην παράδοση στον πράκτορα.
322
358
 
323
- ## Πώς λειτουργεί το σκόρ
359
+ **Πόσο ελέγχθηκε — το επίπεδο εμπιστοσύνης.** Τα περισσότερα ευρήματα προκύπτουν από την ανάγνωση του κώδικά σας. Δώστε στο Mjölnir την αναφορά μιας πραγματικής εκτέλεσης τεστ και μπορεί να επιβεβαιώσει ότι ο κώδικας όντως εκτελέστηκε.
324
360
 
325
361
  <p align="center">
326
- <img src="assets/readme/terminal-hero.svg" alt="Έξοδος τερματικού Mjölnir — WORTHINESS 75/100 NEEDS WORK, ανάλυση διαγνώσεων ανά κατηγορία και λίστα FIX THIS FIRST" width="820" />
362
+ <img src="assets/readme/trust-ladder.svg" alt="Η κλίμακα εμπιστοσύνης από L0 έως L5. Τα L0 έως L2 προκύπτουν από την ανάγνωση του κώδικα· τα L3 έως L5 χρειάζονται πραγματική αναφορά εκτέλεσης, κάτι που σημειώνεται με ένα κενό στην κλίμακα." width="100%" />
327
363
  </p>
328
364
 
329
- <sub>Αναδημιουργείται με `npm run docs:hero`;
330
- [`tests/hero-asset-reproducibility.spec.ts`](tests/hero-asset-reproducibility.spec.ts)
331
- ρίχνει το CI αν ο artifact αποκλίνει από ό,τι τυπώνει ο reporter.</sub>
365
+ | Επίπεδο | Με απλά λόγια | Τι χρειάζεται |
366
+ | ------- | ------------------------- | ------------------------------------------------------------------------------ |
367
+ | **L0** | Σημειώθηκε | Ανάγνωση του κώδικα |
368
+ | **L1** | Μοιάζει με το πρόβλημα | Ανάγνωση του κώδικα: ταίριαξε ένα μοτίβο |
369
+ | **L2** | Αποδεδειγμένο στον κώδικα | Ανάγνωση του κώδικα: το ελάττωμα είναι δομικό |
370
+ | **L3** | Το αρχείο εκτελέστηκε | Μια αναφορά εκτέλεσης δείχνει ότι το αρχείο του ευρήματος εκτελέστηκε |
371
+ | **L4** | Το τεστ εκτελέστηκε | Μια αναφορά εκτέλεσης δείχνει ότι το τεστ του ευρήματος εκτελέστηκε |
372
+ | **L5** | Η εκτέλεση συμφωνεί | Το ίδιο το αποτέλεσμα της εκτέλεσης επιβεβαιώνει την κατηγορία του ελαττώματος |
332
373
 
333
- Το σκόρ είναι διαφανές: **error −8, warning −3, info −1**, μετά
334
- κανονικοποίηση με την έκθεση της σουίτας (αφαιρέσεις ανά δήλωση τεστ).
335
- Οι αφαίρεσεις σταθμισμένες με αποδείξεις σημαίνουν ότι τα αδύναμα σήματα
336
- κοστίζουν λιγότερο. Το τερματικό δείχνει τους ίδιους εκπτώτους αριθμούς
337
- που χρησιμοποιεί το σκόρ — καμία μαύρη κάψουλα. Πλήρης μέθοδος:
338
- [docs/SCORING.md](docs/SCORING.md).
374
+ Μια στατική σάρωση σταματά στο L2. Μόνο μια πραγματική αναφορά εκτέλεσης (Playwright JSON, Jest ή Vitest JSON, JUnit XML) μπορεί να ανεβάσει ένα εύρημα στο L3 ή παραπάνω, οπότε ένα εύρημα που δεν εθεάθη ποτέ να εκτελείται δεν μπορεί ποτέ να ισχυριστεί ότι εκτελέστηκε. Ορισμοί: [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md).
339
375
 
340
- **Ετυμηγορίες**
376
+ ### Πόσο από αυτό είναι μετρημένο
341
377
 
342
- | Score | Ετυμηγορία |
343
- | ------- | ---------------- |
344
- | ≥ 80 | ✓ **WORTHY** |
345
- | 50 – 79 | ⚠ **NEEDS WORK** |
346
- | < 50 | ✖ **UNWORTHY** |
378
+ **74 από 79 κανόνες έχουν ποσοστό ψευδώς θετικών μετρημένο σε πραγματικό κώδικα OSS** (τουλάχιστον 10 ευρήματα ταξινομημένα με το χέρι ο καθένας· δείτε το [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). Οι υπόλοιποι 5 βασίζονται στην εκτίμηση του δημιουργού και το δηλώνουν, κανόνα προς κανόνα, στο `mjolnir explain`. Το `mjolnir rules --unmeasured` τους απαριθμεί, και το υποσέλιδο κάθε σάρωσης αναφέρει πόσοι από τους κανόνες που πράγματι _ενεργοποιήθηκαν_ είναι μετρημένοι.
347
379
 
348
- **Επίπεδα αποδείξεων** — κάθε εύρημα φέρει ένα· ορίζει το βάρος του
349
- ευρήματος στο σκόρ:
380
+ Τα ποσοστά παραμένουν δημόσια ακόμη κι όταν είναι κακά. Ο QA-TEST-001 (ένα `.only` σε commit) τα πάει άσχημα στον έλεγχο σε πραγματικά αποθετήρια και γι' αυτό βρίσκεται σε quarantine. Ο τρέχων αριθμός για κάθε κανόνα, μαζί με τον QA-PW-141, βρίσκεται στον έλεγχο.
350
381
 
351
- | Επίπεδο | Σημασία | Επίδραση στο σκόρ | Παράδειγμα |
352
- | ------- | -------------------- | ----------------- | --------------------------------------------------- |
353
- | E2 | Καθορισμένο ελάττωμα | Πλήρης αφαίρεση | Commitμένο `.only` — δομικά αποδείξιμο |
354
- | E1 | Ευρετικό μοτίβο | Μισή αφαίρεση | Regex-βρεμένο `sleep()` — ισχυρό σήμα, όχι απόδειξη |
355
- | E0 | Παρατήρηση | Μηδέν (μόνο info) | Αναφέρεται αλλά δεν gated ποτέ CI ούτε αφαιρεί |
382
+ ### Επίπεδα εμπιστοσύνης κανόνων
356
383
 
357
- Οι περισσότεροι κανόνες είναι **E1**. Το σύνθημα «we prove it»
358
- αναφέρεται σε αυτό το σύστημα: τα ευρήματα E2 είναι δομική απόδειξη·
359
- τα ευρήματα E1 είναι σωστά τοποθετημένες προειδοποιήσεις, όχι τυπικές
360
- αποδείξεις.
384
+ Τα επίπεδα ακολουθούν το μετρημένο ποσοστό ψευδώς θετικών, όχι γνώμες:
361
385
 
362
- Ένα άδειο repo σκοράρει `null`, ποτέ ψεύτικα 100 — δες
363
- [Μοντέλο εμπιστοσύνης](#μοντέλο-εμπιστοσύνης).
386
+ | Επίπεδο | Μετρημένο FP | Συμπεριφορά |
387
+ | --------------- | --------------------- | --------------------------------------------------------- |
388
+ | **core** | ≤ 10% | Προεπιλεγμένη αναφορά, μπλοκάρει |
389
+ | **extended** | ≤ 30% | Προεπιλεγμένη αναφορά, χαμηλότερη βεβαιότητα |
390
+ | **quarantine** | > 30% ή ρητά δηλωμένο | Μόνο `--strict`, περιορισμένο σε info, δεν μπλοκάρει ποτέ |
391
+ | _μη μετρημένος_ | n < 10 | Δεν μπορεί να προαχθεί σε core μέχρι να μετρηθεί |
364
392
 
365
- ---
393
+ Οι ζώνες FP μπορούν μόνο να υποβιβάσουν ένα επίπεδο — δεν προάγουν ποτέ έναν κανόνα εκτός `quarantine` αν έχει δηλωθεί ρητά εκεί. Ένας ρητά τεθείς σε καραντίνα κανόνας παραμένει στο quarantine ανεξαρτήτως του μετρημένου ποσοστού FP.
366
394
 
367
- ## 🎭 Selector Health Score
395
+ Προαγωγή, υποβιβασμός και ωριμότητα ανά γλώσσα: [κύκλος ζωής των κανόνων](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle).
368
396
 
369
- Η headline μετρική για σουίτες Playwright — πόσο ανθεκτικοί είναι οι
370
- locators σου:
397
+ ### Γιατί αυτό δεν είναι linter
371
398
 
372
- ```text
373
- ▚ SELECTOR HEALTH — e2e/checkout.spec.ts
399
+ Οι linters σάς λένε αν ο κώδικας ακολουθεί κανόνες. Το Mjölnir σάς λέει αν μπορείτε να εμπιστευτείτε την επαλήθευσή σας.
374
400
 
375
- [█████████████████░░░] 83 / 100
376
- role/text: 2 · testid: 1 · css-chains: 1 ⚠ · xpath: 0
377
- ```
401
+ | | Linters (ESLint, SonarQube) | Εργαλεία κάλυψης | Έλεγχος κώδικα με ΤΝ | **Mjölnir** |
402
+ | -------------------------------------------------------------------------- | :-------------------------: | :--------------: | :------------------: | :----------------: |
403
+ | Βαθμολογεί το **σύστημα επαλήθευσης**, όχι τον κώδικα του προϊόντος | Όχι | Όχι | Όχι | Ναι |
404
+ | Ακεραιότητα των CI workflows (`continue-on-error`, `\|\| true`) | Όχι | Όχι | μόνο το diff | Ναι |
405
+ | Βαθμολογεί την ανθεκτικότητα των locators του Playwright (Selector Health) | Όχι | Όχι | Όχι | Ναι |
406
+ | Διαβάζει πραγματικά δεδομένα εκτελέσεων για ετυμηγορίες `TRUE-FLAKE` | Όχι | Όχι | Όχι | Ναι |
407
+ | Δημοσιεύει μετρημένο ποσοστό ψευδώς θετικών ανά κανόνα | Όχι | Όχι | Όχι | Ναι |
408
+ | Σημειώνει τεστ χωρίς ισχυρισμούς | Ναι\* | Όχι | μερικές φορές | Ναι |
409
+ | Εντοπίζει σταθερά sleep (`waitForTimeout`, `time.sleep`) | Ναι\* | Όχι | μερικές φορές | Ναι |
410
+ | Ντετερμινιστικό (ίδια είσοδος, ίδια έξοδος) | Ναι | Ναι | Όχι | Ναι |
411
+ | Κόστος ανά σάρωση | δωρεάν | δωρεάν | tokens | **μηδέν** (τοπικά) |
412
+
413
+ <sub>\*Καλύπτεται από τα `eslint-plugin-jest` και `eslint-plugin-playwright` (`expect-expect`, `no-wait-for-timeout`) και από τους δικούς κανόνες ισχυρισμών του SonarQube. Οι στήλες περιγράφουν την προεπιλεγμένη συμπεριφορά για την επαλήθευση σουιτών τεστ· πρόσθετα, επί πληρωμή πλάνα και προσαρμοσμένοι κανόνες αλλάζουν ορισμένες απαντήσεις. Αυτή είναι μια σύνοψη τοποθέτησης, όχι benchmark.</sub>
378
414
 
379
- Locators με βάση τα roles παίρνουν πλήρες σκόρ. Οι αλυσίδες CSS class
380
- και το XPath βυθίζουν το σκόρ — σπάνε σε κάθε refactor DOM χωρίς να σου
381
- λένε ποια συμπεριφορά παλινδρόμησε.
415
+ Χρησιμοποιήστε και έλεγχο με ΤΝ. Πιάνει αποχρώσεις, πρόθεση και σχεδιαστικά λάθη που κανένα μοτίβο δεν μπορεί να βρει. Το Mjölnir πιάνει ό,τι ξεφεύγει από τον έλεγχο με ΤΝ επειδή φαίνεται σκόπιμο: ένα `.only` σε commit, έναν καταπιωμένο κωδικό εξόδου, ένα `continue-on-error` σε job τεστ. Αυτά χρειάζονται σάρωση, όχι συλλογισμό.
382
416
 
383
- ---
417
+ <br />
384
418
 
385
- ## 🔬 Αποδείξεις runtime
419
+ ## Ανάλυση εκτελέσεων τεστ
386
420
 
387
- Η στατική ανίχνευση flakiness είναι μαντεψιά. Το Mjölnir διαβάζει
388
- **πραγματικά δεδομένα εκτέλεσης** — αναφορές JSON Playwright και XML
389
- JUnit από οποιονδήποτε runner:
421
+ Η στατική ανάλυση συλλογίζεται για κώδικα που δεν εκτελέστηκε ποτέ. Η ανάλυση εκτελέσεων διαβάζει τι πραγματικά συνέβη: Playwright JSON, Jest JSON, Vitest JSON και JUnit XML από οποιονδήποτε runner.
390
422
 
391
423
  ```bash
392
424
  mjolnir forensics ./test-results/
393
425
  ```
394
426
 
395
427
  ```text
396
- ▚ FLAKINESS LEADERBOARD
428
+ ▍ FLAKINESS LEADERBOARD
397
429
 
398
430
  3 tests · 1 failed · 1 flaky · 1 retried
399
431
 
@@ -403,300 +435,184 @@ FAILING declines an expired card (e2e/checkout.spec.ts)
403
435
  ████░░░░░░░░░░░░░░░░ 1.1s · 1 attempt
404
436
  ```
405
437
 
406
- Τεστ που περνά μόνο από την προσπάθεια ≥ 2 δεν είναι τεστ που περνά —
407
- είναι τυχερό τεστ. Χαρακτηρίζεται `TRUE-FLAKE` ανεξάρτητα από το τελικό
408
- πράσινο τσεκ.
438
+ Το `TRUE-FLAKE` δεν σημαίνει ότι το τεστ επαναλήφθηκε. Σημαίνει ότι το τεστ **απέτυχε σε τουλάχιστον μία προσπάθεια και μετά τελείωσε πράσινο**: μια τυχερή επιτυχία, που σημειώνεται ό,τι κι αν λέει το τελικό τικ. Το `mjolnir triage` μετατρέπει αυτό το ιστορικό σε πρόταση καραντίνας και το `mjolnir pw-report` συνοψίζει μια εκτέλεση. Οι ίδιες αναφορές εκτέλεσης είναι αυτές που ανεβάζουν τα ευρήματα στα επίπεδα εμπιστοσύνης L3 και πάνω.
409
439
 
410
- ---
440
+ <br />
411
441
 
412
- ## ⚡ Το Mjölnir δεν είναι ακόμα ένα linter
442
+ ## Ακεραιότητα CI
413
443
 
414
- Τα linters σου λένε αν ο κώδικας ακολουθεί κανόνες. Το Mjölnir σου λέει
415
- αν η επαλήθευσή σου μπορεί να εμπιστευτεί.
444
+ Ένα τεστ μπορεί να περνά ενώ το pipeline γύρω του δεν μπορεί να αποτύχει. Το Mjölnir διαβάζει και τα workflows: `continue-on-error`, `|| true`, κωδικούς εξόδου που δεν μεταφέρονται ποτέ, steps που πετυχαίνουν πάντα, αναφορές που καταναλώνονται αλλά δεν δημιουργούνται ποτέ, και πύλες που παραλείπονται ακριβώς στα γεγονότα που θα έπρεπε να μπλοκάρουν. Κάθε εύρημα κατονομάζει το job, το step και τη γραμμή, και φέρει το δικό του επίπεδο τεκμηρίωσης.
416
445
 
417
- | | ESLint / SonarQube | Εργαλεία coverage | Χειροκίνητο review | **Mjölnir** |
418
- | -------------------------------------------------------------- | :----------------: | :---------------: | :----------------: | :---------: |
419
- | Ακεραιότητα CI workflow (`continue-on-error`, `\|\| true`) | ❌ | ❌ | σπάνια | ✅ |
420
- | Cross-γλώσσα (TS, Python, Java, C#) από ένα εργαλείο | ❌ | ❌ | ❌ | ✅ |
421
- | Βαθμολογεί ανθεκτικότητα Playwright locators (Selector Health) | ❌ | ❌ | σπάνια | ✅ |
422
- | Σημαίνει τεστ χωρίς πραγματικές assertions | ✅ (plugin)\* | ❌ | καμιά φορά | ✅ |
423
- | Πιάνει σκληρά sleeps (`waitForTimeout`, `time.sleep`) | ✅ (plugin)\* | ❌ | καμιά φορά | ✅ |
424
- | Τρέχει σε δευτερόλεπτα, μηδέν κλήσεις δικτύου κατά το σκαν | ✅ | ✅ | — | ✅ |
446
+ Δημιουργήστε το workflow για PR, συμβουλευτικό από προεπιλογή:
425
447
 
426
- \*Το `eslint-plugin-jest` (`expect-expect`) και το
427
- `eslint-plugin-playwright` (`expect-expect`, `no-wait-for-timeout`)
428
- καλύπτουν αυτά για τα αντίστοιχα frameworks τους.
448
+ ```bash
449
+ mjolnir ci install
450
+ ```
429
451
 
430
- **Η ανάλυση runtime** είναι ξεχωριστή κατηγορία δίπλα στο στατικό
431
- linting:
452
+ Ή προσθέστε το action του Marketplace σε ένα workflow που ήδη έχετε:
432
453
 
433
- | | Playwright retry reporter | Allure / ReportPortal | **Mjölnir forensics** |
434
- | -------------------------------------------------------------- | :-----------------------: | :-------------------: | :-------------------: |
435
- | Διαβάζει πραγματικά δεδομένα runs για ετυμηγορίες `TRUE-FLAKE` | μερικώς\* | μερικώς (tag) | ✅ |
436
- | Αναφορά triage flakiness από ιστορικό εκτέλεσης | ❌ | ✅ | ✅ |
437
- | Ενσωματώνεται με τον στατικό δείκτη αξιοπιστίας | ❌ | ❌ | ✅ |
454
+ ```yaml
455
+ - uses: Sergey-Bar/Mjolnir@v1
456
+ with:
457
+ scope: changed
458
+ fail-on: error
459
+ ```
438
460
 
439
- \*Το Playwright παρακολουθεί εσωτερικά τα retries αλλά δεν παράγει
440
- αυτόνομη αναφορά flakiness με ετικέτες ετυμηγοριών.
461
+ Καρφιτσώστε το `@v1` για να ακολουθείτε την κύρια γραμμή, ή ένα ακριβές tag (`@v0.5.32`) για αναπαραγώγιμη πύλη. Το [docs/DISTRIBUTION-KIT.md](docs/DISTRIBUTION-KIT.md) καλύπτει το Marketplace, το Smithery και τα μητρώα MCP.
441
462
 
442
- ---
463
+ Για να στείλετε τα ευρήματα στο GitHub Code Scanning, ανεβάστε SARIF (απαιτεί `security-events: write` σε επίπεδο workflow ή job):
443
464
 
444
- ## 🤖 Γιατί όχι απλώς AI code review;
465
+ ```yaml
466
+ - run: npx mjolnir-qa@latest --format sarif > mjolnir.sarif
467
+ continue-on-error: true
468
+ - uses: github/codeql-action/upload-sarif@v3
469
+ if: ${{ !cancelled() }}
470
+ with:
471
+ sarif_file: mjolnir.sarif
472
+ ```
445
473
 
446
- Διαφορετικό πρόβλημα, διαφορετικό στρώμα. Το AI review μπορεί να πιάσει
447
- ύποπτη αλλαγή τεστ σε ένα diff· δεν αποδεικνύει ότι το σύστημα
448
- επαλήθευσης συνολικά αξίζει εμπιστοσύνη — και βλέπει μόνο το diff που
449
- του δείχνεις.
474
+ Στο GitLab, το `--format codequality` γράφει την αναφορά Code Quality που διαβάζουν το widget του MR και οι σημειώσεις του diff ([docs/GITLAB-CI.md](docs/GITLAB-CI.md)). Ρύθμιση επεξεργαστή και pipeline: [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
450
475
 
451
- | | AI code review (Copilot κ.λπ.) | **Mjölnir** |
452
- | -------------------------------------------- | :--------------------------------------: | :--------------------------------------: |
453
- | Κόστος ανά σκαν | Tokens (κλιμακώνεται με το μέγεθος diff) | **Μηδέν** (τοπικό, εγκατεστημένο) |
454
- | Βλέπει όλη τη σουίτα + όλες τις ρυθμίσεις CI | Μόνο το PR diff που δείχνεις | **Όλα, κάθε φορά** |
455
- | Καθοριστικό (ίδιο input → ίδιο output) | ❌ (μη καθοριστικό) | **✅** |
456
- | Πιάνει μοτίβα που κοιμούνται μήνες | Μόνο αν είναι στο context | **✅** (σκανάρει όλα τα αρχεία) |
457
- | Θυμάται ευρήματα μεταξύ runs | ❌ (καμία μνήμη μεταξύ συνεδριών) | **✅** (baseline + diff) |
458
- | Τρέχει χωρίς ανθρώπινο έναυσμα | Χρειάζεται PR ή prompt | **✅** (CI hook, τρέχει σε δευτερόλεπτα) |
476
+ ### Απόδοση στο εύρος των αλλαγών
459
477
 
460
- **Χρησιμοποίησέ τα και τα δύο.** Το AI πιάνει νύαντσε, πρόθεση και
461
- σχεδιαστικά ελαττώματα που καμία regex δεν βρίσκει. Το Mjölnir πιάνει
462
- τα δομικά μοτίβα που το AI παραβλέπει επειδή φαίνονται «εσκεμμένα» —
463
- ένα commitμένο `.only`, ένα καταπιμένο exit code, ένα `continue-on-error`
464
- σε τεστ job. Δεν είναι bugs που χρειάζονται συλλογισμό· είναι γεγονότα
465
- που χρειάζονται σκαν.
478
+ ```bash
479
+ npx mjolnir-qa@latest --scope changed
480
+ ```
466
481
 
467
- ---
482
+ Τα ευρήματα αποδίδονται στις γραμμές που πρόσθεσε το branch σας, μετρημένες ως προς το **merge-base**. Το εύρος είναι το ίδιο σύνολο αρχείων που ανακαλύπτει μια πλήρης σάρωση (specs TS/JS και ρυθμίσεις adapters, `test_*.py`, `*Test.java`, `*Tests.cs`, `.github/workflows/*.yml`), συν τις αλλαγές χωρίς commit και τις μη παρακολουθούμενες, οπότε λειτουργεί πριν κάνετε commit. Η βάση επιλύεται με τη σειρά `main → master → origin/main → origin/master → origin/HEAD`· αντικαταστήστε τη με `--base <ref>`.
468
483
 
469
- ## 🤖 Ενσωμάτωση CI
484
+ Όταν το merge-base δεν μπορεί να επιλυθεί (ρηχός κλώνος, αποσυνδεδεμένο HEAD, στόχος εκτός git), τα ευρήματα επιστρέφουν σε απόδοση σε ολόκληρο το αρχείο **και η αναφορά το λέει.** Μια σιωπηλή εναλλακτική θα ήταν ακριβώς το είδος ελαττώματος που υπάρχει αυτό το εργαλείο για να πιάνει.
470
485
 
471
- Μία εντολή παράγει PR workflow — συμβουλευτικό από προεπιλογή, ποτέ
472
- μπλοκάρισμα:
486
+ <br />
473
487
 
474
- ```bash
475
- mjolnir ci install
476
- ```
488
+ ## Πράκτορες ΤΝ
477
489
 
478
- Ή σύνδεσέ το εγγενώς σε GitHub Code Scanning μέσω SARIF:
490
+ Τα ευρήματα αξίζουν κάτι μόνο αν κάτι ενεργεί με βάση αυτά.
479
491
 
480
- ```yaml
481
- - run: npx mjolnir-qa@latest --format sarif > mjolnir.sarif
482
- - uses: github/codeql-action/upload-sarif@v3
483
- with:
484
- sarif_file: mjolnir.sarif
492
+ ```text
493
+ SCAN → EVIDENCE → HANDOFF → AGENT → RE-SCAN → PROOF
485
494
  ```
486
495
 
487
- Ρύθμιση editor και pipeline για SARIF:
488
- [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
496
+ **Η ΤΝ γράφει τη διόρθωση. Το Mjölnir την επαληθεύει.** Η απόδειξη προέρχεται από τη νέα σάρωση, ποτέ από την αναφορά επιτυχίας του ίδιου του πράκτορα.
489
497
 
490
- ### Κάλυψη changed-scope
498
+ | Εντολή | Τι παίρνει ο πράκτορας |
499
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
500
+ | `mjolnir mcp` | Ένας διακομιστής [MCP](https://modelcontextprotocol.io) μέσω stdio. Τα `scan`, `explain` και `diff` γίνονται εργαλεία που καλούνται. |
501
+ | `mjolnir handoff` | Μια αποθηκευμένη αναφορά `--json` γίνεται ντετερμινιστικό σχέδιο σε Markdown: τι εντοπίστηκε, το όριο τεκμηρίωσης ανά εύρημα, τι **δεν** πρέπει να αλλάξει, πώς να επαληθευτεί. |
502
+ | `mjolnir install` | Γράφει στις επιφάνειες πρακτόρων που ήδη έχει το αποθετήριό σας (`.claude/`, `.cursor/`, `.kilo/`, `AGENTS.md`), ώστε ο πράκτορας να ξανασαρώνει πριν δηλώσει ότι τελείωσε. |
491
503
 
492
- Το `--scope changed` αποδίδει ευρήματα σε γραμμές που πρόσθεσε το branch
493
- σου σε σχέση με το merge-base με το `main`. Καλύπτει αρχεία τεστ
494
- (`*.spec.*`, `*.test.*`) συν αρχεία GitHub workflow και ρυθμίσεις
495
- Playwright στο diff. Όταν το merge-base δεν λύνεται — shallow clone,
496
- detached HEAD, μη-git στόχος, διαφορετικό default branch — υποβαθμίζει
497
- ειλικρινά: τα ευρήματα επιστρέφουν σε απόδοση κατά σύνολο αρχείου και η
498
- αναφορά το λέει. Υπενόμησε την base ref με `--base <ref>`.
504
+ Προσθέστε το σε έναν client που έχει δικό του CLI:
499
505
 
500
- ---
501
-
502
- ## Διαμόρφωση
503
-
504
- Το Mjölnir είναι zero-config. Ένα προαιρετικό `mjolnir.config.json` (ή
505
- `.mjolnir.json`) στη ρίζα του repo ρυθμίζει severity, gating και scope —
506
- δεν αλλάζει ποτέ τη σημασιολογία ανίχνευσης.
506
+ ```bash
507
+ claude mcp add mjolnir -- npx -y mjolnir-qa@latest mcp
508
+ ```
507
509
 
508
- | Key | Τύπος | Επίδραση |
509
- | ------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
510
- | `exclude` | `string[]` | Επιπλέον ignore globs (υποσύνολο gitignore), πάνω από τα ενσωματωμένα defaults |
511
- | `gate` | `"advisory" \| "error" \| "warning"` | Ποια severity βγαίνουν μη μηδενικά (default `error`; το `advisory` δεν μπλοκάρει ποτέ) |
512
- | `severityOverrides` | `{ "<RULE-ID>": severity }` | Επανατάσσει τα ευρήματα ενός κανόνα για το repo σου |
513
- | `ignore` | `IgnoreEntry[]` | Καταστέλλει ευρήματα — **το `reason` απαιτείται**· οι εγγραφές λήγουν μετά από 90 ημέρες (ρητό `expires` date, ή time last-modified του αρχείου ρυθμίσεων για εγγραφές χωρίς) |
514
- | `plugins` | `string[]` | Πακέτα κανόνων τρίτων (δες [Μοντέλο εμπιστοσύνης](#μοντέλο-εμπιστοσύνης)) |
510
+ Ή σε οποιονδήποτε client δέχεται ένα μπλοκ `mcpServers`:
515
511
 
516
512
  ```json
517
513
  {
518
- "gate": "error",
519
- "exclude": ["legacy/**"],
520
- "severityOverrides": { "QA-PW-141": "warning" },
521
- "ignore": [
522
- {
523
- "ruleId": "QA-TEST-004",
524
- "files": ["e2e/legacy-login.spec.ts"],
525
- "reason": "Third-party widget needs a settle delay; tracked in JIRA-4821",
526
- "expires": "2026-12-31"
527
- }
528
- ]
514
+ "mcpServers": {
515
+ "mjolnir": { "command": "npx", "args": ["-y", "mjolnir-qa@latest", "mcp"] }
516
+ }
529
517
  }
530
518
  ```
531
519
 
532
- - **`.mjolnirignore`** — απλό αρχείο τύπου gitignore για εξαιρέσεις
533
- διαδρομών, ίδια διάλεκτος με το `exclude`. Χρησιμοποίησέ το για θόρυβο
534
- ανά μηχανή· χρησιμοποίησε `exclude` όταν η λίστα ανήκει στον version
535
- control, δίπλα στην υπόλοιπη ρύθμιση.
536
- - **CLI overrides** — `--strict` (συμπερίληψη κανόνων καραντίνας),
537
- `--width <cols>` και `--ascii` / `--no-ascii` (απόδοση τερματικού),
538
- `--tone blunt` (πιο άκαμπτα μηνύματα), `--max-duration <sec>`
539
- (περιορισμένη μερική σκαν).
540
- - Καταστολή κανόνων και κύκλος ζωής deprecation:
541
- [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md).
542
-
543
- Οι εγγραφές `ignore` τροφοδοτούν και την αυτόνομη εντολή
544
- `mjolnir suppressions`, που παραθέτει τι είναι κατασταλμένο τώρα και
545
- πότε λήγει κάθε εγγραφή.
546
-
547
- ---
548
-
549
- ## 📐 Exit codes & συμβόλαια
550
-
551
- Παγωμένα — ασφαλή για χτίσιμο CI λογικής:
552
-
553
- | Exit code | Σημασία |
554
- | --------- | ------------------------------------------------------------------------------------- |
555
- | `0` | Καθαρό — κανένα εύρημα στο ή πάνω από το gate |
556
- | `1` | Ευρήματα στο ή πάνω από το gate |
557
- | `2` | Μερικό σκαν (τέλος χρονικού προϋπολογισμού, δυσανάγνωστα αρχεία) — δεν μπλοκάρει ποτέ |
558
- | `10` | Λάθος χρήσης (bad flag, λείπει στόχος) |
559
- | `20` | Εσωτερικό λάθος |
560
-
561
- Η αναφορά JSON/SARIF είναι `schemaVersion: 1`. Τα IDs κανόνων
562
- (`QA-<FAMILY>-NNN`) είναι αμετάβλητα μόλις κυκλοφορήσουν και δεν
563
- επαναχρησιμοποιούνται ποτέ.
564
-
565
- ---
566
-
567
- ## Μοντέλο εμπιστοσύνης
568
-
569
- - **Local-first** — μηδέν κλήσεις δικτύου κατά το σκαν. Ποτέ. Μηδενική
570
- τηλεμετρία.
571
- - **Καμία ψεύτικη απόδειξη** — προτιμούμε να πούμε «άγνωστο» παρά
572
- «επαληθευμένο». Άδειο repo παίρνει `score: null`, ποτέ ψεύτικα 100.
573
- - **Μερική ειλικρίνεια** — αν η ανάλυση κόπηκε, η έξοδος το λέει.
574
- Ποτέ «complete» όταν δεν είναι.
575
- - **FP τείχος** — η ανίχνευση τρέχει σε άποψη κώδικα χωρίς
576
- σχόλια/strings (οι κανόνες TypeScript χρησιμοποιούν AST
577
- μεταγλωττιστή): ένα μοτίβο μέσα σε σχόλιο πρόζας ή doc-παράδειγμα
578
- string είναι τεκμηρίωση, όχι εύρημα.
579
- - **Μετρημένο, όχι δηλωμένο** — μόνο κανόνες με ποσοστό false positive
580
- από πραγματικό OSS κώδικα κυκλοφορούν στα headline tiers (δες
581
- [Πόσο από αυτό είναι μετρημένο](#πόσο-από-αυτό-είναι-μετρημένο)); το
582
- υποσέλιδο σκαν και το `mjolnir rules --unmeasured` σου λένε ποιος
583
- ποιος.
584
- - **Εμπιστοσύνη plugins και πύλη εκτέλεσης** — τα plugins είναι πακέτα npm
585
- δηλωμένα κάτω
586
- από `"plugins"`· τα JS modules ζουν στο `mjolnir-rules/*.mjs`.
587
- **Δεν υπάρχει sandbox**: ο κώδικας plugin τρέχει με
588
- πλήρη δικαιώματα Node, το ίδιο μοντέλο εμπιστοσύνης με plugins ESLint
589
- ή Vitest. Γι' αυτό η εκτέλεση κώδικα είναι **opt-in σε κάθε σκαν**:
590
- δώστε `--enable-plugins` (ή ορίστε `MJOLNIR_ENABLE_PLUGINS=1`),
591
- αλλιώς οι πηγές ΔΕΝ φορτώνονται — μια δυνατή ειδοποίηση stderr
592
- παραθέτει ακριβώς τι παραλείφθηκε. Το σκανάρει αν αξιόπιστο κώδικα
593
- δεν τον εκτελεί ποτέ. Τα JSON rule manifests (`mjolnir-rules/*.json`)
594
- δεν επηρεάζονται: δηλώνουν regex μοτίβα και δεν εκτελούν κώδικα εκ
595
- σχεδίασης. Core προθέματα rule-ID είναι δεσμευμένα και απορρίπτονται
596
- από plugins και εξωτερικούς κανόνες κατά της πλαστοπροσωπίας.
597
- - **Εξωτερικοί κανόνες τοπικοί στο workspace** (φάκελος, μηδέν δίκτυο) —
598
- ένας φάκελος `mjolnir-rules/` δίπλα στον στόχο σκαν φορτώνει custom
599
- κανόνες: JSON αρχεία δηλώνουν regex μοτίβα (κανένας κώδικας δεν
600
- εκτελείται), `.mjs`/`.js` modules εξάγουν `rules` (πλήρης εμπιστοσύνη
601
- Node, όπως plugins). Οι εξωτερικοί κανόνες φέρουν τα ίδια trust
602
- metadata με το core· δεν μπορούν ποτέ να κυκλοφορήσουν στο core tier
603
- (το core απαιτεί μετρημένο FP από το corpus sidecar — δηλωμένο
604
- `tier: "core"` σφίγγεται σε `extended`), τηρούν tier πλαφόν και
605
- ελέγχονται για drift: `mjolnir rules --md --external` απεικονίζει τον
606
- κατάλογο από τα φορτωμένα αρχεία (provenance `external`), και ο
607
- generator matrix δέχεται `--external <root>`.
608
-
609
- ---
610
-
611
- ## 🏗️ Αρχιτεκτονική
520
+ **Το προστατευτικό κιγκλίδωμα μετράει περισσότερο από την ευκολία.** Κάθε εύρημα σε μια παράδοση φέρει το όριό του. Το **E2** λέει _ντετερμινιστικό: ελέγξτε τη θέση και εφαρμόστε τη διόρθωση_. Το **E1** λέει _ΑΠΑΙΤΕΙΤΑΙ ΕΠΙΒΕΒΑΙΩΣΗ: η παρατήρηση από μόνη της δεν αποδεικνύει το ελάττωμα_. Ένας πράκτορας που διορθώνει τυφλά ένα E1, καταστέλλει έναν κανόνα ή τροποποιεί έναν κανόνα για να ανεβάσει τη βαθμολογία κάνει ακριβώς αυτό που υπάρχει αυτό το εργαλείο για να πιάνει, γι' αυτό η παράδοση το λέει στο prompt, δίπλα στο εύρημα.
612
521
 
613
- <details>
614
- <summary>Ανάπτυξη δέντρου</summary>
522
+ <br />
615
523
 
616
- ```
617
- mjolnir/
618
- ├── src/
619
- │ ├── engine/ # LanguageAdapter interface + rule runner
620
- │ ├── adapters/ # typescript · python · java · csharp · github-actions
621
- │ ├── rules/ # rules across 8 families + the measured-FP table
622
- │ ├── playwright/ # Selector Health Score engine
623
- │ ├── discovery/ # workspace, frameworks, ignore resolution
624
- │ ├── scope/ # git merge-base changed-scope engine
625
- │ ├── scorer/ # transparent deduction table + prioritization
626
- │ ├── reporter/ # terminal · JSON · SARIF 2.1 · Mermaid
627
- │ ├── forensics/ # run-data ingestion · flake verdicts · triage
628
- │ ├── config/ # mjolnir.config.json + suppressions
629
- │ ├── plugins/ # third-party rule loading (no sandbox)
630
- │ └── commands/ # every subcommand
631
- └── tests/
632
- ├── fixtures/ # must-fire / must-not-fire per rule
633
- └── golden/ # frozen score regression locks
634
- ```
524
+ ## Εμπιστοσύνη και ασφάλεια
635
525
 
636
- </details>
526
+ **Τοπικά πρώτα, μηδενική τηλεμετρία.** Κανένα API με δυνατότητα δικτύου (`fetch`, `http`, `https`, `net`, `dns`, `dgram`, WebSocket) δεν υπάρχει πουθενά στο `src/`, και το [`privacy-network-isolation.spec.ts`](tests/contract/privacy-network-isolation.spec.ts) αποτυγχάνει το build αν εμφανιστεί κάποιο. Απαγορεύει επίσης τα `eval` και `new Function`. Η σάρωση μη αξιόπιστου κώδικα δεν τον εκτελεί ποτέ: η στατική ανάλυση διαβάζει πηγαίο κείμενο και η ανάλυση εκτελέσεων αναλύει αρχεία αναφορών που ήδη υπάρχουν στον δίσκο.
527
+
528
+ Δύο επιφυλάξεις: το ίδιο το `npx` κατεβάζει το πακέτο πριν εκτελεστεί οτιδήποτε, και η εγγύηση καλύπτει το `src/`, όχι πρόσθετα τρίτων.
529
+
530
+ **Τα πρόσθετα δεν εκτελούνται σε sandbox.** Τα πρόσθετα JS (`mjolnir-rules/*.mjs` ή πακέτα npm που αναφέρονται στο `"plugins"`) εκτελούνται με πλήρη δικαιώματα Node, με το ίδιο μοντέλο εμπιστοσύνης όπως τα πρόσθετα του ESLint ή του Vitest. Η φόρτωσή τους είναι ρητή επιλογή **ανά σάρωση**: χωρίς `--enable-plugins` (ή `MJOLNIR_ENABLE_PLUGINS=1`) οι πηγές τους δεν φορτώνονται ποτέ, και μια ειδοποίηση στο stderr απαριθμεί τι παραλείφθηκε. Τα manifests κανόνων σε JSON δεν εκτελούν κώδικα, και τα προθέματα ID των κανόνων core είναι δεσμευμένα, ώστε κανένα πρόσθετο να μην μπορεί να υποδυθεί κάποιον. Αναφέρετε ευπάθειες μέσω του [SECURITY.md](SECURITY.md).
531
+
532
+ **Εκτελείται πάνω στον εαυτό του.** Μια μηχανή εμπιστοσύνης επαλήθευσης δεν έχει καμία αξιοπιστία αν δεν είναι η ίδια επαληθεύσιμη. Κάθε εκτέλεση του CI σαρώνει αυτό το αποθετήριο με το build που παρήγαγε η ίδια εκτέλεση. Η πύλη αποτυγχάνει σε οποιοδήποτε εύρημα σοβαρότητας error, καθώς και σε **μερική** σάρωση ή σε **κανόνα που κατέρρευσε**, γιατί μια κομμένη αυτοσάρωση που δεν αναφέρει τίποτα είναι ακριβώς το ψεύτικο πράσινο που υπάρχει αυτό το έργο για να πιάνει. Το `mjolnir doctor` ελέγχει ξανά τη βάση κανόνων στην ίδια εκτέλεση (τείχος προστασίας fixtures, ειλικρίνεια επιπέδων, το ανώτατο όριο του επιπέδου core), και ένας έλεγχος με αποτέλεσμα INCONCLUSIVE αποτυγχάνει ακριβώς όπως ένας αποτυχημένος. Και οι δύο αναφορές ανεβαίνουν ως artifacts του build.
533
+
534
+ ### Κωδικοί εξόδου και το συμβόλαιο μηχανής
637
535
 
638
- - **Οι κανόνες είναι καθαρές συναρτήσεις** —
639
- `(SourceFileContext) → Finding[]`, χωρίς I/O, χωρίς globals. Νέο
640
- οικοσύστημα = ένας adapter + οι κανόνες του.
641
- - **TypeScript/Playwright χρησιμοποιεί AST μεταγλωττιστή** (ts-morph).
642
- Python, Java και C# τρέχουν σε κοινό regex στρώμα με μεταμφιεσμένα
643
- σχόλια/strings.
644
- - Ένα στρώμα AST tree-sitter WASM για Java και C# υπάρχει και είναι το
645
- επόμενο βήμα ακρίβειας — δεν είναι ακόμα συνδεμένο στον σύγχρονο
646
- σκαν pipeline.
536
+ Παγωμένοι, ώστε να μπορείτε να χτίσετε λογική CI πάνω τους:
647
537
 
648
- ---
538
+ | Κωδικός εξόδου | Σημασία |
539
+ | -------------- | -------------------------------------------------------------------------------------- |
540
+ | `0` | Καθαρό: κανένα εύρημα στο επίπεδο της πύλης ή πάνω από αυτό |
541
+ | `1` | Ευρήματα στο επίπεδο της πύλης ή πάνω από αυτό |
542
+ | `2` | Μερική σάρωση (εξαντλήθηκε το χρονικό όριο, μη αναγνώσιμα αρχεία). Δεν μπλοκάρει ποτέ. |
543
+ | `10` | Σφάλμα χρήσης (λάθος σημαία, λείπει ο στόχος) |
544
+ | `20` | Εσωτερικό σφάλμα |
649
545
 
650
- ## 📚 Τεκμηρίωση
546
+ Το `2` είναι σκόπιμα διαφορετικό από το `0`: μια σάρωση που δεν ολοκληρώθηκε δεν «βρήκε τίποτα». Απλώς δεν τελείωσε την αναζήτηση.
651
547
 
652
- | Έγγραφο | Τι περιέχει |
653
- | ------------------------------------------------------ | ------------------------------------------- |
654
- | [docs/SCORING.md](docs/SCORING.md) | Κανονικοποίηση σκόρ + στάθμιση αποδείξεων |
655
- | [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Μετρημένα ποσοστά false positive + μέθοδος |
656
- | [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Καταστάσεις κανόνων, καταστολή, deprecation |
657
- | [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | Έξοδος SARIF + ρύθμιση editor/CI |
658
- | [docs/rules/](docs/rules/) | Δημιουργημένος κατάλογος ανά κανόνα |
659
- | [CONTRIBUTING.md](CONTRIBUTING.md) | Dev setup + workflow συμβολής |
660
- | [CHANGELOG.md](CHANGELOG.md) | Ιστορικό εκδόσεων |
661
- | [SECURITY.md](SECURITY.md) | Αναφορά ευπαθειών |
548
+ Ό,τι καταναλώνει μια μηχανή (αποτελέσματα εργαλείων MCP, `--json`, SARIF 2.1) προέρχεται από ένα κανονικό αποτέλεσμα με εκδοσιοποιημένο σχήμα που **μόνο επεκτείνεται** (`schemaVersion: 1`, `contractVersion: 1`), ώστε κανένας καταναλωτής να μη χρειάζεται να ανασυνθέτει το νόημα από αποδοσμένο κείμενο. Δείτε [το συμβόλαιο μηχανής](docs/machine-contract.md). Τα ID κανόνων (`QA-<FAMILY>-NNN`) είναι αμετάβλητα μόλις κυκλοφορήσουν και δεν επαναχρησιμοποιούνται ποτέ.
662
549
 
663
- ---
550
+ <br />
664
551
 
665
- ## 📈 Κατάσταση
552
+ ## Τι δεν μπορεί να σας πει το Mjölnir
666
553
 
667
- **v0.5.x · ανοιχτή beta.** Το JSON schema και τα exit codes είναι
668
- παγωμένα συμβόλαια. TypeScript και Python έχουν την ευρύτερη μετρημένη
669
- κάλυψη· Java και C# είναι νεότερα — διαβάστε τα μέσω του
670
- [πίνακα tiers](#tiers-κανόνων-και-ωριμότητα-γλωσσών).
554
+ - **Δεν εκτελεί τα τεστ σας.** Μια καθαρή σάρωση δεν είναι μια σουίτα που περνά.
555
+ - **Δεν μπορεί να σας πει ότι ένας ισχυρισμός είναι _λάθος_.** Το `expect(total).toBe(41)` φαίνεται υγιές. Το Mjölnir βρίσκει τεστ που _δεν μπορούν να αποτύχουν_ και pipelines που _δεν μπορούν να γίνουν κόκκινα_, όχι τεστ που ελέγχουν το λάθος πράγμα.
556
+ - **Δεν αποδεικνύει την επιχειρησιακή ορθότητα.** Τίποτα εδώ δεν λέει ότι το προϊόν σας κάνει αυτό που ζητούσε η απαίτηση.
557
+ - **Ένα 100 δεν αποδεικνύει μια καλή σουίτα.** Το αν η σουίτα σας καλύπτει τον πραγματικό σας κίνδυνο είναι άλλο ερώτημα, και αυτό το εργαλείο δεν το απαντά.
558
+ - **5 από 79 κανόνες βασίζονται σε εκτίμηση**, όχι σε μετρημένο ποσοστό. Ο καθένας το δηλώνει στο δικό του εύρημα.
559
+ - **Το E1 δεν είναι E2.** Τα ευρετικά ευρήματα αξίζει να διαβάζονται, όχι να εφαρμόζονται στα τυφλά.
560
+ - **Ένα άδειο αποθετήριο παίρνει `null`, ποτέ 100.**
561
+ - **Ένα αρχείο με όνομα `*.spec.ts` χωρίς δηλώσεις τεστ δεν μετρά ως κάλυψη.** Ένα αποθετήριο του οποίου τα μόνα αρχεία spec περιέχουν imports ή τύπους (μηδέν κλήσεις `it`/`test`) παίρνει `null`, όχι 100.
671
562
 
672
- ---
563
+ <br />
673
564
 
674
- ## 🤝 Συνεισφορά
565
+ ## Τεκμηρίωση
675
566
 
676
- Νέοι κανόνες είναι ο ευκολότερος πρώτος συνεισφορά — μία εντολή
677
- σκαφφάρει τον κανόνα συν τα fixtures must-fire **και** must-not-fire (ο
678
- δημιουργημένος κανόνας αστοχεί σκόπιμα στα fixtures μέχρι να
679
- υλοποιήσεις πραγματική ανίχνευση — stub δεν μπορεί να κυκλοφορήσει):
567
+ Ο πλήρης ιστότοπος τεκμηρίωσης βρίσκεται στο <https://sergey-bar.github.io/Mjolnir/>.
568
+
569
+ | Έγγραφο | Τι περιέχει |
570
+ | ------------------------------------------------------ | ----------------------------------------------------- |
571
+ | [docs/SCORING.md](docs/SCORING.md) | Κανονικοποίηση βαθμολογίας και στάθμιση τεκμηρίων |
572
+ | [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md) | Κανονικό λεξιλόγιο: μία λέξη ανά έννοια |
573
+ | [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Μετρημένα ποσοστά ψευδώς θετικών και η μέθοδος |
574
+ | [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Καταστάσεις κανόνων, επίπεδα, καταστολή, απόσυρση |
575
+ | [docs/VERSIONING.md](docs/VERSIONING.md) | Πολιτική semver, παγωμένες διεπαφές, κύκλος απόσυρσης |
576
+ | [docs/machine-contract.md](docs/machine-contract.md) | Το κανονικό αποτέλεσμα αναγνώσιμο από μηχανές |
577
+ | [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | Έξοδος SARIF και ρύθμιση επεξεργαστή ή CI |
578
+ | [docs/GITLAB-CI.md](docs/GITLAB-CI.md) | GitLab: αναφορά Code Quality, συνταγή για MR, πύλη |
579
+ | [docs/rules/](docs/rules/) | Παραγόμενος κατάλογος ανά κανόνα |
580
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | Περιβάλλον ανάπτυξης και ροή συνεισφοράς |
581
+ | [SUPPORT.md](SUPPORT.md) | Πού να ρωτήσετε, να αναφέρετε και να βρείτε βοήθεια |
582
+ | [SECURITY.md](SECURITY.md) | Αναφορά ευπαθειών |
583
+ | [CHANGELOG.md](CHANGELOG.md) | Ιστορικό εκδόσεων |
584
+
585
+ ### Κατάσταση
586
+
587
+ **Έκδοση 1.** Το σχήμα JSON και οι κωδικοί εξόδου είναι παγωμένα συμβόλαια. Οι TypeScript και Python έχουν την ευρύτερη μετρημένη κάλυψη. Οι Java και C# είναι νεότερες· διαβάστε τις μέσα από τον [πίνακα ωριμότητας](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle). Τι έρχεται μετά, χωρίς επινοημένες ημερομηνίες: [ο δημόσιος οδικός χάρτης](https://sergey-bar.github.io/Mjolnir/reference/roadmap).
588
+
589
+ ### Συνεισφορά
590
+
591
+ Οι νέοι κανόνες είναι η ευκολότερη πρώτη συνεισφορά. Μία εντολή δημιουργεί τον σκελετό του κανόνα με τα fixtures must-fire **και** must-not-fire. Ο κανόνας που δημιουργείται αποτυγχάνει σκόπιμα στα δικά του fixtures μέχρι να γραφτεί πραγματική ανίχνευση, γιατί ένα stub που κυκλοφορεί είναι ένας κανόνας που κανείς δεν μέτρησε:
680
592
 
681
593
  ```bash
682
594
  mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
683
595
  ```
684
596
 
685
- Πλήρες dev setup, οι εντολές standing gate και οι νόμοι anti-creep /
686
- τείχος fixtures είναι στο [CONTRIBUTING.md](CONTRIBUTING.md).
597
+ Το περιβάλλον ανάπτυξης, οι εντολές των μόνιμων πυλών και οι νόμοι anti-creep και τείχους προστασίας fixtures βρίσκονται στο [CONTRIBUTING.md](CONTRIBUTING.md).
687
598
 
688
- ---
599
+ <br />
689
600
 
690
601
  <div align="center">
691
602
 
692
- **Σταμάτα να στέλνεις τεστ που δεν εμπιστεύεσαι.**
603
+ <img src="assets/readme/closing.svg" alt="Τρέξτε το στο αποθετήριό σας." width="100%" />
693
604
 
694
605
  ```bash
695
606
  npx mjolnir-qa@latest
696
607
  ```
697
608
 
698
- **Star ⭐ · Watch 👀 · Contribute 🤝**
609
+ [Διαβάστε τον οδηγό](https://sergey-bar.github.io/Mjolnir/guide/getting-started) · [Ιστότοπος τεκμηρίωσης](https://sergey-bar.github.io/Mjolnir/) · [npm](https://www.npmjs.com/package/mjolnir-qa)
610
+
611
+ <br />
612
+
613
+ Μη ρωτάτε αν πέρασαν τα τεστ.<br />
614
+ Ρωτήστε αν τα τεκμήρια αποδεικνύουν ότι αξίζουν εμπιστοσύνη.
699
615
 
700
- Κατασκευάστηκε από [Sergey Bar](https://www.linkedin.com/in/sergeybar/)
616
+ <sub>Δημιουργήθηκε από τον [Sergey Bar](https://www.linkedin.com/in/sergeybar/) · Άδεια MIT</sub>
701
617
 
702
618
  </div>