Back to Developer Guide

Quality Gates

Last updated

Every check enforced from developer workstation to production deployment — aligned with BSI C5, OWASP Top 10, EHDS regulation, and WCAG 2.2 AA.

Pipeline Overview

Four-stage quality pipeline from commit to compliance

Stage 1 — Pre-commit Hooks

The 32 hooks configured in .pre-commit-config.yaml, in the order they run. They run before every git commit, and the PR Gate runs them again on the pull request's diff. Hooks that rewrite a file (Prettier, end-of-file) fail the commit; stage the file again and commit.

HookSourceStage
trailing-whitespacepre-commit-hookspre-commit
end-of-file-fixerpre-commit-hookspre-commit
check-yamlpre-commit-hookspre-commit
check-jsonpre-commit-hookspre-commit
check-added-large-filespre-commit-hookspre-commit
check-merge-conflictpre-commit-hookspre-commit
detect-private-keypre-commit-hookspre-commit
check-case-conflictpre-commit-hookspre-commit
check-symlinkspre-commit-hookspre-commit
check-executables-have-shebangspre-commit-hookspre-commit
check-shebang-scripts-are-executablepre-commit-hookspre-commit
shellcheckshellcheck-pypre-commit
hadolint-dockerhadolintpre-commit
prettiermirrors-prettierpre-commit
TypeScript (UI)localpre-commit
ESLint (UI)localpre-commit
Vitest (UI)localpre-push
CodeQL on the iPhone app (Swift, about 15 min)localpre-push
Secret Scan (gitleaks)localpre-commit
Static analysis (Semgrep)localpre-commit
Semgrep rule tests (.semgrep/)localpre-commit
Broken links (Markdown)localpre-commit
No screenshot images in doc pageslocalpre-commit
API spec covers every routelocalpre-commit
API spec describes the shape the hub answers withlocalpre-commit
Docs facts and last-updated dateslocalpre-commit
API collection covers every route, and can faillocalpre-commit
A successful request cannot pass on an empty answerlocalpre-commit
Workflows re-run when what they run changeslocalpre-commit
npm audit (UI — HIGH+)localpre-push
Lint GitHub Actions workflowslocalpre-commit
CVE scan covers every compose imagelocalpre-commit

Stage 2 — Pre-push Gates

Run before git push. These catch issues that are too slow for pre-commit.

Unit Tests

vitest run --bail 1 — stops on first failure

Blocks

Dependency Audit

npm audit --audit-level=high — HIGH + CRITICAL CVEs

Blocks

Stage 3 — CI Pipeline

GitHub Actions workflow .github/workflows/test.yml — 13 jobs on every push. View latest run →

JobTestsToolStandardGate
PR Gate—pre-commit on the diff, API spec drift, Bruno coverage, knip, gitleaksBSI C5 DEV-02Blocks
CodeQL—codeql.yml (JS/TS, Python, Actions) on every PR; codeql-swift.yml when clients/ios changes, or locally with Scripts/codeql-swift.shOWASP Top 10Reports
Security scan—Source SBOM, image and deployed-image CVEs (security-scan.yml)EU CRA Art. 13Blocks
UI Tests (Vitest)—Vitest 5.0.2 + v8 coverageBSI C5 DEV-03Blocks
Neo4j Proxy Tests—VitestBSI C5 DEV-03Blocks
Lint—Next.js ESLintBSI C5 DEV-02Blocks
Secret Scan—Gitleaks v8.27.2BSI C5 DEV-08Blocks
Dependency Audit—npm audit (HIGH+)OWASP A06Blocks
Trivy Scan—Trivy v0.69.3OWASP A06Reports
K8s Posture—Kubescape (NSA + CIS)NSA K8s GuideBlocks
E2E Tests—Playwright v1.63.0—Reports
WCAG 2.2 AA Audit—axe-core/playwrightEN 301 549Blocks
Security Pentest—OWASP/BSI patternsOWASP Top 10Reports
SBOM Generation2CycloneDX npmEU CRA Art. 13Blocks
Licence Compliance—license-checkerBSI C5 OPS-04Blocks
Lighthouse CI12Lighthouse CI (4 pages × 3 runs)Core Web VitalsReports

Supply-Chain Hardening

  • Gitleaks and Trivy binaries pinned to exact versions with SHA-256 checksum verification
  • Trivy v0.69.3 used explicitly — versions 0.69.4–0.69.6 were compromised (CVE-2026-33634)
  • Two dev-only secrets allowlisted in .gitleaksignore (JAD stack in-memory credentials)

Security Headers (Runtime)

Configured in next.config.js (BSI C5 DEV-07 / OWASP A05):

X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Content-Security-Policy: default-src 'self' + scoped allowlist

Stage 4 — Protocol Compliance

Weekly and on pushes to main. Each suite must stay at or above the floor recorded in scripts/compliance-baseline.json; a floor is raised when a suite improves and never lowered without a reason. Workflow: .github/workflows/compliance.yml View latest run →

DSP 2025-1 TCK

Dataspace Protocol

≥ 21passed, at most 6 failed

DCP v1.0

Decentralised Claims

≥ 22passed, at most 0 failed

EHDS Domain

EHDS Art. 3–51

≥ 18passed, at most 0 failed

API collection (CI)

Bruno, persona folders

≥ 149passed, at most 2 failed

API collection (Azure)

Bruno, ehds.mabu.red

≥ 123passed, at most 0 failed

Infrastructure Requirements

Protocol compliance tests require the full JAD stack (22 services, 8 GB RAM). In CI, the workflow starts JAD infrastructure with graceful fallback — tests produce results only when the controlplane is healthy.

Local execution: ./scripts/run-dsp-tck.sh, ./scripts/run-dcp-tests.sh, ./scripts/run-ehds-tests.sh

Coverage Floors

Enforced by ui/vitest.config.ts: the UI suite fails when coverage drops below these. The measured numbers are in the published test report.

≥ 78%
Statements
≥ 69%
Branches
≥ 79%
Functions
≥ 80%
Lines

Test Inventory

Vitest
Unit tests, UI and Neo4j proxy
Playwright
E2E journeys, incl. WCAG 2.2 AA
5
Compliance suites with a floor

Future Quality Gates

Recommended improvements prioritised by impact and regulatory alignment.

1

Enforce Coverage Thresholds

Done — vitest.config.ts

Minimum coverage thresholds in vitest.config.ts: 78% statements, 69% branches, 79% functions, 80% lines. Vitest fails if coverage drops below.

Enforcement prevents silent regression; raise a floor whenever coverage rises.

BSI C5 DEV-03
2

Mutation Testing

Medium — new tool + CI job

Add Stryker Mutator to measure test effectiveness. Target mutation score > 60%.

Line coverage does not guarantee tests catch bugs. Mutation testing verifies tests detect real defects.

OWASP Testing Guide v4.2
3

Licence Compliance Scanning

Done — implemented in test.yml

license-checker in CI with allowlist: MIT, Apache-2.0, ISC, BSD-2/3-Clause, 0BSD, CC0-1.0, CC-BY-4.0. Blocks build on copyleft violations.

EU CRA and SIMPL-Open require licence transparency. EUPL compatibility must be verified for all transitive dependencies.

EU CRA Art. 13, BSI C5 OPS-04, SIMPL-Open
4

API Contract Testing

Partly done — spec drift ratchet in the PR Gate

scripts/check-api-spec-drift.py already blocks any new route missing from openapi.yaml (59 operations documented). Next: validate response shapes against the spec with swagger-parser or Prism.

No formal schema enforces response shapes. Contract tests prevent frontend/backend drift.

DSP 2025-1 §4.2
5

SBOM Generation

Done — implemented in test.yml

CycloneDX 1.5 SBOM generated on every CI run for UI and Neo4j Proxy. Uploaded as 90-day artifact. Required by EU CRA Art. 13(5) and critical for SIMPL-Open supply chain transparency.

Supply chain attacks (XZ Utils, Trivy compromise) make SBOMs non-negotiable. SIMPL-Open must provide SBOMs for downstream consumers. EU CRA mandates machine-readable SBOMs by 2027.

EU CRA Art. 13, NTIA SBOM, SIMPL-Open
6

Performance Regression Testing

Done — Lighthouse CI in test.yml

Lighthouse CI with Core Web Vitals budgets: LCP < 4s (error), CLS < 0.1 (error), TBT < 300ms (warn), bundle < 500 KB (warn). Runs on 4 key pages.

Healthcare professionals use the platform under time pressure. Performance regressions now blocked in CI.

WCAG 2.2 SC 2.2.1, Core Web Vitals
7

Runtime ODRL Policy Enforcement

High — new engine + tests

Implement ODRL engine — validate API responses respect the caller's permitted datasets and temporal limits.

Currently ODRL policies are decorative. Any authenticated user can query any dataset. This is the largest EHDS compliance gap.

EHDS Art. 44, ODRL 2.2 §3
8

WCAG Blocking Gate

Done — removed continue-on-error

WCAG 2.2 AA audit promoted to blocking gate — zero-violation budget enforced. Build fails on accessibility regressions.

Current state is zero violations. Now enforced — any new component that introduces violations will block the build.

EN 301 549, EU Directive 2016/2102
9

IaC Policy Enforcement

Done — blocking in test.yml

Kubescape promoted to blocking on critical findings (--severity-threshold critical). NSA and CIS frameworks enforced.

K8s manifests define production topology. Critical security findings now block the build.

BSI C5 OPS-01, NSA K8s Guide
10

Dependency Freshness

Done — renovate.json

Renovate Bot configured: auto-merge patches, weekly PRs for minor, manual review for major. Security updates bypass schedule.

Automated dependency updates prevent CVE accumulation. Supply chain freshness is critical for CRA compliance.

OWASP A06, EU CRA Art. 14

Compliance Mapping

Quality GateBSI C5OWASPEHDSWCAG
TypeScript strictDEV-01———
ESLintDEV-02A03——
Unit tests + coverage thresholdsDEV-03———
Secret scan (Gitleaks)DEV-08A07——
Dependency auditDEV-05A06——
Trivy vuln scanDEV-05A06——
Security headersDEV-07A05——
WCAG 2.2 AA (blocking)———2.2 AA
DSP 2025-1 TCK——Art. 50—
DCP v1.0 compliance——Art. 50—
EHDS domain tests——Art. 3–51—
SBOM (CycloneDX 1.5)OPS-04A06Art. 50—
Licence complianceOPS-04—Art. 50—
Lighthouse perf budget———2.2 SC2.2.1
Kubescape (blocking)OPS-01———
Renovate freshnessDEV-05A06——
ODRL enforcement (planned)—A01Art. 44—

Related Documentation