Skip to content

plan: PR-H1 — FEIGN_CLIENT role to CLIENT + HTTP_CLIENT capability#33

Merged
HumanBean17 merged 1 commit into
masterfrom
cursor/pr-h1-client-role-rename
May 6, 2026
Merged

plan: PR-H1 — FEIGN_CLIENT role to CLIENT + HTTP_CLIENT capability#33
HumanBean17 merged 1 commit into
masterfrom
cursor/pr-h1-client-role-rename

Conversation

@HumanBean17
Copy link
Copy Markdown
Owner

Summary

  • implement PR-H1 from plans/PLAN-CLIENT-ROLE-RENAME.md: rename role literal FEIGN_CLIENT to CLIENT across inference, flow stages, entry roles, ranking weights, and MCP tool descriptions
  • add HTTP_CLIENT capability auto-detection for @FeignClient, bump ONTOLOGY_VERSION to 9, and update README/CODEBASE_REQUIREMENTS for the new vocabulary and reindex requirement
  • add focused regression coverage in tests/test_client_role_rename.py (9 tests) and update the trace-flow e2e role allowlist

Test plan

  • pytest tests/test_client_role_rename.py -q
  • pytest tests/test_kuzu_queries.py -k "trace_flow or list_by_role_controller" -q
  • pytest tests/test_lancedb_e2e.py -q (heavy-gated; skipped in default env)
  • ruff check ast_java.py kuzu_queries.py search_lancedb.py server.py tests/test_client_role_rename.py tests/test_lancedb_e2e.py

Made with Cursor

Switch Feign role inference and flow/ranking role literals to CLIENT, add HTTP_CLIENT capability detection for @FeignClient, and update docs/tool enums to reflect ontology version 9 vocabulary. Add focused rename regression coverage for graph role/capability behavior and brownfield warn-and-drop/acceptance paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
@HumanBean17
Copy link
Copy Markdown
Owner Author

Review: PR-H1 — FEIGN_CLIENT role → CLIENT + HTTP_CLIENT capability

Verdict: Approved ✅

Clean implementation of plans/PLAN-CLIENT-ROLE-RENAME.md. Hard rename lands in exactly the surface area the plan called out, ontology bumps 8 → 9, all 9 enumerated tests pass, full suite at the target count of 290 passed, 4 skipped (281 baseline + 9). Scope discipline is tight — no async work, no schema column changes, no new MCP tools, no deprecation alias. Manual evidence reproduces against cross_service_smoke end-to-end including the brownfield warn-and-drop path.

Scope discipline (out-of-scope checks)

Sentinel Status
MESSAGE_PRODUCER (20 hits) ✅ docstring/enum-list updates adding HTTP_CLIENT to capability lists + 1 regression test #7 — no async logic touched
RestTemplate / WebClient (3 each) ✅ README/CODEBASE_REQUIREMENTS doc-only — no code change, no auto-promotion
RegisterRestClient (2 hits) ✅ in CODEBASE_REQUIREMENTS.md doc snippet only (matches the role table format users see); not a Python code change
@mcp.tool ✅ 0 matches — no new MCP tools registered
CREATE NODE TABLE / CREATE REL TABLE / DROP TABLE ✅ 0 matches — no schema column changes
_SCHEMA_META / _META_PR_* ✅ 0 matches — no new tier in the meta() query chain (correctly out of scope per plan)
alias ✅ 0 matches — no backwards-compat alias (correct, breaking change explicitly allowed)
FEIGN_CLIENT literals in production code ✅ 0 (only an intentional phase-7 comment at ast_java.py:74 documenting the rename)

Plan compliance (Definition of Done)

# Step from plan Verified
1 ROLE_ANNOTATIONS["FeignClient"]"CLIENT" ast_java.py:92
2 _TYPE_ANN_TO_CAPABILITY["FeignClient"] = "HTTP_CLIENT" ast_java.py:116
3 _FLOW_STAGES[2], _ENTRYPOINT_ROLES, trace_flow docstring kuzu_queries.py:997, 1006
4 _ROLE_SCORE_WEIGHTS["CLIENT"] = 0.06 search_lancedb.py:188
5 Six server.py literal references ✅ all updated, including entry_roles default at server.py:1418
6 README.md (3 lines + brownfield note)
7 CODEBASE_REQUIREMENTS.md (146, 162, 346-347)
8 tests/test_lancedb_e2e.py:342 allow-list ✅ now {"CONTROLLER", "COMPONENT", "SERVICE", "CLIENT"}
9 ONTOLOGY_VERSION 8 → 9 ast_java.py:117
10 All 9 new tests in test_client_role_rename.py ✅ all 9 named per plan, all pass

Tests

290 passed, 4 skipped in 103.42s

Matches the plan target of 281 + 9 = 290 passed, 4 skipped exactly. No regressions in test_kuzu_queries, test_lancedb_e2e, or any of the previously-green files.

Manual evidence reproduced

Build against tests/fixtures/cross_service_smoke:

CLIENT symbols: ['smoke.a.BFeignClient']
legacy FEIGN_CLIENT count: 0
HTTP_CLIENT symbols: ['smoke.a.BFeignClient']
ontology_version: 9

✅ matches plan expected output exactly.

Brownfield warn-and-drop (test #4 path), with the correct nested YAML shape role_overrides.fqn.<fqn>.role:

[lancedb-mcp] role_overrides.annotations: unknown role 'FEIGN_CLIENT' for 'FeignClient' — dropped
[lancedb-mcp] role_overrides.fqn: unknown role 'FEIGN_CLIENT' for 'smoke.a.BFeignClient' — dropped
BFeignClient role: ['CLIENT']
legacy FEIGN_CLIENT count: 0

✅ override silently dropped (warn-and-drop, not exception), role lands on the auto-detected CLIENT. Plan delta from propose §5.3 is correctly encoded in the test.

Determinism: built twice into /tmp/det_a and /tmp/det_b, sorted (fqn, role, capabilities) tuples for CLIENT symbols are identical.

Notes that earned my trust

  • Plan delta on test Add per-PR Cursor task prompts for Tier 1 completion #4 honoured. Asserts stderr "unknown role" substring + role-stays-CLIENT, matching graph_enrich.py:443-447, 481-486 reality, not the propose's raise ValueError example. This is exactly the alignment the plan promised.
  • Single source-of-truth flips. The two-line change at ast_java.py:92 (role) and ast_java.py:116 (capability) propagates correctly through the auto-derived VALID_ROLES / VALID_CAPABILITIES — no java_ontology.py edit was needed, and none was made.
  • Entry-roles list rewritten in two places consistently. kuzu_queries.py:1006 (the _ENTRYPOINT_ROLES constant) and server.py:1418 (the MCP tool's entry_roles default) both now have "CLIENT" instead of "FEIGN_CLIENT" — easy to miss one or the other, both got it.
  • Phase-7 comment at ast_java.py:74 documents the rename inline next to the ontology bump — future-archeology friendly.
  • No _SCHEMA_META / meta() tiered chain extension. The plan correctly identified that Symbol.role is a STRING column and the new literal needs no schema migration; the diff confirms no tier was added.

Observations (non-blocking)

  1. Plan's manual-evidence snippet uses an outdated r['symbol'] indexing pattern. The plan at lines 285-288 shows [r['symbol'] for r in g.list_by_role(...)], but KuzuGraph.list_by_role actually returns SymbolHit dataclass instances accessed via h.fqn / h.role etc. Cosmetic; doesn't affect anything that ships, but worth fixing in the plan if anyone later runs the snippet verbatim. Not a blocker — the test suite uses the correct API.
  2. RegisterRestClient MicroProfile entry in CODEBASE_REQUIREMENTS.md doc snippet got upgraded to CLIENT as a side effect of updating the sample role table. This is fine (the doc literal needed updating) but be aware: there's no actual RegisterRestClient annotation handler in ast_java.py yet — that's still followup Add Cursor rules and agent settings for CLI agents #3. Doc snippet is now slightly aspirational. Worth adding a parenthetical "(see followup Add Cursor rules and agent settings for CLI agents #3 for actual support)" in a future doc pass.
  3. exposes_suppressed_feign=1 still appears in the build summary — this is correct (PR-F1 behaviour), but the metric name keeps the legacy feign token. Out of scope here; could rename to exposes_suppressed_client in a future cleanup PR if you want full vocabulary alignment.

Plan deltas needed

None. The implementation matches the plan as written, including the warn-and-drop semantics for test #4. (Optional: tweak the plan's manual-evidence snippet to use h.fqn instead of r['symbol'] as noted in observation #1.)


Ready to merge. Next: H1 implementation is complete — when you're ready, the queue items are PR-H1 doc-snippet polish (observations #1, #2 above, optional) and the followups captured in the plan (real-codebase honesty audit, capability-weighted search, @RegisterRestClient actual support, multi-attribution PR #24).

@HumanBean17 HumanBean17 merged commit d62b48c into master May 6, 2026
HumanBean17 added a commit that referenced this pull request May 6, 2026
* chore: tidy completed plans/proposes and refresh stale docs

Move completed plans to plans/completed/:
- PLAN-CLIENT-ROLE-RENAME.md (PR #33 merged)
- PLAN-CROSS-SERVICE-RESOLUTION-FLAG.md (PR #30 merged)
- PLAN-FEIGN-NOT-AN-EXPOSER.md (PR #31 merged)

Move completed proposes to propose/completed/:
- CLIENT-ROLE-RENAME-PROPOSE.md (PR #28 merged)
- CROSS-SERVICE-RESOLUTION-FLAG-PROPOSE.md (PR #26 merged)
- FEIGN-NOT-AN-EXPOSER-PROPOSE.md (PR #25 merged)

Refresh active docs:
- README.md "Deferred" section: trace_request_flow, find_route_callers,
  HTTP_CALLS/ASYNC_CALLS are shipped (not deferred). Add explicit pointers
  to the still-active TIER2-INCREMENTAL-REBUILD and REFRESH-CODE-INDEX-AUTO-MODE
  proposes for the incremental Kuzu work.
- CODEBASE_REQUIREMENTS.md A.3: drop the stale 'ontology version 3' literal
  (now 9) and fix references to PLAN-CAPABILITIES-MODEL and CALL-GRAPH-PROPOSE
  to use their completed/ paths. Tense matches reality (call-graph layer is
  shipped, not deferred).
- CODEBASE_REQUIREMENTS.md B.9: same fix for the propose/DEFERRED-CALL-GRAPH-PROPOSE.md
  reference; the propose lives under propose/completed/CALL-GRAPH-PROPOSE.md.

No code changes. Test baseline unchanged: 290 passed, 4 skipped.

* docs: add inline Java stubs for @CodebaseRoute / @CodebaseClient / @CodebaseProducer

Per pushback on PR #34: the route, client, and producer brownfield
annotations were mentioned 4x in README + CODEBASE_REQUIREMENTS but
their @interface stubs were never shown inline. Users had to spelunk
through tests/fixtures/ to know what to copy into their project.

README §5 'Brownfield overrides — Last resort — source stubs' now has
three explicit subsections:

  - 3a. Roles & capabilities — @CodebaseRole / @CodebaseCapability
        / @CodebaseCapabilities (class-level), with usage example.
  - 3b. Routes — @CodebaseRoute / @CodebaseRoutes +
        CodebaseRouteFrameworkKind / CodebaseRouteKind (method-level),
        with HTTP-endpoint and Kafka-consumer usage examples.
  - 3c. Clients & producers — @CodebaseClient / @CodebaseClients and
        @CodebaseProducer / @CodebaseProducers (method-level), with
        rest_template + kafka_send usage examples.

Stub Java in the doc matches the verbatim sources under
tests/fixtures/brownfield_route_stubs/ and brownfield_client_stubs/
(also referenced for copy-paste). Enum values mirror VALID_ROUTE_*
and VALID_CLIENT_KINDS in java_ontology.py.

CODEBASE_REQUIREMENTS.md A.2.1 updated to enumerate all three
annotation families (roles, routes, clients/producers) and link to
the matching README sections instead of only mentioning role stubs.

No code change. Test baseline unchanged: 290 passed, 4 skipped.
@HumanBean17 HumanBean17 deleted the cursor/pr-h1-client-role-rename branch May 10, 2026 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant