mjolnir-qa 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2909 -15
- package/README.md +81 -760
- package/dist/cli.d.mts +459 -290
- package/dist/cli.mjs +31329 -15271
- package/dist/mcp/stdio.mjs +916 -228
- package/package.json +59 -32
- package/README.ar.md +0 -647
- package/README.bn.md +0 -647
- package/README.br.md +0 -647
- package/README.bs.md +0 -647
- package/README.da.md +0 -647
- package/README.de.md +0 -647
- package/README.es.md +0 -647
- package/README.fr.md +0 -647
- package/README.gr.md +0 -647
- package/README.he.md +0 -647
- package/README.it.md +0 -647
- package/README.ja.md +0 -647
- package/README.ko.md +0 -647
- package/README.no.md +0 -647
- package/README.pl.md +0 -647
- package/README.ru.md +0 -647
- package/README.th.md +0 -647
- package/README.tr.md +0 -647
- package/README.uk.md +0 -647
- package/README.vi.md +0 -647
- package/README.zh.md +0 -647
- package/README.zht.md +0 -647
- package/dist/scan-pipeline-DNYbnWjE.mjs +0 -2
- package/dist/scan-pipeline-DT8DWAMl.mjs +0 -16501
package/README.uk.md
DELETED
|
@@ -1,647 +0,0 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
<img src="assets/readme/hero.svg" alt="Mjölnir. Тести кажуть, що пройшло. Mjölnir каже, чому можна довіряти." width="100%" />
|
|
4
|
-
|
|
5
|
-
<br />
|
|
6
|
-
|
|
7
|
-
Mjölnir знаходить тести, які не можуть впасти, і пайплайни, які не можуть почервоніти,<br />
|
|
8
|
-
а потім оцінює, наскільки можна довіряти результату, з доказом для кожного пункту.
|
|
9
|
-
|
|
10
|
-
<br />
|
|
11
|
-
|
|
12
|
-
[](https://www.npmjs.com/package/mjolnir-qa)
|
|
13
|
-
[](https://www.npmjs.com/package/mjolnir-qa)
|
|
14
|
-
[](https://github.com/Sergey-Bar/Mjolnir/actions/workflows/ci.yml)
|
|
15
|
-
[](https://codecov.io/gh/Sergey-Bar/Mjolnir)
|
|
16
|
-
[](https://scorecard.dev/viewer/?uri=github.com/Sergey-Bar/Mjolnir)
|
|
17
|
-
[](LICENSE)
|
|
18
|
-
[](https://nodejs.org)
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npx mjolnir-qa@3.0.0
|
|
22
|
-
```
|
|
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.bn.md) | [Ελληνικά](README.gr.md) | [Tiếng Việt](README.vi.md) | [עברית](README.he.md) | [العربية](README.ar.md) | [Bosanski](README.bs.md)
|
|
30
|
-
|
|
31
|
-
> 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-26.
|
|
32
|
-
|
|
33
|
-
<!-- Source hash: `de04dfb1677b` -->
|
|
34
|
-
|
|
35
|
-
</details>
|
|
36
|
-
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
|
-
<br />
|
|
40
|
-
|
|
41
|
-
## Release status (English canonical)
|
|
42
|
-
|
|
43
|
-
The published line is `3.0.0`; this working tree is the `4.0.0-rc.1`
|
|
44
|
-
candidate. `3.0.0` must not be republished or retagged. The M26–M50 program is
|
|
45
|
-
tracked in
|
|
46
|
-
[`docs/ROADMAP.yaml`](docs/ROADMAP.yaml); provisional capability contracts
|
|
47
|
-
are not automatically enabled or certified. Repository-owned checks pass, but
|
|
48
|
-
Trust certification remains `NOT_CERTIFIED` until the protected holdout,
|
|
49
|
-
real-world, platform/consumer, remote-workflow, support-matrix, and corpus
|
|
50
|
-
evidence gates pass. Run `npm run m26:readiness` before treating any candidate
|
|
51
|
-
as releasable. This document does not publish a tag or authorize a release.
|
|
52
|
-
|
|
53
|
-
> Machine-assisted canonical text. Translate this block before treating it as localized copy.
|
|
54
|
-
|
|
55
|
-
## Зелена галочка — це заява, а не доказ
|
|
56
|
-
|
|
57
|
-
Зелена галочка означає, що пайплайн не впав. Вона не означає, що тести запускалися або що вони могли впасти. Кожен із цих випадків проходить зеленим:
|
|
58
|
-
|
|
59
|
-
- закомічений `.only`, через який запустилося 3 тести замість 900
|
|
60
|
-
- `continue-on-error: true` на джобі, яка мала блокувати
|
|
61
|
-
- `|| true` після команди запуску тестів
|
|
62
|
-
- тест, який нічого не перевіряє або має порожнє тіло
|
|
63
|
-
- обгортка з повторами, яка перетворює справжній провал на випадковий успіх
|
|
64
|
-
- звіт, який workflow завантажує, але ніколи не створював
|
|
65
|
-
- жорсткий sleep, на якому тримається стан гонитви
|
|
66
|
-
|
|
67
|
-
Жоден із них не робить пайплайн червоним, і кожен на рев'ю виглядає навмисним. Саме тому вони виживають. Ось як Mjölnir читає реальний приклад:
|
|
68
|
-
|
|
69
|
-
<p align="center">
|
|
70
|
-
<img src="assets/readme/scan.svg" alt="CI-workflow демонстраційного репозиторію, прочитаний рядок за рядком. Mjölnir позначає кожну знахідку на вказаному рядку: правило, що не так, рівень доказовості та виміряну частку хибних спрацювань." width="800" />
|
|
71
|
-
</p>
|
|
72
|
-
|
|
73
|
-
<sub>Кожна знахідка, яку демонстраційне сканування видало для цього workflow, на вказаному рядку. Згенеровано командою `npm run docs:readme-brand` з [`demo-report.json`](assets/readme/demo-report.json) і захищено від розбіжностей у CI.</sub>
|
|
74
|
-
|
|
75
|
-
**Суворий режим.** Найагресивніші детекції — `.only`, `continue-on-error`, порожні тести, зловживання повторами — живуть у карантинному ярусі. Вони запускаються лише з `--strict` і обмежені серйозністю `info`: позначають, але ніколи не блокують. Сканування за замовчуванням (`npx mjolnir-qa@3.0.0` без `--strict`) покриває лише основні та розширені правила. Додайте `--strict`, коли хочете і консультаційний шар.
|
|
76
|
-
|
|
77
|
-
Mjölnir читає набір тестів, CI-workflow і, якщо він є, звіт реального прогону. Він не запускає ваші тести, не встановлює залежності й не виконує код, який сканує. А коли доказів немає, він так і каже, замість того щоб вигадувати впевненість:
|
|
78
|
-
|
|
79
|
-
| Ситуація | Що повідомляє Mjölnir |
|
|
80
|
-
| ----------------------------------------------------- | --------------------------------------------------------------------- |
|
|
81
|
-
| Оголошень тестів не знайдено | Оцінка `null`, відображається як **UNKNOWN**. Ніколи не вигадані 100. |
|
|
82
|
-
| Немає базової лінії або порівнянної ревізії | **UNKNOWN**, із зазначеною причиною. Ніколи не припущений 0. |
|
|
83
|
-
| Сканування перервано (ліміт часу, нечитабельні файли) | **PARTIAL**, код виходу `2`. Ніколи не видається за чистий результат. |
|
|
84
|
-
|
|
85
|
-
<p align="center">
|
|
86
|
-
<img src="assets/readme/how-it-works.svg" alt="Як працює Mjölnir. Він статично читає набір тестів і CI-пайплайн, а також звіт реального прогону, якщо він є. Кожну знахідку він зважує за рівнем доказовості та рівнем довіри, причому лише реальний прогін може досягти L3–L5, і видає знахідки, оцінку надійності та CI-гейт із замороженими кодами виходу. У циклі агента ШІ пише виправлення, а Mjölnir сканує повторно, щоб його довести." width="880" />
|
|
87
|
-
</p>
|
|
88
|
-
|
|
89
|
-
<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>
|
|
90
|
-
|
|
91
|
-
<br />
|
|
92
|
-
|
|
93
|
-
## Подивитися в роботі
|
|
94
|
-
|
|
95
|
-
Реальне сканування [`examples/demo-repo`](examples/demo-repo), невеликого набору тестів Playwright із CI-workflow. Ось куди пішли його бали:
|
|
96
|
-
|
|
97
|
-
<p align="center">
|
|
98
|
-
<img src="assets/readme/terminal-hero.svg" alt="Розбивка вирахувань Mjölnir: WORTHINESS 80/100 WORTHY, оцінка за категоріями, блок вирахувань за серйозністю та список FIX THIS FIRST" width="520" />
|
|
99
|
-
</p>
|
|
100
|
-
|
|
101
|
-
<sub>Згенеровано командою `npm run docs:hero` з реального сканування і захищено від розбіжностей у CI. Повний звіт `--verbose` того самого сканування — [`demo.svg`](assets/readme/demo.svg) (`npm run docs:demo`).</sub>
|
|
102
|
-
|
|
103
|
-
<details>
|
|
104
|
-
<summary><strong>Дивитися</strong> — сканування, виправлення, яке воно виводить, і повторне сканування, яке його доводить</summary>
|
|
105
|
-
|
|
106
|
-
<br />
|
|
107
|
-
|
|
108
|
-
<p align="center">
|
|
109
|
-
<a href="assets/video/mjolnir-demo.mp4">
|
|
110
|
-
<img src="assets/video/mjolnir-demo-poster.png" alt="Кадр демонстраційного запису: npx mjolnir-qa@3.0.0 сканує демонстраційний репозиторій у вікні термінала" width="900" />
|
|
111
|
-
</a>
|
|
112
|
-
</p>
|
|
113
|
-
|
|
114
|
-
<sub>Відрендерено кадр за кадром з реального сканування командою `npm run docs:video`; ніколи не записувалося з екрана. Виберіть кадр, щоб відкрити [`mjolnir-demo.mp4`](assets/video/mjolnir-demo.mp4).</sub>
|
|
115
|
-
|
|
116
|
-
</details>
|
|
117
|
-
|
|
118
|
-
### Одна знахідка зблизька
|
|
119
|
-
|
|
120
|
-
Кожна знахідка відповідає на чотири запитання: де вона, наскільки Mjölnir упевнений, як часто правило помиляється і як це виправити.
|
|
121
|
-
|
|
122
|
-
<p align="center">
|
|
123
|
-
<img src="assets/readme/finding-anatomy.svg" alt="Перша знахідка демонстраційного сканування, саме так, як її виводить термінал, із позначеними чотирма частинами: де, наскільки впевнено, як часто правило помиляється, і виправлення." width="100%" />
|
|
124
|
-
</p>
|
|
125
|
-
|
|
126
|
-
`mjolnir explain QA-CI-001` виводить повне досьє довіри правила, зокрема виміряну частку хибних спрацювань і рівень, який ця частка йому забезпечила:
|
|
127
|
-
|
|
128
|
-
```text
|
|
129
|
-
▍ QA-CI-001 — continue-on-error masks a failing verification gate
|
|
130
|
-
|
|
131
|
-
Severity: error
|
|
132
|
-
Confidence: high
|
|
133
|
-
Tier: quarantine
|
|
134
|
-
Evidence: E2
|
|
135
|
-
QA impact: False-green risk (FALSE-GREEN)
|
|
136
|
-
Measured FP: 11% (19 hand-classified corpus verdicts)
|
|
137
|
-
FP risk: low (author estimate)
|
|
138
|
-
Languages: yaml
|
|
139
|
-
Frameworks: github-actions, azure-pipelines
|
|
140
|
-
|
|
141
|
-
WHAT WAS FOUND (real detector output, not a mockup)
|
|
142
|
-
Job `security-scan` runs a verification gate under `continue-on-error: true`.
|
|
143
|
-
|
|
144
|
-
WHY IT MATTERS
|
|
145
|
-
This job can fail every day and CI will still show green. The checkmark on
|
|
146
|
-
this workflow cannot be trusted.
|
|
147
|
-
|
|
148
|
-
HOW TO FIX
|
|
149
|
-
Remove continue-on-error, or scope it to individual non-blocking steps only.
|
|
150
|
-
|
|
151
|
-
Example from this rule's own must-fire fixture: QA-CI-001/must-fire/masked.yml
|
|
152
|
-
|
|
153
|
-
WHAT WOULD CHANGE THE VERDICT
|
|
154
|
-
- a run report next to the scan target (mjolnir.report.json or test-results/)
|
|
155
|
-
corroborating this file lifts its findings to L3–L5
|
|
156
|
-
- a documented suppression (mjolnir.config.json) lowers the finding count
|
|
157
|
-
without claiming correctness
|
|
158
|
-
- quarantine findings run only under --strict and are advisory (E0) — they can
|
|
159
|
-
never gate CI
|
|
160
|
-
|
|
161
|
-
NEXT ACTION
|
|
162
|
-
Fix the first occurrence, then re-run: `mjolnir --scope changed`. Every
|
|
163
|
-
occurrence of this rule is listed in the scan output.
|
|
164
|
-
|
|
165
|
-
HOW TO VERIFY THE FIX
|
|
166
|
-
Re-run `mjolnir` on the changed file(s) — this finding should no longer
|
|
167
|
-
appear. `mjolnir --scope changed` scopes the check to just what you touched.
|
|
168
|
-
|
|
169
|
-
Docs: mjolnir rules --md (full catalog, this rule included)
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Ось одиниця цінності: одне місце, де CI повідомляє про успіх, якого не заслужив.
|
|
173
|
-
|
|
174
|
-
<br />
|
|
175
|
-
|
|
176
|
-
## Швидкий старт
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
npx mjolnir-qa@3.0.0
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Він сканує поточний каталог і виводить Trust Report: що знайдено, наскільки цьому можна довіряти, чому і що робити далі. Він завершується з кодом `0`, якщо на рівні гейта або вище нічого не знайдено.
|
|
183
|
-
|
|
184
|
-
У CI скануйте лише те, що внесла гілка, щоб успадкований набір тестів не втопив ваш перший pull request:
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
npx mjolnir-qa@3.0.0 --scope changed
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
`mjolnir ci install` записує це як workflow GitHub Actions з [action](https://github.com/Sergey-Bar/Mjolnir#readme), закріпленим на мажорному тезі `v3` (або просто `npx` з `--no-action`). Він залишається рекомендаційним, доки ви не вирішите, що він має блокувати.
|
|
191
|
-
|
|
192
|
-
| Команда | Що робить |
|
|
193
|
-
| --------------------------------------------- | ---------------------------------------------------------- |
|
|
194
|
-
| `mjolnir` | Trust Report: вердикт, упевненість, наступна дія |
|
|
195
|
-
| `mjolnir --scope changed` | Лише те, що внесла ваша гілка (варіант для CI) |
|
|
196
|
-
| `mjolnir ci install` | Створює рекомендаційний workflow для PR (на основі action) |
|
|
197
|
-
| `mjolnir business-case` | ROI estimate: projected savings per finding |
|
|
198
|
-
| `mjolnir release-report` | Release readiness: GO, CONDITIONAL GO, or NO-GO |
|
|
199
|
-
| `mjolnir release-trust` | 12-dimension release assurance verdict |
|
|
200
|
-
| `mjolnir report` | Generate a Playwright-compatible report |
|
|
201
|
-
| `mjolnir trend` | Record, show, or diff local quality snapshots |
|
|
202
|
-
| `mjolnir policy` | Initialize, validate, or check policy gates |
|
|
203
|
-
| `mjolnir quarantine` | Review deterministic proposals (prototype) |
|
|
204
|
-
| `mjolnir analyze --cross-file` | Bounded cross-file analysis |
|
|
205
|
-
| `mjolnir ci-adapter github .` | Generate CI templates for supported providers |
|
|
206
|
-
| `mjolnir dashboard` | Generate a self-contained quality dashboard |
|
|
207
|
-
| `mjolnir exec-report` | Executive KPIs and recommendations (advisory) |
|
|
208
|
-
| `mjolnir enterprise` | Self-hosted templates (prototype) |
|
|
209
|
-
| `mjolnir maturity` | Assess maturity or display maturity levels |
|
|
210
|
-
| `mjolnir mutation tests/mutation-report.json` | Analyze mutation reports; never promotes trust |
|
|
211
|
-
| `mjolnir mcp` | Read-only MCP tools over stdio |
|
|
212
|
-
| `mjolnir explain QA-CI-001` | Що, чому і як виправити, плюс виміряна частка FP |
|
|
213
|
-
| `mjolnir why src/a.spec.ts:42` | Чому позначено саме цей рядок. Ніколи не блокує. |
|
|
214
|
-
| `mjolnir forensics ./test-results/` | Докази з реального прогону |
|
|
215
|
-
| `mjolnir trust-report` | Самодостатній Trust Artifact (md + json) |
|
|
216
|
-
| `mjolnir handoff` | План виправлень для агента-програміста |
|
|
217
|
-
| `mjolnir --json` / `--format sarif` | Машинозчитуваний вивід, GitHub Code Scanning |
|
|
218
|
-
| `mjolnir --format codequality` | Звіт GitLab Code Quality (артефакт віджета MR) |
|
|
219
|
-
| `mjolnir --strict` | Також запускає правила рівня quarantine (вищий ризик FP) |
|
|
220
|
-
|
|
221
|
-
<details>
|
|
222
|
-
<summary><strong>Усі інші команди</strong> — розбір нестабільних тестів, звіти, контроль</summary>
|
|
223
|
-
|
|
224
|
-
<br />
|
|
225
|
-
|
|
226
|
-
| Команда | Що робить |
|
|
227
|
-
| ----------------------------------- | ------------------------------------------------------------------------------- |
|
|
228
|
-
| `mjolnir --classic` | Банер оцінки з часів до Trust Report |
|
|
229
|
-
| `mjolnir explain verdict` | Чому вердикт збереженого сканування саме такий |
|
|
230
|
-
| `mjolnir triage ./test-results/` | Покроковий розбір. Кожен рядок завершується наступною дією. |
|
|
231
|
-
| `mjolnir pw-report ./test-results/` | Зведення прогону Playwright: повтори, нестабільні тести, найповільніші |
|
|
232
|
-
| `mjolnir doctor:playwright` | Глибоке сканування лише для Playwright плюс Selector Health Score |
|
|
233
|
-
| `mjolnir fix --dry-run` / `fix` | Безпечні автовиправлення, кожне пересканується, щоб довести, що воно спрацювало |
|
|
234
|
-
| `mjolnir baseline` / `diff` | Знімок знахідок, потім звіт лише про нові або погіршені |
|
|
235
|
-
| `mjolnir impact --since <ref>` | Що вніс і що виправив коміт |
|
|
236
|
-
| `mjolnir summary` | Анотації CI і зведення кроку на основі звіту |
|
|
237
|
-
| `mjolnir pr-comment` | Коментар до PR у межах змін, у форматі Markdown |
|
|
238
|
-
| `mjolnir debt` | Реєстр тестового боргу з моделлю витрат |
|
|
239
|
-
| `mjolnir handover` | Карта набору тестів для нового QA-інженера |
|
|
240
|
-
| `mjolnir init` | Визначає фреймворки, виводить чекліст налаштування |
|
|
241
|
-
| `mjolnir suppressions` | Список придушених знахідок для контролю |
|
|
242
|
-
| `mjolnir rules --unmeasured` | Правила, що працюють на припущенні, а не на вимірюванні |
|
|
243
|
-
| `mjolnir rules --md` | Повний каталог правил (JSON або Markdown) |
|
|
244
|
-
| `mjolnir doctor` | Самоаудит власної бази правил Mjölnir |
|
|
245
|
-
| `mjolnir create-rule <ID>` | Створює заготовку нового правила та його фікстур |
|
|
246
|
-
| `mjolnir stats` | Локальні лічильники всіх помічених виправлень |
|
|
247
|
-
| `mjolnir badge` | JSON для ендпоінта shields.io і фрагмент коду |
|
|
248
|
-
| `mjolnir --cache` | Інкрементальні пересканування через локальний кеш вердиктів |
|
|
249
|
-
| `mjolnir --format mermaid` | Діаграма архітектури тестів для коментаря до PR |
|
|
250
|
-
|
|
251
|
-
`mjolnir help <command>` виводить використання, приклади та наступний крок для будь-якої з них.
|
|
252
|
-
|
|
253
|
-
</details>
|
|
254
|
-
|
|
255
|
-
Потрібен **Node.js ≥ 22.18** на Windows, macOS або Linux. Віддаєте перевагу глобальному встановленню? `npm i -g mjolnir-qa`. Мінімальна версія визначається інструментами збирання (tsdown орієнтований на неї, а пайплайн релізів проганяє на ній smoke-тести); залежностям часу виконання більшого не потрібно.
|
|
256
|
-
|
|
257
|
-
<br />
|
|
258
|
-
|
|
259
|
-
## Що знаходить Mjölnir
|
|
260
|
-
|
|
261
|
-
<p align="center">
|
|
262
|
-
<img src="assets/readme/stack.svg" alt="Працює з вашим стеком: мови, тестові фреймворки та CI-системи, які покривають його правила, за даними реєстру правил." width="100%" />
|
|
263
|
-
</p>
|
|
264
|
-
|
|
265
|
-
**79 правил** у чотирьох родинах — гігієна тестів, якість тестів, Playwright і цілісність CI — для TypeScript і JavaScript, Python, Java, C# та YAML GitHub Actions. Вони охоплюють Playwright у всіх чотирьох прив'язках, а також pytest, JUnit, TestNG, NUnit, xUnit, MSTest, Jest, Vitest і Mocha, з початковим покриттям Cypress і Selenium. Дев'ять із них, щоб показати загальний вигляд:
|
|
266
|
-
|
|
267
|
-
| ID | Правило | Серйозність | Рівень |
|
|
268
|
-
| ------------ | ----------------------------------------------------------------------- | ----------- | ---------- |
|
|
269
|
-
| QA-CI-001 | `continue-on-error` маскує гейт перевірки, що падає | error | quarantine |
|
|
270
|
-
| QA-CI-009 | Код виходу тестів не передається далі (`\|` без pipefail, ланцюжки `;`) | error | extended |
|
|
271
|
-
| QA-TEST-001 | Закомічено сфокусований тест (`.only`, `fit`) | error | quarantine |
|
|
272
|
-
| QA-TEST-003 | Тест без тверджень | error | quarantine |
|
|
273
|
-
| QA-TQUAL-009 | Твердження на promise без await | error | quarantine |
|
|
274
|
-
| QA-PW-002 | Твердження на локаторі без await | error | core |
|
|
275
|
-
| QA-PW-004 | Крихкі селектори CSS/XPath | warning | quarantine |
|
|
276
|
-
| QA-PY-002 | Пропущений тест (`skip`, нестрогий `xfail`) | warning | core |
|
|
277
|
-
| QA-CS-103 | Тестовий метод без тверджень | error | core |
|
|
278
|
-
|
|
279
|
-
Повний каталог генерується з реєстру й ніколи не ведеться вручну: `mjolnir rules --md`, [`docs/rules/`](docs/rules/) або [посібник про те, що він перевіряє](https://sergey-bar.github.io/Mjolnir/guide/what-it-checks).
|
|
280
|
-
|
|
281
|
-
<details>
|
|
282
|
-
<summary><strong>Усі правила, згадані в цьому README</strong>, в одній таблиці</summary>
|
|
283
|
-
|
|
284
|
-
<br />
|
|
285
|
-
|
|
286
|
-
> Правила `quarantine` запускаються лише з `--strict` і ніколи не блокують (їхній рівень обмежено info). Показано серйозність, задану автором.
|
|
287
|
-
|
|
288
|
-
| ID | Родина | Правило | Серйозність | Рівень |
|
|
289
|
-
| ------------ | ---------- | ------------------------------------------------------------------- | ----------- | ---------- |
|
|
290
|
-
| QA-TEST-001 | Гігієна | Закомічено сфокусований тест (`.only`, `fit`) | error | quarantine |
|
|
291
|
-
| QA-TEST-002 | Гігієна | Пропущений тест. Без відстежуваної причини підвищується до `error`. | warning | quarantine |
|
|
292
|
-
| QA-TEST-003 | Гігієна | Тест без тверджень | error | quarantine |
|
|
293
|
-
| QA-TEST-004 | Гігієна | Жорсткий sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning | extended |
|
|
294
|
-
| QA-TEST-006 | Гігієна | Зловживання повторами, що приховує нестабільність | warning | quarantine |
|
|
295
|
-
| QA-TEST-010 | Гігієна | Порожнє тіло тесту | error | quarantine |
|
|
296
|
-
| QA-TQUAL-002 | Якість | Тавтологічне твердження | error | quarantine |
|
|
297
|
-
| QA-TQUAL-009 | Якість | Твердження на promise без await | error | quarantine |
|
|
298
|
-
| QA-TQUAL-011 | Якість | Закоментовані тести | warning | extended |
|
|
299
|
-
| QA-PW-002 | Playwright | Твердження на локаторі без await | error | core |
|
|
300
|
-
| QA-PW-003 | Playwright | Закомічено `page.pause()` / `test.only()` | error | core |
|
|
301
|
-
| QA-PW-004 | Playwright | Крихкі селектори CSS/XPath | warning | quarantine |
|
|
302
|
-
| QA-PW-123 | Playwright | Жорстко задані URL оточень | warning | quarantine |
|
|
303
|
-
| QA-PW-140 | Playwright | Скриншот без `maxDiffPixelRatio` | warning | core |
|
|
304
|
-
| QA-CI-001 | CI | `continue-on-error` маскує гейт, що падає | error | quarantine |
|
|
305
|
-
| QA-CI-002 | CI | `\|\| true` ковтає коди виходу | error | extended |
|
|
306
|
-
| QA-CI-005 | CI | Звіт використовується, але ніколи не створюється | error | quarantine |
|
|
307
|
-
| QA-CI-007 | CI | Обгортки з повторами навколо тестів | warning | extended |
|
|
308
|
-
| QA-CI-008 | CI | Завжди успішний крок маскує падіння | error | quarantine |
|
|
309
|
-
| QA-CI-009 | CI | Код виходу не передається далі (`\|` без pipefail, ланцюжки `;`) | error | extended |
|
|
310
|
-
| QA-CI-010 | CI | Тести пропускаються там, де мають блокувати | error | quarantine |
|
|
311
|
-
| QA-PY-002 | Python | Пропущений тест (`skip`, нестрогий `xfail`) | warning | core |
|
|
312
|
-
| QA-PY-003 | Python | Тестова функція без тверджень | error | quarantine |
|
|
313
|
-
| QA-PY-005 | Python | `time.sleep()` у тестах | warning | extended |
|
|
314
|
-
| QA-PY-012 | Python | Тавтологічне твердження | error | quarantine |
|
|
315
|
-
| QA-JV-101 | Java | Вимкнений тест (`@Disabled`) | warning | core |
|
|
316
|
-
| QA-JV-102 | Java | Жорсткий sleep (`Thread.sleep()`) | warning | extended |
|
|
317
|
-
| QA-JV-103 | Java | Тестовий метод без тверджень | error | extended |
|
|
318
|
-
| QA-JV-105 | Java | Жорсткий sleep через `waitForTimeout()` у Playwright | warning | core |
|
|
319
|
-
| QA-JV-106 | Java | Крихкий селектор замість локатора за роллю | warning | quarantine |
|
|
320
|
-
| QA-CS-101 | C# | Пропущений тест (`[Ignore]`, `[Fact(Skip=)]`) | warning | core |
|
|
321
|
-
| QA-CS-102 | C# | Жорсткий sleep (`Thread.Sleep` / `Task.Delay`) | warning | core |
|
|
322
|
-
| QA-CS-103 | C# | Тестовий метод без тверджень | error | core |
|
|
323
|
-
| QA-CS-105 | C# | Жорсткий sleep через `WaitForTimeoutAsync()` | warning | extended |
|
|
324
|
-
| QA-CS-106 | C# | Крихкий селектор замість локатора за роллю | warning | quarantine |
|
|
325
|
-
|
|
326
|
-
Для Python також є QA-PY-001…012 (гігієна pytest) і QA-PY-101…108 (Playwright для Python). Cypress і Selenium мають стартові набори по три правила.
|
|
327
|
-
|
|
328
|
-
</details>
|
|
329
|
-
|
|
330
|
-
Кожне правило постачається з фікстурою must-fire **і** фікстурою must-not-fire, а правило, що спрацьовує на власній негативній фікстурі, не може бути випущене. Це захист від хибних спрацювань; `mjolnir doctor` забезпечує його у власному CI цього репозиторію.
|
|
331
|
-
|
|
332
|
-
### Selector Health Score
|
|
333
|
-
|
|
334
|
-
`mjolnir doctor:playwright` оцінює кожен локатор за тим, як він знаходить елемент: так, як це зробив би користувач (роль, мітка, текст), через явний контракт (`data-testid`) або через структурну випадковість (ланцюжки CSS, XPath). Кожен файл отримує оцінку від 0 до 100:
|
|
335
|
-
|
|
336
|
-
```text
|
|
337
|
-
▍ SELECTOR HEALTH
|
|
338
|
-
|
|
339
|
-
e2e/login.spec.ts
|
|
340
|
-
[█████████████░░░░░░░] 65 / 100
|
|
341
|
-
role/text: 1 · testid: 0 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
|
|
342
|
-
|
|
343
|
-
e2e/checkout.spec.ts
|
|
344
|
-
[██████████████████░░] 88 / 100
|
|
345
|
-
role/text: 4 · testid: 1 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
Це вимірює **стійкість, а не коректність**. `.btn.btn-primary > div:nth-child(2)` проходить сьогодні й проходитиме, доки хтось не торкнеться розмітки. Низька оцінка ніколи не стверджує, що тест зламаний, — лише що він залежить від розмітки, яку ніхто не обіцяв зберігати.
|
|
349
|
-
|
|
350
|
-
<br />
|
|
351
|
-
|
|
352
|
-
## Оцінка надійності
|
|
353
|
-
|
|
354
|
-
<p align="center">
|
|
355
|
-
<img src="assets/readme/score-gauge.svg" alt="Шкала надійності від 0 до 100 з маркером, що проходить по кожній оцінці: UNWORTHY нижче 50, NEEDS WORK від 50 до 79, WORTHY від 80 до 99, FORGED при 100" width="720" />
|
|
356
|
-
</p>
|
|
357
|
-
|
|
358
|
-
<sub>Кожна оцінка від 0 до 100, розміщена справжнім `deriveScoreState`. Згенеровано командою `npm run docs:gauge` і захищено від розбіжностей у CI.</sub>
|
|
359
|
-
|
|
360
|
-
| Оцінка | Вердикт |
|
|
361
|
-
| --------- | ----------------------------------------- |
|
|
362
|
-
| `0 – 49` | **UNWORTHY** |
|
|
363
|
-
| `50 – 79` | **NEEDS WORK** |
|
|
364
|
-
| `80 – 99` | **WORTHY** |
|
|
365
|
-
| `100` | **FORGED** |
|
|
366
|
-
| `null` | **UNKNOWN**: оголошень тестів не знайдено |
|
|
367
|
-
|
|
368
|
-
**Як вона обчислюється.** Серйозність задає базове вирахування (`error −8`, `warning −3`, `info −1`), а рівень доказовості його зменшує: E2 враховується повністю, E1 наполовину (з округленням униз), E0 не враховується. Сума нормується за охопленням набору, тобто вирахування на одне оголошення тесту, а не на файл. Термінал виводить ті самі зменшені числа, які використала оцінка; прихованої другої моделі немає. Подробиці: [docs/SCORING.md](docs/SCORING.md) і [посібник з оцінки](https://sergey-bar.github.io/Mjolnir/guide/scoring).
|
|
369
|
-
|
|
370
|
-
**Чого не означає 100.** Це не означає, що програма коректна, набір тестів достатній або продукт вільний від дефектів. Це означає лише одне: **жодне з правил, перевірених Mjölnir, не дало вирахування в цьому скануванні та за цієї моделі доказів.**
|
|
371
|
-
|
|
372
|
-
<br />
|
|
373
|
-
|
|
374
|
-
## Модель доказів
|
|
375
|
-
|
|
376
|
-
Кожна знахідка має дві мітки: наскільки впевнений Mjölnir і наскільки далеко знахідку перевірено. У цьому різниця між інструментом, що повідомляє про шаблони, та інструментом, від якого можна ставити в залежність реліз.
|
|
377
|
-
|
|
378
|
-
**Наскільки впевнено — рівень доказовості.**
|
|
379
|
-
|
|
380
|
-
| Рівень | Назва | Значення | Вирахування |
|
|
381
|
-
| ------ | -------------------- | -------------------------------------------------------- | ----------- |
|
|
382
|
-
| **E2** | Детермінований доказ | Дефект присутній у коді в тому вигляді, як він написаний | Повне |
|
|
383
|
-
| **E1** | Доказ за шаблоном | Збігся шаблон, тісно пов'язаний із дефектом | Половина |
|
|
384
|
-
| **E0** | Спостереження | Варто знати. Не твердження, що щось не так. | Нуль |
|
|
385
|
-
|
|
386
|
-
Упевненість у виявленні — це не сила доказу. Правило може бути впевнене, що знайшло те, що шукало, і все одно дивитися на евристику. Знахідки E1 призначені для того, щоб їх читали й оцінювали, а не застосовували наосліп, і ця межа позначена на знахідці в терміналі, у JSON і в передачі агенту.
|
|
387
|
-
|
|
388
|
-
**Наскільки далеко перевірено — рівень довіри.** Більшість знахідок отримано читанням вашого коду. Дайте Mjölnir звіт реального прогону тестів, і він зможе підтвердити, що код справді виконувався.
|
|
389
|
-
|
|
390
|
-
<p align="center">
|
|
391
|
-
<img src="assets/readme/trust-ladder.svg" alt="Драбина довіри від L0 до L5. L0–L2 отримуються читанням коду; для L3–L5 потрібен звіт реального прогону, що позначено розривом у драбині." width="100%" />
|
|
392
|
-
</p>
|
|
393
|
-
|
|
394
|
-
| Рівень | Простими словами | Що для цього потрібно |
|
|
395
|
-
| ------ | ------------------ | -------------------------------------------------- |
|
|
396
|
-
| **L0** | Помічено | Читання коду |
|
|
397
|
-
| **L1** | Схоже на проблему | Читання коду: збігся шаблон |
|
|
398
|
-
| **L2** | Доведено в коді | Читання коду: дефект структурний |
|
|
399
|
-
| **L3** | Файл виконувався | Звіт прогону показує, що файл знахідки виконувався |
|
|
400
|
-
| **L4** | Тест виконувався | Звіт прогону показує, що тест знахідки виконувався |
|
|
401
|
-
| **L5** | Прогін підтверджує | Власний результат прогону підтверджує клас дефекту |
|
|
402
|
-
|
|
403
|
-
Статичне сканування зупиняється на L2. Лише звіт реального прогону (Playwright JSON, Jest або Vitest JSON, JUnit XML) може підняти знахідку до L3 і вище, тож знахідка, яку жодного разу не бачили в роботі, ніколи не може стверджувати протилежне. Визначення: [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md).
|
|
404
|
-
|
|
405
|
-
### Скільки з цього виміряно
|
|
406
|
-
|
|
407
|
-
**У 74 з 79 правил частку хибних спрацювань виміряно на реальному OSS-коді** (щонайменше 10 вручну класифікованих знахідок на кожне; див. [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). Решта 5 спираються на оцінку автора й прямо про це кажуть, правило за правилом, у `mjolnir explain`. `mjolnir rules --unmeasured` перелічує їх, а підвал кожного сканування повідомляє, скільки з правил, які справді _спрацювали_, виміряно.
|
|
408
|
-
|
|
409
|
-
Показники залишаються публічними, навіть коли вони погані. QA-TEST-001 (закомічений `.only`) погано проходить аудит на реальних репозиторіях і тому перебуває в quarantine. Актуальне значення для кожного правила, зокрема QA-PW-141, є в аудиті.
|
|
410
|
-
|
|
411
|
-
### Рівні довіри правил
|
|
412
|
-
|
|
413
|
-
Рівні визначаються виміряною часткою хибних спрацювань, а не думкою:
|
|
414
|
-
|
|
415
|
-
| Рівень | Виміряна FP | Поведінка |
|
|
416
|
-
| -------------- | ------------------------ | ------------------------------------------------------- |
|
|
417
|
-
| **core** | ≤ 10% | Звіт за замовчуванням, блокує |
|
|
418
|
-
| **extended** | ≤ 30% | Звіт за замовчуванням, знижена впевненість |
|
|
419
|
-
| **quarantine** | > 30% або явно оголошене | Лише `--strict`, обмежено рівнем info, ніколи не блокує |
|
|
420
|
-
| _не виміряно_ | n < 10 | Не може бути підвищене до core, доки не виміряне |
|
|
421
|
-
|
|
422
|
-
Смуги FP можуть лише понизити рівень — вони ніколи не підвищують правило з `quarantine`, якщо воно було туди явно оголошене. Явно поміщене в карантин правило залишається в quarantine незалежно від виміряного рівня FP.
|
|
423
|
-
|
|
424
|
-
Підвищення, пониження і зрілість за мовами: [життєвий цикл правил](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle).
|
|
425
|
-
|
|
426
|
-
### Чому це не лінтер
|
|
427
|
-
|
|
428
|
-
Лінтери кажуть, чи дотримується код правил. Mjölnir каже, чи можна довіряти вашій перевірці.
|
|
429
|
-
|
|
430
|
-
| | Лінтери (ESLint, SonarQube) | Інструменти покриття | Код-рев'ю зі ШІ | **Mjölnir** |
|
|
431
|
-
| -------------------------------------------------------------- | :-------------------------: | :------------------: | :-------------: | :-----------------: |
|
|
432
|
-
| Оцінює **систему перевірки**, а не код продукту | Ні | Ні | Ні | Так |
|
|
433
|
-
| Цілісність CI-workflow (`continue-on-error`, `\|\| true`) | Ні | Ні | лише diff | Так |
|
|
434
|
-
| Оцінює стійкість локаторів Playwright (Selector Health) | Ні | Ні | Ні | Так |
|
|
435
|
-
| Читає реальні дані прогонів для вердиктів `TRUE-FLAKE` | Ні | Ні | Ні | Так |
|
|
436
|
-
| Публікує виміряну частку хибних спрацювань для кожного правила | Ні | Ні | Ні | Так |
|
|
437
|
-
| Позначає тести без тверджень | Так\* | Ні | іноді | Так |
|
|
438
|
-
| Знаходить жорсткі sleep (`waitForTimeout`, `time.sleep`) | Так\* | Ні | іноді | Так |
|
|
439
|
-
| Детермінованість (однаковий вхід — однаковий вихід) | Так | Так | Ні | Так |
|
|
440
|
-
| Вартість сканування | безкоштовно | безкоштовно | токени | **нуль** (локально) |
|
|
441
|
-
|
|
442
|
-
<sub>\*Покривається `eslint-plugin-jest` і `eslint-plugin-playwright` (`expect-expect`, `no-wait-for-timeout`), а також власними правилами SonarQube для тверджень. Стовпці описують поведінку за замовчуванням під час перевірки наборів тестів; плагіни, платні тарифи й власні правила змінюють деякі відповіді. Це зведення позиціонування, а не бенчмарк.</sub>
|
|
443
|
-
|
|
444
|
-
Використовуйте й рев'ю зі ШІ. Воно вловлює нюанси, наміри та помилки проєктування, яких не знайде жоден шаблон. Mjölnir знаходить те, що рев'ю зі ШІ пропускає, бо це виглядає навмисним: закомічений `.only`, проковтнутий код виходу, `continue-on-error` на тестовій джобі. Тут потрібне сканування, а не міркування.
|
|
445
|
-
|
|
446
|
-
<br />
|
|
447
|
-
|
|
448
|
-
## Аналіз прогонів тестів
|
|
449
|
-
|
|
450
|
-
Статичний аналіз міркує про код, який ніколи не виконувався. Аналіз прогонів читає те, що сталося насправді: Playwright JSON, Jest JSON, Vitest JSON і JUnit XML від будь-якого ранера.
|
|
451
|
-
|
|
452
|
-
```bash
|
|
453
|
-
mjolnir forensics ./test-results/
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
```text
|
|
457
|
-
▍ FLAKINESS LEADERBOARD
|
|
458
|
-
|
|
459
|
-
3 tests · 1 failed · 1 flaky · 1 retried
|
|
460
|
-
|
|
461
|
-
TRUE-FLAKE completes checkout with saved card (e2e/checkout.spec.ts)
|
|
462
|
-
████████████████████ 6.0s · 2 attempts
|
|
463
|
-
FAILING declines an expired card (e2e/checkout.spec.ts)
|
|
464
|
-
████░░░░░░░░░░░░░░░░ 1.1s · 1 attempt
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
`TRUE-FLAKE` не означає, що тест перезапускався. Це означає, що тест **провалив щонайменше одну спробу, а потім завершився зеленим**: випадковий успіх, позначений незалежно від того, що показує підсумкова галочка. `mjolnir triage` перетворює цю історію на пропозицію карантину, а `mjolnir pw-report` підсумовує прогін. Саме ці звіти прогонів піднімають знахідки до рівнів довіри L3 і вище.
|
|
468
|
-
|
|
469
|
-
<br />
|
|
470
|
-
|
|
471
|
-
## Цілісність CI
|
|
472
|
-
|
|
473
|
-
Тест може проходити, поки навколишній пайплайн не здатен упасти. Mjölnir читає і workflow: `continue-on-error`, `|| true`, коди виходу, які ніколи не передаються далі, завжди успішні кроки, звіти, які використовуються, але ніколи не створюються, і гейти, що пропускаються саме в тих подіях, які мають блокувати. Кожна знахідка називає джобу, крок і рядок і має власний рівень доказовості.
|
|
474
|
-
|
|
475
|
-
Створіть workflow для PR, за замовчуванням рекомендаційний:
|
|
476
|
-
|
|
477
|
-
```bash
|
|
478
|
-
mjolnir ci install
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
Або додайте action із Marketplace до вже наявного workflow:
|
|
482
|
-
|
|
483
|
-
```yaml
|
|
484
|
-
- uses: Sergey-Bar/Mjolnir@v3
|
|
485
|
-
with:
|
|
486
|
-
scope: changed
|
|
487
|
-
fail-on: error
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
Закріпіть `@v3`, щоб слідувати мажорній лінії, або точний тег (`@v0.5.32`) для відтворюваного гейта. [docs/DISTRIBUTION-KIT.md](docs/DISTRIBUTION-KIT.md) описує Marketplace, Smithery та реєстри MCP.
|
|
491
|
-
|
|
492
|
-
Щоб надіслати знахідки в GitHub Code Scanning, завантажте SARIF (потрібен `security-events: write` на рівні workflow або job):
|
|
493
|
-
|
|
494
|
-
```yaml
|
|
495
|
-
- run: npx mjolnir-qa@3.0.0 --format sarif > mjolnir.sarif
|
|
496
|
-
continue-on-error: true
|
|
497
|
-
- uses: github/codeql-action/upload-sarif@v3
|
|
498
|
-
if: ${{ !cancelled() }}
|
|
499
|
-
with:
|
|
500
|
-
sarif_file: mjolnir.sarif
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
У GitLab `--format codequality` записує звіт Code Quality, який читають віджет MR і анотації diff ([docs/GITLAB-CI.md](docs/GITLAB-CI.md)). Налаштування редактора й пайплайна: [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
|
|
504
|
-
|
|
505
|
-
### Прив'язка до змін гілки
|
|
506
|
-
|
|
507
|
-
```bash
|
|
508
|
-
npx mjolnir-qa@3.0.0 --scope changed
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
Знахідки прив'язуються до рядків, доданих вашою гілкою, відносно **merge-base**. Область — той самий набір файлів, що знаходить повне сканування (специфікації TS/JS і конфігурації адаптерів, `test_*.py`, `*Test.java`, `*Tests.cs`, `.github/workflows/*.yml`), плюс незакомічені й невідстежувані зміни, тож це працює ще до коміту. Базу визначають у порядку `main → master → origin/main → origin/master → origin/HEAD`; її можна перевизначити через `--base <ref>`.
|
|
512
|
-
|
|
513
|
-
Якщо merge-base визначити не вдається (неглибокий клон, від'єднаний HEAD, ціль поза git), знахідки відкочуються до прив'язки до всього файлу, **і звіт про це повідомляє.** Тихий відкат був би саме тим дефектом, заради пошуку якого існує цей інструмент.
|
|
514
|
-
|
|
515
|
-
<br />
|
|
516
|
-
|
|
517
|
-
## ШІ-агенти
|
|
518
|
-
|
|
519
|
-
Знахідки чогось варті, лише якщо на них хтось реагує.
|
|
520
|
-
|
|
521
|
-
```text
|
|
522
|
-
SCAN → EVIDENCE → HANDOFF → AGENT → RE-SCAN → PROOF
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
**ШІ пише виправлення. Mjölnir його перевіряє.** Доказ дає повторне сканування, а не власний звіт агента про успіх.
|
|
526
|
-
|
|
527
|
-
| Команда | Що отримує агент |
|
|
528
|
-
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
529
|
-
| `mjolnir mcp` | Сервер [MCP](https://modelcontextprotocol.io) через stdio. `scan`, `explain` і `diff` стають інструментами, які можна викликати. |
|
|
530
|
-
| `mjolnir handoff` | Збережений звіт `--json` перетворюється на детермінований план у Markdown: що виявлено, межа доказовості для кожної знахідки, що **не** має змінюватися і як це перевірити. |
|
|
531
|
-
| `mjolnir install` | Записує в місця для агентів, які вже є у вашому репозиторії (`.claude/`, `.cursor/`, `.kilo/`, `AGENTS.md`), щоб агент пересканував код, перш ніж заявити, що закінчив. |
|
|
532
|
-
|
|
533
|
-
Додайте його до клієнта, який має власний CLI:
|
|
534
|
-
|
|
535
|
-
```bash
|
|
536
|
-
claude mcp add mjolnir -- npx -y mjolnir-qa@3.0.0 mcp
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
Або до будь-якого клієнта, що приймає блок `mcpServers`:
|
|
540
|
-
|
|
541
|
-
```json
|
|
542
|
-
{
|
|
543
|
-
"mcpServers": {
|
|
544
|
-
"mjolnir": { "command": "npx", "args": ["-y", "mjolnir-qa@3.0.0", "mcp"] }
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
**Обмежувач важливіший за зручність.** Кожна знахідка в передачі має свою межу. **E2** каже _детерміновано: перевірте місце і застосуйте виправлення_. **E1** каже _ПОТРІБНЕ ПІДТВЕРДЖЕННЯ: саме спостереження не доводить дефект_. Агент, який наосліп виправляє E1, придушує правило або редагує правило, щоб підняти оцінку, робить саме те, заради пошуку чого існує цей інструмент, тому передача каже про це прямо в промпті, поруч зі знахідкою.
|
|
550
|
-
|
|
551
|
-
<br />
|
|
552
|
-
|
|
553
|
-
## Довіра і безпека
|
|
554
|
-
|
|
555
|
-
**Локально, без телеметрії.** Ніде в `src/` немає жодного API з мережевими можливостями (`fetch`, `http`, `https`, `net`, `dns`, `dgram`, WebSocket), а [`privacy-network-isolation.spec.ts`](tests/contract/privacy-network-isolation.spec.ts) провалює збірку, якщо такий з'явиться. Він також забороняє `eval` і `new Function`. Сканування недовіреного коду ніколи його не виконує: статичний аналіз читає вихідний текст, а аналіз прогонів розбирає файли звітів, які вже є на диску.
|
|
556
|
-
|
|
557
|
-
Два застереження: сам `npx` завантажує пакет до того, як щось запуститься, а гарантія поширюється на `src/`, але не на сторонні плагіни.
|
|
558
|
-
|
|
559
|
-
**Плагіни не ізольовані в пісочниці.** JS-плагіни (`mjolnir-rules/*.mjs` або npm-пакети, перелічені в `"plugins"`) працюють із повними привілеями Node — та сама модель довіри, що й у плагінів ESLint чи Vitest. Їх завантаження вмикається явно **для кожного сканування**: без `--enable-plugins` (або `MJOLNIR_ENABLE_PLUGINS=1`) їхні вихідні файли ніколи не завантажуються, а повідомлення в stderr перелічує пропущене. JSON-маніфести правил не виконують код, а префікси ID core-правил зарезервовані, щоб плагін не міг видати себе за одне з них. Повідомляйте про вразливості через [SECURITY.md](SECURITY.md).
|
|
560
|
-
|
|
561
|
-
**Він перевіряє сам себе.** Рушій довіри до перевірок нічого не вартий, якщо його самого не можна перевірити. Кожен прогін CI сканує цей репозиторій збіркою, створеною тим самим прогоном. Гейт падає за будь-якої знахідки рівня error, а також за **часткового** сканування чи **правила, що впало**, бо обрізане самосканування, яке ні про що не повідомляє, — це і є хибний зелений, заради пошуку якого існує цей проєкт. `mjolnir doctor` у тому самому прогоні заново перевіряє базу правил (захист фікстур, чесність рівнів, ліміт рівня core), а перевірка з результатом INCONCLUSIVE падає так само, як провалена. Обидва звіти завантажуються як артефакти збірки.
|
|
562
|
-
|
|
563
|
-
### Коди виходу та машинний контракт
|
|
564
|
-
|
|
565
|
-
Заморожені, щоб на них можна було будувати логіку CI:
|
|
566
|
-
|
|
567
|
-
| Код виходу | Значення |
|
|
568
|
-
| ---------- | --------------------------------------------------------------------------------- |
|
|
569
|
-
| `0` | Чисто: немає знахідок на рівні гейта або вище |
|
|
570
|
-
| `1` | Є знахідки на рівні гейта або вище |
|
|
571
|
-
| `2` | Часткове сканування (вичерпано ліміт часу, нечитабельні файли). Ніколи не блокує. |
|
|
572
|
-
| `10` | Помилка використання (неправильний прапорець, немає цілі) |
|
|
573
|
-
| `20` | Внутрішня помилка |
|
|
574
|
-
|
|
575
|
-
`2` навмисно відрізняється від `0`: сканування, яке не завершилося, не «нічого не знайшло». Воно просто не закінчило шукати.
|
|
576
|
-
|
|
577
|
-
Усе, що споживає машина (результати інструментів MCP, `--json`, SARIF 2.1), береться з одного канонічного результату за версіонованою схемою, **що розширюється лише додаванням** (`schemaVersion: 1`, `contractVersion: 1`), тож жодному споживачеві не треба відновлювати зміст із відрендереного тексту. Див. [машинний контракт](docs/machine-contract.md). ID правил (`QA-<FAMILY>-NNN`) незмінні після випуску й ніколи не використовуються повторно.
|
|
578
|
-
|
|
579
|
-
<br />
|
|
580
|
-
|
|
581
|
-
## Чого Mjölnir сказати не може
|
|
582
|
-
|
|
583
|
-
- **Він не запускає ваші тести.** Чисте сканування — це не набір тестів, що проходить.
|
|
584
|
-
- **Він не може сказати, що твердження _хибне_.** `expect(total).toBe(41)` виглядає здоровим. Mjölnir знаходить тести, які _не можуть упасти_, і пайплайни, які _не можуть почервоніти_, а не тести, що перевіряють не те.
|
|
585
|
-
- **Він не доводить бізнес-коректність.** Ніщо тут не каже, що ваш продукт робить те, чого вимагала вимога.
|
|
586
|
-
- **100 — не доказ хорошого набору тестів.** Чи покриває ваш набір реальні ризики — окреме питання, і цей інструмент на нього не відповідає.
|
|
587
|
-
- **5 з 79 правил спираються на оцінку**, а не на виміряну частку. Кожне з них каже про це у своїй знахідці.
|
|
588
|
-
- **E1 — це не E2.** Евристичні знахідки варто читати, але не варто застосовувати наосліп.
|
|
589
|
-
- **Порожній репозиторій отримує `null`, ніколи не 100.**
|
|
590
|
-
- **Файл з ім'ям `*.spec.ts` без оголошень тестів не вважається покриттям.** Репозиторій, де єдині spec-файли містять імпорти або типи (нуль викликів `it`/`test`), отримує `null`, а не 100.
|
|
591
|
-
|
|
592
|
-
<br />
|
|
593
|
-
|
|
594
|
-
## Документація
|
|
595
|
-
|
|
596
|
-
Повний сайт документації розміщено за адресою <https://sergey-bar.github.io/Mjolnir/>.
|
|
597
|
-
|
|
598
|
-
| Документ | Що всередині |
|
|
599
|
-
| ------------------------------------------------------ | --------------------------------------------------------------- |
|
|
600
|
-
| [docs/SCORING.md](docs/SCORING.md) | Нормування оцінки та зважування доказів |
|
|
601
|
-
| [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md) | Канонічний словник: одне слово на поняття |
|
|
602
|
-
| [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Виміряні частки хибних спрацювань і методика |
|
|
603
|
-
| [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Стани правил, рівні, придушення, виведення з ужитку |
|
|
604
|
-
| [docs/VERSIONING.md](docs/VERSIONING.md) | Політика semver, заморожені інтерфейси, цикл виведення з ужитку |
|
|
605
|
-
| [docs/machine-contract.md](docs/machine-contract.md) | Канонічний машинозчитуваний результат |
|
|
606
|
-
| [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | Вивід SARIF і налаштування редактора або CI |
|
|
607
|
-
| [docs/GITLAB-CI.md](docs/GITLAB-CI.md) | GitLab: звіт Code Quality, рецепт для MR, гейт |
|
|
608
|
-
| [docs/rules/](docs/rules/) | Згенерований каталог за правилами |
|
|
609
|
-
| [CONTRIBUTING.md](CONTRIBUTING.md) | Середовище розробки та процес внесення змін |
|
|
610
|
-
| [SUPPORT.md](SUPPORT.md) | Де запитати, повідомити про проблему й отримати допомогу |
|
|
611
|
-
| [SECURITY.md](SECURITY.md) | Повідомлення про вразливості |
|
|
612
|
-
| [CHANGELOG.md](CHANGELOG.md) | Історія релізів |
|
|
613
|
-
|
|
614
|
-
### Статус
|
|
615
|
-
|
|
616
|
-
**Версія 1.** JSON-схема та коди виходу — заморожені контракти. TypeScript і Python мають найширше виміряне покриття. Java і C# новіші; оцінюйте їх за [таблицею зрілості](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle). Що буде далі, без вигаданих дат: [публічна дорожня карта](https://sergey-bar.github.io/Mjolnir/reference/roadmap).
|
|
617
|
-
|
|
618
|
-
### Участь у розробці
|
|
619
|
-
|
|
620
|
-
Нові правила — найпростіший перший внесок. Одна команда створює заготовку правила з фікстурами must-fire **і** must-not-fire. Згенероване правило навмисно провалює власні фікстури, доки не написано справжнє виявлення, бо випущена заглушка — це правило, яке ніхто не вимірював:
|
|
621
|
-
|
|
622
|
-
```bash
|
|
623
|
-
mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
Середовище розробки, команди постійних гейтів, а також закони anti-creep і захисту фікстур описано в [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
627
|
-
|
|
628
|
-
<br />
|
|
629
|
-
|
|
630
|
-
<div align="center">
|
|
631
|
-
|
|
632
|
-
<img src="assets/readme/closing.svg" alt="Запустіть його на своєму репозиторії." width="100%" />
|
|
633
|
-
|
|
634
|
-
```bash
|
|
635
|
-
npx mjolnir-qa@3.0.0
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
[Читати посібник](https://sergey-bar.github.io/Mjolnir/guide/getting-started) · [Сайт документації](https://sergey-bar.github.io/Mjolnir/) · [npm](https://www.npmjs.com/package/mjolnir-qa)
|
|
639
|
-
|
|
640
|
-
<br />
|
|
641
|
-
|
|
642
|
-
Не питайте, чи пройшли тести.<br />
|
|
643
|
-
Запитайте, чи доводять докази, що вони заслуговують на довіру.
|
|
644
|
-
|
|
645
|
-
<sub>Створив [Sergey Bar](https://www.linkedin.com/in/sergeybar/) · Ліцензія MIT</sub>
|
|
646
|
-
|
|
647
|
-
</div>
|