Files
2026-07-13 13:39:12 +08:00

116 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Quality-Gate Maturity Re-evaluation (Fase 9)"
---
# Maturity Re-evaluation — post-Waves 03 (Quality-Gate v2)
> **What this document is.** A re-measurement of the quality-gates system maturity
> **after** Waves 03 of the Quality-Gate v2 program, compared to the baseline recorded in
> [`QUALITY_GATE_PLAYBOOK.md`](./QUALITY_GATE_PLAYBOOK.md) (2026-06-16). Measures what changed,
> against DSOMM L5 / OpenSSF Scorecard 9 / SLSA L3, separating what is **CI-measurable**
> (already delivered / deliverable by code) from what is **process/owner** (organization settings).
>
> **Date:** 2026-06-30. Generated from the actual state of the repository, not from memory.
> **Benchmarks:** OWASP DSOMM · OpenSSF Scorecard · SLSA · SonarQube "Clean as You Code".
---
## 1. Updated verdict
**Overall grade: A → A ("Advanced", top ~5%).** The **two biggest structural weaknesses**
of the 06-16 baseline — the _fast-gates gap_ and the _mutation-score-not-a-ratchet_ — have been **closed**.
The residual gaps for "absolute maximum" are almost all **owner/infra-gated** (branch-protection,
SLSA L3, CodeQL advanced); the code side of the program is essentially complete.
| Reference framework | Baseline 06-16 | Now 06-30 | Movement | Evidence |
| --------------------------------- | ------------------------------ | ----------------------------------------------------------------- | -------- | --------------------------------------------------------------------- |
| **OWASP DSOMM** (5 levels) | L3→L4 | **L4** in _Test Intensity_ and _Static Depth_; solid L3 in others | ▲ | blocking mutation-ratchet + deterministic suite at merge gate |
| **OpenSSF Scorecard** | ~78/10 | ~78/10 (unchanged — gate is the **owner**) | = | missing Branch-Protection on `main` (owner setting) + actions pinning |
| **SLSA** | L2→L3 | **L2** (approaching L3) | = | missing hermetic/reproducible builder (infra/owner) |
| **SonarQube "Clean as You Code"** | Aligned with caveat | Aligned with caveat | = | _sprawl_ caveat (~46+ gates) persists — ROI review pending |
| **Quality-Ratchet pattern** | Exemplar | **Exemplar+** | ▲ | new `dedicatedGate` for `mutationScore` (direction up) |
| **Mutation testing** | "Almost there" (not a ratchet) | **Active ratchet** | ▲▲ | `check-mutation-ratchet.mjs` + seeded baseline + blocking nightly job |
---
## 2. Deltas since 2026-06-16 (what Waves 03 delivered)
### 2.1 🔴→✅ Fast-gates gap CLOSED (was structural weakness #1)
The baseline warned: `quality.yml` (PR→`release/**`) ran **only filesystem gates** — no
typecheck, tests, or build —, so deterministic regressions only exploded on PR→`main`.
**Today** `.github/workflows/quality.yml` runs, in the _Fast Quality Gates_ job: `typecheck:core`,
**blocking impacted unit tests (TIA) with fail-safe to the full suite**, the
vitest fast-path, and unit shards. The gate now runs **where the merge happens** (shift-left),
exactly the cross-cutting principle the playbook prescribes.
### 2.2 🟠→✅ Mutation score became a RATCHET (was weakness #3 / P0 #1)
The strongest antidote against coverage-gaming was **advisory**. **Today**:
- `scripts/check/check-mutation-ratchet.mjs` (advisory by default, `--ratchet` blocking, graceful skip);
- `config/quality/quality-baseline.json` has seeded `mutationScore.<module>` entries (`direction: up`, `dedicatedGate`);
- `.github/workflows/nightly-mutation.yml` has the **"Mutation score ratchet (blocking)"** job that unifies batch reports and ratchets merged per-module scores.
Result: the per-module mutation score **cannot regress** — coverage has ceased to be a vanity metric.
### 2.3 ✅ Quick-win gates (Phase 6A/7) delivered
- **a11y axe-core "fake-green" fixed:** `@axe-core/playwright` in devDeps; `a11y.spec.ts` with conditional `REQUIRE_AXE` skip; job in `nightly-resilience.yml`.
- **complexity scans `bin/`+`electron`:** `check-complexity.mjs` includes those directories in `ESLINT_ARGS`.
- **tracked-artifacts in pre-commit + pre-push:** `.husky/pre-commit` + `pre-push` block accidentally tracked artifacts.
---
## 3. The 12 categories — status (delta-focused)
| # | Category | Status 06-30 |
| --- | -------------------------------- | ---------------------------------------------------------------------------------------- |
| 1 | Style & formatting | ✅ unchanged (Prettier+ESLint lint-staged) |
| 2 | Types | ✅ **reinforced**`typecheck:core` now also in the PR→release gate |
| 3 | Tests (intensity) | ✅ **reinforced** — mutation testing became a ratchet; deterministic suite at merge gate |
| 4 | Test policy (anti-gaming) | ✅ unchanged (pr-test-policy/test-masking/pr-evidence) |
| 5 | Complexity & health | ✅ **reinforced** — complexity scans bin/electron |
| 6 | Static security (SAST+secrets) | 🟡 CodeQL default-setup (advanced = owner); semgrep cloud not versioned |
| 7 | Supply-chain (deps) | ✅ unchanged (osv/audit/Trivy/Dependabot + allowlist) |
| 8 | Supply-chain (build/release) | 🟡 SLSA L2 (L3 = hermetic builder, owner/infra) |
| 9 | Contracts & API | 🟡 oasdiff/osv advisory (candidates for blocking-with-scope, P1) |
| 10 | Docs & i18n (anti-rot) | ✅ **reinforced**`fabricated-docs --strict` blocking (exit 0 verified) |
| 11 | Anti-hallucination / consistency | ✅ unchanged (known-symbols/fetch-targets/docs-symbols/db-rules) |
| 12 | Resilience & domain | ✅ unchanged (chaos/heap/k6/promptfoo/garak nightly) |
---
## 4. Residual gaps for "absolute maximum"
### 4.1 CI-measurable / deliverable by code (this program's backlog)
- **P1 — osv/oasdiff → blocking with the right scope:** osv only `CRITICAL`+fixable (two-step like Trivy); oasdiff blocks contract-breaking changes.
- **P1 — `require-tighten` blocking (end of cycle):** locks metric gains (prevents loosening the baseline without recording).
- **P1/P2 — ROI review / gate sprawl:** consolidate doc-sync micro-gates; measure per-gate timing in `ci-summary` (combats fatigue — SonarQube/DORA caveat). Deferred ROI merges (unified complexity; unified `/api` anti-hallucination) fall here.
- **P2 — CodeQL config committed + semgrep versioned:** more control/reproducibility.
### 4.2 Process / owner (CI cannot move — organization settings)
- **Branch-protection on `main`** (raises Scorecard, closes the DSOMM gap). See [`BRANCH_PROTECTION_MAIN.md`](./BRANCH_PROTECTION_MAIN.md).
- **CodeQL Default → Advanced setup.**
- **SLSA L3** — hermetic/reproducible builder (GitHub SLSA generator). Stretch (diminishing returns).
### 4.3 Explicitly out of scope
- **DSOMM L5** is largely **org-level / process** (not CI-encodable).
- **SLSA L4** (bit-for-bit reproducibility) is a declared stretch goal.
---
## 5. Deferred / removed items (tail housekeeping)
- **`semcheck.yaml` (LLM layer for semantic drift docs↔code) — REMOVED.** It was **orphaned**
(no workflow/script invoked it) and had stale counts in the rules. Deterministic coverage
already exists (`check:fabricated-docs --strict` + `check:docs-counts-sync` + `check:docs-symbols`),
and the _gate sprawl_ caveat discourages adding an LLM advisory gate with recurring cost.
It may be re-introduced in the future as an opt-in nightly job if semantic drift becomes a real problem.
- **`agent-lsp` scaffold — DEFERRED / opt-in not enabled.** Exists as a mention in docs
(`docs/architecture/QUALITY_GATES.md`, CHANGELOG) but **without wiring** and without `.mcp.json.example`
in the repo. Remains as a documented opt-in scaffold; it is not an active gate nor a maturity gap.