mjolnir-qa 1.0.9 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ar.md CHANGED
@@ -1,384 +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 لضمان الجودة.** يراجع Mjölnir أطقم الاختبارات
8
- وخطوط CI، ويُبلّغ عن درجة الجدارة، ويُظهر بدقة أين ينكسر الثقة.
7
+ يعثر Mjölnir على الاختبارات التي لا يمكن أن تفشل وخطوط CI التي لا يمكن أن تتحول إلى الأحمر،<br />
8
+ ثم يقيّم إلى أي حد يمكن الوثوق بالنتيجة، مع الدليل على كل نقطة.
9
9
 
10
- [![npm](https://img.shields.io/npm/v/mjolnir-qa.svg?style=flat-square&color=C19A34&labelColor=0A1119)](https://www.npmjs.com/package/mjolnir-qa)
11
- [![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)
12
- [![license](https://img.shields.io/badge/license-MIT-C19A34.svg?style=flat-square&labelColor=0A1119)](LICENSE)
13
- [![node](https://img.shields.io/badge/node-%E2%89%A5%2022.18-37ABBD.svg?style=flat-square&labelColor=0A1119)](https://nodejs.org)
14
-
15
- [English](README.md) | [简体中文](README.zh.md) | [繁體中文](README.zht.md) | [한국어](README.ko.md) | [Deutsch](README.de.md) | [Español](README.es.md) | [Français](README.fr.md) | [Italiano](README.it.md) | [Dansk](README.da.md) | [日本語](README.ja.md) | [Polski](README.pl.md) | [Русский](README.ru.md) | [Norsk](README.no.md) | [Português (Brasil)](README.br.md) | [ไทย](README.th.md) | [Türkçe](README.tr.md) | [Українська](README.uk.md) | [বাংলা](README.bn.md) | [Ελληνικά](README.gr.md) | [Tiếng Việt](README.vi.md) | [עברית](README.he.md) | العربية | [Bosanski](README.bs.md)
10
+ <br />
16
11
 
17
- > 🤖 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)
18
19
 
19
20
  ```bash
20
21
  npx mjolnir-qa@latest
21
22
  ```
22
23
 
23
- **هل اختباراتك جديرة بالثقة؟**
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) | [Ελληνικά](README.gr.md) | [Tiếng Việt](README.vi.md) | [עברית](README.he.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 -->
24
34
 
25
- [شاهده يعمل](#-شاهده-يعمل) ·
26
- [البداية السريعة](#-البداية-السريعة) ·
27
- [ماذا يفحص](#-ماذا-يفحص-mjölnir) ·
28
- [التنقيط](#كيف-يعمل-التنقيط) ·
29
- [CI](#-تكامل-ci) · [الإعداد](#الإعداد) ·
30
- [الوثائق](#-الوثائق)
35
+ </details>
31
36
 
32
37
  </div>
33
38
 
34
- ---
39
+ <br />
40
+
41
+ ## علامة الصح الخضراء ادعاء، وليست دليلًا
42
+
43
+ علامة الصح الخضراء تعني أن خط CI لم يفشل. لا تعني أن الاختبارات عملت، ولا أنها كان يمكن أن تفشل. كل واحدة من هذه تمر باللون الأخضر:
44
+
45
+ - ‏`.only` بقي في commit فشغّل 3 اختبارات بدل 900
46
+ - ‏`continue-on-error: true` على الـ job الذي كان يُفترض أن يمنع الدمج
47
+ - ‏`|| true` بعد أمر الاختبار
48
+ - اختبار لا يتحقق من أي شيء، أو جسمه فارغ
49
+ - غلاف إعادة محاولة يحوّل فشلًا حقيقيًا إلى نجاح بالحظ
50
+ - تقرير يرفعه الـ workflow لكنه لم يُنشأ قط
51
+ - ‏sleep ثابت يُبقي حالة تسابق متماسكة
52
+
53
+ لا يحوّل أيٌّ منها خط CI إلى الأحمر، وكل واحد منها يبدو مقصودًا عند المراجعة. لهذا تبقى. هذا Mjölnir يقرأ مثالًا حقيقيًا:
54
+
55
+ <p align="center">
56
+ <img src="assets/readme/scan.svg" alt="‏workflow الـ CI في مستودع العرض، مقروءًا سطرًا بسطر. يعلّم 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 مجموعة الاختبارات وملفات workflow الخاصة بـ CI، وتقرير تشغيل حقيقي إن وُجد. لا يشغّل اختباراتك، ولا يثبّت اعتمادياتك، ولا ينفّذ الشيفرة التي يفحصها. وعندما لا يملك دليلًا، يقول ذلك بدل أن يختلق ثقة:
64
+
65
+ | الحالة | ما يبلّغ عنه Mjölnir |
66
+ | -------------------------------------------------------- | ---------------------------------------------------------- |
67
+ | لم يُعثر على تعريفات اختبارات | الدرجة `null`، وتُعرض كـ **UNKNOWN**. لا 100 مختلقة أبدًا. |
68
+ | لا يوجد خط أساس أو مراجعة قابلة للمقارنة | ‏**UNKNOWN**، مع ذكر السبب. لا 0 مفترضة أبدًا. |
69
+ | توقف الفحص قبل اكتماله (ميزانية الوقت، ملفات غير مقروءة) | ‏**PARTIAL**، رمز الخروج `2`. لا يُعرض أبدًا على أنه نظيف. |
70
+
71
+ <p align="center">
72
+ <img src="assets/readme/how-it-works.svg" alt="كيف يعمل Mjölnir. يقرأ مجموعة الاختبارات وخط CI قراءة ساكنة، وتقرير تشغيل حقيقي عند وجوده. يزن كل نتيجة حسب مستوى دليلها ومستوى الثقة بها، حيث لا يصل إلى L3 حتى L5 إلا تشغيل حقيقي، وينتج نتائج ودرجة جدارة وبوابة CI برموز خروج مجمّدة. وفي حلقة الوكيل، يكتب الذكاء الاصطناعي الإصلاح ويعيد Mjölnir الفحص لإثباته." width="880" />
73
+ </p>
74
+
75
+ <sub>صُمّم لهذه الصفحة ويُعرض بمقياس 1:1. مولَّد بواسطة `npm run docs:readme-brand` ومقفل ضد الانحراف في CI؛ الدرجة والأعداد ومعرّف القاعدة تأتي من [`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
+ ## شاهده وهو يعمل
80
+
81
+ فحص حقيقي لـ [`examples/demo-repo`](examples/demo-repo)، وهي مجموعة Playwright صغيرة مع workflow لـ CI. هنا ذهبت نقاطها:
82
+
83
+ <p align="center">
84
+ <img src="assets/readme/terminal-hero.svg" alt="تفصيل الخصومات في Mjölnir: WORTHINESS 75/100 NEEDS WORK، والدرجة حسب الفئة، ومربع الخصومات حسب الخطورة، وقائمة FIX THIS FIRST" width="520" />
85
+ </p>
86
+
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>
35
91
 
36
- ## 🎬 شاهده يعمل
92
+ <br />
37
93
 
38
94
  <p align="center">
39
- <img src="assets/readme/demo.svg" alt="تقرير --verbose الكامل لـ Mjölnir على مستودع تجريبي: WORTHINESS 75/100 NEEDS WORK، تفصيل تشخيصات بحسب الفئة، قائمة FIX THIS FIRST، وكل اكتشاف مع معرّف القاعدة ورقم السطر — عبر قواعد CI وPlaywright ونظافة الاختبارات وPython" width="900" />
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>
40
98
  </p>
41
99
 
42
- <sub>الناتج الكامل لـ `npx mjolnir-qa ./examples/demo-repo --verbose`
43
- معروض من المُبلِّغ الحقيقي — لا شيء مقتطع. يُعاد توليده بـ
44
- `npm run docs:demo`؛
45
- [`tests/demo-asset-reproducibility.spec.ts`](tests/demo-asset-reproducibility.spec.ts)
46
- يُسقط CI إذا انحرفت المخرجات عمّا تطبعه الأداة.</sub>
100
+ <sub>رُسم إطارًا بإطار من فحص حقيقي بواسطة `npm run docs:video`؛ ولم يُسجَّل من الشاشة قط. اختر الإطار لفتح [`mjolnir-demo.mp4`](assets/video/mjolnir-demo.mp4).</sub>
101
+
102
+ </details>
47
103
 
48
- **ما الذي حدث للتو:**
104
+ ### نتيجة واحدة عن قرب
49
105
 
50
- 1. اكتشف Mjölnir مواصفات Playwright وإعداده وسير عمل CI وملف اختبارات
51
- Python — أربع لغات/صيغ في تمريرة واحدة.
52
- 2. وجد أدلة تُضعف الثقة في الطقم — `continue-on-error` يُخفي مهمة، و
53
- `|| true` يبتلع رمز الخروج، وسبات صارم، ومحدِّد هشّ، وعناوين تجريبية
54
- مضمّنة، وانتظار `networkidle`.
55
- 3. حوّل كلًّا منها إلى اكتشاف ملموس بمعرّف قاعدة وموقع وإصلاح — وإلى
56
- درجة واحدة يمكنك بوابت PR على أساسها.
106
+ كل نتيجة تجيب عن أربعة أسئلة: أين هي، ومدى تأكد Mjölnir، وكم مرة تخطئ القاعدة، وكيف تُصلح.
57
107
 
58
- ### اكتشاف واحد عن قرب
108
+ <p align="center">
109
+ <img src="assets/readme/finding-anatomy.svg" alt="النتيجة الأولى من فحص العرض، تمامًا كما تطبعها الطرفية، مع تعليم أجزائها الأربعة: أين، ومدى التأكد، وكم مرة تخطئ القاعدة، والإصلاح." width="100%" />
110
+ </p>
59
111
 
60
- شغّل `mjolnir explain QA-CI-001` على الاكتشاف الأول أعلاه وستحصل على:
112
+ يطبع `mjolnir explain QA-CI-001` سجل الثقة الكامل لقاعدة ما، بما في ذلك معدل الإيجابيات الكاذبة المقيس لها والمستوى الذي منحها إياه هذا المعدل:
61
113
 
62
114
  ```text
63
- ▚ QA-CI-001 — continue-on-error masks a failing verification gate
115
+ ▍ QA-CI-001 — continue-on-error masks a failing verification gate
64
116
 
65
117
  Severity: error
66
118
  Confidence: high
119
+ Tier: quarantine
67
120
  Evidence: E2
68
- 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
69
126
 
70
127
  WHAT WAS FOUND (real detector output, not a mockup)
71
128
  Job `security-scan` runs a verification gate under `continue-on-error: true`.
72
129
 
73
130
  WHY IT MATTERS
74
- This job can fail every day and CI will still show green. The checkmark
75
- 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.
76
133
 
77
134
  HOW TO FIX
78
135
  Remove continue-on-error, or scope it to individual non-blocking steps only.
79
- ```
80
136
 
81
- هذه هي وحدة القيمة: ليست ملاحظة أسلوب، بل مكانٌ يقول لك فيه CI إن شيئًا
82
- ما قدّم — وهو لم يقدّم.
137
+ Example from this rule's own must-fire fixture: QA-CI-001/must-fire/masked.yml
83
138
 
84
- ---
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
85
146
 
86
- ## ⚡ البداية السريعة
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.
87
150
 
88
- شغّله على مستودع للحصول على تقرير كامل ودرجة جدارة:
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.
89
154
 
90
- ```bash
91
- npx mjolnir-qa@latest
155
+ Docs: mjolnir rules --md (full catalog, this rule included)
92
156
  ```
93
157
 
94
- **في CI، المنتج أمر واحد.** يفحص فقط ما لمسه الفرع ويخرج برمز غير صفري
95
- عند المشكلات الجديدة:
158
+ هذه هي وحدة القيمة: موضع واحد يبلّغ فيه CI عن نجاح لم يستحقه.
159
+
160
+ <br />
161
+
162
+ ## البدء السريع
96
163
 
97
164
  ```bash
98
- npx mjolnir-qa@latest --scope changed
165
+ npx mjolnir-qa@latest
99
166
  ```
100
167
 
101
- ضعه في فحص PR — `mjolnir ci install` يكتب سير العمل — وانتهى الأمر.
102
- كل ما عدا ذلك اختياري.
168
+ يفحص الدليل الحالي ويطبع Trust Report: ما الذي وجده، وإلى أي حد يمكنك الوثوق به، ولماذا، وما الخطوة التالية. ويخرج بالرمز `0` عندما لا يُعثر على شيء عند مستوى البوابة أو فوقه.
103
169
 
104
- | الأمر | ما يفعله |
105
- | ----------------------------------- | ---------------------------------------------------- |
106
- | `mjolnir` | فحص المستودع كاملًا + درجة الجدارة |
107
- | `mjolnir --scope changed` | ما أدخله فرعك فقط — صيغة CI |
108
- | `mjolnir ci install` | يولّد سير عمل PR استشاريًا |
109
- | `mjolnir explain QA-CI-001` | ماذا / لماذا / الإصلاح + معدل FP المقيس لقاعدة واحدة |
110
- | `mjolnir rules --unmeasured` | القواعد العاملة بالافتراض لا بالقياس |
111
- | `mjolnir --json` / `--format sarif` | قابل للقراءة آليًا / GitHub Code Scanning |
112
- | `mjolnir --strict` | يشغّل أيضًا قواعد طبقة الحجر الصحي (خطر FP أعلى) |
113
-
114
- <details>
115
- <summary><strong>عندما يتبدّد استقرار شيء ما</strong></summary>
170
+ في CI، افحص فقط ما أدخله الفرع، حتى لا تُغرق مجموعة اختبارات قديمة أول pull request لك:
116
171
 
117
- | الأمر | ما يفعله |
118
- | ----------------------------------- | ------------------------------------------------------- |
119
- | `mjolnir forensics ./test-results/` | بيانات تشغيل حقيقية → أحكام `TRUE-FLAKE`، و`FLAKY.md` |
120
- | `mjolnir triage ./test-results/` | اقتراح حجر صحي من سجل التنفيذ |
121
- | `mjolnir pw-report ./test-results/` | ملخص تشغيل Playwright — المحاولات / المتذبذبات / الأبطأ |
122
- | `mjolnir doctor:playwright` | فحص عميق لـ Playwright وحده + Selector Health Score |
172
+ ```bash
173
+ npx mjolnir-qa@latest --scope changed
174
+ ```
123
175
 
124
- </details>
176
+ يكتب `mjolnir ci install` ذلك كـ workflow لـ GitHub Actions، باستخدام [الـ action](https://github.com/Sergey-Bar/Mjolnir#readme) المثبّت على الوسم الرئيسي `v1` (أو `npx` عادي مع `--no-action`). ويبقى استشاريًا إلى أن تقرر أنه يجب أن يمنع الدمج.
177
+
178
+ | الأمر | ما الذي يفعله |
179
+ | ----------------------------------- | ------------------------------------------------------------ |
180
+ | `mjolnir` | ‏Trust Report: الحكم، ودرجة الثقة، والإجراء التالي |
181
+ | `mjolnir --scope changed` | فقط ما أدخله فرعك (صيغة CI) |
182
+ | `mjolnir ci install` | ينشئ workflow استشاريًا لطلبات الدمج (قائمًا على الـ 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 (عنصر لأداة طلب الدمج) |
190
+ | `mjolnir --strict` | يشغّل أيضًا قواعد مستوى quarantine (خطر FP أعلى) |
125
191
 
126
192
  <details>
127
- <summary><strong>عادي / تقارير</strong></summary>
128
-
129
- | الأمر | ما يفعله |
130
- | ------------------------------- | -------------------------------------------- |
131
- | `mjolnir fix --dry-run` / `fix` | إصلاحات تلقائية آمنة مع برهان |
132
- | `mjolnir baseline` / `diff` | لقطة للاكتشافات ثم تقرير الجديد/المتدهور فقط |
133
- | `mjolnir impact --since <ref>` | ما تغيّر منذ إيداع سابق |
134
- | `mjolnir debt` | سجل دَّين الاختبارات مع نموذج كلفة |
135
- | `mjolnir handover` | خريطة تهيئة الطقم لمسؤول جودة جديد |
136
- | `mjolnir stats` | عدّادات محلية تراكمية للإصلاحات المرصودة |
137
- | `mjolnir badge` | JSON لنقطة نهاية shields.io + مقطع كود |
138
- | `mjolnir rules --md` | كتالوج القواعد الكامل (JSON أو Markdown) |
139
- | `mjolnir doctor` | تدقيق ذاتي لقاعدة قواعد Mjölnir نفسها |
140
- | `mjolnir create-rule <ID>` | هيكلة قاعدة جديدة + تجهيزاتها |
141
- | `mjolnir --format mermaid` | مخطط معماري للاختبارات لتعليق PR |
193
+ <summary><strong>كل الأوامر الأخرى</strong> — فرز الاختبارات غير المستقرة، والتقارير، والحوكمة</summary>
194
+
195
+ <br />
196
+
197
+ | الأمر | ما الذي يفعله |
198
+ | ----------------------------------- | ------------------------------------------------------------------------- |
199
+ | `mjolnir --classic` | لافتة الدرجة السابقة لـ 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 وملخص للخطوة من تقرير |
208
+ | `mjolnir pr-comment` | تعليق محدد النطاق على طلب الدمج، بصيغة Markdown |
209
+ | `mjolnir debt` | سجل الدَّين التقني للاختبارات مع نموذج تكلفة |
210
+ | `mjolnir handover` | خريطة تعريفية بمجموعة الاختبارات لمهندس QA جديد |
211
+ | `mjolnir init` | يكتشف أُطر العمل ويطبع قائمة تحقق للإعداد |
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 لنقطة نهاية shields.io ومقتطف |
219
+ | `mjolnir --cache` | إعادات فحص تزايدية عبر ذاكرة تخزين مؤقت محلية للأحكام |
220
+ | `mjolnir --format mermaid` | مخطط لبنية الاختبارات لتعليق على طلب الدمج |
221
+
222
+ يطبع `mjolnir help <command>` طريقة الاستخدام والأمثلة والخطوة التالية لأي منها.
142
223
 
143
224
  </details>
144
225
 
145
- ثبّته عالميًا بدل `npx` إن فضّلت: `npm i -g mjolnir-qa`.
146
- يتطلب Node.js ≥ 22.18. يعمل على Windows وmacOS وLinux.
147
-
148
- ---
149
-
150
- ## 👥 لمن هذا؟
151
-
152
- - **QA / SDET** يملكون طقم e2e أو تكامل، ويحتاجون دليلًا على أن الطقم
153
- يستحق فعليًا علامة النجاح الخضراء التي يُنتجها.
154
- - **فرق Platform / DevEx** المسؤولة عن نزاهة CI وبوابات الإصدار —
155
- الأشخاص الذين يهتمون ألا يحوّل `continue-on-error` خطًّا أحمر إلى
156
- أخضر بصمت.
157
- - **مشرفو OSS** يريدون بوابة تحقق رخيصة دائمة التشغيل تعمل محليًا وفي
158
- CI دون أي نداءات شبكة.
159
-
160
- ---
226
+ يتطلب **Node.js ≥ 22.18** على Windows أو macOS أو Linux. تفضّل التثبيت العام؟ `npm i -g mjolnir-qa`. يأتي هذا الحد الأدنى من سلسلة أدوات البناء (يستهدفه tsdown ويُجري خط الإصدار اختبارات دخان عليه)؛ ولا تحتاج اعتماديات وقت التشغيل أكثر من ذلك.
161
227
 
162
- ## 🔨 ماذا يفحص Mjölnir
228
+ <br />
163
229
 
164
- | | |
165
- | --- | --------------------------------------------------------------------------------------------------------------------- |
166
- | ⚖️ | **درجة الجدارة** — رقم واحد، جدول خصم شفاف، بلا صندوق أسود |
167
- | 🎭 | **Selector Health Score** — يقيّم محدِّدات Playwright لديك، لا معدل نجاحك فقط |
168
- | 🔬 | **الأدلة الجنائية للتنفيذ** — يقرأ بيانات تشغيل Playwright/JUnit الحقيقية ليلتقط `TRUE-FLAKE`، لا مجرد تخمينات ثابتة |
169
- | 🚨 | **قواعد نزاهة CI** — يلتقط `continue-on-error` و`\|\| true` وحيل الأخضر الكاذب الأخرى |
170
- | 🐍 | **ترابطات Playwright الأربعة جميعًا** — TypeScript وPython وJava وC#/.NET — إضافة إلى pytest وJUnit/TestNG وأسيرات CI |
171
- | 🔒 | **Local-first** — صفر نداءات شبكة أثناء الفحص، صفر قياس عن بُعد، يجري في ثوانٍ |
230
+ ## ما الذي يكتشفه Mjölnir
172
231
 
173
- ### القواعد
232
+ <p align="center">
233
+ <img src="assets/readme/stack.svg" alt="يعمل مع حزمة تقنياتك: اللغات وأُطر الاختبار وأنظمة CI التي تغطيها قواعده، من سجل القواعد." width="100%" />
234
+ </p>
174
235
 
175
- كل قاعدة تأتي مع تجهيزات must-fire **و**must-not-fire. القاعدة التي
176
- تنطلق على تجهيزتها السالبة ذاتها لا يمكن أن تُشحن — ذلك هو جدار الإنذارات
177
- الكاذبة.
236
+ **79 قاعدة** في أربع عائلات — نظافة الاختبارات، وجودة الاختبارات، وPlaywright، وسلامة CI — عبر TypeScript وJavaScript وPython وJava وC# وYAML الخاص بـ GitHub Actions. تغطي Playwright في روابطه الأربعة، إضافة إلى pytest وJUnit وTestNG وNUnit وxUnit وMSTest وJest وVitest وMocha، مع تغطية مبدئية لـ Cypress وSelenium. تسع منها، لإظهار الشكل:
178
237
 
179
- <details>
180
- <summary><strong>نظافة الاختبارات</strong></summary>
181
-
182
- | ID | القاعدة | Severity |
183
- | ----------- | -------------------------------------------------- | -------- |
184
- | QA-TEST-001 | اختبار مركّز مُودَع (`.only`، `fit`) | error |
185
- | QA-TEST-002 | اختبار متجاوز بلا مسوّغ | error |
186
- | QA-TEST-002 | اختبار متجاوز مع مسوّغ مسجَّل | warning |
187
- | QA-TEST-003 | اختبار بلا تأكيدات | error |
188
- | QA-TEST-004 | سبات صارم (`waitForTimeout`، `sleep()`، `delay()`) | warning |
189
- | QA-TEST-006 | إساءة استخدام المحاولات تُخفي التذبذب | warning |
190
- | 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 |
191
249
 
192
- </details>
250
+ يُولَّد الفهرس الكامل من السجل ولا يُصان يدويًا أبدًا: `mjolnir rules --md`، أو [`docs/rules/`](docs/rules/)، أو [دليل ما الذي يفحصه](https://sergey-bar.github.io/Mjolnir/guide/what-it-checks).
193
251
 
194
252
  <details>
195
- <summary><strong>جودة الاختبارات</strong></summary>
196
-
197
- | ID | القاعدة | Severity |
198
- | ------------ | ------------------------- | -------- |
199
- | QA-TQUAL-002 | تأكيد مُبرهن ذاتيًا | error |
200
- | QA-TQUAL-009 | تأكيد وعد بلا await | error |
201
- | QA-TQUAL-011 | اختبارات معطَّلة بالتعليق | warning |
253
+ <summary><strong>كل قاعدة مذكورة في هذا الملف</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 | أغلفة إعادة المحاولة حول الاختبارات | warning | extended |
279
+ | QA-CI-008 | CI | خطوة تنجح دائمًا تخفي الإخفاقات | 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 مجموعة مبدئية من ثلاث قواعد.
202
298
 
203
299
  </details>
204
300
 
205
- <details>
206
- <summary><strong>Playwright 🎭</strong></summary>
301
+ تُطلق كل قاعدة مع ملف fixture من نوع must-fire **و**آخر من نوع must-not-fire، ولا يمكن إطلاق قاعدة تنطلق على ملف fixture السلبي الخاص بها. هذا هو جدار الحماية من الإيجابيات الكاذبة؛ ويفرضه `mjolnir doctor` في CI الخاص بهذا المستودع.
207
302
 
208
- | ID | القاعدة | Severity |
209
- | --------- | ------------------------------------ | -------- |
210
- | QA-PW-002 | تأكيد محدِّد بلا await | error |
211
- | QA-PW-003 | `page.pause()` / `test.only()` مودعة | error |
212
- | QA-PW-004 | محدِّدات CSS/XPath هشّة | warning |
213
- | QA-PW-123 | عناوين بيئات مضمّنة | warning |
303
+ ### Selector Health Score
214
304
 
215
- </details>
305
+ يقيّم `mjolnir doctor:playwright` كل locator حسب طريقة عثوره على العنصر: كما يفعل المستخدم (الدور، التسمية، النص)، أو عبر عقد صريح (`data-testid`)، أو بمصادفة بنيوية (سلاسل CSS، XPath). يحصل كل ملف على درجة من 0 إلى 100:
216
306
 
217
- <details>
218
- <summary><strong>نزاهة CI</strong></summary>
219
-
220
- | ID | القاعدة | Severity |
221
- | --------- | ----------------------------------------------------------- | -------- |
222
- | QA-CI-001 | `continue-on-error` يُخفي الإخفاقات | error |
223
- | QA-CI-002 | `\|\| true` يبتلع رموز الخروج | error |
224
- | QA-CI-005 | تقرير يُستهلك ولا يُولَّد أبدًا | error |
225
- | QA-CI-007 | أغلفة محاولات حول الاختبارات | warning |
226
- | QA-CI-008 | خطوة دائمة النجاح تُخفي الإخفاقات | error |
227
- | QA-CI-009 | رمز خروج الاختبار لا يُمرَّر (`\|` بلا pipefail، سلاسل `;`) | error |
228
- | QA-CI-010 | اختبارات تُتجاوز حيث يجب أن تحجب (حرّاس skip-on-PR) | error |
229
-
230
- </details>
231
-
232
- <details>
233
- <summary><strong>Python / pytest 🐍</strong></summary>
234
-
235
- | ID | القاعدة | Severity |
236
- | --------- | ---------------------------------------- | -------- |
237
- | QA-PY-002 | اختبار متجاوز (`skip`، `xfail` غير صارم) | warning |
238
- | QA-PY-003 | دالة اختبار بلا تأكيدات | error |
239
- | QA-PY-005 | `time.sleep()` في الاختبارات | warning |
240
- | QA-PY-012 | تأكيد مُبرهن ذاتيًا | error |
241
-
242
- 20 قاعدة Python إجمالًا (QA-PY-001…012 نظافة pytest + QA-PY-101…108 Playwright-Python).
307
+ ```text
308
+ ▍ SELECTOR HEALTH
243
309
 
244
- </details>
310
+ e2e/login.spec.ts
311
+ [█████████████░░░░░░░] 65 / 100
312
+ role/text: 1 · testid: 0 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
245
313
 
246
- <details>
247
- <summary><strong>Java / JUnit · TestNG ☕</strong></summary>
314
+ e2e/checkout.spec.ts
315
+ [█████████████████░░░] 86 / 100
316
+ role/text: 3 · testid: 1 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
317
+ ```
248
318
 
249
- | ID | القاعدة | Severity |
250
- | --------- | ------------------------------------------ | -------- |
251
- | QA-JV-101 | اختبار معطَّل (`@Disabled`) | warning |
252
- | QA-JV-102 | سبات صارم (`Thread.sleep()`) | warning |
253
- | QA-JV-103 | طريقة اختبار بلا تأكيدات | error |
254
- | QA-JV-105 | سبات صارم في Playwright `waitForTimeout()` | warning |
255
- | QA-JV-106 | محدِّد هشّ بدل role locator | warning |
319
+ هذا يقيس **المتانة، لا الصحة**. ينجح `.btn.btn-primary > div:nth-child(2)` اليوم ويظل ينجح إلى أن يلمس أحدٌ الترميز. الدرجة المنخفضة لا تدّعي أبدًا أن الاختبار معطوب، بل فقط أنه يعتمد على ترميز لم يعد أحد بالحفاظ عليه.
256
320
 
257
- </details>
321
+ <br />
258
322
 
259
- <details>
260
- <summary><strong>C# / .NET — NUnit · xUnit · MSTest 🟣</strong></summary>
323
+ ## درجة الجدارة
261
324
 
262
- | ID | القاعدة | Severity |
263
- | --------- | ------------------------------------------- | -------- |
264
- | QA-CS-101 | اختبار متجاوز (`[Ignore]`، `[Fact(Skip=)]`) | warning |
265
- | QA-CS-102 | سبات صارم (`Thread.Sleep` / `Task.Delay`) | warning |
266
- | QA-CS-103 | طريقة اختبار بلا تأكيدات | error |
267
- | QA-CS-105 | سبات صارم `WaitForTimeoutAsync()` | warning |
268
- | QA-CS-106 | محدِّد هشّ بدل 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>
269
328
 
270
- </details>
329
+ <sub>كل درجة من 0 إلى 100، موضوعة بواسطة `deriveScoreState` الحقيقي. مولَّد بواسطة `npm run docs:gauge` ومقفل ضد الانحراف في CI.</sub>
271
330
 
272
- > الكتالوج الحي الكامل — كل قاعدة بطبقتها وثقتها وخطر إنذارها الكاذب
273
- > وتوافر إصلاحها الآلي — يُولَّد من السجل:
274
- >
275
- > ```bash
276
- > mjolnir rules --md
277
- > ```
278
- >
279
- > صفحات كل قاعدة تقع تحت [`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**: لم يُعثر على تعريفات اختبارات |
280
338
 
281
- ### كم من هذا مقيس
339
+ **كيف تُحسب.** تحدد الخطورة خصمًا أساسيًا (`error −8`، `warning −3`، `info −1`) ويخفّضه مستوى الدليل: E2 يُحتسب كاملًا، وE1 نصفه (مقرّبًا للأسفل)، وE0 لا شيء. يُطبَّع المجموع حسب تعرّض مجموعة الاختبارات، أي الخصومات لكل تعريف اختبار لا لكل ملف. تطبع الطرفية الأرقام المخفّضة نفسها التي استخدمتها الدرجة؛ ولا يوجد نموذج ثانٍ مخفي. التفاصيل: [docs/SCORING.md](docs/SCORING.md) و[دليل الدرجة](https://sergey-bar.github.io/Mjolnir/guide/scoring).
282
340
 
283
- **78 من 99 قاعدة تحمل معدل إنذارات كاذبة مقيسًا على كود OSS حقيقي**
284
- (≥ 10 اكتشافات مصنفة يدويًا لكل منها؛ راجع
285
- [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). الـ21 الأخرى تُشحن على تقدير
286
- المؤلف. ذيل كل فحص يخبرك كم من القواعد التي _انطلقت_ مقيسة؛ و
287
- `mjolnir rules --unmeasured` يسرد غير المقيسة؛ وصفحة `mjolnir explain`
288
- يدقّق عند 95% ولذلك هو في الحجر الصحي. تنمية ذلك العدد هي العمل
289
- المستمر للمشروع.
341
+ **ما لا تعنيه 100.** لا تعني أن البرنامج صحيح، ولا أن مجموعة الاختبارات كافية، ولا أن المنتج خالٍ من العيوب. تعني شيئًا واحدًا: **لم تُنتج أيٌّ من القواعد التي قيّمها Mjölnir خصمًا في هذا الفحص وضمن نموذج الأدلة هذا.**
290
342
 
291
- ### طبقات القواعد ونضج اللغات
343
+ <br />
292
344
 
293
- كل قاعدة هي `core` أو `extended` أو `quarantine`، تُخصَّص وفق معدل
294
- إنذاراتها الكاذبة **المقيس**:
345
+ ## نموذج الأدلة
295
346
 
296
- | الطبقة | المعنى | الفحص الافتراضي | `--strict` |
297
- | ------------ | ------------------------------- | :-------------: | :--------: |
298
- | `core` | ≤ 10% إنذارات مقيسة | ✅ | ✅ |
299
- | `extended` | ≤ 30% إنذارات مقيسة | ✅ | ✅ |
300
- | `quarantine` | فوق 30%، أو لم يقس بعد (n < 10) | ❌ | ✅ |
347
+ تحمل كل نتيجة وسمين: مدى تأكد Mjölnir، وإلى أي حد جرى التحقق من النتيجة. هذا هو الفرق بين أداة تبلّغ عن أنماط وأداة يمكنك أن تربط بها قرار الإصدار.
301
348
 
302
- | اللغة | المهايئ | التغطية اليوم |
303
- | --------------- | ----------- | ---------------------------------------------------- |
304
- | TypeScript / JS | AST المترجم | الأوسع والأكثر قياسًا — غالبًا `core`/`extended` |
305
- | Python / pytest | طبقة regex | واسعة، مدقَّقة على corpus — غالبًا `core`/`extended` |
306
- | Java | طبقة regex | أحدث — غالبًا `extended`/`quarantine` |
307
- | C# / .NET | طبقة regex | أحدث — غالبًا `extended`/`quarantine` |
349
+ **مدى التأكد — مستوى الدليل.**
308
350
 
309
- TypeScript وPython يمتلكان أوسع تغطية مقيسة. Java وC# مُشحونان وموثَّقان
310
- وتبقيان خارج الرقم الرئيسي حتى يُدقَّق طقم مستهلك حقيقي (لا اختبارات
311
- مكتبة الترابط نفسها).
351
+ | المستوى | الاسم | المعنى | الخصم |
352
+ | ------- | --------- | --------------------------------------------- | ----- |
353
+ | **E2** | دليل حتمي | العيب موجود في الشيفرة كما هي مكتوبة | كامل |
354
+ | **E1** | دليل نمطي | تطابق نمط مرتبط ارتباطًا وثيقًا بالعيب | نصف |
355
+ | **E0** | ملاحظة | تستحق المعرفة. ليست ادعاءً بأن شيئًا ما خاطئ. | صفر |
312
356
 
313
- ---
357
+ الثقة في الاكتشاف ليست قوة الدليل. قد تكون القاعدة متأكدة من أنها طابقت ما كانت تبحث عنه، ومع ذلك تنظر إلى استدلال تقريبي. نتائج E1 موجودة لتُقرأ ويُحكم عليها، لا لتُطبّق دون تمحيص، وهذا الحد مختوم على النتيجة في الطرفية وفي JSON وفي التسليم إلى الوكيل.
314
358
 
315
- ## كيف يعمل التنقيط
359
+ **إلى أي حد جرى التحقق — مستوى الثقة.** معظم النتائج تأتي من قراءة شيفرتك. أعطِ Mjölnir تقرير تشغيل اختبارات حقيقي ويمكنه أن يؤكد أن الشيفرة عملت فعلًا.
316
360
 
317
361
  <p align="center">
318
- <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%" />
319
363
  </p>
320
364
 
321
- <sub>يُعاد توليده بـ `npm run docs:hero`؛
322
- [`tests/hero-asset-reproducibility.spec.ts`](tests/hero-asset-reproducibility.spec.ts)
323
- يُسقط CI إذا انحرفت المخرجات عمّا يطبعه المُبلِّغ فعليًا.</sub>
365
+ | المستوى | بكلمات بسيطة | ما الذي يتطلبه |
366
+ | ------- | ---------------- | ------------------------------------------- |
367
+ | **L0** | مُلاحَظ | قراءة الشيفرة |
368
+ | **L1** | يبدو أنه المشكلة | قراءة الشيفرة: تطابق نمط |
369
+ | **L2** | مُثبت في الشيفرة | قراءة الشيفرة: العيب بنيوي |
370
+ | **L3** | الملف عمل | تقرير التشغيل يُظهر أن ملف النتيجة نُفّذ |
371
+ | **L4** | الاختبار عمل | تقرير التشغيل يُظهر أن اختبار النتيجة نُفّذ |
372
+ | **L5** | التشغيل يؤكد | نتيجة التشغيل نفسها تؤكد فئة العيب |
324
373
 
325
- الدرجة شفافة: **error −8، warning −3، info −1**، ثم تُطبَّع بمستوى تعرض
326
- الطقم (خصم لكل إعلان اختبار). الخصوم المرجَّحة بالأدلة تعني أن الإشارات
327
- الضعيفة أرخص. تعرض الطرفية الأرقام المخفَّضة نفسها التي تستخدمها الدرجة —
328
- لا صندوق أسود. المنهج الكامل: [docs/SCORING.md](docs/SCORING.md).
374
+ يتوقف الفحص الساكن عند L2. وحده تقرير تشغيل حقيقي (Playwright JSON، أو Jest أو Vitest JSON، أو JUnit XML) يمكنه رفع نتيجة إلى L3 أو أعلى، فالنتيجة التي لم تُرَ وهي تعمل لا يمكنها أبدًا أن تدّعي أنها عملت. التعريفات: [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md).
329
375
 
330
- **الأحكام**
376
+ ### كم من هذا مقيس
331
377
 
332
- | Score | الحكم |
333
- | ------- | ---------------- |
334
- | ≥ 80 | ✓ **WORTHY** |
335
- | 50 – 79 | ⚠ **NEEDS WORK** |
336
- | < 50 | ✖ **UNWORTHY** |
378
+ **74 من أصل 79 قاعدة لديها معدل إيجابيات كاذبة مقيس على شيفرة OSS حقيقية** (10 نتائج مصنّفة يدويًا على الأقل لكل منها؛ انظر [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). أما الـ 5 الأخرى فتُطلق بتقدير المؤلف وتقول ذلك، قاعدةً قاعدة، في `mjolnir explain`. يسردها `mjolnir rules --unmeasured`، ويبلّغ تذييل كل فحص عن عدد القواعد المقيسة من بين تلك التي _انطلقت_ فعلًا.
337
379
 
338
- **مستويات الدليل** — كل اكتشاف يحمل واحدًا؛ وهو يحدد وزن الاكتشاف في
339
- الدرجة:
380
+ تبقى المعدلات علنية حتى عندما تكون سيئة. نتيجة تدقيق QA-TEST-001 (‏`.only` بقي في commit) سيئة على المستودعات الحقيقية ولذلك يقبع في quarantine. الرقم الحالي لكل قاعدة، بما فيها QA-PW-141، موجود في التدقيق.
340
381
 
341
- | المستوى | المعنى | الأثر على الدرجة | مثال |
342
- | ------- | ------------ | ---------------- | ------------------------------------------------- |
343
- | E2 | عيب حتمي | خصم كامل | `.only` مودعة — قابلة للإثبات بنيويًّا |
344
- | E1 | نمط استدلالي | نصف الخصم | `sleep()` أعادته regex — إشارة قوية، ليست برهانًا |
345
- | E0 | ملاحظة | صفر (إخباري فقط) | يُبلَّغ عنه لكنه لا يبوّت CI أبدًا ولا يخصم |
382
+ ### مستويات الثقة بالقواعد
346
383
 
347
- معظم القواعد **E1**. شعار «we prove it» يشير إلى هذا النظام: اكتشافات
348
- E2 إثبات بنيوي؛ واكتشافات E1 تحذيرات موزونة الموضع، لا براهين رسمية.
384
+ تتبع المستويات معدل الإيجابيات الكاذبة المقيس، لا الرأي:
349
385
 
350
- المستودع الفارغ يحصد `null`، لا 100 مزوّرة أبدًا — انظر
351
- [نموذج الثقة](#نموذج-الثقة).
386
+ | المستوى | ‏FP المقيس | السلوك |
387
+ | -------------- | ------------------------- | ------------------------------------------------------ |
388
+ | **core** | ≤ 10% | التقرير الافتراضي، يمنع الدمج |
389
+ | **extended** | ≤ 30% | التقرير الافتراضي، ثقة أقل |
390
+ | **quarantine** | > 30% أو مُعلن عنه صراحةً | مع `--strict` فقط، محدود عند info، لا يمنع الدمج أبدًا |
391
+ | _غير مقيسة_ | n < 10 | لا يمكن ترقيتها إلى core قبل قياسها |
352
392
 
353
- ---
393
+ يمكن لأحزمة FP أن تخفض مستوى القاعدة فقط — لا تُرقى قاعدة من `quarantine` أبدًا إذا أُعلن عنها هناك صراحةً. تبقى القاعدة المُحجرة صراحةً في quarantine بغض النظر عن معدل الإيجابيات الكاذبة المقيس.
354
394
 
355
- ## 🎭 Selector Health Score
395
+ الترقية والتخفيض والنضج حسب اللغة: [دورة حياة القواعد](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle).
356
396
 
357
- المقياس الرئيسي لأطقم Playwright — ما مدى صمود محدِّداتك:
397
+ ### لماذا هذا ليس linter
358
398
 
359
- ```text
360
- ▚ SELECTOR HEALTH — e2e/checkout.spec.ts
399
+ أدوات linter تخبرك إن كانت الشيفرة تتبع القواعد. Mjölnir يخبرك إن كان يمكن الوثوق بعملية التحقق لديك.
361
400
 
362
- [█████████████████░░░] 83 / 100
363
- role/text: 2 · testid: 1 · css-chains: 1 ⚠ · xpath: 0
364
- ```
401
+ | | أدوات linter ‏(ESLint، SonarQube) | أدوات التغطية | مراجعة الشيفرة بالذكاء الاصطناعي | **Mjölnir** |
402
+ | ------------------------------------------------------------- | :-------------------------------: | :-----------: | :------------------------------: | :--------------: |
403
+ | يقيّم **نظام التحقق**، لا شيفرة المنتج | لا | لا | لا | نعم |
404
+ | سلامة ملفات workflow في CI (`continue-on-error`، `\|\| true`) | لا | لا | الفرق فقط | نعم |
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. تصف الأعمدة السلوك الافتراضي للتحقق من مجموعات الاختبار؛ والإضافات والخطط المدفوعة والقواعد المخصصة تغيّر بعض الإجابات. هذا ملخص تموضع، وليس اختبار أداء مقارنًا.</sub>
365
414
 
366
- المحدِّدات القائمة على الدور تحصد الدرجة الكاملة. سلاسل أصناف CSS وXPath
367
- تبطئ الدرجة — تتحطم مع أي إعادة هيكلة DOM دون إخبارك بأي سلوك ارتدّ.
415
+ استخدم مراجعة الذكاء الاصطناعي أيضًا. فهي تلتقط الفروق الدقيقة والنية وعيوب التصميم التي لا يجدها أي نمط. ويلتقط Mjölnir ما تغفله مراجعة الذكاء الاصطناعي لأنه يبدو مقصودًا: `.only` بقي في commit، ورمز خروج مبتلع، و`continue-on-error` على job اختبار. هذه تحتاج إلى فحص، لا إلى استدلال.
368
416
 
369
- ---
417
+ <br />
370
418
 
371
- ## 🔬 أدلة التنفيذ
419
+ ## تحليل تشغيلات الاختبار
372
420
 
373
- الكشف الثابت عن التذبذب مجرد تخمين. يقرأ Mjölnir **بيانات تنفيذ حقيقية** —
374
- تقارير JSON من Playwright وXML من JUnit من أي مشغّل:
421
+ التحليل الساكن يستدل على شيفرة لم تعمل قط. أما تحليل التشغيلات فيقرأ ما حدث فعلًا: Playwright JSON وJest JSON وVitest JSON وJUnit XML من أي أداة تشغيل.
375
422
 
376
423
  ```bash
377
424
  mjolnir forensics ./test-results/
378
425
  ```
379
426
 
380
427
  ```text
381
- ▚ FLAKINESS LEADERBOARD
428
+ ▍ FLAKINESS LEADERBOARD
382
429
 
383
430
  3 tests · 1 failed · 1 flaky · 1 retried
384
431
 
@@ -388,275 +435,184 @@ FAILING declines an expired card (e2e/checkout.spec.ts)
388
435
  ████░░░░░░░░░░░░░░░░ 1.1s · 1 attempt
389
436
  ```
390
437
 
391
- الاختبار الذي ينجح من المحاولة ≥ 2 فقط ليس اختبارًا ناجحًا — إنه اختبار
392
- محظوظ. يوسم `TRUE-FLAKE` بغضّ النظر عن علامة النجاح الخضراء النهائية.
438
+ لا يعني `TRUE-FLAKE` أن الاختبار أُعيدت محاولته. بل يعني أن الاختبار **فشل في محاولة واحدة على الأقل ثم انتهى باللون الأخضر**: نجاح بالحظ، يُعلَّم مهما قالت علامة الصح النهائية. يحوّل `mjolnir triage` هذا السجل إلى اقتراح عزل، ويلخّص `mjolnir pw-report` التشغيل. وتقارير التشغيل نفسها هي ما يرفع النتائج إلى مستويات الثقة L3 فما فوق.
393
439
 
394
- ---
440
+ <br />
395
441
 
396
- ## ⚡ Mjölnir ليس أداة lint أخرى
442
+ ## سلامة CI
397
443
 
398
- أدوات lint تخبرك إن كان الكود يتبع القواعد. Mjölnir يخبرك إن كان يمكن
399
- الثقة بتحقّقك.
444
+ قد ينجح اختبار بينما خط CI المحيط به لا يستطيع أن يفشل. يقرأ Mjölnir ملفات workflow أيضًا: `continue-on-error`، و`|| true`، ورموز خروج لا تُمرَّر أبدًا، وخطوات تنجح دائمًا، وتقارير تُستهلك ولا تُنشأ، وبوابات تُتخطى في الأحداث نفسها التي يجب أن تمنع الدمج. كل نتيجة تسمّي الـ job والخطوة والسطر، وتحمل مستوى دليلها الخاص.
400
445
 
401
- | | ESLint / SonarQube | أدوات التغطية | المراجعة اليدوية | **Mjölnir** |
402
- | ---------------------------------------------------- | :----------------: | :-----------: | :--------------: | :---------: |
403
- | نزاهة أسيرات CI (`continue-on-error`، `\|\| true`) | ❌ | ❌ | نادرًا | ✅ |
404
- | عبر اللغات (TS، Python، Java، C#) من أداة واحدة | ❌ | ❌ | ❌ | ✅ |
405
- | يقيّم صمود محدِّدات Playwright (Selector Health) | ❌ | ❌ | نادرًا | ✅ |
406
- | يميّز الاختبارات بلا تأكيدات حقيقية | ✅ (إضافة)\* | ❌ | أحيانًا | ✅ |
407
- | يلتقط السبات الصارم (`waitForTimeout`، `time.sleep`) | ✅ (إضافة)\* | ❌ | أحيانًا | ✅ |
408
- | يجري في ثوانٍ، صفر نداءات شبكة أثناء الفحص | ✅ | ✅ | — | ✅ |
446
+ أنشئ workflow طلبات الدمج، استشاريًا افتراضيًا:
409
447
 
410
- \*`eslint-plugin-jest` (`expect-expect`) و`eslint-plugin-playwright`
411
- (`expect-expect`، `no-wait-for-timeout`) يغطيان ذلك لإطاريهما.
448
+ ```bash
449
+ mjolnir ci install
450
+ ```
412
451
 
413
- **التحليل التنفيذي** فئة منفصلة عن الـlint الثابت:
452
+ أو أضف الـ action من Marketplace إلى workflow لديك بالفعل:
414
453
 
415
- | | Playwright retry reporter | Allure / ReportPortal | **Mjölnir forensics** |
416
- | -------------------------------------------- | :-----------------------: | :-------------------: | :-------------------: |
417
- | يقرأ بيانات تشغيل حقيقية لأحكام `TRUE-FLAKE` | جزئيًّا\* | جزئيًّا (tag) | ✅ |
418
- | تقرير فرز التذبذب من سجل التنفيذ | ❌ | ✅ | ✅ |
419
- | يتكامل مع درجة الجدارة الثابتة | ❌ | ❌ | ✅ |
454
+ ```yaml
455
+ - uses: Sergey-Bar/Mjolnir@v1
456
+ with:
457
+ scope: changed
458
+ fail-on: error
459
+ ```
420
460
 
421
- \*Playwright يتتبع المحاولات داخليًا لكنه لا ينتج تقرير تذبذب مستقلًّا
422
- بملصقات أحكام.
461
+ ثبّت `@v1` لتتبع الخط الرئيسي، أو وسمًا دقيقًا (`@v0.5.32`) لبوابة قابلة لإعادة الإنتاج. يغطي [docs/DISTRIBUTION-KIT.md](docs/DISTRIBUTION-KIT.md) كلًّا من Marketplace وSmithery وسجلات MCP.
423
462
 
424
- ---
463
+ لوضع النتائج في GitHub Code Scanning، ارفع SARIF (يتطلب `security-events: write` على مستوى الـ workflow أو الـ job):
425
464
 
426
- ## 🤖 لماذا لا تكتفون بمراجعة الكود بالذكاء الاصطناعي؟
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
+ ```
427
473
 
428
- مشكلة مختلفة، طبقة مختلفة. المراجعة الآلية قد تلتقط تغيير اختبار مشبوهًا
429
- في فرق؛ لكنها لا تثبت أن نظام التحقق ككل جدير بالثقة — وهي لا ترى إلا
430
- الفرق الذي تريه لها.
474
+ على GitLab، يكتب `--format codequality` تقرير Code Quality الذي تقرؤه أداة طلب الدمج وتعليقات الفرق ([docs/GITLAB-CI.md](docs/GITLAB-CI.md)). إعداد المحرر وخط CI: [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
431
475
 
432
- | | مراجعة بالذكاء الاصطناعي (Copilot وغيره) | **Mjölnir** |
433
- | ----------------------------- | :--------------------------------------: | :-------------------------------: |
434
- | الكلفة لكل فحص | رموز (تتدرج بحجم الفرق) | **صفر** (محلي، مثبَّت) |
435
- | يرى الطقم كله + كل إعدادات CI | الفرق الذي تريه فقط | **كل شيء، كل مرة** |
436
- | حتمي (مدخل واحد → مخرج واحد) | ❌ (غير حتمي) | **✅** |
437
- | يلتقط أنماطًا راقدة أشهرًا | فقط إن وردت في السياق | **✅** (يفحص كل الملفات) |
438
- | يتذكر الاكتشافات بين الجولات | ❌ (لا ذاكرة عبر الجلسات) | **✅** (baseline + diff) |
439
- | يعمل دون استداء بشري | يحتاج PR أو موجهًا | **✅** (خُطّاف CI، يعمل في ثوانٍ) |
476
+ ### إسناد النتائج إلى نطاق التغييرات
440
477
 
441
- **استخدم كليهما.** يلتقط الذكاء الاصطناعي الدقائق والقصد وعيوب التصميم
442
- التي لا يعثر عليها أي regex. يلتقط Mjölnir الأنماط البنيوية التي يغفلها
443
- الذكاء الاصطناعي لأنها تبدو «مقصودة» — `.only` مودعة، ورمز خروج مبتلع،
444
- و`continue-on-error` على مهمة اختبار. ليست أخطاء تحتاج تفكيرًا؛ بل حقائق
445
- تحتاج فحصًا.
478
+ ```bash
479
+ npx mjolnir-qa@latest --scope changed
480
+ ```
446
481
 
447
- ---
482
+ تُسند النتائج إلى الأسطر التي أضافها فرعك، مقيسةً مقابل **merge-base**. النطاق هو مجموعة الملفات نفسها التي يكتشفها الفحص الكامل (ملفات spec لـ TS/JS وإعدادات المحوّلات، `test_*.py`، `*Test.java`، `*Tests.cs`، `.github/workflows/*.yml`)، إضافة إلى التغييرات غير المُثبتة وغير المتتبَّعة، لذا يعمل قبل أن تُجري commit. يُحدَّد الأساس بالترتيب `main → master → origin/main → origin/master → origin/HEAD`؛ ويمكنك تجاوزه بـ `--base <ref>`.
448
483
 
449
- ## 🤖 تكامل CI
484
+ عندما يتعذر تحديد merge-base (نسخة ضحلة، أو HEAD منفصل، أو هدف خارج git)، تعود النتائج إلى الإسناد إلى الملف كاملًا **ويقول التقرير ذلك.** فالتراجع الصامت سيكون تمامًا نوع العيب الذي وُجدت هذه الأداة لالتقاطه.
450
485
 
451
- أمر واحد يولّد سير عمل PR — استشاري افتراضيًا، ولا يحجب أبدًا:
486
+ <br />
452
487
 
453
- ```bash
454
- mjolnir ci install
455
- ```
488
+ ## وكلاء الذكاء الاصطناعي
456
489
 
457
- أو اربطه أصلًا في GitHub Code Scanning عبر SARIF:
490
+ لا قيمة للنتائج إلا إذا تصرّف شيء بناءً عليها.
458
491
 
459
- ```yaml
460
- - run: npx mjolnir-qa@latest --format sarif > mjolnir.sarif
461
- - uses: github/codeql-action/upload-sarif@v3
462
- with:
463
- sarif_file: mjolnir.sarif
492
+ ```text
493
+ SCAN → EVIDENCE → HANDOFF → AGENT → RE-SCAN → PROOF
464
494
  ```
465
495
 
466
- إعداد المحرر والخط لـ SARIF:
467
- [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
496
+ **الذكاء الاصطناعي يكتب الإصلاح. Mjölnir يتحقق منه.** يأتي الدليل من إعادة الفحص، لا من تقرير الوكيل نفسه عن نجاحه.
468
497
 
469
- ### تغطية النطاق المتغيّر
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`) حتى يعيد الوكيل الفحص قبل أن يدّعي أنه انتهى. |
470
503
 
471
- `--scope changed` يسند الاكتشافات إلى الأسطر التي أضافها فرعك مقارنة
472
- بنقطة دمج `main`. يغطي ملفات الاختبار (`*.spec.*`، `*.test.*`) زائد
473
- ملفات أسيرات GitHub وإعدادات Playwright في الفرق. عندما يتعذّر فهم
474
- نقطة الدمج — نسخة سطحية، HEAD منفصل، هدف بلا git، فرع افتراضي مختلف —
475
- يتدهور بصدق: تعود الاكتشافات إلى الإسناد بملف كامل والتقرير يقول ذلك.
476
- استبدل المرجع الأساس بـ `--base <ref>`.
504
+ أضفه إلى عميل يأتي مع CLI خاص به:
477
505
 
478
- ---
479
-
480
- ## الإعداد
481
-
482
- Mjölnir صفر إعداد. ملف `mjolnir.config.json` اختياري (أو `.mjolnir.json`)
483
- في جذر المستودع يضبط الشدة والحجب والنطاق — لا يغيّر دلالات الكشف أبدًا.
506
+ ```bash
507
+ claude mcp add mjolnir -- npx -y mjolnir-qa@latest mcp
508
+ ```
484
509
 
485
- | المفتاح | النوع | الأثر |
486
- | ------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
487
- | `exclude` | `string[]` | أنماط تجاهل إضافية (مجموعة فرعية من gitignore)، فوق الافتراضيات المدمجة |
488
- | `gate` | `"advisory" \| "error" \| "warning"` | أي شدّات تخرج برمز غير صفري (الافتراضي `error`؛ `advisory` لا يحجب أبدًا) |
489
- | `severityOverrides` | `{ "<RULE-ID>": severity }` | يعيد ترتيب اكتشافات قاعدة لمستودعك |
490
- | `ignore` | `IgnoreEntry[]` | يكتم الاكتشافات — **`reason` إلزامي**؛ تنتهي صلاحية المدخلات بعد 90 يومًا (تاريخ `expires` صريح، أو زمن آخر تعديل لملف الإعداد لمن لا يذكره) |
491
- | `plugins` | `string[]` | حزم قواعد من طرف ثالث (انظر [نموذج الثقة](#نموذج-الثقة)) |
510
+ أو إلى أي عميل يقبل كتلة `mcpServers`:
492
511
 
493
512
  ```json
494
513
  {
495
- "gate": "error",
496
- "exclude": ["legacy/**"],
497
- "severityOverrides": { "QA-PW-141": "warning" },
498
- "ignore": [
499
- {
500
- "ruleId": "QA-TEST-004",
501
- "files": ["e2e/legacy-login.spec.ts"],
502
- "reason": "Third-party widget needs a settle delay; tracked in JIRA-4821",
503
- "expires": "2026-12-31"
504
- }
505
- ]
514
+ "mcpServers": {
515
+ "mjolnir": { "command": "npx", "args": ["-y", "mjolnir-qa@latest", "mcp"] }
516
+ }
506
517
  }
507
518
  ```
508
519
 
509
- - **`.mjolnirignore`** — ملف بأسلوب gitignore بسيط لاستثناء المسارات،
510
- بنفس لهجة `exclude`. استخدمه للضجيج الخاص بالجهاز؛ واستخدم `exclude`
511
- عندما تعود القائمة للتحكم بالإصدارات إلى جانب بقية الإعداد.
512
- - **تجاوزات سطر الأوامر** — `--strict` (تضمين قواعد الحجر الصحي)،
513
- `--width <cols>` و`--ascii` / `--no-ascii` (عرض الطرفية)،
514
- `--tone blunt` (رسائل أقسح)، `--max-duration <sec>` (فحص جزئي محدود).
515
- - كتم القواعد ودورة إخراجها من الخدمة:
516
- [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md).
517
-
518
- مدخلات `ignore` تُغذّي أيضًا الأمر المستقل `mjolnir suppressions` الذي
519
- يسرد ما هو مكتوم الآن ومتى تنتهي صلاحية كل مدخل.
520
-
521
- ---
522
-
523
- ## 📐 رموز الخروج والعقود
524
-
525
- مجمَّدة — آمنة لبناء منطق CI فوقها:
526
-
527
- | رمز الخروج | المعنى |
528
- | ---------- | ---------------------------------------------------------------------- |
529
- | `0` | نظيف — لا اكتشافات عند البوابة أو فوقها |
530
- | `1` | اكتشافات عند البوابة أو فوقها |
531
- | `2` | فحص جزئي (نفدت ميزانية الوقت، ملفات غير قابلة للقراءة) — لا يحجب أبدًا |
532
- | `10` | خطأ استعمال (راية خاطئة، غياب هدف) |
533
- | `20` | خطأ داخلي |
534
-
535
- تقرير JSON/SARIF هو `schemaVersion: 1`. معرّفات القواعد
536
- (`QA-<FAMILY>-NNN`) لا تتغير بعد الإطلاق ولا تُعاد استخدامها أبدًا.
537
-
538
- ---
539
-
540
- ## نموذج الثقة
541
-
542
- - **Local-first** — صفر نداءات شبكة أثناء الفحص. قطعًا. صفر قياس عن بُعد.
543
- - **لا برهان كاذب** — نقول «مجهول» قبل «متحقَّق منه». المستودع الفارغ
544
- يأخذ `score: null`، لا 100 مزوّرة.
545
- - **صدق جزئي** — إذا قُطع التحليل قَصِرًا، يقول الناتج ذلك. لا «complete»
546
- أبدًا حين لا يكون.
547
- - **جدار الإنذارات الكاذبة** — يعمل الكشف على رؤية كود خالية من
548
- التعليقات/النصوص (قواعد TypeScript تستخدم AST المترجم): النمط داخل
549
- تعليق نثري أو نص مثال توثيقي توثيق، لا اكتشاف.
550
- - **مقيس، لا مُدَّعى** — فقط القواعد ذات معدل إنذارات كاذبة من كود OSS
551
- حقيقي تُشحن في الطبقات الرئيسية (انظر
552
- [كم من هذا مقيس](#كم-من-هذا-مقيس))؛ ذيل الفحص و`mjolnir rules --unmeasured`
553
- يخبرانك أيُّها أي.
554
- - **الثقة بالإضافات وبوابة التنفيذ** — الإضافات حزم npm معلنة تحت
555
- `"plugins"`؛ وحدات JS تعيش في `mjolnir-rules/*.mjs`.
556
- **لا غرفة رمل**: كود الإضافة يجري بكامل صلاحيات Node، النموذج نفسه
557
- لإضافات ESLint أو Vitest. لهذا فإن تنفيذ الكود **اختياري في كل فحص**:
558
- مرّر `--enable-plugins` (أو اضبط `MJOLNIR_ENABLE_PLUGINS=1`)، وإلا
559
- فلن تُحمَّل المصادر — تنبيه صريح على stderr يسرد بالضبط ما تم تخطيه.
560
- فحص كود غير موثوق لا ينفّذه أبدًا. بيانات القواعد JSON
561
- (`mjolnir-rules/*.json`) غير متأثرة: تعلن أنماط regex ولا تنفذ أي
562
- كود بحكم تصميمها. بادئات معرّفات القواعد الأساسية محجوزة
563
- وتُرفض من الإضافات والقواعد الخارجية منعًا للانتحال.
564
- - **قواعد خارجية محلية للمساحة** (مجلدية، صفر شبكة) — مجلد
565
- `mjolnir-rules/` بجوار هدف الفحص يحمّل قواعد مخصصة: ملفات JSON تعلن
566
- أنماط regex (لا يُنفَّذ كود)، ووحدات `.mjs`/`.js` تصدّر `rules` (ثقة
567
- Node كاملة، كالإضافات). القواعد الخارجية تحمل البيانات الوصفية للثقة
568
- نفسها كالأساسية؛ لا يمكنها أبدًا أن تُشحن في الطبقة الأساسية (الأساسية
569
- تشترط معدل إنذارات مقيسًا من ملف corpus الجانبي — التصريح بـ
570
- `tier: "core"` يُقصر إلى `extended`)، وتلتزم سقوف الطبقات وتُفحص ضد
571
- الانحراف: `mjolnir rules --md --external` يعرض الكتالوج من الملفات
572
- المحمّلة (المصدر `external`)، ومولّد المصفوفة يقبل `--external <root>`.
573
-
574
- ---
575
-
576
- ## 🏗️ المعمارية
520
+ **الحاجز الواقي أهم من الراحة.** كل نتيجة في التسليم تحمل حدّها. يقول **E2** _حتمي: تحقق من الموضع وطبّق الإصلاح_. ويقول **E1** _يتطلب تأكيدًا: الملاحظة وحدها لا تثبت العيب_. الوكيل الذي يصلح E1 دون تمحيص، أو يكتم قاعدة، أو يعدّل قاعدة لرفع الدرجة، يفعل تمامًا ما وُجدت هذه الأداة لالتقاطه، ولذلك يقول التسليم ذلك في الموجِّه، بجوار النتيجة.
577
521
 
578
- <details>
579
- <summary>فصّل الشجرة</summary>
522
+ <br />
580
523
 
581
- ```
582
- mjolnir/
583
- ├── src/
584
- │ ├── engine/ # LanguageAdapter interface + rule runner
585
- │ ├── adapters/ # typescript · python · java · csharp · github-actions
586
- │ ├── rules/ # rules across 8 families + the measured-FP table
587
- │ ├── playwright/ # Selector Health Score engine
588
- │ ├── discovery/ # workspace, frameworks, ignore resolution
589
- │ ├── scope/ # git merge-base changed-scope engine
590
- │ ├── scorer/ # transparent deduction table + prioritization
591
- │ ├── reporter/ # terminal · JSON · SARIF 2.1 · Mermaid
592
- │ ├── forensics/ # run-data ingestion · flake verdicts · triage
593
- │ ├── config/ # mjolnir.config.json + suppressions
594
- │ ├── plugins/ # third-party rule loading (no sandbox)
595
- │ └── commands/ # every subcommand
596
- └── tests/
597
- ├── fixtures/ # must-fire / must-not-fire per rule
598
- └── golden/ # frozen score regression locks
599
- ```
524
+ ## الثقة والأمان
600
525
 
601
- </details>
526
+ **محلي أولًا، بلا أي قياس عن بُعد.** لا توجد أي واجهة برمجية قادرة على الاتصال بالشبكة (`fetch`، `http`، `https`، `net`، `dns`، `dgram`، WebSocket) في أي مكان داخل `src/`، ويُفشل [`privacy-network-isolation.spec.ts`](tests/contract/privacy-network-isolation.spec.ts) عملية البناء إذا ظهرت واحدة. ويحظر أيضًا `eval` و`new Function`. فحص شيفرة غير موثوقة لا ينفّذها أبدًا: التحليل الساكن يقرأ النص المصدري، وتحليل التشغيلات يحلّل ملفات تقارير موجودة أصلًا على القرص.
527
+
528
+ تحفظان: `npx` نفسه يجلب الحزمة قبل أن يعمل أي شيء، والضمان يغطي `src/` وليس إضافات الأطراف الثالثة.
529
+
530
+ **الإضافات لا تعمل في بيئة معزولة.** إضافات JS (`mjolnir-rules/*.mjs`، أو حزم npm المدرجة تحت `"plugins"`) تعمل بصلاحيات Node كاملة، بنموذج الثقة نفسه الخاص بإضافات ESLint أو Vitest. تحميلها اختيار صريح **لكل فحص**: من دون `--enable-plugins` (أو `MJOLNIR_ENABLE_PLUGINS=1`) لا تُحمَّل مصادرها أبدًا، ويسرد إشعار على stderr ما جرى تخطيه. ملفات تعريف القواعد بصيغة JSON لا تنفّذ أي شيفرة، وبادئات معرّفات قواعد core محجوزة حتى لا تنتحل إضافةٌ صفة إحداها. أبلغ عن الثغرات عبر [SECURITY.md](SECURITY.md).
531
+
532
+ **يعمل على نفسه.** لا مصداقية لمحرك ثقة في التحقق ما لم يكن هو نفسه قابلًا للتحقق. كل تشغيل لـ CI يفحص هذا المستودع بالبناء الذي أنتجه التشغيل نفسه. تفشل البوابة عند أي نتيجة بخطورة error، وكذلك عند فحص **جزئي** أو **قاعدة انهارت**، لأن فحصًا ذاتيًا مبتورًا لا يبلّغ عن شيء هو بالضبط الأخضر الزائف الذي وُجد هذا المشروع لالتقاطه. يعيد `mjolnir doctor` تدقيق قاعدة القواعد في التشغيل نفسه (جدار حماية الـ fixtures، وصدق المستويات، وسقف مستوى core)، والفحص الذي نتيجته INCONCLUSIVE يفشل تمامًا كالفحص الفاشل. ويُرفع التقريران كنواتج بناء.
533
+
534
+ ### رموز الخروج وعقد الآلة
602
535
 
603
- - **القواعد دوال نقية** — `(SourceFileContext) → Finding[]`، بلا I/O،
604
- بلا متغيرات عامة. إضافة بيئة جديدة = مهايئ واحد + قواعده.
605
- - **TypeScript/Playwright تستخدم AST المترجم** (ts-morph). Python وJava
606
- وC# تجري على طبقة regex مشتركة مع إخفاء التعليقات/النصوص.
607
- - طبقة AST من tree-sitter WASM لـ Java وC# موجودة وهي خطوة الدقة التالية —
608
- لم تُوصَّل بعد إلى خط الفحص المتزامن.
536
+ مجمّدة، حتى تتمكن من بناء منطق CI عليها:
609
537
 
610
- ---
538
+ | رمز الخروج | المعنى |
539
+ | ---------- | --------------------------------------------------------------------- |
540
+ | `0` | نظيف: لا نتائج عند مستوى البوابة أو فوقه |
541
+ | `1` | نتائج عند مستوى البوابة أو فوقه |
542
+ | `2` | فحص جزئي (نفدت ميزانية الوقت، ملفات غير مقروءة). لا يمنع الدمج أبدًا. |
543
+ | `10` | خطأ في الاستخدام (خيار غير صالح، هدف مفقود) |
544
+ | `20` | خطأ داخلي |
611
545
 
612
- ## 📚 الوثائق
546
+ ‏`2` مختلف عن `0` عمدًا: الفحص الذي لم يكتمل لم "يجد لا شيء". هو ببساطة لم ينتهِ من البحث.
613
547
 
614
- | المستند | ما فيه |
615
- | ------------------------------------------------------ | ----------------------------------------- |
616
- | [docs/SCORING.md](docs/SCORING.md) | تطبيع الدرجة + ترجيح الأدلة |
617
- | [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | معدلات الإنذارات الكاذبة المقيسة + المنهج |
618
- | [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | حالات القواعد، الكتم، الإخراج من الخدمة |
619
- | [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | ناتج SARIF + إعداد المحرر/CI |
620
- | [docs/rules/](docs/rules/) | كتالوج مولَّد لكل قاعدة |
621
- | [CONTRIBUTING.md](CONTRIBUTING.md) | تجهيز التطوير + مساهَمة العمل |
622
- | [CHANGELOG.md](CHANGELOG.md) | سجل الإصدارات |
623
- | [SECURITY.md](SECURITY.md) | الإبلاغ عن الثغرات |
548
+ كل ما تستهلكه الآلة (نتائج أدوات MCP، و`--json`، وSARIF 2.1) يأتي من نتيجة معيارية واحدة وفق مخطط ذي إصدارات **لا يتوسع إلا بالإضافة** (`schemaVersion: 1`، `contractVersion: 1`)، فلا يضطر أي مستهلك إلى إعادة بناء المعنى من نص معروض. انظر [عقد الآلة](docs/machine-contract.md). معرّفات القواعد (`QA-<FAMILY>-NNN`) لا تتغير بعد إطلاقها ولا يُعاد استخدامها أبدًا.
624
549
 
625
- ---
550
+ <br />
626
551
 
627
- ## 📈 الحالة
552
+ ## ما لا يستطيع Mjölnir أن يخبرك به
628
553
 
629
- **v0.5.x · بيتا مفتوحة.** مخطط JSON ورموز الخروج عقود مجمَّدة. TypeScript
630
- وPython لهما أوسع تغطية مقيسة؛ Java وC# أحدث — اقرأهما عبر
631
- [جدول الطبقات](#طبقات-القواعد-ونضج-اللغات).
554
+ - **لا يشغّل اختباراتك.** الفحص النظيف ليس مجموعة اختبارات ناجحة.
555
+ - **لا يستطيع أن يخبرك بأن تأكيدًا ما _خاطئ_.** يبدو `expect(total).toBe(41)` سليمًا. يجد Mjölnir اختبارات _لا يمكن أن تفشل_ وخطوط CI _لا يمكن أن تتحول إلى الأحمر_، لا الاختبارات التي تتحقق من الشيء الخطأ.
556
+ - **لا يثبت صحة منطق العمل.** لا شيء هنا يقول إن منتجك يفعل ما طلبته المتطلبات.
557
+ - **الـ 100 ليست دليلًا على مجموعة اختبارات جيدة.** أما إن كانت مجموعتك تغطي مخاطرك الحقيقية فذلك سؤال مختلف، وهذه الأداة لا تجيب عنه.
558
+ - **5 من أصل 79 قاعدة تُطلق بناءً على تقدير**، لا على معدل مقيس. وكل واحدة منها تقول ذلك في نتيجتها.
559
+ - **E1 ليس E2.** النتائج الاستدلالية تستحق القراءة، لا التطبيق دون تمحيص.
560
+ - **المستودع الفارغ يحصل على `null`، لا على 100 أبدًا.**
561
+ - **الملف المسمى `*.spec.ts` الذي لا يحتوي تعريفات اختبارات لا يُحتسب تغطية.** المستودع الذي لا تحتوي ملفات spec الوحيدة فيه إلا على imports أو أنواع (صفر استدعاءات `it`/`test`) يحصل على `null`، لا على 100.
632
562
 
633
- ---
563
+ <br />
634
564
 
635
- ## 🤝 المساهمة
565
+ ## التوثيق
636
566
 
637
- القواعد الجديدة أسهل مساهمة أولى — أمر واحد يهيكل القاعدة مع تجهيزاتها
638
- must-fire **و**must-not-fire (القاعدة المولَّدة تفشل في تجهيزاتها عمدًا
639
- حتى تنفّذ كشفًا حقيقيًا — الهيكل الفارغ لا يُشحن):
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، ووصفة طلب الدمج، والبوابة |
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 الخاصة بها عمدًا إلى أن يُكتب اكتشاف حقيقي، لأن الهيكل الفارغ الذي يُطلق هو قاعدة لم يقسها أحد:
640
592
 
641
593
  ```bash
642
594
  mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
643
595
  ```
644
596
 
645
- التجهيز التطويري الكامل، وأوامر البوابة الدائمة، وقوانين منع التوسع /
646
- جدار التجهيزات في [CONTRIBUTING.md](CONTRIBUTING.md).
597
+ إعداد بيئة التطوير، وأوامر البوابات الدائمة، وقانونا anti-creep وجدار حماية الـ fixtures موجودة في [CONTRIBUTING.md](CONTRIBUTING.md).
647
598
 
648
- ---
599
+ <br />
649
600
 
650
601
  <div align="center">
651
602
 
652
- **كفّوا عن شحن اختبارات لا تثقون بها.**
603
+ <img src="assets/readme/closing.svg" alt="شغّله على مستودعك." width="100%" />
653
604
 
654
605
  ```bash
655
606
  npx mjolnir-qa@latest
656
607
  ```
657
608
 
658
- **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
+ اسأل إن كانت الأدلة تثبت أنها تستحق الثقة.
659
615
 
660
- بُني على يد [Sergey Bar](https://www.linkedin.com/in/sergeybar/)
616
+ <sub>من تطوير [Sergey Bar](https://www.linkedin.com/in/sergeybar/) · برخصة MIT</sub>
661
617
 
662
618
  </div>