feat: B2b brownfield client/producer overrides (PR-D2)#13
Conversation
Mirror route-side brownfield layering for caller-side outgoing calls and apply the per-method replacement rule so brownfield assertions replace builtin client/producer edges instead of double-counting single call sites. Co-authored-by: Cursor <cursoragent@cursor.com>
Drop unused imports flagged by F401 so the repository passes ruff checks without changing runtime behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
Review: PR-D2 — B2b brownfield client/producer overridesVerdict: Approved ✅ PR-D2 lands cleanly: the 5-layer composition mirrors Scope discipline (out-of-scope checks)
Plan compliance
Caller-side option-(b) divergence — verificationImplementation at return brownfield_calls if brownfield_calls else builtin_http # http
return brownfield_calls if brownfield_calls else builtin_async # asyncLock-in tests are surgical:
Risk #5 citation (mandatory)PR description cites TestsMaster baseline: 233 collected. PR-D2 branch: 247 collected → +14 tests, exact match to plan §4 (12 PR-A3-parity cases + 31a + 31b). Manual evidence reproducedWith sample override injected into http_client_overrides:
annotations:
"org.springframework.stereotype.Component":
client_kind: rest_template
target_service: chat-coreBuild output: Meta: ✅ Identical to PR description claims. The Notes that earned my trust
Observations (non-blocking)
Plan deltas neededNone for the plan itself. Two minor doc-only follow-ups to consider after PR-D3 lands:
Ready to merge. Next: PR-D3 — |
…-E2 plan (#16) Catches from PR-D1, PR-D2, PR-D3 reviews that were intentionally deferred until Tier 1B landed are gathered into one document to prevent them from getting lost across review threads. PR-E1 (small, 1-day): risk_score [0,1] re-normalisation, VALID_HTTP_CALL_MATCHES rename, two inline comments, two doc fixes. PR-E2 (refactor): consolidate the second three-strategy ladder in graph_enrich.py:720-724 onto the canonical resolver. Refs: - PR-D1 #12 obs 2 (strategy-ladder duplicate) - PR-D2 #13 post-D3 follow-ups (anchor-fills-from-builtin doc, channel field) - PR-D3 #15 obs 1-3, 5 (risk-score contract, VALID_HTTP_CALL_MATCHES rename, two reader comments)
Summary
BrownfieldOverrides(no parallel override structures), addingHttpClientHint/AsyncProducerHint, parsinghttp_client_overrides+async_producer_overrides, and wiringresolve_http_client_for_method/resolve_async_producer_for_methodintopass5_imperative_edges.@CodebaseClient/@CodebaseProducer(including repeatable containers) and new graph meta countershttp_clients_from_brownfield_pct/async_producers_from_brownfield_pct.tests/test_brownfield_clients.py, cases 20–31 + 31a + 31b) covering all PR-D2 layering and the per-method replacement boundary.Mandatory Layering Evidence (risk #5)
resolve_http_client_for_methodmirrors the canonical resolver execution-order guidance fromPLAN-BROWNFIELD-ROLE-OVERRIDES-design-fixes.md:Applied to caller-side layers exactly as PR-D2 requires:
@CodebaseClient/@CodebaseProducer)Caller-side divergence (intentional)
Unlike B2a route composition, caller-side composition replaces built-in outgoing calls for a method when layers 2-5 emit at least one brownfield outgoing call for that same method. This avoids double-counting a single network/producer call site. Per-method scope is locked by tests
27,31a,31b.Test Plan
python3 -m pytest tests/test_brownfield_clients.py -qpython3 -m pytest tests -q(243 passed, 4 skipped)class BrownfieldClientOverrides|class BrownfieldProducerOverridesin*.py: no matchesannotation_to_http_client_hint|fqn_to_http_client_hintreferences ingraph_enrich.py: 5 (>= 4)Manual Evidence
Sample override injected into fixture root (
tests/bank-chat-system/.lancedb-mcp.yml) for verification only and reverted before PR:Build command:
python3 build_ast_graph.py --source-root tests/bank-chat-system --kuzu-path /tmp/check_d2 --verboseObserved tail:
[pass5] HTTP_CALLS: 41 edges, ASYNC_CALLS: 5 edges; ... http_by_strategy={'layer_b_ann': 41}, async_by_strategy={'kafka_template': 5}Meta check:
http_clients_from_brownfield_pct=100.0async_producers_from_brownfield_pct=0.0Made with Cursor