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
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.
| Hook | Source | Stage |
|---|---|---|
| trailing-whitespace | pre-commit-hooks | pre-commit |
| end-of-file-fixer | pre-commit-hooks | pre-commit |
| check-yaml | pre-commit-hooks | pre-commit |
| check-json | pre-commit-hooks | pre-commit |
| check-added-large-files | pre-commit-hooks | pre-commit |
| check-merge-conflict | pre-commit-hooks | pre-commit |
| detect-private-key | pre-commit-hooks | pre-commit |
| check-case-conflict | pre-commit-hooks | pre-commit |
| check-symlinks | pre-commit-hooks | pre-commit |
| check-executables-have-shebangs | pre-commit-hooks | pre-commit |
| check-shebang-scripts-are-executable | pre-commit-hooks | pre-commit |
| shellcheck | shellcheck-py | pre-commit |
| hadolint-docker | hadolint | pre-commit |
| prettier | mirrors-prettier | pre-commit |
| TypeScript (UI) | local | pre-commit |
| ESLint (UI) | local | pre-commit |
| Vitest (UI) | local | pre-push |
| CodeQL on the iPhone app (Swift, about 15 min) | local | pre-push |
| Secret Scan (gitleaks) | local | pre-commit |
| Static analysis (Semgrep) | local | pre-commit |
| Semgrep rule tests (.semgrep/) | local | pre-commit |
| Broken links (Markdown) | local | pre-commit |
| No screenshot images in doc pages | local | pre-commit |
| API spec covers every route | local | pre-commit |
| API spec describes the shape the hub answers with | local | pre-commit |
| Docs facts and last-updated dates | local | pre-commit |
| API collection covers every route, and can fail | local | pre-commit |
| A successful request cannot pass on an empty answer | local | pre-commit |
| Workflows re-run when what they run changes | local | pre-commit |
| npm audit (UI — HIGH+) | local | pre-push |
| Lint GitHub Actions workflows | local | pre-commit |
| CVE scan covers every compose image | local | pre-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
Dependency Audit
npm audit --audit-level=high — HIGH + CRITICAL CVEs
Stage 3 — CI Pipeline
GitHub Actions workflow .github/workflows/test.yml — 13 jobs on every push. View latest run →
| Job | Tests | Tool | Standard | Gate |
|---|---|---|---|---|
| PR Gate | — | pre-commit on the diff, API spec drift, Bruno coverage, knip, gitleaks | BSI C5 DEV-02 | Blocks |
| CodeQL | — | codeql.yml (JS/TS, Python, Actions) on every PR; codeql-swift.yml when clients/ios changes, or locally with Scripts/codeql-swift.sh | OWASP Top 10 | Reports |
| Security scan | — | Source SBOM, image and deployed-image CVEs (security-scan.yml) | EU CRA Art. 13 | Blocks |
| UI Tests (Vitest) | — | Vitest 5.0.2 + v8 coverage | BSI C5 DEV-03 | Blocks |
| Neo4j Proxy Tests | — | Vitest | BSI C5 DEV-03 | Blocks |
| Lint | — | Next.js ESLint | BSI C5 DEV-02 | Blocks |
| Secret Scan | — | Gitleaks v8.27.2 | BSI C5 DEV-08 | Blocks |
| Dependency Audit | — | npm audit (HIGH+) | OWASP A06 | Blocks |
| Trivy Scan | — | Trivy v0.69.3 | OWASP A06 | Reports |
| K8s Posture | — | Kubescape (NSA + CIS) | NSA K8s Guide | Blocks |
| E2E Tests | — | Playwright v1.63.0 | — | Reports |
| WCAG 2.2 AA Audit | — | axe-core/playwright | EN 301 549 | Blocks |
| Security Pentest | — | OWASP/BSI patterns | OWASP Top 10 | Reports |
| SBOM Generation | 2 | CycloneDX npm | EU CRA Art. 13 | Blocks |
| Licence Compliance | — | license-checker | BSI C5 OPS-04 | Blocks |
| Lighthouse CI | 12 | Lighthouse CI (4 pages × 3 runs) | Core Web Vitals | Reports |
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):
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
DCP v1.0
Decentralised Claims
EHDS Domain
EHDS Art. 3–51
API collection (CI)
Bruno, persona folders
API collection (Azure)
Bruno, ehds.mabu.red
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.
Test Inventory
Future Quality Gates
Recommended improvements prioritised by impact and regulatory alignment.
Enforce Coverage Thresholds
Done — vitest.config.tsMinimum 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-03Mutation Testing
Medium — new tool + CI jobAdd 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.2Licence Compliance Scanning
Done — implemented in test.ymllicense-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-OpenAPI Contract Testing
Partly done — spec drift ratchet in the PR Gatescripts/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.2SBOM Generation
Done — implemented in test.ymlCycloneDX 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-OpenPerformance Regression Testing
Done — Lighthouse CI in test.ymlLighthouse 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 VitalsRuntime ODRL Policy Enforcement
High — new engine + testsImplement 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 §3WCAG Blocking Gate
Done — removed continue-on-errorWCAG 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/2102IaC Policy Enforcement
Done — blocking in test.ymlKubescape 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 GuideDependency Freshness
Done — renovate.jsonRenovate 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. 14Compliance Mapping
| Quality Gate | BSI C5 | OWASP | EHDS | WCAG |
|---|---|---|---|---|
| TypeScript strict | DEV-01 | — | — | — |
| ESLint | DEV-02 | A03 | — | — |
| Unit tests + coverage thresholds | DEV-03 | — | — | — |
| Secret scan (Gitleaks) | DEV-08 | A07 | — | — |
| Dependency audit | DEV-05 | A06 | — | — |
| Trivy vuln scan | DEV-05 | A06 | — | — |
| Security headers | DEV-07 | A05 | — | — |
| 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-04 | A06 | Art. 50 | — |
| Licence compliance | OPS-04 | — | Art. 50 | — |
| Lighthouse perf budget | — | — | — | 2.2 SC2.2.1 |
| Kubescape (blocking) | OPS-01 | — | — | — |
| Renovate freshness | DEV-05 | A06 | — | — |
| ODRL enforcement (planned) | — | A01 | Art. 44 | — |