This page describes what happens between mvn package and the first 200 OK. It follows the code through vidocq-runtime-maven-plugin, vidocq-runtime-core and the SPI, and details the extension grammar.
Boot sequence diagram
Phases 4 and 5 run in distinct virtual threads via StructuredTaskScope, allowing Cassini to register its routes while Mansart validates the database connection.
Extension mechanism
Public SPI
The vidocq-runtime-spi module exposes the contribution interfaces. The main classes shipped today:
| Type | Role |
|---|---|
|
Marker interface declared via |
|
Contribution API — access to the |
|
Interface read at build time to resolve the extension’s options. |
|
Re-exposed |
Source: vidocq-runtime-spi/src/main/java/io/vidocq/runtime/spi/.
APT processor
The vidocq-runtime-processor (derived from vauban-processor) scans classes annotated @BuildStep, @Recorder, @Path, @ApplicationScoped, etc. It produces:
-
an index
META-INF/vidocq/extensions.list(one line per extension class); -
an index
META-INF/vauban/beans.list(reused by Vauban); -
the configuration option file consumed by recorders.
No runtime reflection — the index is read at startup with a plain getResourceAsStream.
Class-File API generation
When a build step calls a method on a @Recorder, the engine does not execute the call: it records it. At the end of the graph, vidocq-runtime-core synthesises a RuntimeBootstrap class via Class-File API (JEP 484). That class contains a sequence of invokevirtual instructions which, replayed at startup, reproduce the desired effect with no reflection.
Concretely:
@Recorder
public class HttpRecorder {
public RuntimeValue<Server> startServer(int port) { ... }
}
@BuildStep
@Record(RUNTIME_INIT)
public ServerStartedBuildItem boot(HttpRecorder rec, HttpConfig cfg) {
rec.startServer(cfg.port()); // <-- recorded
return new ServerStartedBuildItem();
}
At compile time, vidocq-runtime-core emits:
// generated class — pseudo-code
class RuntimeBootstrap_HttpRecorder {
static void __runtimeInit() {
new HttpRecorder().startServer(8080); // <-- replayed
}
}
Threading model
-
Bootstrap — a single platform thread, no pool. Boot is intentionally sequential to ease diagnosis.
-
HTTP I/O —
Executors.newVirtualThreadPerTaskExecutor()on the Chappe side. One connection = one virtual thread. No reactor, no callbacks. -
Persistence — JDBC pool from Mansart with non-fair
Semaphore.ScopedValue<Connection>propagates the current connection inside a transaction withoutThreadLocal. -
Periodic health checks — virtual threads scheduled via
StructuredTaskScope.
No platform thread pool is created by default. The rule is documented in the workspace root CLAUDE.md.
Recommended reading
-
Source:
vidocq-runtime-core/src/main/java/io/vidocq/runtime/core/(boot orchestrator) -
SPI:
vidocq-runtime-spi/src/main/java/io/vidocq/runtime/spi/ -
Maven plugin:
vidocq-runtime-maven-plugin/ -
Examples:
vidocq-runtime-examples/vidocq-runtime-cassini-rest-example/,vidocq-runtime-mansart-h2-example/
Next steps
-
Concepts — formal vocabulary
-
TCK status — conformance verification
-
vidocq-runtime-core — boot, lifecycle