mjolnir-qa 6.0.0 → 6.0.1
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 +384 -1
- package/README.md +314 -29
- package/dist/cli.d.mts +1 -477
- package/dist/cli.mjs +664 -554
- package/dist/mcp/stdio.mjs +254 -366
- package/package.json +24 -34
- package/dist/rolldown-runtime-8H4AJuhK.mjs +0 -14
package/README.md
CHANGED
|
@@ -9,21 +9,31 @@
|
|
|
9
9
|
<br />
|
|
10
10
|
|
|
11
11
|
[](https://www.npmjs.com/package/mjolnir-qa)
|
|
12
|
+
[](https://www.npmjs.com/package/mjolnir-qa)
|
|
12
13
|
[](https://github.com/Sergey-Bar/Mjolnir/actions/workflows/ci.yml)
|
|
13
14
|
[](https://codecov.io/gh/Sergey-Bar/Mjolnir)
|
|
14
15
|
[](LICENSE)
|
|
15
16
|
[](https://nodejs.org)
|
|
16
17
|
|
|
17
18
|
```bash
|
|
18
|
-
npx mjolnir-qa@
|
|
19
|
+
npx mjolnir-qa@latest
|
|
19
20
|
```
|
|
20
21
|
|
|
22
|
+
Pin it for reproducible CI: `npx mjolnir-qa@6.0.1`. Requires **Node.js ≥ 22.18** on Windows, macOS or Linux.
|
|
23
|
+
|
|
21
24
|
[**Interactive walkthrough**](https://sergey-bar.github.io/Mjolnir/) · [Docs](https://sergey-bar.github.io/Mjolnir/) · [CHANGELOG](CHANGELOG.md) · [Video](assets/video/mjolnir-demo.mp4)
|
|
22
25
|
|
|
23
26
|
</div>
|
|
24
27
|
|
|
25
28
|
---
|
|
26
29
|
|
|
30
|
+
## Release status
|
|
31
|
+
|
|
32
|
+
The published line is `6.0.1`, and this working tree is that line. The version table is
|
|
33
|
+
[`docs/ROADMAP.yaml`](docs/ROADMAP.yaml). This document does not publish a tag or authorize a release.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
27
37
|
## The problem: a green check is a claim, not proof
|
|
28
38
|
|
|
29
39
|
A green check means the pipeline did not fail. It does **not** mean the tests ran, or that they could have failed.
|
|
@@ -31,10 +41,8 @@ A green check means the pipeline did not fail. It does **not** mean the tests ra
|
|
|
31
41
|
```yaml
|
|
32
42
|
# These all ship green. None earned it.
|
|
33
43
|
steps:
|
|
34
|
-
- run: npm test || true # exit code swallowed
|
|
35
|
-
- run:
|
|
36
|
-
- run: playwright test --workers=1 # serial but no --exit-on-failure
|
|
37
|
-
- uses: some/action@main # mutable ref
|
|
44
|
+
- run: npm test || true # exit code swallowed (QA-CI-002)
|
|
45
|
+
- run: npm test | tee test.log # exit code lost without pipefail (QA-CI-009)
|
|
38
46
|
```
|
|
39
47
|
|
|
40
48
|
Mjölnir reads your test suite, your CI workflows, and (when available) the report of a real run. It reports every finding with a **trust level** (L0–L5, where L3+ requires a real run) and a **measured false-positive rate** where corpus evidence exists.
|
|
@@ -45,14 +53,27 @@ Mjölnir reads your test suite, your CI workflows, and (when available) the repo
|
|
|
45
53
|
|
|
46
54
|
---
|
|
47
55
|
|
|
56
|
+
## See it work
|
|
57
|
+
|
|
58
|
+
A real scan of [`examples/demo-repo`](examples/demo-repo):
|
|
59
|
+
|
|
60
|
+
<p align="center">
|
|
61
|
+
<img src="assets/readme/terminal-hero.svg" alt="Mjölnir's deduction breakdown: WORTHINESS 80/100 WORTHY, the score by category, the per-severity deduction box, and a FIX THIS FIRST list" width="520" />
|
|
62
|
+
</p>
|
|
63
|
+
|
|
64
|
+
<sub>Generated by `npm run docs:hero` from a real scan and drift-locked in CI. The full `--verbose` report is
|
|
65
|
+
[`demo.svg`](assets/readme/demo.svg); the architecture poster is [`architecture.svg`](assets/readme/architecture.svg).</sub>
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
48
69
|
## Quickstart
|
|
49
70
|
|
|
50
71
|
```bash
|
|
51
72
|
# 1. Scan — Trust Report, exits 1 on gate findings
|
|
52
|
-
npx mjolnir-qa@
|
|
73
|
+
npx mjolnir-qa@latest
|
|
53
74
|
|
|
54
75
|
# 2. Block in CI — scan only what your branch changed
|
|
55
|
-
npx mjolnir-qa@
|
|
76
|
+
npx mjolnir-qa@latest --scope changed
|
|
56
77
|
|
|
57
78
|
# 3. Fix and re-verify — safe auto-fixes, each re-scanned to prove it landed
|
|
58
79
|
mjolnir fix
|
|
@@ -61,25 +82,56 @@ mjolnir fix
|
|
|
61
82
|
**Prove the fix with a baseline, then delta:**
|
|
62
83
|
|
|
63
84
|
```bash
|
|
64
|
-
npx mjolnir-qa@
|
|
85
|
+
npx mjolnir-qa@latest --save-baseline # once: writes .mjolnir/baseline.json
|
|
65
86
|
# … make the fix …
|
|
66
87
|
mjolnir ci verify # RESOLVED (gone) / NEW (introduced)
|
|
67
88
|
```
|
|
68
89
|
|
|
69
90
|
---
|
|
70
91
|
|
|
71
|
-
## What it catches
|
|
92
|
+
## What it catches
|
|
93
|
+
|
|
94
|
+
**<!-- census:total-rules -->79 rules<!-- /census:total-rules -->** in four families — test hygiene, test quality, Playwright and CI integrity — across TypeScript/JavaScript, Python, Java, C# and GitHub Actions YAML.
|
|
72
95
|
|
|
73
|
-
| Family | Example rules
|
|
74
|
-
| ---------------- |
|
|
75
|
-
| **CI integrity** |
|
|
76
|
-
| **Test hygiene** | Committed `.only`/`fit` (`QA-TEST-001`), tests with no assertions (`QA-TEST-003`), hard sleeps (`QA-TEST-004`)
|
|
77
|
-
| **Test quality** | Unawaited promise assertions (`QA-TQUAL-009`), tautological assertions (`QA-TQUAL-002`)
|
|
78
|
-
| **Playwright** | Unawaited locator assertions (`QA-PW-002`), `page.pause()` committed (`QA-PW-003`), brittle selectors (`QA-PW-004`)
|
|
79
|
-
| **Python** | Skipped tests (`QA-PY-002`), `time.sleep()` (`QA-PY-005`), tautological assertions (`QA-PY-012`)
|
|
80
|
-
| **Java / C#** | Disabled tests, hard sleeps, no assertions, brittle selectors
|
|
96
|
+
| Family | Example rules |
|
|
97
|
+
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
98
|
+
| **CI integrity** | `\|\| true` swallowing exit codes (`QA-CI-002`), `continue-on-error` on gate jobs (`QA-CI-001`), always-success steps masking failures (`QA-CI-008`) |
|
|
99
|
+
| **Test hygiene** | Committed `.only`/`fit` (`QA-TEST-001`), tests with no assertions (`QA-TEST-003`), hard sleeps (`QA-TEST-004`) |
|
|
100
|
+
| **Test quality** | Unawaited promise assertions (`QA-TQUAL-009`), tautological assertions (`QA-TQUAL-002`) |
|
|
101
|
+
| **Playwright** | Unawaited locator assertions (`QA-PW-002`), `page.pause()` committed (`QA-PW-003`), brittle selectors (`QA-PW-004`) |
|
|
102
|
+
| **Python** | Skipped tests (`QA-PY-002`), `time.sleep()` (`QA-PY-005`), tautological assertions (`QA-PY-012`) |
|
|
103
|
+
| **Java / C#** | Disabled tests, hard sleeps, no assertions, brittle selectors |
|
|
104
|
+
|
|
105
|
+
Full catalog: `mjolnir explain --list --md` or [what-it-checks](https://sergey-bar.github.io/Mjolnir/guide/what-it-checks). **<!-- census:measured-of-total -->73 of 79<!-- /census:measured-of-total --> rules carry a false-positive rate measured against real OSS code.** The other <!-- census:unmeasured -->6<!-- /census:unmeasured --> ship on the author's estimate and say so on each finding.
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary><strong>Every rule named in this README</strong>, in one table</summary>
|
|
109
|
+
|
|
110
|
+
<br />
|
|
81
111
|
|
|
82
|
-
|
|
112
|
+
> `warn-only` rules run only under `--include-warn` and never gate. The severity shown is the authored severity.
|
|
113
|
+
|
|
114
|
+
| ID | Family | Rule | Severity | Default scan |
|
|
115
|
+
| ------------ | ---------- | ------------------------------------------------------------ | -------- | ------------ |
|
|
116
|
+
| QA-TEST-001 | Hygiene | Focused test committed (`.only`, `fit`) | error | warn-only |
|
|
117
|
+
| QA-TEST-003 | Hygiene | Test with no assertions | error | warn-only |
|
|
118
|
+
| QA-TEST-004 | Hygiene | Hard sleep (`waitForTimeout`, `sleep()`, `delay()`) | warning | default |
|
|
119
|
+
| QA-TQUAL-002 | Quality | Tautological assertion | error | warn-only |
|
|
120
|
+
| QA-TQUAL-009 | Quality | Unawaited promise assertion | error | warn-only |
|
|
121
|
+
| QA-PW-002 | Playwright | Unawaited locator assertion | error | default |
|
|
122
|
+
| QA-PW-003 | Playwright | `page.pause()` / `test.only()` committed | error | default |
|
|
123
|
+
| QA-PW-004 | Playwright | Brittle CSS/XPath selectors | warning | warn-only |
|
|
124
|
+
| QA-CI-001 | CI | `continue-on-error` masks a failing gate | error | warn-only |
|
|
125
|
+
| QA-CI-002 | CI | `\|\| true` swallows exit codes | error | default |
|
|
126
|
+
| QA-CI-008 | CI | Always-success step masks failures | error | warn-only |
|
|
127
|
+
| QA-CI-009 | CI | Exit code not propagated (`\|` without pipefail, `;` chains) | error | default |
|
|
128
|
+
| QA-PY-002 | Python | Skipped test (`skip`, non-strict `xfail`) | warning | default |
|
|
129
|
+
| QA-PY-005 | Python | `time.sleep()` in tests | warning | default |
|
|
130
|
+
| QA-PY-012 | Python | Tautological assertion | error | warn-only |
|
|
131
|
+
| QA-JV-101 | Java | Disabled test (`@Disabled`) | warning | default |
|
|
132
|
+
| QA-CS-103 | C# | Test method with no assertions | error | default |
|
|
133
|
+
|
|
134
|
+
</details>
|
|
83
135
|
|
|
84
136
|
---
|
|
85
137
|
|
|
@@ -105,11 +157,221 @@ Static scans stop at **L2** (proven in code). Give Mjölnir a real run report (P
|
|
|
105
157
|
|
|
106
158
|
---
|
|
107
159
|
|
|
160
|
+
## Reference
|
|
161
|
+
|
|
162
|
+
<details>
|
|
163
|
+
<summary><strong>Every command</strong></summary>
|
|
164
|
+
|
|
165
|
+
<br />
|
|
166
|
+
|
|
167
|
+
| Command | What it does |
|
|
168
|
+
| --------------------------------- | ------------------------------------------------------- |
|
|
169
|
+
| `mjolnir` | Trust Report: verdict, confidence, next action |
|
|
170
|
+
| `mjolnir --scope changed` | Only what your branch introduced (CI form) |
|
|
171
|
+
| `mjolnir --blocking error` | Exit 1 on error findings — gate releases |
|
|
172
|
+
| `mjolnir ci install` | Write the advisory PR workflow (default) |
|
|
173
|
+
| `mjolnir ci install --gate error` | Opt into the blocking PR workflow |
|
|
174
|
+
| `mjolnir ci verify` | Delta against `.mjolnir/baseline.json` — RESOLVED / NEW |
|
|
175
|
+
| `mjolnir ci release-trust` | 12-dimension release assurance verdict |
|
|
176
|
+
| `mjolnir share` | One self-contained HTML trust report to hand over |
|
|
177
|
+
|
|
178
|
+
| `mjolnir contract-verify --contract <scan.json>` | Verify a persisted machine contract against a scan |
|
|
179
|
+
|
|
180
|
+
| `mjolnir policy` | Initialize, validate, or check policy gates |
|
|
181
|
+
| `mjolnir analyze --cross-file` | Bounded cross-file analysis |
|
|
182
|
+
| `mjolnir ci adapters github .` | Generate CI templates for supported providers |
|
|
183
|
+
|
|
184
|
+
| `mjolnir mcp` | Read-only MCP tools over stdio |
|
|
185
|
+
| `mjolnir explain QA-CI-001` | What, why and fix, plus measured/unmeasured state |
|
|
186
|
+
| `mjolnir explain <file:line> src/a.spec.ts:42` | Why this exact line was flagged. Never gates. |
|
|
187
|
+
|
|
188
|
+
| `mjolnir handoff` | Remediation plan for a coding agent |
|
|
189
|
+
| `mjolnir --json` / `--format sarif` | Machine-readable output, GitHub Code Scanning |
|
|
190
|
+
| `mjolnir --format codequality` | GitLab Code Quality report (MR widget artifact) |
|
|
191
|
+
| `mjolnir --include-warn` | Also run WARN-tier rules (higher FP risk) |
|
|
192
|
+
|
|
193
|
+
<details>
|
|
194
|
+
<summary><strong>Every other command</strong> — flake triage, reporting, governance</summary>
|
|
195
|
+
|
|
196
|
+
<br />
|
|
197
|
+
|
|
198
|
+
| Command | What it does |
|
|
199
|
+
| ------------------------- | ------------------------------------------ |
|
|
200
|
+
| `mjolnir --classic` | The pre-Trust-Report score banner render |
|
|
201
|
+
| `mjolnir explain verdict` | Why the saved scan's verdict is what it is |
|
|
202
|
+
|
|
203
|
+
| `mjolnir explain --playwright ./test-results/` | Playwright run summary: retries, flakes, slowest |
|
|
204
|
+
| `mjolnir doctor --frameworks` | Playwright-only deep scan plus Selector Health Score |
|
|
205
|
+
| `mjolnir fix --dry-run` / `fix` | Safe auto-fixes, each re-scanned to prove it landed |
|
|
206
|
+
|
|
207
|
+
| `mjolnir scan` | The whole tree. This is the default: bare `mjolnir` is the same command |
|
|
208
|
+
| `mjolnir scan --scope changed` | Only what this branch changed — the PR gate |
|
|
209
|
+
| `mjolnir scan --format github-summary` | CI annotations and a step summary from a report |
|
|
210
|
+
| `mjolnir scan --format pr-comment` | A scoped PR comment, as Markdown |
|
|
211
|
+
|
|
212
|
+
| `mjolnir explain --plan` | Onboarding map of the suite for a new QA engineer |
|
|
213
|
+
|
|
214
|
+
| `mjolnir scan --suppressions` | List suppressed findings, for governance |
|
|
215
|
+
| `mjolnir ci integrity` | Verify blocking CI scans and suppression policy |
|
|
216
|
+
| `mjolnir doctor --frameworks` | Inspect bounded maturity with human calibration |
|
|
217
|
+
| `mjolnir suppression-gate` | Enforce expiry, allowlist, and mass-suppression rules |
|
|
218
|
+
| `mjolnir explain --callers` | Analyze duplicate, shared, and circular test signals |
|
|
219
|
+
| `mjolnir contract-verify` | Verify a persisted machine contract artifact |
|
|
220
|
+
| `mjolnir ci release-trend` | Persist and compare trust snapshots over time |
|
|
221
|
+
| `mjolnir evidence-graph` | Build or query the verification evidence graph |
|
|
222
|
+
| `mjolnir explain --list --unmeasured` | The rules running on assumption, not measurement |
|
|
223
|
+
| `mjolnir explain --list --md` | Full rule catalog (JSON or Markdown) |
|
|
224
|
+
| `mjolnir explain --list capability` | The capability registry, at provable maturity only |
|
|
225
|
+
| `mjolnir doctor` | Self-audit of Mjölnir's own rule base |
|
|
226
|
+
| `mjolnir stats` | Local all-time counters of fixes seen |
|
|
227
|
+
| `mjolnir ci verify` | Verify the blocking CI scan and the suppression policy |
|
|
228
|
+
| `mjolnir --cache` | Incremental re-scans via a local verdict cache |
|
|
229
|
+
| `mjolnir --format mermaid` | Test-architecture diagram for a PR comment |
|
|
230
|
+
|
|
231
|
+
`mjolnir help <command>` prints usage, examples and the next step for any
|
|
232
|
+
of them.
|
|
233
|
+
|
|
234
|
+
</details>
|
|
235
|
+
|
|
236
|
+
<details>
|
|
237
|
+
<summary><strong>One finding, up close</strong> — <code>mjolnir explain QA-CI-001</code></summary>
|
|
238
|
+
|
|
239
|
+
<br />
|
|
240
|
+
|
|
241
|
+
Every finding answers four questions: where it is, how sure Mjölnir is,
|
|
242
|
+
how often the rule is wrong, and how to fix it.
|
|
243
|
+
|
|
244
|
+
<p align="center">
|
|
245
|
+
<img src="assets/readme/finding-anatomy.svg" alt="The first finding of the demo scan, exactly as the terminal prints it, with its four parts marked: where, how sure, how often the rule is wrong, and the fix." width="100%" />
|
|
246
|
+
</p>
|
|
247
|
+
|
|
248
|
+
`mjolnir explain QA-CI-001` prints a rule's whole trust record, including
|
|
249
|
+
its measured false-positive rate and the tier that rate earned it:
|
|
250
|
+
|
|
251
|
+
```text
|
|
252
|
+
▍ QA-CI-001 — continue-on-error masks a failing verification gate
|
|
253
|
+
|
|
254
|
+
Severity: error
|
|
255
|
+
Confidence: high
|
|
256
|
+
Tier: quarantine
|
|
257
|
+
Evidence: E2
|
|
258
|
+
QA impact: False-green risk (FALSE-GREEN)
|
|
259
|
+
Measured FP: 11% (19 hand-classified corpus verdicts)
|
|
260
|
+
FP risk: low (author estimate)
|
|
261
|
+
Languages: yaml
|
|
262
|
+
Frameworks: github-actions, azure-pipelines
|
|
263
|
+
|
|
264
|
+
COPY-READY REVIEW COMMENT
|
|
265
|
+
Advisory finding — this does not block merging: Job `security-scan` runs a
|
|
266
|
+
verification gate under `continue-on-error: true`.
|
|
267
|
+
Why it weakens verification: This job can fail every day and CI will still
|
|
268
|
+
show green. The checkmark on this workflow cannot be trusted.
|
|
269
|
+
Confidence: high, evidence E2, tier quarantine; measured FP 11% (19 verdicts).
|
|
270
|
+
Suggested fix: Remove continue-on-error, or scope it to individual
|
|
271
|
+
non-blocking steps only.
|
|
272
|
+
Verify with: mjolnir --scope changed, then mjolnir explain QA-CI-001 if the
|
|
273
|
+
finding still appears.
|
|
274
|
+
|
|
275
|
+
WHAT WAS FOUND (real detector output, not a mockup)
|
|
276
|
+
Job `security-scan` runs a verification gate under `continue-on-error: true`.
|
|
277
|
+
|
|
278
|
+
WHY IT MATTERS
|
|
279
|
+
This job can fail every day and CI will still show green. The checkmark on
|
|
280
|
+
this workflow cannot be trusted.
|
|
281
|
+
|
|
282
|
+
HOW TO FIX
|
|
283
|
+
Remove continue-on-error, or scope it to individual non-blocking steps only.
|
|
284
|
+
|
|
285
|
+
Example from this rule's own must-fire fixture: QA-CI-001/must-fire/masked.yml
|
|
286
|
+
|
|
287
|
+
WHAT WOULD CHANGE THE VERDICT
|
|
288
|
+
- a run report next to the scan target (mjolnir.report.json or test-results/)
|
|
289
|
+
corroborating this file lifts its findings to L3–L5
|
|
290
|
+
- a documented suppression (mjolnir.config.json) lowers the finding count
|
|
291
|
+
without claiming correctness
|
|
292
|
+
- WARN-tier findings run only under --include-warn and never gate CI
|
|
293
|
+
|
|
294
|
+
NEXT ACTION
|
|
295
|
+
Fix the first occurrence, then re-run: `mjolnir --scope changed`. Every
|
|
296
|
+
occurrence of this rule is listed in the scan output.
|
|
297
|
+
|
|
298
|
+
HOW TO VERIFY THE FIX
|
|
299
|
+
Re-run `mjolnir` on the changed file(s) — this finding should no longer
|
|
300
|
+
appear. `mjolnir --scope changed` scopes the check to just what you touched.
|
|
301
|
+
|
|
302
|
+
Docs: mjolnir explain --list --md (full catalog, this rule included)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
That is the unit of value: one place where CI reports a pass it did not earn.
|
|
306
|
+
|
|
307
|
+
</details>
|
|
308
|
+
|
|
309
|
+
<details>
|
|
310
|
+
<summary><strong>Runtime forensics</strong> — what a real run report adds</summary>
|
|
311
|
+
|
|
312
|
+
<br />
|
|
313
|
+
|
|
314
|
+
Static analysis reasons about code that never ran. The evidence path reads
|
|
315
|
+
what actually happened: Playwright JSON, Jest JSON, Vitest JSON, and JUnit
|
|
316
|
+
XML from any runner. The `forensics` and `triage` verbs are retired in the
|
|
317
|
+
v6 carve; this capability arrives as `mjolnir explain --evidence <dir>` with
|
|
318
|
+
the next slice.
|
|
319
|
+
|
|
320
|
+
```text
|
|
321
|
+
▍ FLAKINESS LEADERBOARD
|
|
322
|
+
|
|
323
|
+
3 tests · 1 failed · 1 flaky · 1 retried
|
|
324
|
+
|
|
325
|
+
TRUE-FLAKE completes checkout with saved card (e2e/checkout.spec.ts)
|
|
326
|
+
████████████████████ 6.0s · 2 attempts
|
|
327
|
+
FAILING declines an expired card (e2e/checkout.spec.ts)
|
|
328
|
+
████░░░░░░░░░░░░░░░░ 1.1s · 1 attempt
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
`TRUE-FLAKE` does not mean the test retried. It means the test **failed at
|
|
332
|
+
least one attempt and then finished green**: a lucky pass, flagged whatever
|
|
333
|
+
the final checkmark says. The evidence path turns that history into a
|
|
334
|
+
quarantine proposal, and `mjolnir explain --playwright` summarizes a run. The same run
|
|
335
|
+
reports are what lift findings to trust levels L3 and above.
|
|
336
|
+
|
|
337
|
+
</details>
|
|
338
|
+
|
|
339
|
+
<details>
|
|
340
|
+
<summary><strong>Selector Health Score</strong> — <code>mjolnir doctor --frameworks</code></summary>
|
|
341
|
+
|
|
342
|
+
<br />
|
|
343
|
+
|
|
344
|
+
`mjolnir doctor --frameworks` grades every locator by how it finds an
|
|
345
|
+
element: the way a user would (role, label, text), an explicit contract
|
|
346
|
+
(`data-testid`), or a structural accident (CSS chains, XPath). Each file
|
|
347
|
+
gets a score from 0 to 100:
|
|
348
|
+
|
|
349
|
+
```text
|
|
350
|
+
▍ SELECTOR HEALTH
|
|
351
|
+
|
|
352
|
+
e2e/login.spec.ts
|
|
353
|
+
[█████████████░░░░░░░] 65 / 100
|
|
354
|
+
role/text: 1 · testid: 0 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
|
|
355
|
+
|
|
356
|
+
e2e/checkout.spec.ts
|
|
357
|
+
[██████████████████░░] 88 / 100
|
|
358
|
+
role/text: 4 · testid: 1 · plain-css: 0 · css-chains: 1 ⚠ · xpath: 0
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
This measures **resilience, not correctness**.
|
|
362
|
+
`.btn.btn-primary > div:nth-child(2)` passes today and keeps passing until
|
|
363
|
+
someone touches the markup. A low score never claims the test is broken,
|
|
364
|
+
only that it depends on markup nobody promised to keep.
|
|
365
|
+
|
|
366
|
+
</details>
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
108
370
|
## AI agents: SCAN → EVIDENCE → HANDOFF → AGENT → RE-SCAN → PROOF
|
|
109
371
|
|
|
110
372
|
```bash
|
|
111
373
|
# MCP server over stdio (read-only tools: scan, explain, diff, verify, forensics, triage, pw-report)
|
|
112
|
-
claude mcp add mjolnir -- npx -y mjolnir-qa mcp
|
|
374
|
+
claude mcp add mjolnir -- npx -y mjolnir-qa@latest mcp
|
|
113
375
|
|
|
114
376
|
# Deterministic handoff plan for any agent
|
|
115
377
|
mjolnir handoff
|
|
@@ -132,15 +394,15 @@ Every finding in a handoff carries its boundary: **E2** = deterministic, apply f
|
|
|
132
394
|
|
|
133
395
|
## Exit codes (frozen contract)
|
|
134
396
|
|
|
135
|
-
| Code | Meaning
|
|
136
|
-
| ---- |
|
|
137
|
-
| `0` | Clean — no findings at or above the gate
|
|
138
|
-
| `1` | Findings at or above the gate
|
|
139
|
-
| `2` | Inconclusive — partial scan, unreadable files, or crashed rule |
|
|
140
|
-
| `10` | Usage error
|
|
141
|
-
| `20` | Internal error
|
|
397
|
+
| Code | Meaning |
|
|
398
|
+
| ---- | -------------------------------------------------------------------------------- |
|
|
399
|
+
| `0` | Clean — no findings at or above the gate |
|
|
400
|
+
| `1` | Findings at or above the gate |
|
|
401
|
+
| `2` | Inconclusive — partial scan, unreadable files, or crashed rule. A CI step fails. |
|
|
402
|
+
| `10` | Usage error |
|
|
403
|
+
| `20` | Internal error |
|
|
142
404
|
|
|
143
|
-
`2` is distinct from `0`: an incomplete scan has not found nothing — it has not finished looking. No flag turns it into `0`.
|
|
405
|
+
`2` is distinct from `0`: an incomplete scan has not found nothing — it has not finished looking. No flag turns it into `0`. [`docs/VERSIONING.md`](docs/VERSIONING.md) is the law.
|
|
144
406
|
|
|
145
407
|
---
|
|
146
408
|
|
|
@@ -150,17 +412,40 @@ Every finding in a handoff carries its boundary: **E2** = deterministic, apply f
|
|
|
150
412
|
- It cannot tell you an assertion is **wrong** — only that it **cannot fail**.
|
|
151
413
|
- It does not prove business correctness.
|
|
152
414
|
- A score of 100 means: _none of Mjölnir's evaluated rules produced a deduction under this scan and evidence model._
|
|
153
|
-
- 6 of 79 rules ship on an
|
|
415
|
+
- <!-- census:unmeasured-of-total -->6 of 79<!-- /census:unmeasured-of-total --> rules ship on an estimate, not a measured FP rate. Each says so on its finding.
|
|
154
416
|
- E1 is not E2 — heuristic findings are worth reading, not worth applying blindly.
|
|
155
417
|
|
|
156
418
|
---
|
|
157
419
|
|
|
420
|
+
## Documentation
|
|
421
|
+
|
|
422
|
+
| Document | What's in it |
|
|
423
|
+
| ------------------------------------------------------------ | ------------------------------------------------------- |
|
|
424
|
+
| [docs/VERSIONING.md](docs/VERSIONING.md) | Semver policy, frozen surfaces, deprecation cycle |
|
|
425
|
+
| [docs/machine-contract.md](docs/machine-contract.md) | The canonical machine-readable result |
|
|
426
|
+
| [docs/MIGRATION-CONTRACT-2.md](docs/MIGRATION-CONTRACT-2.md) | Machine-contract v2: `coverageState` and degraded scans |
|
|
427
|
+
| [docs/FP-AUDIT.md](docs/FP-AUDIT.md) | Measured false-positive rates and the method |
|
|
428
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | Dev setup and contribution workflow |
|
|
429
|
+
| [SUPPORT.md](SUPPORT.md) | Where to ask, report and get help |
|
|
430
|
+
| [SECURITY.md](SECURITY.md) | Vulnerability reporting |
|
|
431
|
+
|
|
432
|
+
### Status
|
|
433
|
+
|
|
434
|
+
**Version 6.0.1 published.** The JSON schema and the exit codes are frozen contracts. What comes next, with no invented dates:
|
|
435
|
+
[the public roadmap](https://sergey-bar.github.io/Mjolnir/reference/roadmap).
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
<p align="center">
|
|
440
|
+
<img src="assets/readme/how-it-works.svg" alt="How Mjölnir works" width="880" />
|
|
441
|
+
</p>
|
|
442
|
+
|
|
158
443
|
<div align="center">
|
|
159
444
|
|
|
160
445
|
<img src="assets/readme/closing.svg" alt="Run it on your repo." width="100%" />
|
|
161
446
|
|
|
162
447
|
```bash
|
|
163
|
-
npx mjolnir-qa@
|
|
448
|
+
npx mjolnir-qa@latest
|
|
164
449
|
```
|
|
165
450
|
|
|
166
451
|
[Read the guide](https://sergey-bar.github.io/Mjolnir/guide/getting-started) · [Docs](https://sergey-bar.github.io/Mjolnir/) · [npm](https://www.npmjs.com/package/mjolnir-qa)
|