fix(cross-repo): normalize URLs, match templates, run both directions#810
Merged
Conversation
Distills the pass_cross_repo.c half of #536; the pass_calls.c half landed separately as beaa776 (broader: covers the parallel path too). match_http_routes could not match a stored HTTP_CALLS url_path that was a full URL (scheme://host:port/path is stored raw from the call's first string argument), never matched a concrete client path against a templated route QN, and only ran consumer->provider, so a provider-side run found nothing - and worse, destroyed previously recorded links: delete_cross_edges wiped the provider's reverse edges and nothing recreated them. - cr_url_path(): strip scheme://host[:port] before route-QN construction; a bare base URL maps to the root route path. - cr_path_matches_template() + find_route_handler_fuzzy(): segment-wise fallback so /v2/orders/123 matches /v2/orders/{} (method-gated, only for edges the exact lookup missed; O(calls x routes) per project pair, bounded by CR_MAX_EDGES). - Reverse-direction match_http_routes run so provider-side invocations find the consumer's HTTP_CALLS and re-create the wiped reverse edges. Row dedup needs no insert guard: the edges table upserts on its (source_id, target_id, type) UNIQUE key. Four reproduce-first tests in tests/repro/repro_issue523.c (scheme-strip, template fuzzy match, provider-side run, bidirectional convergence), all red on the previous code, green with the fix. Refs #523 Co-authored-by: RithvikReddy0-0 <rithvikreddymukkara@gmail.com> Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The hardcoded-URL security audit flags http:// literals in src/; the comment only illustrates the shape of stored url_path values. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
DeusData
enabled auto-merge
July 3, 2026 22:38
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(cross-repo): normalize URLs, match templates, run both directions
Distills the still-valid half of #536 (thanks @RithvikReddy0-0 — co-credited on the commit).
Refs #523.
Summary
cbm_cross_repo_match/match_http_routeshad three matcher gaps that madecross-repo-intelligence report 0 edges for perfectly matching call/route pairs:
url_pathon HTTP_CALLS edges is stored raw from thecall's first string argument, so it can be
http://svc:8080/v2/orders.cbm_route_canon_pathonly canonicalizes placeholder syntax — it never stripsscheme/authority (verified at
src/pipeline/pass_route_nodes.c:59) — so the builtroute QN embedded the host and the exact lookup missed.
→ new
cr_url_path()stripsscheme://host[:port]first; a bare base URL maps tothe root path
/(consistent withurl_path()in pass_route_nodes.c)./v2/orders/123cannotexact-match
__route__GET__/v2/orders/{}.→ new
cr_path_matches_template()+find_route_handler_fuzzy(): segment-wisetemplate matching, method-gated (route method must equal the caller's or be
ANY),run only for edges the exact lookup missed, and only accepting Route nodes that
actually carry a HANDLES edge. Cost is O(calls × routes) per project pair
(documented in the code; calls are capped at
CR_MAX_EDGES).provider has no outbound HTTP_CALLS) — and worse, destroyed existing links:
delete_cross_edgeswiped the provider's reverse edges at the start of the run andnothing recreated them.
→ the pass now also runs
match_http_routes(tgt→src). The two directions scandisjoint HTTP_CALLS sets (a caller edge lives in exactly one DB), so no pair is
double-counted.
Taken / dropped / corrected from #536
src/pipeline/pass_calls.chunk (emit HTTP_CALLS for unindexed client libs)cr_url_path()scheme/host stripping/for a bare base URL (PR returned the unstripped URL, a silent never-match) — consistent with the existingurl_path()helper in pass_route_nodes.c.cr_path_matches_template()+find_route_handler_fuzzy()LIKE '__route__%'SQL prefilter (_is a SQL wildcard, so it was a misleading no-op next to the label filter +strncmpprefix guard); magic numbers replaced with named enum constants.match_http_routesruninsert_cross_edge(pre-insert SELECT + inserted-flag counting)UNIQUE(source_id, target_id, type)andcbm_store_insert_edgeupserts on conflict — duplicate rows are impossible; the guard was a redundant query per insert. Its "rows actually added" count semantics would also make a provider-side re-run reporthttp_edges=0for an already-recorded link — the exact symptom #523 complains about. Counting stays "matches found" (stable across directions and re-runs); the convergence test pins row uniqueness.Tests (reproduce-first,
tests/repro/repro_issue523.c)All four were RED on the unfixed tree (verified by reverting
src/pipeline/pass_cross_repo.cand re-running) and are GREEN with the fix:repro_issue523_scheme_stripped_url_matchhttp://order-api.internal:8080/v2/orders, server route/v2/ordershttp_edges (0) not >= 1repro_issue523_template_fuzzy_match/v2/orders/123, server route/v2/orders/{order_id}http_edges (0) not >= 1repro_issue523_reverse_direction_matchcbm_cross_repo_match(server, [client])http_edges (0) not >= 1repro_issue523_idempotent_cross_edgesserver_2 == 0, expected 1(provider-side run destroyed the link)The pre-existing
repro_issue523_crossrepo_http_calls_edge(pass_calls half, fixed by beaa776) stays green.Verification
make -f Makefile.cbm cbm—-Werrorcleanmake -f Makefile.cbm lint-ci— cppcheck + clang-format + NOLINT check passCBM_REPRO_ONLY=repro_issue523 ./build/c/test-repro-runner— 5 passed, 0 failed./build/c/test-runner— 5765 passed, 0 failedRefs #523