Docs & rules

jdubois/boot-uiGitHub

This is a public, read-only report. Striff reads this repository's docs, turns each sentence that makes a claim about the code into a rule, and checks the rule against the code on the default branch. How this works

maind290c7cLast read 10h ago

Is this yours? Install to manage it

Once installed, Striff checks every pull request.

Documents
Rules
69
69
1
1
2
2
20
44
25 docs
jdubois/boot-uiOpen repository

jdubois/boot-ui — documented rules

69 of 69 rules, printed October 12, 2026.

The sentence in your docs
Read Oct 11
The QuarkusRestClientTraceListener (registered via ServiceProviderBuildItem when the capability is present) attaches a QuarkusRestClientTraceFilter on every proxy.
QuarkusRestClientTraceListener depends on QuarkusRestClientTraceFilter
Holds
Read Oct 11
Each check is a small class registered in PentestingCheckRegistry and implemented in PentestingChecks.java.
PentestingCheckRegistry is in bootui-engine
Holds
Read Oct 11
QuarkusPentestingObservationCollector deliberately supplies a neutral PentestingSecurityStatus (securityClassPresent=false, chainsWithCsrf=-1) because Quarkus has no Spring Security equivalent to inspect.
QuarkusPentestingObservationCollector depends on PentestingSecurityStatus
Holds
Read Oct 11
It also includes the per-panel access keys — bootui.panels.<id>.enabled / .read-only and the global bootui.read-only — which are enforced on Quarkus by QuarkusPanelAccessFilter at full behavioral parity with Spring's PanelAccessFilter (same config keys, same BootUiPanels path resolution, same canonical JSON 403 body);
2 rules from this sentence
QuarkusPanelAccessFilter depends on BootUiPanels
Holds
PanelAccessFilter depends on BootUiPanels
Holds
Read Oct 11
@CircuitBreaker, @Retry, @Timeout, @Bulkhead, @RateLimit, and @Fallback declarations are scanned from the build-time Jandex index by a registerFaultTolerancePolicies build step + @Recorder into a synthetic bean, then mapped onto the same FaultTolerancePolicyProvider SPI and DTO contract Spring's Resilience4j/Spring Retry providers use.
FaultTolerancePolicyProvider is a contract
Holds
Read Oct 11
It is computed by the shared engine SqlTraceGrouping helper — the identical code path Spring's LiveActivityService uses — so flagging and call-site aggregation are byte-identical across adapters.
LiveActivityService depends on SqlTraceGrouping
Holds
Read Oct 11
Captured email (MAIL). LiveActivityResource reads the same framework-neutral EmailCaptureService the standalone Email panel uses directly, with no separate Quarkus capture instrumentation, and feeds its merged SSE stream identically to Spring, nesting as a REQUEST child via the same trace-id join.
LiveActivityResource depends on EmailCaptureService
Holds
Read Oct 11
Capture is done by two @ApplicationScoped interceptors — QuarkusKafkaProducerCapture (OutgoingInterceptor) and QuarkusKafkaConsumerCapture (IncomingInterceptor) — that read Kafka record metadata into the shared, framework-neutral KafkaActivityRecorder.
4 rules from this sentence
QuarkusKafkaProducerCapture is annotated with ApplicationScoped
checks “two @ApplicationScoped interceptors — QuarkusKafkaProducerCapture”
Holds
QuarkusKafkaConsumerCapture is annotated with ApplicationScoped
checks “two @ApplicationScoped interceptors”
Holds
QuarkusKafkaProducerCapture depends on KafkaActivityRecorder
checks “QuarkusKafkaProducerCapture (OutgoingInterceptor) and QuarkusKafkaConsumerCapture (IncomingInterceptor) — that read Kafka record metadata into the shared, framework-neutral KafkaActivityRecorder.”
Holds
QuarkusKafkaConsumerCapture depends on KafkaActivityRecorder
checks “QuarkusKafkaProducerCapture (OutgoingInterceptor) and QuarkusKafkaConsumerCapture (IncomingInterceptor) — that read Kafka record metadata into the shared, framework-neutral KafkaActivityRecorder.”
Holds
Read Oct 11
RabbitMQ follows the same SmallRye pattern. QuarkusRabbitProducerCapture/QuarkusRabbitConsumerCapture feed the shared RabbitActivityRecorder, are class-presence-gated on quarkus-messaging-rabbitmq, stop capture whenever the dedicated RabbitMQ panel is disabled, and are excluded from Arc when the connector is absent.
2 rules from this sentence
QuarkusRabbitProducerCapture depends on RabbitActivityRecorder
Holds
QuarkusRabbitConsumerCapture depends on RabbitActivityRecorder
Holds
Read Oct 11
A servlet request runs start-to-finish on one worker thread that serves only one request at a time, so SQL, exceptions, and security events observed on that thread within its time window belong to it exactly, even with no distributed tracing at all (threadMatched is a first-class field on RequestProfileSecurityDto/carried by RequestProfileExceptionDto's thread).
RequestProfileSecurityDto has a threadMatched field
Holds
Read Oct 11
threadMatched always reports false (Quarkus has no thread-identity concept), while principalMatched on RequestProfileSecurityDto is honestly computed by comparing principals.
RequestProfileSecurityDto has principalMatched
Holds
Read Oct 11
In the main feed, ActivityEntryDto.profileable is computed adapter-side in LiveActivityResource: true for request entries with a resolvable trace id, false otherwise;
2 rules from this sentence
ActivityEntryDto has profileable
Holds
LiveActivityResource depends on ActivityEntryDto
Holds
Read Oct 11
Because both beans always exist, LiveActivityResource injects ActivityStore and ActivityPersistenceSettings directly (no Instance<> wrapper) and branches its activity() method on persistenceSettings.enabled() exactly like Spring's controller.
3 rules from this sentence
LiveActivityResource depends on ActivityStore
checks “LiveActivityResource injects ActivityStore”
Holds
LiveActivityResource depends on ActivityPersistenceSettings
checks “LiveActivityResource injects ActivityStore and ActivityPersistenceSettings directly”
Holds
LiveActivityResource has an activity method
Holds
Read Oct 11
The opaque ServiceMapInteractionDto.flowId needed no Quarkus-specific work. ServiceMapAssembler derives it one-way from whatever distributed-trace id was already captured on the HttpExchangeBuffer/RestClientTraceRecorder/ SqlTraceRecorder entries this resource reads — the same capability-gated QuarkusOtelTraceIdProvider stamping.
ServiceMapInteractionDto has flowId
Holds
Read Oct 11
BootUiEngineProducer @Produces a SwitchableActivityStore in front of it, rather than producing ActivityStore directly.
BootUiEngineProducer depends on SwitchableActivityStore
Holds
Read Oct 11
A thin LiveActivityResource#useExistingDatasource mirrors Spring's controller method: 404 when no DataSource is present, 400 when the request is not explicitly confirmed, 200-and-no-op when persistence is already active, and 200 with the store swapped and capturing on success — all behind the shared LocalhostGuard write floor.
LiveActivityResource has an useExistingDatasource method
Holds
Read Oct 11
BootUiProdShellGuardFilter is a CDI Vert.x filter registered by its own always-on @BuildStep (deliberately not launch-mode-gated, the opposite polarity from every other build step in the extension). Its handle() method reads a CDI-injected LaunchMode and answers a plain 404 for the configured UI/API surface and the private /bootui classpath mount only when it is LaunchMode.NORMAL — an immediate no-op pass-through otherwise, so dev/@QuarkusTest behavior is unaffected.
BootUiProdShellGuardFilter has a handle method
Holds
Read Oct 11
They needed zero changes beyond adding one new platform constant (PanelsReport.PLATFORM_SPRING_BOOT_REACTIVE).
PanelsReport has PLATFORM_SPRING_BOOT_REACTIVE
Holds
Read Oct 11
BootUiAutoConfiguration (servlet) and BootUiReactiveAutoConfiguration (reactive) are two separate autoconfigurations in the same bootui-spring-autoconfigure module — not two modules — because nearly all of the underlying @RestControllers, safety decisions, and engine wiring are identical.
2 rules from this sentence
BootUiAutoConfiguration is in bootui-spring-autoconfigure
Holds
BootUiReactiveAutoConfiguration is in bootui-spring-autoconfigure
Holds
Read Oct 11
Resilience4j's event publishers plus the additive BootUiRetryListener bean feed the shared FaultToleranceEventRecorder from whatever thread the protected call runs on, so the panel and its Live Activity FAULT_TOLERANCE entries work with zero adapter-specific code.
BootUiRetryListener depends on FaultToleranceEventRecorder
Holds
Read Oct 11
Panel MCP Server, Reactive binding ReactiveBootUiMcpController — same BootUiMcpService , McpServerState , and McpProtocol as the servlet BootUiMcpController only the transport differs ( DataBuffer payload assembly with the same bootui.mcp.max-payload-bytes limit, and tool execution offloaded to Schedulers.boundedElastic() )
6 rules from this sentence
ReactiveBootUiMcpController depends on BootUiMcpService
checks “Panel MCP Server, Reactive binding ReactiveBootUiMcpController — same BootUiMcpService , McpServerState , and McpProtocol as the servlet BootUiMcpController only the transport differs ( DataBuffer payload assembly with the same bootui.mcp.max-payload-bytes limit”
Holds
ReactiveBootUiMcpController depends on McpProtocol
checks “Panel MCP Server, Reactive binding ReactiveBootUiMcpController — same BootUiMcpService , McpServerState , and McpProtocol as the servlet BootUiMcpController only the transport differs ( DataBuffer payload assembly with the same bootui.mcp.max-payload-bytes limit”
Holds
ReactiveBootUiMcpController depends on McpServerState
checks “Panel MCP Server, Reactive binding ReactiveBootUiMcpController — same BootUiMcpService , McpServerState , and McpProtocol as the servlet BootUiMcpController only the transport differs ( DataBuffer payload assembly with the same bootui.mcp.max-payload-bytes limit”
Holds
BootUiMcpController depends on BootUiMcpService
checks “same BootUiMcpService , McpServerState , and McpProtocol as the servlet BootUiMcpController”
Holds
BootUiMcpController depends on McpProtocol
checks “same BootUiMcpService , McpServerState , and McpProtocol as the servlet BootUiMcpController”
Holds
BootUiMcpController depends on McpServerState
checks “same BootUiMcpService , McpServerState , and McpProtocol as the servlet BootUiMcpController”
Holds
Read Oct 11
Panel Command Line, Reactive binding ReactiveBootUiCliController — same CliService and the same /bootui/api/cli contract and statuses as the servlet BootUiCliController , with tool invocation offloaded to Schedulers.boundedElastic() because BootUI's tools call blocking diagnostics
2 rules from this sentence
ReactiveBootUiCliController depends on CliService
Holds
BootUiCliController depends on CliService
checks “same CliService and the same /bootui/api/cli contract and statuses as the servlet BootUiCliController”
Holds
Read Oct 11
Panel SQL Trace, Reactive source ReactiveSqlTraceController over the new shared ReactiveBootUiChangeStream SSE primitive ( Flux<ServerSentEvent<T>> ), feeding the same SqlTraceRecorder See the fidelity note below
2 rules from this sentence
ReactiveSqlTraceController depends on ReactiveBootUiChangeStream
checks “ReactiveSqlTraceController over the new shared ReactiveBootUiChangeStream SSE primitive”
Holds
ReactiveSqlTraceController depends on SqlTraceRecorder
Holds
Read Oct 11
Panel Transactions, Reactive source ReactiveTransactionsController over ReactiveBootUiChangeStream , feeding the same TransactionRecorder See the fidelity note below
2 rules from this sentence
ReactiveTransactionsController depends on ReactiveBootUiChangeStream
checks “ReactiveTransactionsController over ReactiveBootUiChangeStream”
Holds
ReactiveTransactionsController depends on TransactionRecorder
Holds
Read Oct 11
Panel Log Tail, Reactive source ReactiveLogTailController — same LogTailBuffer /Logback appender, SSE via ReactiveBootUiChangeStream
ReactiveLogTailController depends on LogTailBuffer
Holds
Read Oct 11
Panel REST Client, Reactive source ReactiveRestClientTraceController — same RestClientTraceRecorder , SSE via ReactiveBootUiChangeStream See the fidelity note below
2 rules from this sentence
ReactiveRestClientTraceController depends on RestClientTraceRecorder
Holds
ReactiveRestClientTraceController depends on ReactiveBootUiChangeStream
Holds
Read Oct 11
Panel WebSockets, Reactive source ReactiveWebSocketController + ReactiveWebSocketMetadataProvider — same WebSocketService , SSE via ReactiveBootUiChangeStream See the fidelity note below
2 rules from this sentence
ReactiveWebSocketController depends on WebSocketService
Holds
ReactiveWebSocketController depends on ReactiveBootUiChangeStream
Holds
Read Oct 11
ReactiveBootUiChangeStream is a small shared Sinks.Many-backed SSE broadcaster (open() / signal() / close()) used by every "push an update when something changes" panel above, instead of each controller hand-rolling its own sink.
3 rules from this sentence
ReactiveBootUiChangeStream has an open method
Holds
ReactiveBootUiChangeStream has a signal method
Holds
ReactiveBootUiChangeStream has a close method
Holds
Read Oct 11
REST Client. Availability is gated on RestClientTraceRecorder#hasInstrumentedClient() (a WebClient.Builder auto-configured with the BootUI customizer must have been built).
RestClientTraceRecorder has a hasInstrumentedClient method
Holds
Read Oct 11
REST/WebClient calls are read from the same RestClientTraceRecorder fed by BootUiEngineConfiguration's WebClientCustomizer;
BootUiEngineConfiguration depends on RestClientTraceRecorder
Holds
Read Oct 11
The servlet adapter's LiveActivityController additionally depends on two things with no reactive equivalent. One is a ServletRequestHandledEvent listener, which exists purely as an SSE-refresh trigger, not a data source. The other is a thread-based LiveActivityCorrelator that stitches a request to its downstream activity via serving-thread identity — meaningless on Reactor Netty, where a request is not served start-to-finish on one dedicated worker thread.
LiveActivityController depends on LiveActivityCorrelator
Holds
Read Oct 11
LiveServiceMapController injects only beans both stacks register — the shared HttpExchangesController plus the engine's ConnectionPoolService, SqlTraceRecorder, RestClientTraceRecorder, KafkaActivityRecorder, RabbitActivityRecorder, and CacheActivityRecorder.
7 rules from this sentence
LiveServiceMapController depends on HttpExchangesController
Holds
LiveServiceMapController depends on ConnectionPoolService
Holds
LiveServiceMapController depends on SqlTraceRecorder
Holds
LiveServiceMapController depends on RestClientTraceRecorder
Holds
LiveServiceMapController depends on KafkaActivityRecorder
Holds
LiveServiceMapController depends on RabbitActivityRecorder
Holds
LiveServiceMapController depends on CacheActivityRecorder
Holds
Read Oct 11
LiveServiceMapController injects only beans both stacks register — the shared HttpExchangesController plus the engine's ConnectionPoolService, SqlTraceRecorder, RestClientTraceRecorder, KafkaActivityRecorder, RabbitActivityRecorder, and CacheActivityRecorder. It returns a stable core DTO, so one class registered in both BootUiAutoConfiguration and BootUiReactiveAutoConfiguration makes Spring MVC and WebFlux serve a byte-identical map, including its cache dependency and opaque flow correlation.
2 rules from this sentence
BootUiAutoConfiguration depends on LiveServiceMapController
Holds
BootUiReactiveAutoConfiguration depends on LiveServiceMapController
Holds
Read Oct 11
BootUiReactiveAutoConfiguration already installs the same ReactiveOtelTraceIdProvider on the HTTP exchange, SQL, REST-client, and cache recorders.
BootUiReactiveAutoConfiguration depends on ReactiveOtelTraceIdProvider
Holds
Read Oct 11
ReactiveActivitySignalFilter takes an ObjectProvider<ReactiveLiveActivityController> rather than a direct reference.
ReactiveActivitySignalFilter depends on ReactiveLiveActivityController
Holds
Read Oct 11
WebFilter beans are eagerly resolved by WebFlux at startup to build the filter chain, so a direct constructor dependency would force-eager the controller and defeat its place in BootUiReactiveAutoConfiguration.LAZY_CONTROLLER_CLASS_NAMES.
BootUiReactiveAutoConfiguration has LAZY_CONTROLLER_CLASS_NAMES
Holds
Read Oct 11
HTTP exchange (via a new ReactiveHttpExchangeTraceFilter feeding a side-buffer HttpExchangeTraceRegistry, since Actuator's HttpExchange model has no trace-id field), SQL (SqlTraceRecorder.setTraceIdProvider), exceptions (ReactiveBootUiExceptionHandler.setTraceIdProvider), and security events (ReactiveSecurityLogsController.setTraceIdProvider
4 rules from this sentence
ReactiveHttpExchangeTraceFilter depends on HttpExchangeTraceRegistry
Holds
SqlTraceRecorder has setTraceIdProvider
checks “SQL (SqlTraceRecorder.setTraceIdProvider)”
Holds
ReactiveBootUiExceptionHandler has setTraceIdProvider
checks “exceptions (ReactiveBootUiExceptionHandler.setTraceIdProvider)”
Holds
ReactiveSecurityLogsController has setTraceIdProvider
checks “security events (ReactiveSecurityLogsController.setTraceIdProvider”
Holds
Read Oct 11
HttpExchangeTraceRegistry#match (and its servlet sibling RequestCorrelationRegistry) deliberately requires a unique method+path+time-window candidate.
HttpExchangeTraceRegistry has match
Holds
69 rules from 5 docs

See these where the change is. The browser extension puts a pull request's doc findings, and a diagram of what it changed, on the GitHub page itself, so the code and what your docs say about it are side by side.