--- phase: 02-transaction-search-diagrams plan: 04 type: execute wave: 1 depends_on: ["02-01", "02-02", "02-03"] files_modified: - cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java - cameleer-server-app/pom.xml - cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java autonomous: true gap_closure: true requirements: ["DIAG-02"] must_haves: truths: - "Each transaction links to the RouteGraph version that was active at execution time" - "Full test suite passes with mvn clean verify (no classloader failures)" artifacts: - path: "cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java" provides: "Diagram hash lookup during batch insert" contains: "findContentHashForRoute" - path: "cameleer-server-app/pom.xml" provides: "Surefire fork configuration isolating ELK classloader" contains: "reuseForks" - path: "cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java" provides: "Integration test proving diagram hash is stored during ingestion" key_links: - from: "ClickHouseExecutionRepository" to: "DiagramRepository" via: "constructor injection, findContentHashForRoute call in insertBatch" pattern: "diagramRepository\\.findContentHashForRoute" --- 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` @C:/Users/Hendrik/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/Hendrik/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/02-transaction-search-diagrams/02-VERIFICATION.md Prior plan summaries (needed — touches same files): @.planning/phases/02-transaction-search-diagrams/02-01-SUMMARY.md @.planning/phases/02-transaction-search-diagrams/02-03-SUMMARY.md From cameleer-server-core/.../storage/DiagramRepository.java: ```java Optional findContentHashForRoute(String routeId, String agentId); ``` From cameleer-server-app/.../storage/ClickHouseExecutionRepository.java (line 141): ```java ps.setString(col++, ""); // diagram_content_hash (wired later) ``` The class is @Repository annotated, constructor takes JdbcTemplate only. It needs DiagramRepository injected to perform the lookup. From cameleer-server-app/.../storage/ClickHouseDiagramRepository.java: ```java @Repository public class ClickHouseDiagramRepository implements DiagramRepository { public Optional findContentHashForRoute(String routeId, String agentId) { ... } } ``` Task 1: Populate diagram_content_hash during ingestion and fix Surefire forks cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java, cameleer-server-app/pom.xml, cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java - 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) **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: ```java ps.setString(col++, ""); // diagram_content_hash (wired later) ``` with a lookup: ```java String diagramHash = diagramRepository .findContentHashForRoute(exec.getRouteId(), exec.getAgentId()) .orElse(""); ps.setString(col++, diagramHash); // diagram_content_hash ``` 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. **Gap 2 — Surefire classloader isolation:** 5. In `cameleer-server-app/pom.xml`, add a `` section (after the existing `spring-boot-maven-plugin`) with `maven-surefire-plugin` configuration: ```xml org.apache.maven.plugins maven-surefire-plugin 1 false ``` 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. cd C:/Users/Hendrik/Documents/projects/cameleer-server && mvn clean verify -pl cameleer-server-app -am 2>&1 | tail -30 - diagram_content_hash is populated with the active diagram's SHA-256 hash during ingestion (not empty string) - DiagramLinkingIT passes with both positive and negative cases - `mvn clean verify` passes for cameleer-server-app (no classloader failures from ElkDiagramRendererTest) 1. `mvn clean verify` passes end-to-end (no test failures) 2. DiagramLinkingIT confirms diagram hash is stored during execution ingestion 3. All existing tests still pass (search, detail, diagram render) - DIAG-02 fully satisfied: transactions link to their active RouteGraph version via diagram_content_hash - `mvn clean verify` is green (all ~40+ tests pass without classloader errors) - No regression in existing search, detail, or diagram functionality After completion, create `.planning/phases/02-transaction-search-diagrams/02-04-SUMMARY.md`