The trigger
on: push · pull_request · workflow_dispatchEvery push to main, every pull request, and a manual dispatch. Both jobs start together, each on its own ubuntu-latest.
A clean-architecture-single-module project generated and developed only with Nerviz. Every spec, every run report and every commit is public.
clean-architecture-single-module, 20 minutes, green build.
Open on GitHub →The first approved spec, with one partial per layer.
Open on GitHub →@Scheduled without ShedLock, decided by jobs-architect: the delete partitions work across replicas.
Open on GitHub →A public read, recorded in the spec as an explicit accepted risk.
Open on GitHub →The first Kafka producer, with outbox, relay and prune.
Open on GitHub →310 tests, 0 failures, 96.7% line coverage, 50 minutes.
Open on GitHub →A DELETE that anonymizes the customer and keeps the row and its id. It brings the project's first security filter chain: only the DATA_PROTECTION_OFFICER role may call it.
Open on GitHub →build.yml came with the /init-project scaffold and changed twice since. 54 runs since 2026-10-06: 51 green, 3 red. Count of 2026-10-15.
doctor gate swept 203 source files against them in the latest runWhat each step checks, in the order the latest run went through it. Two jobs run in parallel; any step that fails turns the push red.
on: push · pull_request · workflow_dispatchEvery push to main, every pull request, and a manual dispatch. Both jobs start together, each on its own ubuntu-latest.
actions/checkout · actions/setup-javafetch-depth: 0 · temurin 21 · cache: mavenThe checkout brings the full history, which Sonar uses for blame. Java 21 from Temurin, with Maven's cache.
doctorjava .claude/hooks/ArchHook.java doctor gateA separate job, in parallel. doctor gate fails the build when a gated line fails: the 15 boundary rules, the sweep of every source file for forbidden imports, the extension schema, the hook jar built from the current ArchHook.java, and the hook registrations. Lines that depend on the runner, such as CLAUDE_PROJECT_DIR, show up but never gate.
Boundaries ........ ✅ 15 active rules Boundary violations . ✅ 203 file(s) swept against 15 rule(s) Schema ............ ✅ all extension files pass Hook jar .......... ✅ built from the current .claude/hooks/ArchHook.java Hooks ............. ✅ 28 registration(s) across 12 event(s)✅ doctor gate: no gated line failed (Boundaries, Boundary violations, Schema, Hook jar, Hooks, MCP, Audit overrides).
checkstyle:check (checkstyle-validate)./mvnw -B clean verifyAt validate, Checkstyle reads src/main against config/checkstyle/checkstyle.xml, the mechanical half of rules/code-quality.md: length, parameters, complexity, nesting, magic numbers. One violation fails the build.
[INFO] You have 0 Checkstyle violations.compiler:compile · compiler:testCompileProduction and test code compiled with Java 21. The JaCoCo agent is already attached, to measure coverage of the tests that follow.
surefire:test (default-test)287 tests, with no database and no broker. Among them, ArchitectureTest, with 21 ArchUnit rules.
[INFO] Tests run: 21, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.496 s -- in dev.nerviz.bankapp.ArchitectureTest[INFO] Tests run: 287, Failures: 0, Errors: 0, Skipped: 0
failsafe:integration-test (default)80 tests against real containers started by Testcontainers: postgres:16-alpine and apache/kafka:4.1.0. The GitHub runner has Docker, so none are skipped.
Creating container for image: postgres:16-alpineCreating container for image: apache/kafka:4.1.0[INFO] Tests run: 80, Failures: 0, Errors: 0, Skipped: 0
spotless:check (spotless-check)Spotless checks src/main and src/test with palantir-java-format and fails on an unused import. It catches a file written outside the format hook.
[INFO] Spotless.Java is keeping 202 files clean - 0 needs changes to be clean, 202 were already clean, 0 were skipped because caching determined they were already cleancheckstyle:check (checkstyle-test)src/test against checkstyle-test.xml, a rule set of its own for test code. This is the check that left three runs red on 2026-10-12, with two violations that a28934c fixed.
[INFO] You have 0 Checkstyle violations.jacoco:check (check)JaCoCo requires 80% of lines and 70% of branches across the project, startup and configuration classes excluded. The numbers come from rules/testing.md and are never lowered to make the build pass.
[INFO] All coverage checks have been met.[INFO] BUILD SUCCESS
integration tests actually ranA shell step reads failsafe-summary.xml. If *IT.java sources exist and no integration test ran, or any was skipped, the build fails: a skipped IT proves nothing.
✅ 80 integration test(s) ran, none skipped.sonar analysis./mvnw -B sonar:sonarAfter verify, with JaCoCo's report already there. It runs only when the SONAR_TOKEN secret exists, so a fork's pull request passes without it. The step uploads the analysis and does not wait for the quality gate: the result lives on SonarQube Cloud.
[INFO] ANALYSIS SUCCESSFUL, you can find the results at: https://sonarcloud.io/dashboard?id=nerviz-ai_bank-app&branch=mainEach bar is one build.yml run, in the order it ran. Its height is the tests Maven reported, unit plus integration. The jumps are the use cases.
build.yml · changed| When (UTC) | Commit | Tests | Time | Result |
|---|---|---|---|---|
| 2026-10-06 15:56 | f5eaf3b chore: initial project scaffold — clean-architecture-single-module, m… | 5 (2 unit · 3 integration) | 1m30s | ✓ passed |
| 2026-10-06 16:34 | 1a8432a docs: show the app starting and passing verify in the README | 5 (2 unit · 3 integration) | 1m09s | ✓ passed |
| 2026-10-06 16:35 | 523bcc3 docs: show the app starting and passing verify in the README | 5 (2 unit · 3 integration) | 1m12s | ✓ passed |
| 2026-10-06 16:38 | f561bb0 Merge pull request #1 from nerviz-ai/docs/readme-run-gifs | 5 (2 unit · 3 integration) | 53s | ✓ passed |
| 2026-10-06 16:41 | dd2dd2b docs: describe the CI pipeline and what it covers in the README | 5 (2 unit · 3 integration) | 57s | ✓ passed |
| 2026-10-06 16:48 | badb714 Merge pull request #2 from nerviz-ai/docs/readme-ci-pipeline | 5 (2 unit · 3 integration) | 58s | ✓ passed |
| 2026-10-07 09:02 | 24558a5 docs(UC-001-create-customer): approved spec | 5 (2 unit · 3 integration) | 1m02s | ✓ passed |
| 2026-10-07 09:08 | d62c8d4 commit audit-usage | 5 (2 unit · 3 integration) | 1m03s | ✓ passed |
| 2026-10-07 10:24 | 0e74c8c feat(UC-001-create-customer): create customer with idempotent POST /a… | 113 (98 unit · 15 integration) | 1m56s | ✓ passed |
| 2026-10-07 10:25 | 9861ede commit audit-usage | 113 (98 unit · 15 integration) | 1m53s | ✓ passed |
| 2026-10-07 10:49 | 651b779 ci: run SonarQube Cloud analysis on nerviz-ai_bank-app | 113 (98 unit · 15 integration) | 2m25s | ✓ passed |
| 2026-10-07 10:56 | 249c4fa docs: add SonarQube Cloud badges and public report link to README | 113 (98 unit · 15 integration) | 2m20s | ✓ passed |
| 2026-10-07 11:06 | d7b62a3 chore(arch): adopt nerviz v0.17.8 and gate CI on doctor | 113 (98 unit · 15 integration) | 2m17s | ✓ passed |
| 2026-10-07 12:33 | 31fc27c updating readme | 113 (98 unit · 15 integration) | 1m36s | ✓ passed |
| 2026-10-07 20:43 | 940e578 report issue | 113 (98 unit · 15 integration) | 2m32s | ✓ passed |
| 2026-10-07 23:13 | a59c52c arch-update | 113 (98 unit · 15 integration) | 1m58s | ✓ passed |
| 2026-10-07 23:25 | 2da91cd arch-update | 113 (98 unit · 15 integration) | 2m18s | ✓ passed |
| 2026-10-08 00:53 | 7c4e714 arch-update | 137 (117 unit · 20 integration) | 2m11s | ✓ passed |
| 2026-10-08 01:06 | 1c966b0 chore: arch-update | 137 (117 unit · 20 integration) | 2m04s | ✓ passed |
| 2026-10-08 08:51 | 7985d5d chore(arch): update .claude to nerviz v0.20.0 | 137 (117 unit · 20 integration) | 2m12s | ✓ passed |
| 2026-10-08 11:34 | 3061f71 arch-update | 137 (117 unit · 20 integration) | 2m08s | ✓ passed |
| 2026-10-08 12:00 | 6e57955 chore(arch): update .claude to nerviz v0.22.0 | 137 (117 unit · 20 integration) | 2m10s | ✓ passed |
| 2026-10-08 12:24 | 0f96c8b chore: commit changes from before this run | 149 (126 unit · 23 integration) | 2m11s | ✓ passed |
| 2026-10-08 12:26 | 4fae2c3 audit-usage | 149 (126 unit · 23 integration) | 2m09s | ✓ passed |
| 2026-10-08 13:28 | 5068ff2 audit-usage | 149 (126 unit · 23 integration) | 2m01s | ✓ passed |
| 2026-10-08 13:38 | b3c4896 build(sonar): align coverage exclusions with JaCoCo gate | 149 (126 unit · 23 integration) | 3m06s | ✓ passed |
| 2026-10-08 22:14 | 71015af docs(UC-004-initiate-kyc-verification): approved spec | 149 (126 unit · 23 integration) | 2m07s | ✓ passed |
| 2026-10-08 22:19 | 8be721f audit-usage | 149 (126 unit · 23 integration) | 2m16s | ✓ passed |
| 2026-10-09 00:29 | 7bc5c8f feat(UC-004-initiate-kyc-verification): initiate KYC verification via… | 260 (211 unit · 49 integration) | 2m48s | ✓ passed |
| 2026-10-11 13:05 | 31ff9e0 docs: bring README in line with the current build and CI | 260 (211 unit · 49 integration) | 2m32s | ✓ passed |
| 2026-10-11 13:13 | 08773e6 Merge pull request #3 from nerviz-ai/docs/readme-current-state | 260 (211 unit · 49 integration) | 2m25s | ✓ passed |
| 2026-10-11 15:12 | 1fcda1f audit-usage | 260 (211 unit · 49 integration) | 2m31s | ✓ passed |
| 2026-10-11 15:14 | 13484e7 chore(arch): update .claude to nerviz v0.23.0 | 260 (211 unit · 49 integration) | 2m12s | ✓ passed |
| 2026-10-11 23:12 | 4fe0f0d chore(arch): update .claude to nerviz v0.25.1 and apply single-module… | 260 (211 unit · 49 integration) | 2m40s | ✓ passed |
| 2026-10-12 14:49 | be62511 feat(UC-005-record-kyc-verdict): record KYC verdict on customer | 294 (235 unit · 59 integration) | 2m09s | ✕ failed |
| 2026-10-12 15:23 | 0079e7c audit-usage | 294 (235 unit · 59 integration) | 2m25s | ✕ failed |
| 2026-10-12 16:00 | ba4f5ad gifs | 294 (235 unit · 59 integration) | 2m36s | ✕ failed |
| 2026-10-12 16:06 | a28934c chore(arch): update .claude to nerviz v0.25.3 and pass stop-gate-runs… | 294 (235 unit · 59 integration) | 2m48s | ✓ passed |
| 2026-10-12 21:30 | 076f6f1 chore(arch): update .claude to nerviz v0.26.0 | 294 (235 unit · 59 integration) | 3m24s | ✓ passed |
| 2026-10-12 21:55 | 27e2456 chore(arch): update .claude to nerviz v0.27.0 | 294 (235 unit · 59 integration) | 3m20s | ✓ passed |
| 2026-10-12 23:44 | 79fe59c chore(arch): update .claude to nerviz v0.28.0 | 294 (235 unit · 59 integration) | 2m41s | ✓ passed |
| 2026-10-13 00:12 | 9423b11 docs(UC-006-anonymize-customer): approved spec | 294 (235 unit · 59 integration) | 2m52s | ✓ passed |
| 2026-10-13 00:51 | d1527eb audit-usage | 294 (235 unit · 59 integration) | 3m24s | ✓ passed |
| 2026-10-13 01:06 | 8e8bf56 chore(arch): update .claude to nerviz v0.29.0 | 294 (235 unit · 59 integration) | 3m34s | ✓ passed |
| 2026-10-13 01:08 | 6037ed3 chore(audit-usage): remove stale report citing deleted UC-004-initiate | 294 (235 unit · 59 integration) | 3m08s | ✓ passed |
| 2026-10-13 09:59 | 02c4c17 feat(UC-006-anonymize-customer): anonymize a customer via DELETE /api… | 355 (276 unit · 79 integration) | 3m56s | ✓ passed |
| 2026-10-13 10:21 | 6b55699 feat(UC-006-anonymize-customer): add local Keycloak service to docker… | 355 (276 unit · 79 integration) | 3m03s | ✓ passed |
| 2026-10-13 15:17 | 80564c1 build(sonar): exempt java:S4502 on SecurityConfig | 355 (276 unit · 79 integration) | 4m09s | ✓ passed |
| 2026-10-13 22:14 | 45fc2bb refactor(api): move REST versioning to native API versioning | 359 (280 unit · 79 integration) | 3m26s | ✓ passed |
| 2026-10-14 12:48 | eb89105 chore: update .claude to nerviz v0.34.0 and apply its migrations | 360 (281 unit · 79 integration) | 3m16s | ✓ passed |
| 2026-10-14 17:37 | 7a5c534 chore: commit pending changes | 366 (287 unit · 79 integration) | 3m17s | ✓ passed |
| 2026-10-14 19:58 | 3187bac chore(arch): update .claude to nerviz v0.35.0 | 366 (287 unit · 79 integration) | 3m22s | ✓ passed |
| 2026-10-15 09:02 | c0047d8 chore(arch): update .claude to nerviz v0.36.0 | 366 (287 unit · 79 integration) | 3m18s | ✓ passed |
| 2026-10-15 21:16 | a3cc28a chore: commit pending changes | 367 (287 unit · 80 integration) | 3m40s | ✓ passed |
Every push to main sends the code to SonarQube Cloud, in the CI's sonar analysis step. The report is public: below, its live badges, and a snapshot of the latest analysis.
These badges are drawn by SonarQube Cloud on every page load. SonarQube Cloud does not allow its report inside another site's frame, so the full report opens there. Analysis of 2026-10-24 23:26 UTC, commit 948c8dc.
Sonar way is SonarQube Cloud's default gate. It judges the new code, here everything since the previous version (2026-10-07), on six conditions:
new_reliability_ratingArequired ≤ Anew_security_ratingArequired ≤ Anew_maintainability_ratingArequired ≤ Anew_coverage96.5%required ≥ 80%new_duplicated_lines_density0.0%required ≤ 3%new_security_hotspots_reviewed100%required = 100%3,946 lines of code in 142 files
In the CI, jacoco:check fails the build below 80% of lines or 70% of branches. SonarQube Cloud reads the same JaCoCo report.