From e1bade8e8312a15eebfd5282efc48e419ee87bea Mon Sep 17 00:00:00 2001 From: Dmitry Teryaev Date: Sun, 31 May 2026 18:38:11 +0300 Subject: [PATCH 1/2] fix(ontology): assign CLIENT role to message producer types (#253) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Types injecting KafkaTemplate, RabbitTemplate, JmsTemplate, StreamBridge, or ApplicationEventPublisher now get CLIENT role (symmetry with CONTROLLER covering both HTTP and messaging inbound). Previously these fell through to OTHER despite having MESSAGE_PRODUCER capability. Ontology bumped 15 → 16; re-index required. Co-Authored-By: Claude Opus 4.7 --- agents/java-codebase-rag-explorer.md | 4 ++-- ast_java.py | 20 +++++++++++++++++++- docs/AGENT-GUIDE.md | 4 ++-- skills/explore-codebase/SKILL.md | 4 ++-- tests/test_client_role_rename.py | 6 ++++-- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/agents/java-codebase-rag-explorer.md b/agents/java-codebase-rag-explorer.md index 75da2a6d..02683864 100644 --- a/agents/java-codebase-rag-explorer.md +++ b/agents/java-codebase-rag-explorer.md @@ -17,7 +17,7 @@ You are a codebase navigation specialist powered by the java-codebase-rag MCP. Java production sources plus SQL and YAML (use `search` `table`: `java`, `sql`, `yaml`, or `all`). -## Ontology: 15 +## Ontology: 16 If results look structurally wrong or empty across tools, the index may be missing, stale, or built with a different `ontology_version`; you cannot re-index via MCP — ask the operator to rebuild. @@ -243,7 +243,7 @@ Returns **edges** with `attrs` (`confidence`, `strategy`, `match`, … on cross- | `COMPONENT` | General Spring component | | `CONFIG` | `@Configuration` class | | `ENTITY` | JPA / persistence entity | -| `CLIENT` | Outbound HTTP call wrapper (Feign, RestTemplate, WebClient) | +| `CLIENT` | Outbound call wrapper (HTTP and messaging) | | `MAPPER` | Data mapper / converter | | `DTO` | Data transfer object — data carrier, no logic | | `OTHER` | Infrastructure / utility / framework / JDK / unclassified | diff --git a/ast_java.py b/ast_java.py index f82d688e..0626125e 100644 --- a/ast_java.py +++ b/ast_java.py @@ -83,7 +83,7 @@ # Phase 11: `EDGE_SCHEMA` in `java_ontology.py` (canonical edge navigation schema; v14 re-index). # Phase 12: CALLS `callee_declaring_role`, supertype-walk dedup, pass3 unresolved counters (v15 re-index). # Bumps whenever extraction / enrichment semantics change. -ONTOLOGY_VERSION = 15 +ONTOLOGY_VERSION = 16 ROLE_ANNOTATIONS: dict[str, str] = { # Spring Web @@ -2732,6 +2732,19 @@ def infer_role(annotation_names: Iterable[str]) -> str: return "OTHER" +def _type_injects_messaging(type_decl: "TypeDecl") -> bool: + """True when the type injects a messaging template via field or constructor.""" + for fld in type_decl.fields: + if fld.type_name in _INJECTED_TYPES_TO_CAPABILITY: + return True + for method in type_decl.methods: + if method.is_constructor: + for p in method.parameters: + if p.type_name in _INJECTED_TYPES_TO_CAPABILITY: + return True + return False + + def infer_role_for_type(type_decl: "TypeDecl") -> str: """Role inference that also detects DTO-like passive data carriers. @@ -2763,6 +2776,11 @@ def infer_role_for_type(type_decl: "TypeDecl") -> str: if name.endswith(suffix) and name != suffix: return "DTO" + # Types injecting messaging templates are outbound callers (CLIENT role), + # symmetric with CONTROLLER covering both HTTP and messaging inbound. + if _type_injects_messaging(type_decl): + return "CLIENT" + return "OTHER" diff --git a/docs/AGENT-GUIDE.md b/docs/AGENT-GUIDE.md index d1c421f4..4e214aa5 100644 --- a/docs/AGENT-GUIDE.md +++ b/docs/AGENT-GUIDE.md @@ -14,7 +14,7 @@ Copy the block between `