feat(schema): HTTP_CALLS originates from Client, not Symbol#158
Conversation
Emit HTTP_CALLS from Client nodes in pass5/6 and DDL; replace CallerInfo with RouteCaller in kuzu_queries (find_route_callers, trace_request_flow, impact expansion); two-hop HTTP in pr_analysis; update docs and PR-B tests. Co-authored-by: Cursor <cursoragent@cursor.com>
HumanBean17
left a comment
There was a problem hiding this comment.
Critical review (PR-B / SCHEMA-V2)
Verdict: Request changes on one item; the core HTTP flip looks correct.
What’s solid
- Builder: DDL
FROM Client TO Route,HttpCallRow.client_id, dedup(cid, rid), write Cypher, pass6 viaclients_by_id→member_id— internally consistent. Pass5 already pairsClient+DECLARES_CLIENTbefore HTTP edges. - Ontology + docs:
EDGE_SCHEMA,EDGE-NAVIGATION.md, README re-index callout, agent guides — post-flip two-hop pattern is aligned. - Kuzu: Splitting
HTTP_CALLS|ASYNC_CALLSunions into separate HTTP (three-hop) vs async (Symbol→Route) queries avoids binder pitfalls. RouteCallerHTTP branch: Correctcaller_node_id= Client,declaring_symbol_idback-ref,target_service/raw_uri.- Scope: No second ontology bump, no Producer/ASYNC flip,
CallerInfofully removed from Python.
Must fix
Async callers labeled caller_node_kind="client"
In find_route_callers and trace_request_flow, async still traverses Symbol-[ASYNC_CALLS]->Route, but both set caller_node_kind="client" (and trace_request_flow uses 'client' AS caller_node_kind while caller is a Symbol).
That breaks the PR-B contract (“return the caller-side node”) and will mislead consumers until PR-C.
Suggested fix (pick one for this PR):
- Do not emit async rows in
RouteCaller/ inbound trace until PR-C wires Producer, or - Document an interim shape clearly — but do not label Symbol-backed async callers as
"client".
PR-C should own caller_node_kind="producer"; PR-B should not lie with "client".
Should fix / plan gaps
-
Impact-analysis expansion — Plan Decision 24 / PR-B DoD:
trace_flowcross-service HTTP should surface bridging Client id. Cypher is three-hop butRETURNis still only handlern. Considerc.id AS caller_client_idinRETURN, or call out deferral to PR-C in the PR body. -
test_pr_analysis_changed_methods_finds_routes_via_declares_client— Only asserts the graph has cross-service HTTP edges; never runscompute_riskor the updatedpr_analysis.pyqueries. UC9 is still mostly mocked. A small integration test oncross_service_callers_countwould help. -
mcp_v2.py/server.pyuntouched — Fine if v2 no longer exposesfind_route_callers; worth a one-liner in the PR. Note:neighbors(route, in, ["HTTP_CALLS"])now returns Client ids;test_neighbors_route_in_http_calls_returns_callersstill mocks a Symbol caller (pre-flip mental model).
Behavioral notes (non-blocking)
pr_analysis: HTTP leg now counts Client ids, not declaring symbols — UC5-correct but changes risk-score semantics vs pre-flip; worth documenting.test_call_edges_method_two_http_clients_two_routes: Asserts distinct clients, not distinct routes — name is slightly misleading.- Re-index: Required; old
Symbol→RouteHTTP_CALLS graphs will break until full reprocess.
PR-B DoD snapshot
| Item | Status |
|---|---|
No Symbol-[HTTP_CALLS]->Route in production Python |
✅ |
CallerInfo → RouteCaller |
caller_node_kind wrong |
| Named PR-B tests | Mostly ✅; UC9 integration thin |
| HTTP doc sweep + EDGE-NAVIGATION | ✅ |
| Impact expansion surfaces caller node id | ❌ |
mcp_v2/server alignment |
N/A (note in PR) |
Happy to re-review after the async caller_node_kind fix.
Stop labeling Symbol-backed async callers as client in find_route_callers and trace_request_flow; surface caller_client_id on trace_flow HTTP hops; strengthen UC9 test via compute_risk; fix neighbors mock for Client callers. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
HTTP_CALLSto Client → Route inEDGE_SCHEMA, Kuzu DDL, pass5/6 emission (HttpCallRow.client_id), and graph write Cypher.CallerInfowithRouteCallerinkuzu_queries.py; reshapesfind_route_callers,trace_request_flowinbound (HTTP two-hop), and impact-analysis HTTP expansion (three-hop viaDECLARES_CLIENT).pr_analysis.py: cross-service route reachability usesDECLARES_CLIENT+HTTP_CALLS(async leg unchanged until PR-C).README.md,docs/AGENT-GUIDE.md,docs/skills/java-codebase-explore.md; regenerateddocs/EDGE-NAVIGATION.md.plans/PLAN-SCHEMA-V2.mdadded/updated (verbatim names).Re-index
Graphs built before this PR need a full
java-codebase-rag reprocess(ontology still 14; no second bump).grep -rn 'HTTP_CALLS' --include='*.py' --include='*.md' .accountingProduction / shipped (updated in this PR):
java_ontology.pyEDGE_SCHEMA["HTTP_CALLS"]src=Client, post-fliptypical_traversalsbuild_ast_graph.pyFROM Client TO Route;_CREATE_HTTP_CALLfrom Client;HttpCallRow.client_id; pass6 resolves viaclients_by_idkuzu_queries.pyRouteCaller; two-hopfind_route_callers/ inboundtrace_request_flow; impact HTTP three-hoppr_analysis.pymcp_v2.py,server.pyREADME.md,docs/AGENT-GUIDE.md,docs/skills/java-codebase-explore.md,docs/EDGE-NAVIGATION.md(generated)Tests (updated assertions to Client-anchored edges):
tests/test_call_edges_e2e.py,tests/test_kuzu_queries.py,tests/test_pr_analysis.py,tests/test_client_hint_recovery.py,tests/test_schema_consistency.py,tests/test_brownfield_clients.py,tests/test_mcp_v2.py,tests/test_mcp_hints.py,tests/test_mcp_v2_compose.py,tests/test_feign_not_exposer.py,tests/test_cross_service_resolution_flag.py.Unchanged / reference only:
ast_java.py(comment),CODEBASE_REQUIREMENTS.md,docs/MANUAL-VERIFICATION-CHECKLIST.md,docs/PROPOSES-ORDER.md,.cursor/skills/propose/examples.md,propose/**,plans/**(historical / forward-looking).Out of scope (confirmed)
Producer/DECLARES_PRODUCER/ASYNC_CALLSflip (PR-C)mcp_hints.py/ hints v3 (PR-D)Test plan
.venv/bin/ruff check ..venv/bin/python -m pytest tests/test_call_edges_e2e.py tests/test_kuzu_queries.py tests/test_pr_analysis.py tests/test_client_hint_recovery.py tests/test_schema_consistency.py tests/test_brownfield_clients.py tests/test_mcp_v2_compose.py::test_describe_client_edge_summary_includes_http_calls_out -v(83 passed).venv/bin/python scripts/generate_edge_navigation.py --check.venv/bin/python -m pytest tests -v(522 passed; 18 CLI tests fail locally — systemjava-codebase-ragnot installed in editable venv path)Made with Cursor