Close two verification gaps from Phase 2: (1) populate diagram_content_hash during ingestion instead of storing empty string, and (2) fix Surefire classloader conflict so `mvn clean verify` passes.
Purpose: DIAG-02 requirement is architecturally complete but never populated. The test suite breaks in CI due to ELK static init poisoning the shared JVM.
Output: Working diagram linking during ingestion + green `mvn clean verify`
- Test 1: When a RouteGraph is ingested before a RouteExecution for the same routeId+agentId, the execution's diagram_content_hash column contains the SHA-256 hash of the diagram (not empty string)
- Test 2: When no RouteGraph exists for a route, the execution's diagram_content_hash is stored as empty string (graceful fallback)
</behavior>
<action>
**Gap 1 — Diagram hash linking (DIAG-02):**
1. Modify `ClickHouseExecutionRepository` constructor to accept `DiagramRepository` as a second parameter alongside `JdbcTemplate`. The class is `@Repository` and both dependencies are Spring-managed beans, so constructor injection will autowire both.
2. In `insertBatch()`, inside the `BatchPreparedStatementSetter.setValues()` method, replace line 141:
Note: `findContentHashForRoute` returns the most recent content_hash for the route+agent pair from `route_diagrams` table (ORDER BY created_at DESC LIMIT 1). If no diagram exists yet, it returns empty Optional, and we fall back to empty string.
3. Performance consideration: The lookup happens per-execution in the batch. Since batches are flushed periodically (not per-request) and diagram lookups hit ClickHouse with a simple indexed query, this is acceptable. If profiling shows issues later, a per-batch cache of routeId+agentId -> hash can be added.
4. Create `DiagramLinkingIT` integration test extending `AbstractClickHouseIT`:
- Test 1: Insert a RouteGraph via `ClickHouseDiagramRepository.store()`, then insert a RouteExecution for the same routeId+agentId via `ClickHouseExecutionRepository.insertBatch()`, then query `SELECT diagram_content_hash FROM route_executions WHERE execution_id = ?` and assert it equals the expected SHA-256 hash.
- Test 2: Insert a RouteExecution without any prior RouteGraph for that route. Assert `diagram_content_hash` is empty string.
5. In `cameleer-server-app/pom.xml`, add a `<build><plugins>` section (after the existing `spring-boot-maven-plugin`) with `maven-surefire-plugin` configuration:
This forces Surefire to fork a fresh JVM for each test class, isolating ELK's static initializer (LayeredMetaDataProvider + xtext CollectionLiterals) from Spring Boot's classloader. Trade-off: slightly slower test execution, but correct results.