Stability checkpoint — 24-commit coverage climb + JaCoCo gate ratchet

- test(product): full e-commerce coverage (Product lifecycle, Controller CRUD, HTTP IT)
- test(order): full e-commerce coverage (Order/OrderLine lifecycle, state-machine truth tables, Controller CRUD + status, HTTP IT)
- test(mcp): McpAuditAdvice 0%→97%, McpConfig 0%→100%, EnvironmentSnapshotProvider 0%→100%, ActuatorService 39.8%→100%, MetricsService 85%→97.6%
- test(integration): BioService consumer lambda + RingBufferAppenderRegistration listener
- test(messaging): 4 anonymous Kafka observation conventions (peer.service=kafka tag)
- test(ml): ChurnMcpToolService 31%→100%, MlConfig 0%→100%
- test(customer): CustomerService 84.7%→97.4%, EnrichedCustomerDto + CustomerDtoV2, RecentCustomerBuffer failure paths
- test(observability): DependenciesSectionProvider 77.8%→92.4%, AuditService findAll RowMapper, QualityReportEndpoint formatUptime + buildJarLayersSection
- test(auth): LoginAttemptService 86.8%→100% (auto-expire branch via reflection)
- build(jacoco): ratcheted BUNDLE 0.70→0.85, org.iris.order PACKAGE 0.30→0.90, org.iris.product PACKAGE enabled at 0.90
- fix(test): IT rate-limit + JsonPath cast (X-Forwarded-For per test bypasses 100/min shared 127.0.0.1 bucket; Number→Long cast)

CI :
- ✅ MR pipeline #2486807354 green (post IT-fix push) — https://gitlab.com/iris-7/iris-service-java/-/pipelines/2486807354
- ✅ Post-merge main pipeline #2486850067 green — https://gitlab.com/iris-7/iris-service-java/-/pipelines/2486850067
  - unit-test ✅ 1m 30s
  - integration-test ✅ 2m 15s  (was failing pre-fix, now green)
  - sonar/code-quality ✅ 1m 10s
  - openapi-lint ✅ 1m 09s
  - secret-scan ✅ 1m 44s
  - owasp-dependency-check ✅ 30s
  - build-jar ✅ 52s

Local pre-push lefthook unit-tests hook : ✅ ran on every commit (24/24)

JaCoCo gates verified at the new floors :
- ✅ BUNDLE 0.85 (measured 90.53% UT-only ; merged UT+IT > 0.85 by construction)
- ✅ org.iris.order PACKAGE 0.90 (measured 100%)
- ✅ org.iris.product PACKAGE 0.90 (measured 100%)

Regression check vs stable-v1.2.15 :
- ✅ All previous unit + IT tests still green (no regressions in the 24-commit batch)
- 🆕 Resolved : the rate-limit-cross-test-bleed gotcha (per-IP RateLimitingFilter draining across tests sharing 127.0.0.1) — now defended with X-Forwarded-For per IT test instance

- ⏭ N/A — no LLM/MCP feature changes ; coverage on existing MCP tooling closed (McpAuditAdvice 0%→97%, ActuatorService MCP tools 39.8%→100%, MetricsService 85%→97.6%) so future @Tool additions ship with the audit + observability test floor already raised.

- LoginAttemptService brute-force protection : isBlocked() auto-expire branch and pre-threshold-no-lockout branch now tested — pinned because skipped expire would pin records forever (DoS amplification surface).
- KafkaConfig peer.service=kafka tag conventions across all 4 templates/listeners — pinned so a refactor can't silently lose Kafka identity in the Tempo service map.
- CSRF / STATELESS / per-endpoint role gating in SecurityConfig still 100% verified by AuthITest + Auth0JwtValidationITest (unchanged).

- Order/Product/OrderLine domain : 100% instruction coverage, 96.5%+ branch coverage on org.iris.order, 100% on org.iris.product.
- Order state machine truth table (4×4) and OrderLine state machine truth table (3×3) explicitly enumerated with @ParameterizedTest @CsvSource — every transition has an assertion, no implicit gaps.
- Customer 360 enrichment + ChurnMcpToolService (predict_customer_churn) end-to-end paths covered including the OrtException soft-503 fallback.

- ⏭ N/A — no infra changes in this batch.
- Existing GKE deploy targets + GCP WIF (post-iris-rebrand) + Terraform unchanged.

- AuditService.findAll RowMapper lambda — distinct from findByCustomerId's lambda, captured separately via ArgumentCaptor (pinned the JaCoCo measures synthetic methods independently).
- QualityReportEndpoint.formatUptime — 3 branches (sub-min / sub-hour / multi-hour) covered via reflection.
- QualityReportEndpoint.buildJarLayersSection — synthetic BOOT-INF/layers.idx fixture in src/test/resources (4-layer index including a zero-entries layer to pin that branch).
- DependenciesSectionProvider.parseDependencyAnalysis — staged target/dependency-analysis.txt fixture with both "Used undeclared" / "Unused declared" sections + a no-coord-prefix line filtered by isCoordLine().

- Bundle JaCoCo coverage : 89.1% → **90.53%** (UT-only ; merged UT+IT measured higher in CI).
- Per-package : org.iris.order 32%→100%, org.iris.product 3%→100%, customer 86.7%→92.5%, mcp.actuator 39.8%→100%, mcp.metrics 85%→97.6%, mcp.logs 81.2%→94.5%, integration 70%→100%, messaging 81.4%→97.8%, ml ChurnMcp 31%→100%, observability/quality/providers 87.3%→93.3%.
- Test count delta : ~135 new unit + IT tests across 24 commits.
- Test pyramid pinned : unit (fast) → IT (Testcontainers Postgres) → property tests via jqwik on Order/Product invariants (existing).

- JaCoCo gate ratchets : BUNDLE 0.70→0.85, org.iris.order PACKAGE 0.30→0.90, org.iris.product PACKAGE enabled at 0.90.
- "Climb plan" comment in pom.xml updated : tier 3 (≥ 90%) reached for both e-commerce packages — climb is locked.
- Conventional Commits enforced via Lefthook on every commit (24/24 passed).
- Pipeline stages green : openapi-lint, owasp-dependency-check, secret-scan, unit-test, integration-test, build-jar, sonar/code-quality. Compat matrix + native-build remain manual (unchanged).

- Hexagonal Lite (ADR-0044) preserved : new tests respect domain/port boundaries (controller tests use Mockito only, IT tests go through HTTP).
- Feature-slicing (ADR-0008) preserved : each new test colocated with the production class it tests.
- Test-as-spec discipline : every new test name describes the contract being pinned (e.g. add_swallowsJacksonException_doesNotPropagate, formatUptime_overAnHour_returnsHoursAndMinutes_dropsSeconds).

- ⏭ N/A — backend-only repo (iris-ui has its own stable-v cadence).

- New test fixtures shipped : src/test/resources/BOOT-INF/layers.idx (4-layer Spring Boot fat-jar synthetic).
- Pre-push lefthook unit-tests hook accelerated from 60s baseline to 25-50s warm cache during the batch (Maven incremental compile kicked in).
- IT-test rate-limit-cross-test-bleed gotcha documented + defended : X-Forwarded-For per @BeforeEach gives each IT a private bucket (10.x.x.x derived from System.nanoTime()).

- org.iris.ml ChurnPredictor at 18.7% coverage — needs a real .onnx fixture for the predictProbability happy path. ONNX runtime mock is non-trivial (OrtEnvironment.getEnvironment is a static singleton). Tracked for a future MR with a synthetic 8-feature model.
- org.iris.auth SecurityConfig at 27% coverage — the filter-chain DSL lambdas (authorizeHttpRequests / sessionManagement / exceptionHandling) only execute when Spring builds the filter chain. The MR pipeline's IT data covers them; UT-only local report does not.
- org.iris.observability KafkaHealthIndicator UP path + KeycloakHealthIndicator UP path — need real broker / OAuth server. DOWN paths are unit-tested.

- Build the .onnx fixture for ChurnPredictor → close the last 191-instruction ml gap.
- @SpringBootTest-based SecurityConfig test → cover the filter-chain DSL lambdas at unit speed (SliceTest for security alone, no MockMvc).
- Tag annotation review : re-run on next stable-v* whether the per-package gate should ratchet further (e.g. order/product 0.90 → 0.95 since both are at 100%).