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.br.md
DELETED
|
@@ -1,647 +0,0 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
<img src="assets/readme/hero.svg" alt="Mjölnir. Os testes dizem o que passou. O Mjölnir diz em que você pode confiar." width="100%" />
|
|
4
|
-
|
|
5
|
-
<br />
|
|
6
|
-
|
|
7
|
-
O Mjölnir encontra testes que não podem falhar e pipelines que não podem ficar vermelhos,<br />
|
|
8
|
-
e depois pontua até onde o resultado merece confiança, com a evidência de cada ponto.
|
|
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@5.0.0
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
[Veja funcionando](#veja-funcionando) · [Início rápido](#início-rápido) · [O que encontra](#o-que-o-mjölnir-encontra) · [Pontuação](#a-pontuação-de-confiabilidade) · [Evidência](#o-modelo-de-evidência) · [Forense](#forense-de-execução) · [CI](#integridade-de-ci) · [Agentes](#agentes-de-ia) · [Segurança](#confiança-e-segurança) · [Limites](#o-que-o-mjölnir-não-pode-dizer) · [Docs](#documentação)
|
|
25
|
-
|
|
26
|
-
<details>
|
|
27
|
-
<summary>Leia em outro idioma — 22 traduções</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.th.md) | [Türkçe](README.tr.md) | [Українська](README.uk.md) | [বাংলা](README.bn.md) | [Ελληνικά](README.gr.md) | [Tiếng Việt](README.vi.md) | [עברית](README.he.md) | [العربية](README.ar.md) | [Bosanski](README.bs.md)
|
|
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
|
-
## Um check verde é uma afirmação, não uma prova
|
|
56
|
-
|
|
57
|
-
Um check verde significa que o pipeline não falhou. Não significa que os testes rodaram, nem que poderiam ter falhado. Todos estes casos passam verdes:
|
|
58
|
-
|
|
59
|
-
- um `.only` commitado que rodou 3 testes em vez de 900
|
|
60
|
-
- `continue-on-error: true` no job que deveria bloquear
|
|
61
|
-
- `|| true` depois do comando de testes
|
|
62
|
-
- um teste que não verifica nada, ou que tem o corpo vazio
|
|
63
|
-
- um wrapper de retry que transforma uma falha real em uma aprovação por sorte
|
|
64
|
-
- um relatório que o workflow envia, mas que nunca foi gerado
|
|
65
|
-
- um sleep fixo segurando uma condição de corrida
|
|
66
|
-
|
|
67
|
-
Nenhum deles deixa o pipeline vermelho, e todos parecem intencionais na revisão. É por isso que sobrevivem. Aqui está o Mjölnir lendo um caso real:
|
|
68
|
-
|
|
69
|
-
<p align="center">
|
|
70
|
-
<img src="assets/readme/scan.svg" alt="O workflow de CI do repositório de demonstração, lido linha por linha. O Mjölnir aponta cada achado na linha reportada, com sua regra, o que está errado, seu nível de evidência e sua taxa de falsos positivos medida." width="800" />
|
|
71
|
-
</p>
|
|
72
|
-
|
|
73
|
-
<sub>Cada achado que o scan de demonstração reportou para este workflow, na linha reportada. Gerado por `npm run docs:readme-brand` a partir de [`demo-report.json`](assets/readme/demo-report.json) e travado contra desvios na CI.</sub>
|
|
74
|
-
|
|
75
|
-
**Modo estrito.** As detecções mais agressivas — `.only`, `continue-on-error`, testes vazios, abuso de retry — ficam na quarentena. Só rodam com `--strict` e são limitadas a severidade `info`: elas sinalizam, nunca bloqueiam. O scan padrão (`npx mjolnir-qa@5.0.0` sem `--strict`) cobre apenas regras core e extended. Adicione `--strict` quando quiser a camada de consultoria também.
|
|
76
|
-
|
|
77
|
-
O Mjölnir lê a suíte, os workflows de CI e, se você tiver, o relatório de uma execução real. Ele não roda seus testes, não instala suas dependências e não executa o código que analisa. E quando não tem evidência, ele diz isso em vez de inventar confiança:
|
|
78
|
-
|
|
79
|
-
| Situação | O que o Mjölnir reporta |
|
|
80
|
-
| ---------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
81
|
-
| Nenhuma declaração de teste encontrada | Pontuação `null`, exibida como **UNKNOWN**. Nunca um 100 inventado. |
|
|
82
|
-
| Nenhuma baseline ou revisão comparável | **UNKNOWN**, com o motivo informado. Nunca um 0 presumido. |
|
|
83
|
-
| Scan interrompido (orçamento de tempo, arquivos ilegíveis) | **PARTIAL**, saída `2`. Nunca apresentado como limpo. |
|
|
84
|
-
|
|
85
|
-
<p align="center">
|
|
86
|
-
<img src="assets/readme/how-it-works.svg" alt="Como o Mjölnir funciona. Ele lê a suíte de testes e o pipeline de CI de forma estática, e o relatório de uma execução real quando existe um. Ele pondera cada achado pelo nível de evidência e pelo nível de confiança, em que só uma execução real alcança L3 a L5, e produz achados, uma pontuação de confiabilidade e um gate de CI com códigos de saída congelados. No ciclo do agente, a IA escreve a correção e o Mjölnir refaz o scan para prová-la." width="880" />
|
|
87
|
-
</p>
|
|
88
|
-
|
|
89
|
-
<sub>Composto para esta página e exibido em 1:1. Gerado por `npm run docs:readme-brand` e travado contra desvios na CI; a pontuação, as contagens e o ID da regra vêm de [`script.demo.json`](assets/video/script.demo.json), [`demo-report.json`](assets/readme/demo-report.json) e do registro de regras, nunca digitados à mão. A mesma imagem como pôster: [`architecture.svg`](assets/readme/architecture.svg).</sub>
|
|
90
|
-
|
|
91
|
-
<br />
|
|
92
|
-
|
|
93
|
-
## Veja funcionando
|
|
94
|
-
|
|
95
|
-
Um scan real de [`examples/demo-repo`](examples/demo-repo), uma pequena suíte Playwright com um workflow de CI. Foi para cá que os pontos dela foram:
|
|
96
|
-
|
|
97
|
-
<p align="center">
|
|
98
|
-
<img src="assets/readme/terminal-hero.svg" alt="O detalhamento das deduções do Mjölnir: WORTHINESS 80/100 WORTHY, a pontuação por categoria, o quadro de deduções por severidade e uma lista FIX THIS FIRST" width="520" />
|
|
99
|
-
</p>
|
|
100
|
-
|
|
101
|
-
<sub>Gerado por `npm run docs:hero` a partir de um scan real e travado contra desvios na CI. O relatório `--verbose` completo do mesmo scan é [`demo.svg`](assets/readme/demo.svg) (`npm run docs:demo`).</sub>
|
|
102
|
-
|
|
103
|
-
<details>
|
|
104
|
-
<summary><strong>Assista</strong> — um scan, a correção que ele imprime e o novo scan que a prova</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="Um quadro da gravação de demonstração: npx mjolnir-qa@5.0.0 analisando o repositório de demonstração em uma janela de terminal" width="900" />
|
|
111
|
-
</a>
|
|
112
|
-
</p>
|
|
113
|
-
|
|
114
|
-
<sub>Renderizado quadro a quadro a partir de um scan real por `npm run docs:video`; nunca gravado da tela. Selecione o quadro para abrir [`mjolnir-demo.mp4`](assets/video/mjolnir-demo.mp4).</sub>
|
|
115
|
-
|
|
116
|
-
</details>
|
|
117
|
-
|
|
118
|
-
### Um achado, de perto
|
|
119
|
-
|
|
120
|
-
Todo achado responde a quatro perguntas: onde está, quão seguro o Mjölnir está, com que frequência a regra erra e como corrigir.
|
|
121
|
-
|
|
122
|
-
<p align="center">
|
|
123
|
-
<img src="assets/readme/finding-anatomy.svg" alt="O primeiro achado do scan de demonstração, exatamente como o terminal o imprime, com suas quatro partes destacadas: onde, quão seguro, com que frequência a regra erra, e a correção." width="100%" />
|
|
124
|
-
</p>
|
|
125
|
-
|
|
126
|
-
`mjolnir explain QA-CI-001` imprime o histórico de confiança completo de uma regra, incluindo sua taxa de falsos positivos medida e o nível que essa taxa lhe rendeu:
|
|
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
|
-
Essa é a unidade de valor: um lugar onde a CI reporta uma aprovação que não mereceu.
|
|
173
|
-
|
|
174
|
-
<br />
|
|
175
|
-
|
|
176
|
-
## Início rápido
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
npx mjolnir-qa@5.0.0
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Ele analisa o diretório atual e imprime o Trust Report: o que encontrou, até onde você pode confiar, por quê e o que fazer em seguida. Sai com `0` quando nada foi encontrado no nível do gate ou acima.
|
|
183
|
-
|
|
184
|
-
Na CI, analise só o que a branch introduziu, para que uma suíte legada não afogue seu primeiro pull request:
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
npx mjolnir-qa@5.0.0 --scope changed
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
`mjolnir ci install` grava isso como um workflow do GitHub Actions, usando a [action](https://github.com/Sergey-Bar/Mjolnir#readme) fixada na tag principal `v3` (ou `npx` puro com `--no-action`). Ele continua consultivo até você decidir que deve bloquear.
|
|
191
|
-
|
|
192
|
-
| Comando | O que faz |
|
|
193
|
-
| --------------------------------------------- | ------------------------------------------------------------- |
|
|
194
|
-
| `mjolnir` | Trust Report: veredito, confiança, próxima ação |
|
|
195
|
-
| `mjolnir --scope changed` | Só o que sua branch introduziu (a forma para CI) |
|
|
196
|
-
| `mjolnir ci install` | Gera o workflow consultivo de PR (baseado na 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` | O quê, por quê e correção, mais a taxa de FP medida |
|
|
213
|
-
| `mjolnir why src/a.spec.ts:42` | Por que exatamente esta linha foi apontada. Nunca bloqueia. |
|
|
214
|
-
| `mjolnir forensics ./test-results/` | Evidência de runtime de uma execução real |
|
|
215
|
-
| `mjolnir trust-report` | Trust Artifact autocontido (md + json) |
|
|
216
|
-
| `mjolnir handoff` | Plano de correção para um agente de código |
|
|
217
|
-
| `mjolnir --json` / `--format sarif` | Saída legível por máquina, GitHub Code Scanning |
|
|
218
|
-
| `mjolnir --format codequality` | Relatório do GitLab Code Quality (artefato do widget de MR) |
|
|
219
|
-
| `mjolnir --strict` | Também roda as regras do nível quarantine (maior risco de FP) |
|
|
220
|
-
|
|
221
|
-
<details>
|
|
222
|
-
<summary><strong>Todos os outros comandos</strong> — triagem de testes instáveis, relatórios, governança</summary>
|
|
223
|
-
|
|
224
|
-
<br />
|
|
225
|
-
|
|
226
|
-
| Comando | O que faz |
|
|
227
|
-
| ----------------------------------- | ----------------------------------------------------------------------------- |
|
|
228
|
-
| `mjolnir --classic` | O banner de pontuação anterior ao Trust Report |
|
|
229
|
-
| `mjolnir explain verdict` | Por que o veredito do scan salvo é o que é |
|
|
230
|
-
| `mjolnir triage ./test-results/` | Triagem guiada. Cada linha termina em uma próxima ação. |
|
|
231
|
-
| `mjolnir pw-report ./test-results/` | Resumo da execução do Playwright: retries, instáveis, os mais lentos |
|
|
232
|
-
| `mjolnir doctor:playwright` | Scan profundo só de Playwright mais Selector Health Score |
|
|
233
|
-
| `mjolnir fix --dry-run` / `fix` | Correções automáticas seguras, cada uma reanalisada para provar que funcionou |
|
|
234
|
-
| `mjolnir baseline` / `diff` | Registra os achados e depois reporta só os novos ou piores |
|
|
235
|
-
| `mjolnir impact --since <ref>` | O que um commit introduziu e resolveu |
|
|
236
|
-
| `mjolnir summary` | Anotações de CI e um resumo do step a partir de um relatório |
|
|
237
|
-
| `mjolnir pr-comment` | Um comentário de PR com escopo, em Markdown |
|
|
238
|
-
| `mjolnir debt` | Registro de dívida de testes com um modelo de custo |
|
|
239
|
-
| `mjolnir handover` | Mapa de integração da suíte para um novo engenheiro de QA |
|
|
240
|
-
| `mjolnir init` | Detecta frameworks e imprime um checklist de configuração |
|
|
241
|
-
| `mjolnir suppressions` | Lista os achados suprimidos, para governança |
|
|
242
|
-
| `mjolnir rules --unmeasured` | As regras que rodam por suposição, não por medição |
|
|
243
|
-
| `mjolnir rules --md` | Catálogo completo de regras (JSON ou Markdown) |
|
|
244
|
-
| `mjolnir doctor` | Autoauditoria da base de regras do próprio Mjölnir |
|
|
245
|
-
| `mjolnir create-rule <ID>` | Cria o esqueleto de uma nova regra e suas fixtures |
|
|
246
|
-
| `mjolnir stats` | Contadores locais de todas as correções já vistas |
|
|
247
|
-
| `mjolnir badge` | JSON de endpoint do shields.io e snippet |
|
|
248
|
-
| `mjolnir --cache` | Novos scans incrementais via um cache local de vereditos |
|
|
249
|
-
| `mjolnir --format mermaid` | Diagrama da arquitetura de testes para um comentário de PR |
|
|
250
|
-
|
|
251
|
-
`mjolnir help <command>` imprime uso, exemplos e o próximo passo de qualquer um deles.
|
|
252
|
-
|
|
253
|
-
</details>
|
|
254
|
-
|
|
255
|
-
Requer **Node.js ≥ 22.18** no Windows, macOS ou Linux. Prefere uma instalação global? `npm i -g mjolnir-qa`. O mínimo vem da cadeia de build (o tsdown mira nele e o pipeline de release faz smoke tests contra ele); as dependências de runtime não precisam de mais que isso.
|
|
256
|
-
|
|
257
|
-
<br />
|
|
258
|
-
|
|
259
|
-
## O que o Mjölnir encontra
|
|
260
|
-
|
|
261
|
-
<p align="center">
|
|
262
|
-
<img src="assets/readme/stack.svg" alt="Funciona com a sua stack: as linguagens, frameworks de teste e sistemas de CI cobertos pelas regras, a partir do registro de regras." width="100%" />
|
|
263
|
-
</p>
|
|
264
|
-
|
|
265
|
-
**79 regras** em quatro famílias — higiene de testes, qualidade de testes, Playwright e integridade de CI — para TypeScript e JavaScript, Python, Java, C# e YAML do GitHub Actions. Elas cobrem o Playwright nos quatro bindings, além de pytest, JUnit, TestNG, NUnit, xUnit, MSTest, Jest, Vitest e Mocha, com cobertura inicial para Cypress e Selenium. Nove delas, para mostrar o formato:
|
|
266
|
-
|
|
267
|
-
| ID | Regra | Severidade | Nível |
|
|
268
|
-
| ------------ | ------------------------------------------------------------------------- | ---------- | ---------- |
|
|
269
|
-
| QA-CI-001 | `continue-on-error` mascara um gate de verificação que falha | error | quarantine |
|
|
270
|
-
| QA-CI-009 | Código de saída dos testes não propagado (`\|` sem pipefail, cadeias `;`) | error | extended |
|
|
271
|
-
| QA-TEST-001 | Teste focado commitado (`.only`, `fit`) | error | quarantine |
|
|
272
|
-
| QA-TEST-003 | Teste sem asserções | error | quarantine |
|
|
273
|
-
| QA-TQUAL-009 | Asserção de promise sem await | error | quarantine |
|
|
274
|
-
| QA-PW-002 | Asserção de locator sem await | error | core |
|
|
275
|
-
| QA-PW-004 | Seletores CSS/XPath frágeis | warning | quarantine |
|
|
276
|
-
| QA-PY-002 | Teste pulado (`skip`, `xfail` não estrito) | warning | core |
|
|
277
|
-
| QA-CS-103 | Método de teste sem asserções | error | core |
|
|
278
|
-
|
|
279
|
-
O catálogo completo é gerado a partir do registro, nunca mantido à mão: `mjolnir rules --md`, [`docs/rules/`](docs/rules/) ou o [guia do que ele verifica](https://sergey-bar.github.io/Mjolnir/guide/what-it-checks).
|
|
280
|
-
|
|
281
|
-
<details>
|
|
282
|
-
<summary><strong>Todas as regras citadas neste README</strong>, em uma tabela</summary>
|
|
283
|
-
|
|
284
|
-
<br />
|
|
285
|
-
|
|
286
|
-
> Regras `quarantine` só rodam com `--strict` e nunca bloqueiam (ficam limitadas a info). A severidade mostrada é a definida pelo autor.
|
|
287
|
-
|
|
288
|
-
| ID | Família | Regra | Severidade | Nível |
|
|
289
|
-
| ------------ | ---------- | -------------------------------------------------------------- | ---------- | ---------- |
|
|
290
|
-
| QA-TEST-001 | Higiene | Teste focado commitado (`.only`, `fit`) | error | quarantine |
|
|
291
|
-
| QA-TEST-002 | Higiene | Teste pulado. Escala para `error` sem um motivo rastreado. | warning | quarantine |
|
|
292
|
-
| QA-TEST-003 | Higiene | Teste sem asserções | error | quarantine |
|
|
293
|
-
| QA-TEST-004 | Higiene | Sleep fixo (`waitForTimeout`, `sleep()`, `delay()`) | warning | extended |
|
|
294
|
-
| QA-TEST-006 | Higiene | Abuso de retry escondendo instabilidade | warning | quarantine |
|
|
295
|
-
| QA-TEST-010 | Higiene | Corpo de teste vazio | error | quarantine |
|
|
296
|
-
| QA-TQUAL-002 | Qualidade | Asserção tautológica | error | quarantine |
|
|
297
|
-
| QA-TQUAL-009 | Qualidade | Asserção de promise sem await | error | quarantine |
|
|
298
|
-
| QA-TQUAL-011 | Qualidade | Testes comentados | warning | extended |
|
|
299
|
-
| QA-PW-002 | Playwright | Asserção de locator sem await | error | core |
|
|
300
|
-
| QA-PW-003 | Playwright | `page.pause()` / `test.only()` commitado | error | core |
|
|
301
|
-
| QA-PW-004 | Playwright | Seletores CSS/XPath frágeis | warning | quarantine |
|
|
302
|
-
| QA-PW-123 | Playwright | URLs de ambiente fixas no código | warning | quarantine |
|
|
303
|
-
| QA-PW-140 | Playwright | Screenshot sem `maxDiffPixelRatio` | warning | core |
|
|
304
|
-
| QA-CI-001 | CI | `continue-on-error` mascara um gate que falha | error | quarantine |
|
|
305
|
-
| QA-CI-002 | CI | `\|\| true` engole códigos de saída | error | extended |
|
|
306
|
-
| QA-CI-005 | CI | Relatório consumido, mas nunca gerado | error | quarantine |
|
|
307
|
-
| QA-CI-007 | CI | Wrappers de retry em volta dos testes | warning | extended |
|
|
308
|
-
| QA-CI-008 | CI | Step que sempre passa mascara falhas | error | quarantine |
|
|
309
|
-
| QA-CI-009 | CI | Código de saída não propagado (`\|` sem pipefail, cadeias `;`) | error | extended |
|
|
310
|
-
| QA-CI-010 | CI | Testes pulados onde deveriam bloquear | error | quarantine |
|
|
311
|
-
| QA-PY-002 | Python | Teste pulado (`skip`, `xfail` não estrito) | warning | core |
|
|
312
|
-
| QA-PY-003 | Python | Função de teste sem asserções | error | quarantine |
|
|
313
|
-
| QA-PY-005 | Python | `time.sleep()` nos testes | warning | extended |
|
|
314
|
-
| QA-PY-012 | Python | Asserção tautológica | error | quarantine |
|
|
315
|
-
| QA-JV-101 | Java | Teste desativado (`@Disabled`) | warning | core |
|
|
316
|
-
| QA-JV-102 | Java | Sleep fixo (`Thread.sleep()`) | warning | extended |
|
|
317
|
-
| QA-JV-103 | Java | Método de teste sem asserções | error | extended |
|
|
318
|
-
| QA-JV-105 | Java | Sleep fixo com `waitForTimeout()` do Playwright | warning | core |
|
|
319
|
-
| QA-JV-106 | Java | Seletor frágil em vez de locator por papel | warning | quarantine |
|
|
320
|
-
| QA-CS-101 | C# | Teste pulado (`[Ignore]`, `[Fact(Skip=)]`) | warning | core |
|
|
321
|
-
| QA-CS-102 | C# | Sleep fixo (`Thread.Sleep` / `Task.Delay`) | warning | core |
|
|
322
|
-
| QA-CS-103 | C# | Método de teste sem asserções | error | core |
|
|
323
|
-
| QA-CS-105 | C# | Sleep fixo com `WaitForTimeoutAsync()` | warning | extended |
|
|
324
|
-
| QA-CS-106 | C# | Seletor frágil em vez de locator por papel | warning | quarantine |
|
|
325
|
-
|
|
326
|
-
O Python também traz QA-PY-001…012 (higiene do pytest) e QA-PY-101…108 (Playwright para Python). Cypress e Selenium têm conjuntos iniciais de três regras cada.
|
|
327
|
-
|
|
328
|
-
</details>
|
|
329
|
-
|
|
330
|
-
Toda regra é lançada com uma fixture must-fire **e** uma must-not-fire, e uma regra que dispara na própria fixture negativa não pode ser lançada. Esse é o firewall contra falsos positivos; `mjolnir doctor` o aplica na própria CI deste repositório.
|
|
331
|
-
|
|
332
|
-
### Selector Health Score
|
|
333
|
-
|
|
334
|
-
`mjolnir doctor:playwright` avalia cada locator pela forma como encontra um elemento: do jeito que um usuário faria (papel, rótulo, texto), por um contrato explícito (`data-testid`) ou por um acidente estrutural (cadeias CSS, XPath). Cada arquivo recebe uma pontuação de 0 a 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
|
-
Isso mede **resiliência, não correção**. `.btn.btn-primary > div:nth-child(2)` passa hoje e continua passando até alguém mexer no markup. Uma pontuação baixa nunca afirma que o teste está quebrado, só que ele depende de um markup que ninguém prometeu manter.
|
|
349
|
-
|
|
350
|
-
<br />
|
|
351
|
-
|
|
352
|
-
## A pontuação de confiabilidade
|
|
353
|
-
|
|
354
|
-
<p align="center">
|
|
355
|
-
<img src="assets/readme/score-gauge.svg" alt="A escala de confiabilidade de 0 a 100, com um marcador que percorre cada pontuação: UNWORTHY abaixo de 50, NEEDS WORK de 50 a 79, WORTHY de 80 a 99, FORGED em 100" width="720" />
|
|
356
|
-
</p>
|
|
357
|
-
|
|
358
|
-
<sub>Cada pontuação de 0 a 100, posicionada pelo `deriveScoreState` real. Gerado por `npm run docs:gauge` e travado contra desvios na CI.</sub>
|
|
359
|
-
|
|
360
|
-
| Pontuação | Veredito |
|
|
361
|
-
| --------- | --------------------------------------------------- |
|
|
362
|
-
| `0 – 49` | **UNWORTHY** |
|
|
363
|
-
| `50 – 79` | **NEEDS WORK** |
|
|
364
|
-
| `80 – 99` | **WORTHY** |
|
|
365
|
-
| `100` | **FORGED** |
|
|
366
|
-
| `null` | **UNKNOWN**: nenhuma declaração de teste encontrada |
|
|
367
|
-
|
|
368
|
-
**Como é calculada.** A severidade define uma dedução base (`error −8`, `warning −3`, `info −1`) e o nível de evidência a desconta: E2 conta integralmente, E1 pela metade (arredondado para baixo), E0 nada. O total é normalizado pela exposição da suíte, ou seja, deduções por declaração de teste, e não por arquivo. O terminal imprime os mesmos números descontados que a pontuação usou; não há um segundo modelo escondido. Detalhes: [docs/SCORING.md](docs/SCORING.md) e o [guia de pontuação](https://sergey-bar.github.io/Mjolnir/guide/scoring).
|
|
369
|
-
|
|
370
|
-
**O que 100 não significa.** Não significa que o software está correto, que a suíte é adequada ou que o produto está livre de defeitos. Significa uma única coisa: **nenhuma das regras avaliadas pelo Mjölnir produziu uma dedução neste scan e neste modelo de evidência.**
|
|
371
|
-
|
|
372
|
-
<br />
|
|
373
|
-
|
|
374
|
-
## O modelo de evidência
|
|
375
|
-
|
|
376
|
-
Todo achado carrega dois rótulos: quão seguro o Mjölnir está e até onde o achado foi verificado. Essa é a diferença entre uma ferramenta que reporta padrões e uma ferramenta em que você pode condicionar um release.
|
|
377
|
-
|
|
378
|
-
**Quão seguro — o nível de evidência.**
|
|
379
|
-
|
|
380
|
-
| Nível | Nome | Significa | Dedução |
|
|
381
|
-
| ------ | -------------------- | --------------------------------------------------- | -------- |
|
|
382
|
-
| **E2** | Prova determinística | O defeito está presente no código como escrito | Integral |
|
|
383
|
-
| **E1** | Evidência de padrão | Um padrão fortemente ligado ao defeito correspondeu | Metade |
|
|
384
|
-
| **E0** | Observação | Vale saber. Não afirma que algo está errado. | Zero |
|
|
385
|
-
|
|
386
|
-
A confiança em uma detecção não é a força da prova. Uma regra pode ter certeza de que encontrou o que procurava e ainda assim estar olhando para uma heurística. Achados E1 existem para ser lidos e julgados, nunca aplicados às cegas, e esse limite fica marcado no achado no terminal, no JSON e na passagem para o agente.
|
|
387
|
-
|
|
388
|
-
**Até onde foi verificado — o nível de confiança.** A maioria dos achados vem da leitura do seu código. Dê ao Mjölnir o relatório de uma execução real de testes e ele poderá confirmar que o código de fato rodou.
|
|
389
|
-
|
|
390
|
-
<p align="center">
|
|
391
|
-
<img src="assets/readme/trust-ladder.svg" alt="A escada de confiança de L0 a L5. L0 a L2 vêm da leitura do código; L3 a L5 precisam do relatório de uma execução real, marcado por uma quebra na escada." width="100%" />
|
|
392
|
-
</p>
|
|
393
|
-
|
|
394
|
-
| Nível | Em palavras simples | O que é preciso |
|
|
395
|
-
| ------ | ------------------- | --------------------------------------------------------------------- |
|
|
396
|
-
| **L0** | Anotado | Ler o código |
|
|
397
|
-
| **L1** | Parece o problema | Ler o código: um padrão correspondeu |
|
|
398
|
-
| **L2** | Provado no código | Ler o código: o defeito é estrutural |
|
|
399
|
-
| **L3** | O arquivo rodou | Um relatório de execução mostra que o arquivo do achado foi executado |
|
|
400
|
-
| **L4** | O teste rodou | Um relatório de execução mostra que o teste do achado foi executado |
|
|
401
|
-
| **L5** | A execução concorda | O próprio resultado da execução confirma a classe do defeito |
|
|
402
|
-
|
|
403
|
-
Um scan estático para em L2. Só o relatório de uma execução real (Playwright JSON, Jest ou Vitest JSON, JUnit XML) pode elevar um achado a L3 ou acima, de modo que um achado que nunca foi visto rodando nunca pode afirmar que rodou. Definições: [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md).
|
|
404
|
-
|
|
405
|
-
### Quanto disso é medido
|
|
406
|
-
|
|
407
|
-
**74 de 79 regras têm uma taxa de falsos positivos medida contra código OSS real** (pelo menos 10 achados classificados à mão cada; veja [docs/FP-AUDIT.md](docs/FP-AUDIT.md)). As outras 5 são lançadas com a estimativa do autor e dizem isso, regra por regra, em `mjolnir explain`. `mjolnir rules --unmeasured` as lista, e o rodapé de cada scan informa quantas das regras que de fato _dispararam_ são medidas.
|
|
408
|
-
|
|
409
|
-
As taxas continuam públicas quando são ruins. QA-TEST-001 (um `.only` commitado) vai mal na auditoria em repositórios reais e por isso está em quarantine. O número atual de cada regra, incluindo QA-PW-141, está na auditoria.
|
|
410
|
-
|
|
411
|
-
### Níveis de confiança das regras
|
|
412
|
-
|
|
413
|
-
Os níveis seguem a taxa de falsos positivos medida, não opinião:
|
|
414
|
-
|
|
415
|
-
| Nível | FP medido | Comportamento |
|
|
416
|
-
| -------------- | --------------------------------- | -------------------------------------------------- |
|
|
417
|
-
| **core** | ≤ 10% | Relatório padrão, bloqueia |
|
|
418
|
-
| **extended** | ≤ 30% | Relatório padrão, confiança menor |
|
|
419
|
-
| **quarantine** | > 30% ou explicitamente declarado | Só com `--strict`, limitado a info, nunca bloqueia |
|
|
420
|
-
| _não medida_ | n < 10 | Não pode ser promovida a core até ser medida |
|
|
421
|
-
|
|
422
|
-
As faixas de FP só podem rebaixar um nível — nunca promovem uma regra para fora de `quarantine` se ela foi explicitamente declarada lá. Uma regra explicitamente colocada em quarantine permanece em quarantine independentemente de sua taxa de FP medida.
|
|
423
|
-
|
|
424
|
-
Promoção, rebaixamento e maturidade por linguagem: [ciclo de vida das regras](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle).
|
|
425
|
-
|
|
426
|
-
### Por que isto não é um linter
|
|
427
|
-
|
|
428
|
-
Linters dizem se o código segue regras. O Mjölnir diz se a sua verificação merece confiança.
|
|
429
|
-
|
|
430
|
-
| | Linters (ESLint, SonarQube) | Ferramentas de cobertura | Revisão de código com IA | **Mjölnir** |
|
|
431
|
-
| ------------------------------------------------------------------ | :-------------------------: | :----------------------: | :----------------------: | :--------------: |
|
|
432
|
-
| Pontua o **sistema de verificação**, não o código do produto | Não | Não | Não | Sim |
|
|
433
|
-
| Integridade dos workflows de CI (`continue-on-error`, `\|\| true`) | Não | Não | só o diff | Sim |
|
|
434
|
-
| Avalia a resiliência dos locators do Playwright (Selector Health) | Não | Não | Não | Sim |
|
|
435
|
-
| Lê dados de execução reais para vereditos `TRUE-FLAKE` | Não | Não | Não | Sim |
|
|
436
|
-
| Publica uma taxa de falsos positivos medida por regra | Não | Não | Não | Sim |
|
|
437
|
-
| Aponta testes sem asserções | Sim\* | Não | às vezes | Sim |
|
|
438
|
-
| Detecta sleeps fixos (`waitForTimeout`, `time.sleep`) | Sim\* | Não | às vezes | Sim |
|
|
439
|
-
| Determinístico (mesma entrada, mesma saída) | Sim | Sim | Não | Sim |
|
|
440
|
-
| Custo por scan | grátis | grátis | tokens | **zero** (local) |
|
|
441
|
-
|
|
442
|
-
<sub>\*Coberto por `eslint-plugin-jest` e `eslint-plugin-playwright` (`expect-expect`, `no-wait-for-timeout`) e pelas próprias regras de asserção do SonarQube. As colunas descrevem o comportamento padrão para verificação de suítes de teste; plugins, planos pagos e regras personalizadas mudam algumas respostas. Este é um resumo de posicionamento, não um benchmark.</sub>
|
|
443
|
-
|
|
444
|
-
Use revisão com IA também. Ela percebe nuances, intenção e falhas de design que nenhum padrão encontra. O Mjölnir pega o que a revisão com IA deixa passar porque parece intencional: um `.only` commitado, um código de saída engolido, um `continue-on-error` em um job de testes. Isso exige scan, não raciocínio.
|
|
445
|
-
|
|
446
|
-
<br />
|
|
447
|
-
|
|
448
|
-
## Forense de execução
|
|
449
|
-
|
|
450
|
-
A análise estática raciocina sobre código que nunca rodou. A forense lê o que realmente aconteceu: Playwright JSON, Jest JSON, Vitest JSON e JUnit XML de qualquer runner.
|
|
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` não significa que o teste teve retry. Significa que o teste **falhou em pelo menos uma tentativa e depois terminou verde**: uma aprovação por sorte, apontada não importa o que diga o check final. `mjolnir triage` transforma esse histórico em uma proposta de quarentena, e `mjolnir pw-report` resume uma execução. São esses mesmos relatórios de execução que elevam os achados aos níveis de confiança L3 e acima.
|
|
468
|
-
|
|
469
|
-
<br />
|
|
470
|
-
|
|
471
|
-
## Integridade de CI
|
|
472
|
-
|
|
473
|
-
Um teste pode passar enquanto o pipeline ao redor dele não consegue falhar. O Mjölnir também lê os workflows: `continue-on-error`, `|| true`, códigos de saída que nunca se propagam, steps que sempre passam, relatórios consumidos mas nunca gerados e gates pulados justamente nos eventos que deveriam bloquear. Cada achado nomeia o job, o step e a linha, e carrega seu próprio nível de evidência.
|
|
474
|
-
|
|
475
|
-
Gere o workflow de PR, consultivo por padrão:
|
|
476
|
-
|
|
477
|
-
```bash
|
|
478
|
-
mjolnir ci install
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
Ou adicione a action do Marketplace a um workflow que você já tem:
|
|
482
|
-
|
|
483
|
-
```yaml
|
|
484
|
-
- uses: Sergey-Bar/Mjolnir@v3
|
|
485
|
-
with:
|
|
486
|
-
scope: changed
|
|
487
|
-
fail-on: error
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
Fixe `@v3` para acompanhar a linha principal, ou uma tag exata (`@v0.5.32`) para um gate reproduzível. [docs/DISTRIBUTION-KIT.md](docs/DISTRIBUTION-KIT.md) cobre o Marketplace, o Smithery e os registros MCP.
|
|
491
|
-
|
|
492
|
-
Para levar os achados ao GitHub Code Scanning, envie o SARIF (requer `security-events: write` no escopo do workflow ou job):
|
|
493
|
-
|
|
494
|
-
```yaml
|
|
495
|
-
- run: npx mjolnir-qa@5.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
|
-
No GitLab, `--format codequality` grava o relatório do Code Quality que o widget de MR e as anotações do diff leem ([docs/GITLAB-CI.md](docs/GITLAB-CI.md)). Configuração do editor e do pipeline: [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md).
|
|
504
|
-
|
|
505
|
-
### Atribuição no escopo alterado
|
|
506
|
-
|
|
507
|
-
```bash
|
|
508
|
-
npx mjolnir-qa@5.0.0 --scope changed
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
Os achados são atribuídos às linhas que sua branch adicionou, medidas contra a **merge-base**. O escopo é o mesmo conjunto de arquivos que um scan completo descobre (specs TS/JS e configurações de adaptadores, `test_*.py`, `*Test.java`, `*Tests.cs`, `.github/workflows/*.yml`), mais as alterações não commitadas e não rastreadas, então funciona antes do commit. A base é resolvida como `main → master → origin/main → origin/master → origin/HEAD`; substitua com `--base <ref>`.
|
|
512
|
-
|
|
513
|
-
Quando a merge-base não pode ser resolvida (um clone raso, um HEAD destacado, um alvo fora do git), os achados passam a ser atribuídos ao arquivo inteiro **e o relatório diz isso.** Um fallback silencioso seria exatamente o tipo de defeito que esta ferramenta existe para pegar.
|
|
514
|
-
|
|
515
|
-
<br />
|
|
516
|
-
|
|
517
|
-
## Agentes de IA
|
|
518
|
-
|
|
519
|
-
Achados só valem alguma coisa se algo agir sobre eles.
|
|
520
|
-
|
|
521
|
-
```text
|
|
522
|
-
SCAN → EVIDENCE → HANDOFF → AGENT → RE-SCAN → PROOF
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
**A IA escreve a correção. O Mjölnir a verifica.** A prova vem do novo scan, nunca do próprio relato de sucesso do agente.
|
|
526
|
-
|
|
527
|
-
| Comando | O que o agente recebe |
|
|
528
|
-
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
529
|
-
| `mjolnir mcp` | Um servidor [MCP](https://modelcontextprotocol.io) via stdio. `scan`, `explain` e `diff` viram ferramentas chamáveis. |
|
|
530
|
-
| `mjolnir handoff` | Um relatório `--json` salvo vira um plano determinístico em Markdown: o que foi detectado, o limite de evidência de cada achado, o que **não** pode mudar, como verificar. |
|
|
531
|
-
| `mjolnir install` | Grava nas superfícies de agente que seu repo já tem (`.claude/`, `.cursor/`, `.kilo/`, `AGENTS.md`) para que o agente refaça o scan antes de dizer que terminou. |
|
|
532
|
-
|
|
533
|
-
Adicione-o a um cliente que tenha sua própria CLI:
|
|
534
|
-
|
|
535
|
-
```bash
|
|
536
|
-
claude mcp add mjolnir -- npx -y mjolnir-qa@5.0.0 mcp
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
Ou a qualquer cliente que aceite um bloco `mcpServers`:
|
|
540
|
-
|
|
541
|
-
```json
|
|
542
|
-
{
|
|
543
|
-
"mcpServers": {
|
|
544
|
-
"mjolnir": { "command": "npx", "args": ["-y", "mjolnir-qa@5.0.0", "mcp"] }
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
**A proteção importa mais que a conveniência.** Todo achado em uma passagem carrega seu limite. **E2** diz _determinístico: confira o local e aplique a correção_. **E1** diz _REQUER CONFIRMAÇÃO: a observação sozinha não prova o defeito_. Um agente que corrige E1 às cegas, suprime uma regra ou edita uma regra para aumentar a pontuação está fazendo exatamente o que esta ferramenta existe para pegar, então a passagem diz isso no prompt, ao lado do achado.
|
|
550
|
-
|
|
551
|
-
<br />
|
|
552
|
-
|
|
553
|
-
## Confiança e segurança
|
|
554
|
-
|
|
555
|
-
**Local-first, zero telemetria.** Nenhuma API com acesso à rede (`fetch`, `http`, `https`, `net`, `dns`, `dgram`, WebSocket) existe em lugar nenhum de `src/`, e [`privacy-network-isolation.spec.ts`](tests/contract/privacy-network-isolation.spec.ts) quebra o build se uma aparecer. Ele também proíbe `eval` e `new Function`. Analisar código não confiável nunca o executa: a análise estática lê o texto-fonte, e a forense interpreta arquivos de relatório que já existem em disco.
|
|
556
|
-
|
|
557
|
-
Duas ressalvas: o próprio `npx` baixa o pacote antes de qualquer coisa rodar, e a garantia cobre `src/`, não plugins de terceiros.
|
|
558
|
-
|
|
559
|
-
**Plugins não rodam em sandbox.** Plugins JS (`mjolnir-rules/*.mjs`, ou pacotes npm listados em `"plugins"`) rodam com todos os privilégios do Node, o mesmo modelo de confiança dos plugins do ESLint ou do Vitest. Carregá-los é opcional **por scan**: sem `--enable-plugins` (ou `MJOLNIR_ENABLE_PLUGINS=1`), suas fontes nunca são carregadas, e um aviso no stderr lista o que foi pulado. Manifestos de regras em JSON não executam código, e os prefixos de ID das regras core são reservados para que nenhum plugin possa se passar por uma delas. Reporte vulnerabilidades por meio do [SECURITY.md](SECURITY.md).
|
|
560
|
-
|
|
561
|
-
**Ele roda sobre si mesmo.** Um motor de confiança de verificação não tem credibilidade se não for ele próprio verificável. Cada execução da CI analisa este repositório com o build que essa mesma execução produziu. O gate falha com qualquer achado de severidade error, e também com um scan **parcial** ou uma **regra que travou**, porque um autoscan truncado que não reporta nada é o falso verde que este projeto existe para pegar. `mjolnir doctor` reaudita a base de regras na mesma execução (firewall de fixtures, honestidade dos níveis, o teto do nível core), e uma verificação INCONCLUSIVE falha exatamente como uma que falhou. Os dois relatórios são enviados como artefatos do build.
|
|
562
|
-
|
|
563
|
-
### Códigos de saída e o contrato de máquina
|
|
564
|
-
|
|
565
|
-
Congelados, para que você possa construir lógica de CI em cima deles:
|
|
566
|
-
|
|
567
|
-
| Código de saída | Significado |
|
|
568
|
-
| --------------- | ------------------------------------------------------------------------------- |
|
|
569
|
-
| `0` | Limpo: nenhum achado no nível do gate ou acima |
|
|
570
|
-
| `1` | Achados no nível do gate ou acima |
|
|
571
|
-
| `2` | Scan parcial (orçamento de tempo esgotado, arquivos ilegíveis). Nunca bloqueia. |
|
|
572
|
-
| `10` | Erro de uso (flag inválida, alvo ausente) |
|
|
573
|
-
| `20` | Erro interno |
|
|
574
|
-
|
|
575
|
-
`2` é deliberadamente diferente de `0`: um scan que não terminou não encontrou "nada". Ele só não terminou de procurar.
|
|
576
|
-
|
|
577
|
-
Tudo o que uma máquina consome (resultados das ferramentas MCP, `--json`, SARIF 2.1) vem de um único resultado canônico sob um esquema versionado e **somente aditivo** (`schemaVersion: 1`, `contractVersion: 1`), para que nenhum consumidor precise reconstruir significado a partir de texto renderizado. Veja [o contrato de máquina](docs/machine-contract.md). IDs de regra (`QA-<FAMILY>-NNN`) são imutáveis depois de lançados e nunca são reutilizados.
|
|
578
|
-
|
|
579
|
-
<br />
|
|
580
|
-
|
|
581
|
-
## O que o Mjölnir não pode dizer
|
|
582
|
-
|
|
583
|
-
- **Ele não roda seus testes.** Um scan limpo não é uma suíte aprovada.
|
|
584
|
-
- **Ele não pode dizer que uma asserção está _errada_.** `expect(total).toBe(41)` parece saudável. O Mjölnir encontra testes que _não podem falhar_ e pipelines que _não podem ficar vermelhos_, não testes que verificam a coisa errada.
|
|
585
|
-
- **Ele não prova a correção de negócio.** Nada aqui diz que o seu produto faz o que o requisito pediu.
|
|
586
|
-
- **Um 100 não é prova de uma boa suíte.** Se a sua suíte cobre o seu risco real é outra questão, e esta ferramenta não a responde.
|
|
587
|
-
- **5 de 79 regras são lançadas com uma estimativa**, não com uma taxa medida. Cada uma diz isso no próprio achado.
|
|
588
|
-
- **E1 não é E2.** Achados heurísticos merecem ser lidos, não aplicados às cegas.
|
|
589
|
-
- **Um repo vazio recebe `null`, nunca 100.**
|
|
590
|
-
- **Um arquivo chamado `*.spec.ts` sem declarações de teste não conta como cobertura.** Um repo cujos únicos arquivos spec contêm imports ou tipos (zero chamadas `it`/`test`) recebe `null`, não 100.
|
|
591
|
-
|
|
592
|
-
<br />
|
|
593
|
-
|
|
594
|
-
## Documentação
|
|
595
|
-
|
|
596
|
-
O site completo de documentação está em <https://sergey-bar.github.io/Mjolnir/>.
|
|
597
|
-
|
|
598
|
-
| Documento | O que tem nele |
|
|
599
|
-
| ------------------------------------------------------ | ------------------------------------------------------------------- |
|
|
600
|
-
| [docs/SCORING.md](docs/SCORING.md) | Normalização da pontuação e ponderação da evidência |
|
|
601
|
-
| [docs/TERMINOLOGY.md](docs/TERMINOLOGY.md) | Vocabulário canônico: uma palavra por conceito |
|
|
602
|
-
| [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Taxas de falsos positivos medidas e o método |
|
|
603
|
-
| [docs/RULE-LIFECYCLE.md](docs/RULE-LIFECYCLE.md) | Estados das regras, níveis, supressão, descontinuação |
|
|
604
|
-
| [docs/VERSIONING.md](docs/VERSIONING.md) | Política de semver, superfícies congeladas, ciclo de descontinuação |
|
|
605
|
-
| [docs/machine-contract.md](docs/machine-contract.md) | O resultado canônico legível por máquina |
|
|
606
|
-
| [docs/SARIF-INTEGRATION.md](docs/SARIF-INTEGRATION.md) | Saída SARIF e configuração do editor ou da CI |
|
|
607
|
-
| [docs/GITLAB-CI.md](docs/GITLAB-CI.md) | GitLab: relatório do Code Quality, receita de MR, gate |
|
|
608
|
-
| [docs/rules/](docs/rules/) | Catálogo gerado por regra |
|
|
609
|
-
| [CONTRIBUTING.md](CONTRIBUTING.md) | Ambiente de desenvolvimento e fluxo de contribuição |
|
|
610
|
-
| [SUPPORT.md](SUPPORT.md) | Onde perguntar, reportar e obter ajuda |
|
|
611
|
-
| [SECURITY.md](SECURITY.md) | Relato de vulnerabilidades |
|
|
612
|
-
| [CHANGELOG.md](CHANGELOG.md) | Histórico de versões |
|
|
613
|
-
|
|
614
|
-
### Status
|
|
615
|
-
|
|
616
|
-
**Versão 1.** O esquema JSON e os códigos de saída são contratos congelados. TypeScript e Python têm a cobertura medida mais ampla. Java e C# são mais recentes; leia-os pela [tabela de maturidade](https://sergey-bar.github.io/Mjolnir/reference/rule-lifecycle). O que vem a seguir, sem datas inventadas: [o roadmap público](https://sergey-bar.github.io/Mjolnir/reference/roadmap).
|
|
617
|
-
|
|
618
|
-
### Contribuindo
|
|
619
|
-
|
|
620
|
-
Novas regras são a primeira contribuição mais fácil. Um comando cria o esqueleto da regra com suas fixtures must-fire **e** must-not-fire. A regra gerada falha nas próprias fixtures de propósito até que uma detecção real seja escrita, porque um stub lançado é uma regra que ninguém mediu:
|
|
621
|
-
|
|
622
|
-
```bash
|
|
623
|
-
mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
O ambiente de desenvolvimento, os comandos dos gates permanentes e as leis anti-creep e do firewall de fixtures estão em [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
627
|
-
|
|
628
|
-
<br />
|
|
629
|
-
|
|
630
|
-
<div align="center">
|
|
631
|
-
|
|
632
|
-
<img src="assets/readme/closing.svg" alt="Rode no seu repo." width="100%" />
|
|
633
|
-
|
|
634
|
-
```bash
|
|
635
|
-
npx mjolnir-qa@5.0.0
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
[Leia o guia](https://sergey-bar.github.io/Mjolnir/guide/getting-started) · [Site de documentação](https://sergey-bar.github.io/Mjolnir/) · [npm](https://www.npmjs.com/package/mjolnir-qa)
|
|
639
|
-
|
|
640
|
-
<br />
|
|
641
|
-
|
|
642
|
-
Não pergunte se os testes passaram.<br />
|
|
643
|
-
Pergunte se a evidência prova que eles merecem confiança.
|
|
644
|
-
|
|
645
|
-
<sub>Criado por [Sergey Bar](https://www.linkedin.com/in/sergeybar/) · Licença MIT</sub>
|
|
646
|
-
|
|
647
|
-
</div>
|