From 9db053ee594691c6ae61d8b62258e97f02a10513 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Wed, 11 Mar 2026 16:45:22 +0100 Subject: [PATCH] docs(02): create gap closure plan for DIAG-02 and Surefire fix Co-Authored-By: Claude Opus 4.6 --- .planning/ROADMAP.md | 5 +- .../02-04-PLAN.md | 159 ++++++++++++++++++ 2 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 .planning/phases/02-transaction-search-diagrams/02-04-PLAN.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 8b96d6ba..b6263051 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -45,12 +45,13 @@ Plans: 2. User can full-text search across message bodies, headers, error messages, and stack traces and find matching transactions 3. User can retrieve a transaction's detail view showing the nested processor execution tree 4. Route diagrams are stored with content-addressable versioning (identical definitions stored once), each transaction links to its active diagram version, and diagrams can be rendered from stored definitions -**Plans:** 1/3 plans executed +**Plans:** 4 plans (3 executed, 1 gap closure) Plans: - [ ] 02-01-PLAN.md -- Schema extension, core domain types, ingestion updates for search/detail columns - [ ] 02-02-PLAN.md -- Diagram rendering with ELK layout and JFreeSVG (SVG + JSON via content negotiation) - [ ] 02-03-PLAN.md -- Search endpoints (GET + POST), transaction detail with tree reconstruction, integration tests +- [ ] 02-04-PLAN.md -- Gap closure: populate diagram_content_hash during ingestion, fix Surefire classloader isolation ### Phase 3: Agent Registry + SSE Push **Goal**: Server tracks connected agents through their full lifecycle and can push configuration updates, deep-trace commands, and replay commands to specific agents in real time @@ -89,6 +90,6 @@ Note: Phases 2 and 3 both depend only on Phase 1 and could execute in parallel. | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| | 1. Ingestion Pipeline + API Foundation | 3/3 | Complete | 2026-03-11 | -| 2. Transaction Search + Diagrams | 1/3 | In Progress| | +| 2. Transaction Search + Diagrams | 3/4 | Gap Closure | | | 3. Agent Registry + SSE Push | 0/2 | Not started | - | | 4. Security | 0/1 | Not started | - | diff --git a/.planning/phases/02-transaction-search-diagrams/02-04-PLAN.md b/.planning/phases/02-transaction-search-diagrams/02-04-PLAN.md new file mode 100644 index 00000000..ed2b7dd6 --- /dev/null +++ b/.planning/phases/02-transaction-search-diagrams/02-04-PLAN.md @@ -0,0 +1,159 @@ +--- +phase: 02-transaction-search-diagrams +plan: 04 +type: execute +wave: 1 +depends_on: ["02-01", "02-02", "02-03"] +files_modified: + - cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java + - cameleer3-server-app/pom.xml + - cameleer3-server-app/src/test/java/com/cameleer3/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: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java" + provides: "Diagram hash lookup during batch insert" + contains: "findContentHashForRoute" + - path: "cameleer3-server-app/pom.xml" + provides: "Surefire fork configuration isolating ELK classloader" + contains: "reuseForks" + - path: "cameleer3-server-app/src/test/java/com/cameleer3/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 cameleer3-server-core/.../storage/DiagramRepository.java: +```java +Optional findContentHashForRoute(String routeId, String agentId); +``` + +From cameleer3-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 cameleer3-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 + + cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java, + cameleer3-server-app/pom.xml, + cameleer3-server-app/src/test/java/com/cameleer3/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 `cameleer3-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/cameleer3-server && mvn clean verify -pl cameleer3-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 cameleer3-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` +