Context
Producer (and HTTP client) topics/destinations that reference a Java string constant — kafkaTemplate.send(ChatTopics.COMPLIANCE_REVIEW, …), restTemplate.exchange(Endpoints.X, …) — are indexed as the unresolved expression text ("ChatTopics.COMPLIANCE_REVIEW") instead of the constant's literal value ("banking.chat.compliance.review"). Any topic/endpoint-keyed lookup then misses them.
Concrete failure: jrag overview banking.chat.compliance.review returns the consumer (ComplianceReviewListener, whose @CodebaseAsyncRoute(topic="…") annotation supplies the literal) but not the producer (FollowUpKafkaPublisher#publishComplianceReview), because the producer's stored topic is ChatTopics.COMPLIANCE_REVIEW.
Why it was deferred
Surfaced while fixing test_overview_topic_lists_producers_and_consumers (red since PR-JRAG-4) on feat/cli. The id-free CLI branch patched the symptom by adding a brownfield @CodebaseProducer(topic="banking.chat.compliance.review") annotation to the one fixture producer (tests/bank-chat-system/.../FollowUpKafkaPublisher.java), mirroring the existing @CodebaseProducer on publishIncoming. The underlying engine gap remains.
Root cause
ast_java.py:1145 and :1273-1274 classify Class.FIELD string args as "constant_ref" (confidence 0.7, unresolved) and never look up the value.
public static final String field declarations are not indexed with their initializer value — ChatTopics constant fields do not appear as symbols at all (verified: only the class + constructor are indexed).
graph_enrich.py:821 also falls back to constant_ref for route-path hints.
- No constant-resolution infrastructure exists (no const-value capture, no
Class.FIELD → value map).
What is needed to implement
- Parser (
ast_java.py): capture literal initializer values for public static final String fields (extend the field-decl path).
- Builder (
build_ast_graph.py, pass4 producers/clients): build a {SimpleClass.FIELD → value} and {FQN.FIELD → value} map; resolve constant_ref topic/destination args through it before storing.
- Enrichment (
graph_enrich.py): apply the same resolution in the route-path canonical ladder (:814-821).
- Tests: add coverage in
tests/test_ast_*.py / test_bank_chat_brownfield_integration.py; once it lands, the @CodebaseProducer workaround on publishComplianceReview can stay (harmless) or be removed to exercise the resolution path.
Impact
Without it, producers/clients that reference topic/endpoint constants do not link to their topic/endpoint, so jrag overview <topic>, jrag topics, cross-service ASYNC_CALLS/HTTP_CALLS chains, and trace-request-flow miss them unless a brownfield annotation manually supplies the literal.
Workaround today
@CodebaseProducer(topic=…) / @CodebaseAsyncRoute(topic=…) brownfield annotations supply the resolved literal at index time (graph_enrich.py honors them).
Related
- Test:
tests/test_jrag_orientation.py:157 (test_overview_topic_lists_producers_and_consumers)
- Fixture producer:
tests/bank-chat-system/chat-core/chat-engine/src/main/java/com/bank/chat/engine/kafka/FollowUpKafkaPublisher.java
- Branch:
feat/cli
Context
Producer (and HTTP client) topics/destinations that reference a Java string constant —
kafkaTemplate.send(ChatTopics.COMPLIANCE_REVIEW, …),restTemplate.exchange(Endpoints.X, …)— are indexed as the unresolved expression text ("ChatTopics.COMPLIANCE_REVIEW") instead of the constant's literal value ("banking.chat.compliance.review"). Any topic/endpoint-keyed lookup then misses them.Concrete failure:
jrag overview banking.chat.compliance.reviewreturns the consumer (ComplianceReviewListener, whose@CodebaseAsyncRoute(topic="…")annotation supplies the literal) but not the producer (FollowUpKafkaPublisher#publishComplianceReview), because the producer's stored topic isChatTopics.COMPLIANCE_REVIEW.Why it was deferred
Surfaced while fixing
test_overview_topic_lists_producers_and_consumers(red since PR-JRAG-4) onfeat/cli. The id-free CLI branch patched the symptom by adding a brownfield@CodebaseProducer(topic="banking.chat.compliance.review")annotation to the one fixture producer (tests/bank-chat-system/.../FollowUpKafkaPublisher.java), mirroring the existing@CodebaseProduceronpublishIncoming. The underlying engine gap remains.Root cause
ast_java.py:1145and:1273-1274classifyClass.FIELDstring args as"constant_ref"(confidence 0.7, unresolved) and never look up the value.public static final Stringfield declarations are not indexed with their initializer value —ChatTopicsconstant fields do not appear as symbols at all (verified: only the class + constructor are indexed).graph_enrich.py:821also falls back toconstant_reffor route-path hints.Class.FIELD → valuemap).What is needed to implement
ast_java.py): capture literal initializer values forpublic static final Stringfields (extend the field-decl path).build_ast_graph.py, pass4 producers/clients): build a{SimpleClass.FIELD → value}and{FQN.FIELD → value}map; resolveconstant_reftopic/destination args through it before storing.graph_enrich.py): apply the same resolution in the route-path canonical ladder (:814-821).tests/test_ast_*.py/test_bank_chat_brownfield_integration.py; once it lands, the@CodebaseProducerworkaround onpublishComplianceReviewcan stay (harmless) or be removed to exercise the resolution path.Impact
Without it, producers/clients that reference topic/endpoint constants do not link to their topic/endpoint, so
jrag overview <topic>,jrag topics, cross-serviceASYNC_CALLS/HTTP_CALLSchains, andtrace-request-flowmiss them unless a brownfield annotation manually supplies the literal.Workaround today
@CodebaseProducer(topic=…)/@CodebaseAsyncRoute(topic=…)brownfield annotations supply the resolved literal at index time (graph_enrich.pyhonors them).Related
tests/test_jrag_orientation.py:157(test_overview_topic_lists_producers_and_consumers)tests/bank-chat-system/chat-core/chat-engine/src/main/java/com/bank/chat/engine/kafka/FollowUpKafkaPublisher.javafeat/cli