mjolnir-qa 3.0.0 → 4.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 CHANGED
@@ -11,12 +11,330 @@ once shipped, so this file is the record of what changed between versions.
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ### Breaking changes
15
+
16
+ - **`business-case` no longer prints a dollar figure you did not supply.** The
17
+ `--industry` flag selected from a table of invented incident costs (fintech
18
+ $50 000, healthcare $100 000, …) with no source, and the product of that table
19
+ and a measured false-positive rate was printed as "Expected Savings" and
20
+ "Total potential savings". Pass `--incident-cost <n>` to see the arithmetic;
21
+ the measured FP rates, their sample sizes and the evidence weight behind them
22
+ are always shown. `--industry`, `--history` and `--projected` now exit with a
23
+ reason: `--history` read no history despite promising estimates from scan
24
+ improvements, and `--projected` divided the total by six and called the
25
+ quotient a monthly rate.
26
+ - **`enterprise sso` and `enterprise compliance` no longer write files.** They
27
+ wrote an SSO guide instructing readers to add an `sso` block to
28
+ `mjolnir.config.json` — a key nothing reads — and three auditor-facing SOC 2 /
29
+ HIPAA / PCI-DSS templates mapping controls to capabilities this product does
30
+ not have (SSO/SAML integration, a scan "audit trail", a "privacy scan"). Both
31
+ now refuse with a reason. `enterprise config` emits
32
+ `capability-manifest.json`, whose `notProvided` list records the absences
33
+ instead of inventing a deployment.
34
+ - **The evidence descriptor is now the same on every surface.** The HTML and
35
+ Markdown trust reports showed four bare words (`E2 · deterministic`) where the
36
+ terminal showed the full descriptor. They now show
37
+ `[E2 · deterministic · measured FP 8% · n=14 · trust L3 · runtime: file executed]`.
38
+ A finding with no `evidenceLevel` of its own now derives one from its type and
39
+ confidence instead of defaulting to `E2` — the strongest claim the product can
40
+ make, previously asserted for findings nobody had measured.
41
+ - **Unmeasured counts read "unknown — not measured", not `0`.** The trust
42
+ report, the PR comment and the step summary all rendered
43
+ `testDeclarationCount ?? 0` as "0 tests analyzed in 0 files" for a producer
44
+ that had never measured a declaration. The trust-report JSON twin now emits
45
+ `null` for those fields. A zero is a claim; an absent measurement is not.
46
+ - **The dashboard no longer varies between runs of an unchanged repository.**
47
+ The generation timestamp moved out of the visible body into
48
+ `<meta name="mjolnir-generated-at">`, and `--deterministic` omits it entirely
49
+ so the artifact is byte-identical and can be diffed in review.
50
+ - **Score bands are decided in one place.** The dashboard split at 60 while the
51
+ terminal split at 80, so a score the terminal called UNWORTHY rendered amber
52
+ in HTML; the contributor handover used 90; `mermaid.ts` and
53
+ `monorepo-analysis.ts` each carried their own copy. All of them now read
54
+ `src/reporter/presentation.ts`.
55
+
56
+ ### Added
57
+
58
+ - **Opt-in Sentry crash reporting.** Set `SENTRY_DSN` and the CLI and the MCP
59
+ stdio server report their own fatal errors — release-tagged as
60
+ `mjolnir-qa@<version>`, tagged by surface, and nothing else: no user data
61
+ (`sendDefaultPii: false`), no traced spans (`tracesSampleRate: 0`), no
62
+ findings or file contents. With no DSN the SDK is never even imported, so the
63
+ default install gains no dependency, no startup cost, and no network call. A
64
+ tool that reads private repositories must not phone home on its own, so the
65
+ DSN is the only switch. `@sentry/node` is an OPTIONAL peer dependency for the
66
+ same reason: ~1.5 MB that nothing in a code scanner needs. Capture points are
67
+ the two existing top-level catch blocks rather than `uncaughtException` /
68
+ `unhandledRejection` handlers, which would have changed the frozen exit-code
69
+ contract. `npm run sentry:release` creates the release and uploads source maps
70
+ (the build now emits them; the published tarball still excludes them).
71
+ - `npm run report:honesty` — no surface may print a zero for a measurement that
72
+ may be absent. Four reviewed exceptions are recorded for computation inputs,
73
+ each with a reason and a follow-up.
74
+ - `npm run thresholds:parity` — no score-band literal may exist outside the
75
+ threshold registry. It immediately caught a selector-health threshold that
76
+ shared a number with a trust band but not a meaning.
77
+ - `npm run claims:revalidate` — every claim asserted `fixed` must rest on a
78
+ candidate-bound, independent revalidation. It rejects evidence that cites the
79
+ artifact it is meant to prove, and downgrades rather than deleting a claim
80
+ that loses its evidence.
81
+ - `npm run verbs:budget` — the 5.x law, ratcheted at 50 verbs with a 44 target
82
+ for 5.0.
83
+ - `npm run script:paths` — no `package.json` script may name a `tests/`,
84
+ `src/`, `scripts/`, `docs/`, `site/` or `enterprise/` path that does not
85
+ exist. 107 path references are checked today.
86
+ - `npm run m26:gaps:revalidate` — re-runs every gap row's own
87
+ `revalidation_command` against the working tree and records the exit code and
88
+ the commit it ran at.
89
+ - `tests/contract/artifact-determinism.spec.ts` — two runs of the HTML
90
+ artifact over an unchanged repository must be byte-identical.
91
+ - `src/reporter/presentation.ts` — the one module that makes a presentation
92
+ decision. It reads a finding, a score or a palette and returns the word, band
93
+ or descriptor to print. It opens no file, touches no clock and formats no
94
+ document, and a test enforces that.
95
+
96
+ ### Fixed
97
+
98
+ - **`frontier:contracts` was reporting 19 suites it never ran.** It named 24
99
+ test files; nineteen had been deleted by the `cc5fcb88` cleanup and its
100
+ follow-up. Vitest treats a missing path as "no tests here" rather than an
101
+ error, so the script exited 0 and printed "57 passed" while nineteen contract
102
+ suites — including every `m3x`/`m4x`/`m5x` frontier contract — silently did
103
+ not execute. A missing test file and a green test file are indistinguishable
104
+ from the outside, so a gate that passes because its subject is absent has
105
+ certified nothing. The list is rebuilt from the 23 contract suites that
106
+ exist (1 110 tests, not 57), and `npm run script:paths` now fails the build if
107
+ any `package.json` script names a path that is gone.
108
+ - The certification ladder's language vocabulary could not name the answer its
109
+ own admission gate produces. `admit()` returns `UNMEASURED` as the supported
110
+ state of any claim not backed by evidence, but `LANGUAGE_STATE_RANK` had no
111
+ word for it — so a language claiming `CERTIFIED` with an empty cohort was
112
+ handed a result its own vocabulary could not record. `UNMEASURED` is now
113
+ expressible in both vocabularies, and the four rule-level states
114
+ (`MEASURED-CORE` … `PROVISIONAL`) are declared in `RULE_ONLY_STATES` as
115
+ explicitly _not_ language outcomes rather than being filtered out by a
116
+ hand-maintained list.
117
+ - The contributor handover reported "Welcome aboard — the suite is in good
118
+ shape" whenever no issues were found, including when no run report had been
119
+ ingested and flakiness was therefore unmeasured. It now says what it did not
120
+ check.
121
+ - The confidence table's row labels were encoded as `"k|v"` strings and split
122
+ back apart, so any value containing a pipe was silently truncated. The rows
123
+ are typed pairs. The table also gained a `<caption>`, a `<thead>` and
124
+ `scope` attributes; it was previously a bare `<tbody>` a screen reader
125
+ announced as six unlabelled rows.
126
+ - `handoff` and `summary` each carried a private colourless score bar that
127
+ rendered 99 and 100 identically. Both now use the canonical `scoreGauge`, and
128
+ the redundant `theme.meter` alias is gone.
129
+ - The gap ledger gained three revalidation statuses
130
+ (`ALREADY_FIXED` / `CONFIRMED_STILL_OPEN` / `STALE_UNVERIFIABLE`). A row may
131
+ no longer be cleared without a revalidation that was actually run at a named
132
+ commit, and `STALE_UNVERIFIABLE` deliberately does not clear a release gate —
133
+ an unverifiable claim must never be able to unblock a release.
134
+ - `m26:github:sync` derived every one of 429 issue dispositions from GitHub's
135
+ own `state` field — a pure function of its input, containing no engineering
136
+ judgement — and `GAP-M26-002` then marked that script `fixed`, citing the
137
+ artifacts it produces. Dispositions now come from
138
+ `docs/issue-dispositions.json`, where each entry must carry a non-empty
139
+ reason and a verification naming a command or a source path, and may not be
140
+ verified by the script that wrote it. An untriaged issue stays open and is
141
+ flagged, never guessed and never silently closed. 215 of 429 are now visibly
142
+ awaiting a human decision, which is the honest count.
143
+
144
+ ### Documentation
145
+
146
+ - `PRODUCT-ENHANCEMENT-ANALYSIS.md` is marked `SUPERSEDED-BY: BITTERSWEET` and
147
+ gained a section XII auditing its "all 16 features shipped" claims: six do not
148
+ hold (two shipped fabricated values, two shipped a different capability than
149
+ described, two never shipped). The document is kept as the record of what was
150
+ believed on 2026-09-20, because deleting it would destroy the only evidence
151
+ that the belief was wrong.
152
+ - `docs/RELEASE-TRAINS.md` now records why each of the six scheduled verb
153
+ removals is justified differently, so the deprecation notices do not all send
154
+ the same message to users who acted on different output.
155
+
156
+ ## [4.0.0] — 2026-09-26
157
+
158
+ The first release whose reporting surface is checked against the working tree
159
+ rather than against a plan. Every box below is enforced by a gate in
160
+ `npm run certify`.
161
+
162
+ ### What you get, relative to 3.0.0
163
+
164
+ **The product no longer reports numbers it did not measure.**
165
+
166
+ - [x] A scan that finished now says it finished. A minified bundle or a lockfile
167
+ in the repository used to downgrade a complete scan to `PARTIAL`, and the
168
+ terminal told you "some files were not analyzed, so the surface is
169
+ unverified" when every discovered test file _had_ been analyzed. Across
170
+ the 37-repository corpus, complete scans went from 13/37 to 29/37.
171
+ - [x] Unmeasured counts read `unknown — not measured`, not `0`. The trust report,
172
+ the PR comment and the step summary all printed "0 tests analyzed in 0
173
+ files" for a producer that had never measured a test declaration. A zero
174
+ is a claim; an absent measurement is not.
175
+ - [x] `handover` no longer tells you "the suite is in good shape" when no run
176
+ report was ingested and flakiness was therefore never checked. It now
177
+ names what it did not check.
178
+ - [x] The HTML dashboard produces the same bytes for the same repository. It
179
+ embedded `new Date()` in its visible body, so it could never be diffed in
180
+ review. `--deterministic` omits the timestamp entirely.
181
+ - [x] The trust report's evidence descriptor is the terminal's, on every surface.
182
+ HTML and Markdown showed four bare words (`E2 · deterministic`) where the
183
+ terminal showed the measured FP rate, the sample size, the trust rung and
184
+ what the runtime actually corroborated.
185
+ - [x] A finding with no evidence level derives one from its own type and
186
+ confidence. It used to default to `E2` — the strongest claim the product
187
+ can make — for findings nobody had measured.
188
+ - [x] The contributor handover no longer derives a dollar figure from a table of
189
+ invented incident costs. `business-case` multiplied a measured
190
+ false-positive rate by unsourced per-industry costs and printed the product
191
+ as "Expected Savings". A cost figure now requires `--incident-cost`, so the
192
+ number is yours. `--history` (which read no history) and `--projected`
193
+ (which divided by six) are gone, with reasons.
194
+ - [x] `mjolnir enterprise` no longer writes a deployment config claiming
195
+ `sso-saml`, an SSO guide telling you to add a config key nothing reads, or
196
+ auditor-facing SOC 2 / HIPAA / PCI-DSS templates mapping controls to
197
+ capabilities this product does not have. `sso` and `compliance` refuse;
198
+ `config` emits a capability manifest whose `notProvided` list records the
199
+ absences.
200
+ - [x] The dependency graph no longer prints a count derived from nothing.
201
+ "Reachable files: N" was always the number of files that went in.
202
+
203
+ **The product now sees things it was blind to.**
204
+
205
+ - [x] Node-native TypeScript tests (`.test.mts`, `.spec.mts`, `.test.cts`,
206
+ `.spec.cts`) are scanned. They were not mis-scored — they were never
207
+ scanned, so every rule was silent on them with no finding and no note.
208
+ Verified with two byte-identical tests: the `.ts` copy produced the
209
+ finding, the `.mts` copy produced nothing at all.
210
+ - [x] The CI matrix installs cleanly on all three platforms. `npm ci` failed on
211
+ every job before a test ran, and then failed again with a missing
212
+ `lightningcss` binary for Linux, because a lockfile regenerated on Windows
213
+ cannot contain the other platforms' optional dependencies.
214
+
215
+ **The gates now catch these instead of the next person.**
216
+
217
+ - [x] `report:honesty` — no surface may print a zero for an absent measurement.
218
+ Four reviewed exceptions, each with a reason and a follow-up.
219
+ - [x] `thresholds:parity` — no score-band literal outside the registry. It
220
+ immediately caught a selector-health threshold that shared a number with a
221
+ trust band but not a meaning.
222
+ - [x] `script:paths` — no `package.json` script may name a path that is missing
223
+ or uncommitted. It found `frontier:contracts` naming 19 test files deleted
224
+ by an earlier cleanup: Vitest treats a missing path as "no tests here", so
225
+ the script exited 0 reporting "57 passed" while nineteen contract suites
226
+ never ran. Rebuilt from the 23 that exist — 1 110 tests, not 57.
227
+ - [x] `lockfile:platforms` — the lockfile must carry the optional binaries for
228
+ every platform CI builds on. The failure is invisible locally by
229
+ construction, so it needed a gate that runs everywhere.
230
+ - [x] `claims:revalidate` — a claim asserted `fixed` must rest on a
231
+ candidate-bound, independent revalidation. It rejects evidence citing the
232
+ artifact it is meant to prove, and downgrades rather than deletes a claim
233
+ that loses its evidence.
234
+ - [x] `verbs:budget` — the 5.x law: one new verb requires one removal or a merge.
235
+ - [x] `m26:gaps:revalidate` — re-runs each gap row's own command and records the
236
+ exit code and the commit it ran at.
237
+ - [x] `release:verify` reports every blocker in one run. It was a `&&` chain, so
238
+ it stopped at the first of four and you met them one per run.
239
+ - [x] The coverage gate is a floor and a ratchet, not one number pretending to
240
+ be both.
241
+
242
+ **Truth in the project's own records.**
243
+
244
+ - [x] The gap ledger was revalidated: all 17 rows had their own
245
+ `revalidation_command` run against this tree. `GAP-M26-005` read
246
+ `fixed` / PASS while its command _fails_. A cleared row can no longer
247
+ exist without a revalidation bound to a named commit, and
248
+ `STALE_UNVERIFIABLE` deliberately cannot unblock a release.
249
+ - [x] **A gap row could be marked fixed while its own revalidation failed.**
250
+ The `exit_code === 0` check was reachable through only one of the four
251
+ combinations the schema allows, so a `fixed` row — or an
252
+ `ALREADY_FIXED` row carrying closure evidence — was accepted with
253
+ `exit_code: 1` recorded in its own revalidation. Three of those four
254
+ routes cleared the row. The test that covered it hid the hole, because
255
+ the fixture only set `closure_evidence` for `fixed`.
256
+ - [x] The 429 GitHub dispositions no longer derive from GitHub's own `state`
257
+ field. A snapshot cannot prove itself; each disposition now needs a reason
258
+ and a verification. 215 issues are visibly awaiting a human decision,
259
+ which is the honest count.
260
+ - [x] `PRODUCT-ENHANCEMENT-ANALYSIS.md` claimed 16 shipped features; six do not
261
+ hold. It is marked `SUPERSEDED-BY` and carries a per-feature audit, kept
262
+ rather than deleted because deleting it would destroy the only evidence
263
+ that the belief was wrong.
264
+
265
+ **Found by the pre-release bug sweep, after the fix list was written.** Both
266
+ were live in 3.0.0 and neither was in the plan.
267
+
268
+ - [x] `mjolnir business-case <path>` answered a path that does not exist with
269
+ exit 0 and a clean report: "Measured: 0 of 0 findings carry a
270
+ corpus-measured FP rate". It called `runScan` directly and so never
271
+ passed through `validateScanTarget` — the check whose own comment says a
272
+ typo'd CI path must be a loud red, never a silent green. Thirteen of the
273
+ fifteen scanning verbs were already loud; this one was not, and a green
274
+ table over a path that was never scanned is the most dangerous output
275
+ this product can produce. Now exit 10.
276
+ - [x] The extended TypeScript test-file regex was probed against 27 shapes:
277
+ all 12 that must match do, all 15 that must not are rejected —
278
+ including `a.min.mts`, `a.spec.cts.bak` and `notatest.mts`.
279
+ - [x] `ships()` in `script:paths` was probed for the failure modes a new gate
280
+ usually has: an empty directory, a directory holding only untracked
281
+ files, and a symlink loop. All resolve correctly and none hangs. A
282
+ first version treated a directory as "tracked" only if `git ls-files`
283
+ listed the directory itself, which it never does — that produced two
284
+ false positives and is fixed.
285
+
286
+ ### Known open, deliberately
287
+
288
+ - [ ] `CERTIFICATION_STATES` is not in ladder order, so `rankOf` — the only
289
+ ordering function — ranks `KNOWN` above `TRUST-COMPLETE`, and
290
+ `requiresEvidence` asks `BLOCKED` and `DEGRADED` for a corpus their own
291
+ doc comment says they need none. Two `it.fails` tests record it, so
292
+ reordering the array fails the build. Fixing it moves `rankOf` for every
293
+ state and changes admission outcomes, so it is a contract change, not a
294
+ patch.
295
+ - [ ] 23 corpus count-drifts are unreviewed, the largest being `QA-PY-007`
296
+ firing 1332 times in apache-airflow and 92 now. Not accepted: running
297
+ `--update` without reading them would delete the only evidence that
298
+ detection changed.
299
+ - [ ] 8 of 37 corpus repositories report `PARTIAL` because test-support files
300
+ under `__tests__/` are not scanned. The verdict is honest — an incomplete
301
+ scan is not a pass — and the fix is a design decision about what "the
302
+ surface" means, not a patch.
303
+ - [ ] 215 of 229 GitHub issues are untriaged. Prepared dispositions exist in
304
+ `docs/issue-dispositions.json`; none has been applied, because closing a
305
+ public issue is destructive and is a person's decision.
306
+ - [ ] `BW-022` (one workspace model, real graph edges) is open. The plan claimed
307
+ it is "what makes `impact` honest"; it is not — `impact` never used the
308
+ graph and is honest on its own path. The graph is a no-op on an unshipped
309
+ code path, and the function now reports that instead of implying otherwise.
310
+
311
+ ### Upgrade notes
312
+
313
+ - Node-native TypeScript test files are now scanned, so a project using
314
+ `.mts`/`.cts` tests **will see new findings**. That is the fix working, not a
315
+ regression.
316
+ - `business-case` requires `--incident-cost` for any dollar figure, and now
317
+ exits 10 on a target that does not exist instead of printing an empty report.
318
+ - `enterprise sso` and `enterprise compliance` now exit non-zero with a reason.
319
+ - The trust report JSON's `tests.files` and `tests.declarations` are `null`
320
+ rather than `0` when unmeasured.
321
+
322
+ ## [4.0.0-rc.1] — 2026-09-25
323
+
324
+ ### Breaking changes
325
+
326
+ - The next published version must be a new major line. Generated CI is now
327
+ advisory-first while the direct composite Action remains blocking by default;
328
+ suppression metrics changed from configured to matched findings, and
329
+ zero-finding output no longer implies a clean or green suite. Publishing
330
+ these changes as another `3.0.0` is prohibited.
331
+
14
332
  ### Changed
15
333
 
16
- - **Advisory-first CI adoption** — `mjolnir ci install` and the root
17
- GitHub Action now default to non-blocking findings and non-blocking partial
18
- scans. Blocking remains explicit through `--gate error`, `--gate warning`,
19
- or `fail-on`.
334
+ - **Advisory-first generated CI adoption** — `mjolnir ci install` now
335
+ defaults to non-blocking findings and non-blocking partial scans. The direct
336
+ composite Action remains blocking by default. Blocking behavior is explicit
337
+ through `--gate error`, `--gate warning`, or `fail-on`.
20
338
  - Suppression counts now report matched findings, not configured entries;
21
339
  `suppression-gate` evaluates all-tier pre-suppression findings and enforces
22
340
  total-count limits.
@@ -34,6 +352,44 @@ once shipped, so this file is the record of what changed between versions.
34
352
  before it ships; and `scripts/check-ci-local-parity.mjs`, which keeps
35
353
  `ci.yml`, `merge-verify.yml` and the local gate exercising the same
36
354
  command list. All additive — no frozen surface changed.
355
+ - **M26–M50 execution ledger** — added `docs/ROADMAP.yaml`, dated GitHub
356
+ issue/milestone/PR reconciliation, explicit issue dispositions, an
357
+ append-only gap ledger, a finite support matrix, and an external-validation
358
+ record. Approval authority and staged dependency resolution are recorded;
359
+ external evidence remains `BLOCKED`/`NOT_RUN` and cannot be synthesized.
360
+ - **Provisional capability contracts** — added bounded, non-promoting
361
+ contracts for runtime evidence, provider capabilities, QA domain records,
362
+ agent decision receipts, plugin packs, change intelligence, mutation
363
+ sensitivity, adversarial challenges, simulation, language/framework packs,
364
+ cross-repository systems, history, detector lifecycle, research, benchmark,
365
+ scale, UX parity, and Trust OS release proofs. Each has focused hostile,
366
+ stale, foreign, malformed, and recovery coverage.
367
+ - **Release control surfaces** — added exact version-surface synchronization,
368
+ RC-aware changelog validation, candidate manifest refresh/readiness,
369
+ reporter ramp policy, fail-closed M26 audit gates, and current-major-only
370
+ Action tag maintenance.
371
+ - **README release preparation** — canonical and translated README install
372
+ references, release-status blocks, and new command rows are synchronized to
373
+ `3.0.0`; English fallback blocks are explicitly marked for human translation
374
+ review, and the canonical README states the certification boundary.
375
+ - **Release proof hardening** — stable publication now generates and attaches
376
+ an SPDX SBOM, rejects same-version registry artifacts with a different
377
+ integrity digest, updates only the current `v3` Action major, and never
378
+ clobbers release assets.
379
+ - **Support matrix reconciliation** — 136 cells are classified as 90 tested,
380
+ 44 explicitly blocked, and 2 not applicable, with evidence paths and revisit
381
+ triggers checked locally.
382
+
383
+ ### Fixed
384
+
385
+ - Corpus runs now record complete rule-crash provenance, reject parser
386
+ fallbacks, and support a provenance-only refresh that cannot update counts.
387
+ - QA-PY-004 sanitizes assertion roots before constructing a pattern, removing
388
+ corpus crashes caused by nested call-like targets.
389
+ - Pathological stress runs no longer mask crashes with `|| true`; soak evidence
390
+ no longer claims parent-process RSS as child memory.
391
+ - Exact registry-install smoke can install and verify a published version
392
+ instead of substituting the checkout tarball.
37
393
 
38
394
  ## [3.0.0] — 2026-09-24
39
395
 
@@ -286,8 +642,6 @@ Complete implementation of the Mjolnir Master Engineering Roadmap & Product Spec
286
642
  - `src/commands/doctor.ts` gains check 11 (rule metadata contract validation).
287
643
  - 4 fingerprint implementations consolidated into `src/engine/finding-identity.ts`.
288
644
 
289
- ## [Unreleased] — Nordic brand pass
290
-
291
645
  ### Changed
292
646
 
293
647
  - Terminal report: section headers are marked `▍ TITLE` instead of
package/README.ar.md CHANGED
@@ -18,7 +18,7 @@
18
18
  [![node](https://img.shields.io/badge/node-%E2%89%A5%2022.18-1F6F7C.svg?style=flat-square&labelColor=0A1119)](https://nodejs.org)
19
19
 
20
20
  ```bash
21
- npx mjolnir-qa@latest
21
+ npx mjolnir-qa@3.0.0
22
22
  ```
23
23
 
24
24
  [شاهده وهو يعمل](#شاهده-وهو-يعمل) · [البدء السريع](#البدء-السريع) · [ما الذي يكتشفه](#ما-الذي-يكتشفه-mjölnir) · [الدرجة](#درجة-الجدارة) · [الأدلة](#نموذج-الأدلة) · [تحليل التشغيلات](#تحليل-تشغيلات-الاختبار) · [CI](#سلامة-ci) · [الوكلاء](#وكلاء-الذكاء-الاصطناعي) · [الأمان](#الثقة-والأمان) · [الحدود](#ما-لا-يستطيع-mjölnir-أن-يخبرك-به) · [التوثيق](#التوثيق)
@@ -28,9 +28,9 @@ npx mjolnir-qa@latest
28
28
 
29
29
  [English](README.md) | [简体中文](README.zh.md) | [繁體中文](README.zht.md) | [한국어](README.ko.md) | [Deutsch](README.de.md) | [Español](README.es.md) | [Français](README.fr.md) | [Italiano](README.it.md) | [Dansk](README.da.md) | [日本語](README.ja.md) | [Polski](README.pl.md) | [Русский](README.ru.md) | [Norsk](README.no.md) | [Português (Brasil)](README.br.md) | [ไทย](README.th.md) | [Türkçe](README.tr.md) | [Українська](README.uk.md) | [বাংলা](README.bn.md) | [Ελληνικά](README.gr.md) | [Tiếng Việt](README.vi.md) | [עברית](README.he.md) | العربية | [Bosanski](README.bs.md)
30
30
 
31
- > 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-15.
31
+ > 🤖 Machine-assisted translation. The [English README](README.md) is canonical. Last synced: 2026-09-26.
32
32
 
33
- <!-- Source hash: 3541b09e8d04 -->
33
+ <!-- Source hash: `de04dfb1677b` -->
34
34
 
35
35
  </details>
36
36
 
@@ -38,6 +38,20 @@ npx mjolnir-qa@latest
38
38
 
39
39
  <br />
40
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
+
41
55
  ## علامة الصح الخضراء ادعاء، وليست دليلًا
42
56
 
43
57
  علامة الصح الخضراء تعني أن خط CI لم يفشل. لا تعني أن الاختبارات عملت، ولا أنها كان يمكن أن تفشل. كل واحدة من هذه تمر باللون الأخضر:
@@ -58,7 +72,7 @@ npx mjolnir-qa@latest
58
72
 
59
73
  <sub>كل نتيجة أبلغ عنها فحص العرض لهذا الـ workflow، عند السطر الذي أبلغ عنه. مولَّد بواسطة `npm run docs:readme-brand` من [`demo-report.json`](assets/readme/demo-report.json) ومقفل ضد الانحراف في CI.</sub>
60
74
 
61
- **الوضع الصارم.** الكشف الأكثر عدوانية — `.only`، `continue-on-error`، الاختبارات الفارغة، إساءة إعادة المحاولة — تقع في مستوى الحجر الصحي. تعمل فقط مع `--strict` وتُ限定 بخطورة `info`: تُعلم، لكنها لا تُوقف أبدًا. الفحص الافتراضي (`npx mjolnir-qa@latest` بدون `--strict`) يغطي القواعد الأساسية والموسعة فقط. أضف `--strict` عندما تريد طبقة الاستشارات أيضًا.
75
+ **الوضع الصارم.** الكشف الأكثر عدوانية — `.only`، `continue-on-error`، الاختبارات الفارغة، إساءة إعادة المحاولة — تقع في مستوى الحجر الصحي. تعمل فقط مع `--strict` وتُ限定 بخطورة `info`: تُعلم، لكنها لا تُوقف أبدًا. الفحص الافتراضي (`npx mjolnir-qa@3.0.0` بدون `--strict`) يغطي القواعد الأساسية والموسعة فقط. أضف `--strict` عندما تريد طبقة الاستشارات أيضًا.
62
76
 
63
77
  يقرأ Mjölnir مجموعة الاختبارات وملفات workflow الخاصة بـ CI، وتقرير تشغيل حقيقي إن وُجد. لا يشغّل اختباراتك، ولا يثبّت اعتمادياتك، ولا ينفّذ الشيفرة التي يفحصها. وعندما لا يملك دليلًا، يقول ذلك بدل أن يختلق ثقة:
64
78
 
@@ -93,7 +107,7 @@ npx mjolnir-qa@latest
93
107
 
94
108
  <p align="center">
95
109
  <a href="assets/video/mjolnir-demo.mp4">
96
- <img src="assets/video/mjolnir-demo-poster.png" alt="لقطة من تسجيل العرض: npx mjolnir-qa@latest يفحص مستودع العرض في نافذة طرفية" width="900" />
110
+ <img src="assets/video/mjolnir-demo-poster.png" alt="لقطة من تسجيل العرض: npx mjolnir-qa@3.0.0 يفحص مستودع العرض في نافذة طرفية" width="900" />
97
111
  </a>
98
112
  </p>
99
113
 
@@ -162,7 +176,7 @@ Docs: mjolnir rules --md (full catalog, this rule included)
162
176
  ## البدء السريع
163
177
 
164
178
  ```bash
165
- npx mjolnir-qa@latest
179
+ npx mjolnir-qa@3.0.0
166
180
  ```
167
181
 
168
182
  يفحص الدليل الحالي ويطبع Trust Report: ما الذي وجده، وإلى أي حد يمكنك الوثوق به، ولماذا، وما الخطوة التالية. ويخرج بالرمز `0` عندما لا يُعثر على شيء عند مستوى البوابة أو فوقه.
@@ -170,24 +184,39 @@ npx mjolnir-qa@latest
170
184
  في CI، افحص فقط ما أدخله الفرع، حتى لا تُغرق مجموعة اختبارات قديمة أول pull request لك:
171
185
 
172
186
  ```bash
173
- npx mjolnir-qa@latest --scope changed
187
+ npx mjolnir-qa@3.0.0 --scope changed
174
188
  ```
175
189
 
176
- يكتب `mjolnir ci install` ذلك كـ workflow لـ GitHub Actions، باستخدام [الـ action](https://github.com/Sergey-Bar/Mjolnir#readme) المثبّت على الوسم الرئيسي `v1` (أو `npx` عادي مع `--no-action`). ويبقى استشاريًا إلى أن تقرر أنه يجب أن يمنع الدمج.
177
-
178
- | الأمر | ما الذي يفعله |
179
- | ----------------------------------- | ------------------------------------------------------------ |
180
- | `mjolnir` | ‏Trust Report: الحكم، ودرجة الثقة، والإجراء التالي |
181
- | `mjolnir --scope changed` | فقط ما أدخله فرعك (صيغة CI) |
182
- | `mjolnir ci install` | ينشئ workflow استشاريًا لطلبات الدمج (قائمًا على الـ action) |
183
- | `mjolnir explain QA-CI-001` | ماذا ولماذا وكيف يُصلح، مع معدل FP المقيس |
184
- | `mjolnir why src/a.spec.ts:42` | لماذا عُلّم هذا السطر بالتحديد. لا يمنع الدمج أبدًا. |
185
- | `mjolnir forensics ./test-results/` | أدلة وقت التشغيل من تشغيل حقيقي |
186
- | `mjolnir trust-report` | ‏Trust Artifact مستقل (md + json) |
187
- | `mjolnir handoff` | خطة معالجة لوكيل برمجة |
188
- | `mjolnir --json` / `--format sarif` | مخرجات قابلة للقراءة آليًا، GitHub Code Scanning |
189
- | `mjolnir --format codequality` | تقرير GitLab Code Quality (عنصر لأداة طلب الدمج) |
190
- | `mjolnir --strict` | يشغّل أيضًا قواعد مستوى quarantine (خطر FP أعلى) |
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 استشاريًا لطلبات الدمج (قائمًا على الـ 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 (عنصر لأداة طلب الدمج) |
219
+ | `mjolnir --strict` | يشغّل أيضًا قواعد مستوى quarantine (خطر FP أعلى) |
191
220
 
192
221
  <details>
193
222
  <summary><strong>كل الأوامر الأخرى</strong> — فرز الاختبارات غير المستقرة، والتقارير، والحوكمة</summary>
@@ -452,18 +481,18 @@ mjolnir ci install
452
481
  أو أضف الـ action من Marketplace إلى workflow لديك بالفعل:
453
482
 
454
483
  ```yaml
455
- - uses: Sergey-Bar/Mjolnir@v1
484
+ - uses: Sergey-Bar/Mjolnir@v3
456
485
  with:
457
486
  scope: changed
458
487
  fail-on: error
459
488
  ```
460
489
 
461
- ثبّت `@v1` لتتبع الخط الرئيسي، أو وسمًا دقيقًا (`@v0.5.32`) لبوابة قابلة لإعادة الإنتاج. يغطي [docs/DISTRIBUTION-KIT.md](docs/DISTRIBUTION-KIT.md) كلًّا من Marketplace وSmithery وسجلات MCP.
490
+ ثبّت `@v3` لتتبع الخط الرئيسي، أو وسمًا دقيقًا (`@v0.5.32`) لبوابة قابلة لإعادة الإنتاج. يغطي [docs/DISTRIBUTION-KIT.md](docs/DISTRIBUTION-KIT.md) كلًّا من Marketplace وSmithery وسجلات MCP.
462
491
 
463
492
  لوضع النتائج في GitHub Code Scanning، ارفع SARIF (يتطلب `security-events: write` على مستوى الـ workflow أو الـ job):
464
493
 
465
494
  ```yaml
466
- - run: npx mjolnir-qa@latest --format sarif > mjolnir.sarif
495
+ - run: npx mjolnir-qa@3.0.0 --format sarif > mjolnir.sarif
467
496
  continue-on-error: true
468
497
  - uses: github/codeql-action/upload-sarif@v3
469
498
  if: ${{ !cancelled() }}
@@ -476,7 +505,7 @@ mjolnir ci install
476
505
  ### إسناد النتائج إلى نطاق التغييرات
477
506
 
478
507
  ```bash
479
- npx mjolnir-qa@latest --scope changed
508
+ npx mjolnir-qa@3.0.0 --scope changed
480
509
  ```
481
510
 
482
511
  تُسند النتائج إلى الأسطر التي أضافها فرعك، مقيسةً مقابل **merge-base**. النطاق هو مجموعة الملفات نفسها التي يكتشفها الفحص الكامل (ملفات spec لـ TS/JS وإعدادات المحوّلات، `test_*.py`، `*Test.java`، `*Tests.cs`، `.github/workflows/*.yml`)، إضافة إلى التغييرات غير المُثبتة وغير المتتبَّعة، لذا يعمل قبل أن تُجري commit. يُحدَّد الأساس بالترتيب `main → master → origin/main → origin/master → origin/HEAD`؛ ويمكنك تجاوزه بـ `--base <ref>`.
@@ -504,7 +533,7 @@ SCAN → EVIDENCE → HANDOFF → AGENT → RE-SCAN → PROOF
504
533
  أضفه إلى عميل يأتي مع CLI خاص به:
505
534
 
506
535
  ```bash
507
- claude mcp add mjolnir -- npx -y mjolnir-qa@latest mcp
536
+ claude mcp add mjolnir -- npx -y mjolnir-qa@3.0.0 mcp
508
537
  ```
509
538
 
510
539
  أو إلى أي عميل يقبل كتلة `mcpServers`:
@@ -512,7 +541,7 @@ claude mcp add mjolnir -- npx -y mjolnir-qa@latest mcp
512
541
  ```json
513
542
  {
514
543
  "mcpServers": {
515
- "mjolnir": { "command": "npx", "args": ["-y", "mjolnir-qa@latest", "mcp"] }
544
+ "mjolnir": { "command": "npx", "args": ["-y", "mjolnir-qa@3.0.0", "mcp"] }
516
545
  }
517
546
  }
518
547
  ```
@@ -603,7 +632,7 @@ mjolnir create-rule QA-PW-140 --title "Screenshot without diff bound"
603
632
  <img src="assets/readme/closing.svg" alt="شغّله على مستودعك." width="100%" />
604
633
 
605
634
  ```bash
606
- npx mjolnir-qa@latest
635
+ npx mjolnir-qa@3.0.0
607
636
  ```
608
637
 
609
638
  [اقرأ الدليل](https://sergey-bar.github.io/Mjolnir/guide/getting-started) · [موقع التوثيق](https://sergey-bar.github.io/Mjolnir/) · [npm](https://www.npmjs.com/package/mjolnir-qa)