feat: v0.8.0 β Verification Debt
v0.8.0 β Verification Debt
Closes the original design plan's unfinished verification checks (Β§3) before the v1.0.0 API freeze turns their answers into contracts β plus a CI-flakiness fix found during real-world gate
validation.
π WebFlux/reactive validation (plan Β§3 check #4 β never done until now)
- New
WireDoctorWebFluxIntegrationTestboots a REACTIVE (Netty, non-servlet) context in CI and asserts reports are written, startup timings populated, and ghost analysis runs - Reactive entry points added to ghost detection:
WebHandler,WebSocketHandler,WebExceptionHandler(joiningRouterFunction) β fixes ghost false-positives in reactive apps - Pinned by test: a
RouterFunctionbean is never flagged as a ghost spring-boot-starter-webfluxadded test-scope only; README supported-versions note added
π¬ Bean-scope behavior pinned by tests (plan Β§3 check #2 β doc-only until now)
- New
WireDoctorBeanScopeTestasserts the documented behavior per scope:- prototype definitions appear as graph nodes but are never instantiated (zero-intrusion promise, now regression-tested)
- untouched
@Lazybeans survive the full analysis untouched FactoryBeanproduct edges resolve to the factory's bean name- skipped not-instantiated beans are honestly counted (
proxies.notInstantiatedSkipped)
- README Limitation #5 rewritten from vague ("may not fully map out") to these test-backed facts
π€ Never overwrite a user-set ApplicationStartup (found in plan audit)
- The startup listener previously replaced any
ApplicationStartupthe app (or another tool) had installed β silently breaking foreign instrumentation - Now: a pre-existing non-default instance is kept. Buffering ones keep timings working (INFO); foreign ones get a WARN and the timing section degrades gracefully while every other
analysis runs normally getApplicationStartup()verified available on Boot 2.7 β 4.0 (same floor asBufferingApplicationStartup)- Contract pinned by
WireDoctorStartupCoexistenceTest
β±οΈ Slow-bean gate jitter margin β wiredoctor.slow-bean-margin-ms (default 20)
- Real-world validation on start.spring.io tripped the gate at 101ms vs a 100ms threshold β pure JVM jitter, not a regression. That exact case is now a permanent test
- A NEW slow bean must exceed
threshold + marginto trip; beans inside the margin band stay in the report's slow-bean list but never fail CI - Mirrors the dual-threshold noise tolerance the startup-time gate already has;
0restores exact pre-0.8.0 behavior - Margin surfaces in
gates.configand the HTML gate card ((+20ms jitter margin)) - Docs:
docs/performance-gates.md+ README config section updated
Verified
- 233 tests green (222 autoconfigure + 11 actuator) via full
mvn verifyβ up from 219 - ~60 lines production code, ~350 lines tests β code-light, proof-heavy by design
- Version bumped in all 4 poms; CHANGELOG entry added
Plan Β§3 checklist after this PR
| Check | Status |
|---|---|
| #1 SPI hook timing | β resolved v0.1.0 + CI matrix |
| #2 Bean scopes | β this PR |
| #3 AOT/native | β v1.0.0 (deliberate, task 3) |
| #4 WebFlux | β this PR |