Skip to content

Commit dedc362

Browse files
authored
chore: tidy completed plans/proposes & refresh stale docs (#34)
* 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.
1 parent d62b48c commit dedc362

8 files changed

Lines changed: 195 additions & 27 deletions

CODEBASE_REQUIREMENTS.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,22 @@ Roles are assigned **first hit wins** from the type's annotations
171171
### A.2.1 Brownfield overrides (config + optional source annotations)
172172

173173
Without changing `ast_java` tables, you can adjust how types get `role`
174-
and `capabilities` for a given repo via `.lancedb-mcp.yml` at the
175-
project root (`role_overrides:`) and/or by copying the
176-
`@CodebaseRole` / `@CodebaseCapability` / `@CodebaseCapabilities`
177-
stubs from `README.md` into your sources. See **Brownfield overrides**
178-
in `README.md` for the full schema and execution order.
174+
and `capabilities`, register inbound routes, and register outbound
175+
clients/producers for a given repo via `.lancedb-mcp.yml` at the project
176+
root (`role_overrides:`, `route_overrides:`, `http_client_overrides:`,
177+
`async_producer_overrides:`) and/or by copying the in-source stubs from
178+
`README.md` into your sources:
179+
180+
- `@CodebaseRole` / `@CodebaseCapability` / `@CodebaseCapabilities`
181+
(class-level role + capabilities) — see README §3a.
182+
- `@CodebaseRoute` / `@CodebaseRoutes` + `CodebaseRouteFrameworkKind` /
183+
`CodebaseRouteKind` (method-level inbound routes) — see README §3b.
184+
- `@CodebaseClient` / `@CodebaseClients` and `@CodebaseProducer` /
185+
`@CodebaseProducers` (method-level outbound HTTP / messaging) — see
186+
README §3c.
187+
188+
See **Brownfield overrides** in `README.md` for the full schema, usage
189+
examples, and execution order.
179190

180191
**Layer A index sources:** Kuzu and Lance both use
181192
`graph_enrich.collect_annotation_meta_chain` (one disk walk: sorted
@@ -196,10 +207,11 @@ capabilities are not materialised on graph nodes).
196207

197208
Capabilities are derived at the **type level**: method-level annotation
198209
evidence is aggregated up to the enclosing type. Per-method capability
199-
storage is intentionally out of scope for the current ontology
200-
(version 3) — see `plans/PLAN-CAPABILITIES-MODEL.md`. The deferred
201-
call-graph layer (`propose/DEFERRED-CALL-GRAPH-PROPOSE.md`) is the
202-
designated place to revisit method-granularity if the need arises.
210+
storage is intentionally out of scope for the current ontology — see
211+
`plans/completed/PLAN-CAPABILITIES-MODEL.md` for the original design.
212+
The call-graph layer (`propose/completed/CALL-GRAPH-PROPOSE.md`,
213+
shipped) introduced method-level call edges; method-granularity
214+
capabilities can be revisited in a follow-up if the need arises.
203215

204216
Capabilities are independent of `role` — a `@Service` can simultaneously
205217
be a `MESSAGE_PRODUCER` and a `MESSAGE_LISTENER`, for example. The
@@ -550,9 +562,9 @@ This is a larger change; rough map:
550562
4. `server.py` — expose a new MCP tool (or extend `graph_neighbors` /
551563
`trace_flow` to recognise the new edge type).
552564

553-
See `propose/DEFERRED-CALL-GRAPH-PROPOSE.md` for the planned shape of
554-
CALLS / HTTP_CALLS / ASYNC_CALLS — your custom edge should follow the
555-
same conventions so a future merge is painless.
565+
See `propose/completed/CALL-GRAPH-PROPOSE.md` for the shipped shape of
566+
`CALLS` / `HTTP_CALLS` / `ASYNC_CALLS` — your custom edge should follow
567+
the same conventions.
556568

557569
---
558570

README.md

Lines changed: 171 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -320,18 +320,27 @@ Resolution order for each method mirrors role brownfield: built-in extraction,
320320
then annotation map, then meta-annotation closure (same `collect_annotation_meta_chain`
321321
index as roles — see `plans/completed/PLAN-BROWNFIELD-ROLE-OVERRIDES-design-fixes.md`),
322322
then in-source `@CodebaseRoute` / `@CodebaseRoutes`, then per-type FQN map
323-
(last writer wins on overlapping fields). Copy the `com.example.rag` stubs
324-
from `tests/fixtures/brownfield_route_stubs/` if you want `@CodebaseRoute`
325-
without adding a dependency.
323+
(last writer wins on overlapping fields). For the in-source form, copy the
324+
`@CodebaseRoute` / `@CodebaseRoutes` / `CodebaseRouteFrameworkKind` /
325+
`CodebaseRouteKind` stubs shown under **3. Last resort — source stubs**
326+
below into any package — no Maven dependency needed.
326327

327328
**2. Meta-annotation walk (automatic)** — `@interface` definitions in your
328329
source can carry meta-annotations; Layer A resolves chains to built-in
329330
stereotype and capability trigger names (e.g. `@Service`, `@KafkaListener`)
330331
via `graph_enrich.collect_annotation_meta_chain` (single index for both
331-
Kuzu and Lance — see below). **3. Last resort — source stubs** — copy the following
332-
into your project (any package) and add `@CodebaseRole(CodebaseRoleKind.SERVICE)` /
333-
`@CodebaseCapability(CodebaseCapabilityKind.MESSAGE_LISTENER)` on a class. Matched by **simple
334-
name only** (no Maven dependency on this bundle):
332+
Kuzu and Lance — see below).
333+
334+
**3. Last resort — source stubs** — copy the `@interface` definitions below
335+
into your project (any package) and annotate your classes/methods. All
336+
stubs are matched by **simple name only** (no Maven dependency on this
337+
bundle). The route and client/producer stubs also live verbatim under
338+
`tests/fixtures/brownfield_route_stubs/com/example/rag/` and
339+
`tests/fixtures/brownfield_client_stubs/com/example/rag/` for copy-pasting.
340+
341+
**3a. Roles & capabilities** — class-level. Apply
342+
`@CodebaseRole(CodebaseRoleKind.SERVICE)` /
343+
`@CodebaseCapability(CodebaseCapabilityKind.MESSAGE_LISTENER)` on a class:
335344

336345
```java
337346
package com.example.rag; // any package
@@ -366,10 +375,151 @@ public @interface CodebaseCapabilities {
366375
}
367376
```
368377

378+
Usage:
379+
380+
```java
381+
@CodebaseRole(CodebaseRoleKind.SERVICE)
382+
@CodebaseCapability(CodebaseCapabilityKind.MESSAGE_LISTENER)
383+
@CodebaseCapability(CodebaseCapabilityKind.MESSAGE_PRODUCER)
384+
public class LegacyChatService { /* ... */ }
385+
```
386+
369387
Legacy string-literal forms (`@CodebaseRole("SERVICE")`,
370388
`@CodebaseCapability("MESSAGE_LISTENER")`) are a breaking change and are no
371389
longer applied by the resolver.
372390

391+
**3b. Routes** — method-level. Apply `@CodebaseRoute` on the inbound entry
392+
point (HTTP handler, Kafka listener, JMS consumer, etc.) so route
393+
extraction (pass 4) can register it without recognising the framework:
394+
395+
```java
396+
package com.example.rag; // any package
397+
398+
import java.lang.annotation.*;
399+
400+
/** Mirrors VALID_ROUTE_FRAMEWORKS in java_ontology.py */
401+
public enum CodebaseRouteFrameworkKind {
402+
spring_mvc, webflux, feign, kafka, rabbitmq, jms, stream
403+
}
404+
405+
/** Mirrors VALID_ROUTE_KINDS in java_ontology.py */
406+
public enum CodebaseRouteKind {
407+
http_endpoint, http_consumer, kafka_topic, rabbit_queue, jms_destination, stream_binding
408+
}
409+
410+
@Target(ElementType.METHOD)
411+
@Retention(RetentionPolicy.SOURCE)
412+
@Repeatable(CodebaseRoutes.class)
413+
public @interface CodebaseRoute {
414+
CodebaseRouteFrameworkKind framework();
415+
CodebaseRouteKind kind();
416+
String path() default "";
417+
String method() default "";
418+
String topic() default "";
419+
String broker() default "";
420+
}
421+
422+
@Target(ElementType.METHOD)
423+
@Retention(RetentionPolicy.SOURCE)
424+
public @interface CodebaseRoutes {
425+
CodebaseRoute[] value();
426+
}
427+
```
428+
429+
Usage:
430+
431+
```java
432+
// HTTP endpoint on a legacy framework the built-in extractor doesn't know
433+
@CodebaseRoute(
434+
framework = CodebaseRouteFrameworkKind.spring_mvc,
435+
kind = CodebaseRouteKind.http_endpoint,
436+
path = "/chat/joinOperator",
437+
method = "POST")
438+
public Reply joinOperator(Request req) { /* ... */ }
439+
440+
// Kafka consumer
441+
@CodebaseRoute(
442+
framework = CodebaseRouteFrameworkKind.kafka,
443+
kind = CodebaseRouteKind.kafka_topic,
444+
topic = "chat.follow-up",
445+
broker = "chat-events")
446+
public void onFollowUp(Event e) { /* ... */ }
447+
```
448+
449+
`path` / `method` are required for HTTP kinds; `topic` (and optionally
450+
`broker`) for messaging kinds. Unknown enum values fall through Layer A /
451+
Layer B resolution unchanged. Repeat the annotation to register multiple
452+
routes against the same method — the compiler wraps them in
453+
`@CodebaseRoutes` automatically.
454+
455+
**3c. Clients & producers** — method-level. Apply `@CodebaseClient` on
456+
outbound HTTP call sites and `@CodebaseProducer` on outbound message-publish
457+
calls so caller-side resolution (pass 6) can register them. `clientKind` is
458+
a free-form string but should be one of `feign_method`, `rest_template`,
459+
`web_client`, `kafka_send`, `stream_bridge_send` (see `VALID_CLIENT_KINDS`
460+
in `java_ontology.py`); unknown values are dropped with a stderr warning.
461+
462+
```java
463+
package com.example.rag; // any package
464+
465+
import java.lang.annotation.*;
466+
467+
@Target(ElementType.METHOD)
468+
@Retention(RetentionPolicy.SOURCE)
469+
@Repeatable(CodebaseClients.class)
470+
public @interface CodebaseClient {
471+
String clientKind();
472+
String targetService() default "";
473+
String path() default "";
474+
String method() default "";
475+
}
476+
477+
@Target(ElementType.METHOD)
478+
@Retention(RetentionPolicy.SOURCE)
479+
public @interface CodebaseClients {
480+
CodebaseClient[] value();
481+
}
482+
483+
@Target(ElementType.METHOD)
484+
@Retention(RetentionPolicy.SOURCE)
485+
@Repeatable(CodebaseProducers.class)
486+
public @interface CodebaseProducer {
487+
String clientKind() default "kafka_send";
488+
String topic();
489+
String broker() default "";
490+
}
491+
492+
@Target(ElementType.METHOD)
493+
@Retention(RetentionPolicy.SOURCE)
494+
public @interface CodebaseProducers {
495+
CodebaseProducer[] value();
496+
}
497+
```
498+
499+
Usage:
500+
501+
```java
502+
// Outbound HTTP call to another service
503+
@CodebaseClient(
504+
clientKind = "rest_template",
505+
targetService = "chat-core",
506+
path = "/chat/joinOperator",
507+
method = "POST")
508+
public Reply callJoinOperator(Request req) { /* ... */ }
509+
510+
// Kafka publisher
511+
@CodebaseProducer(
512+
clientKind = "kafka_send",
513+
topic = "chat.follow-up",
514+
broker = "chat-events")
515+
public void publishFollowUp(Event e) { /* ... */ }
516+
```
517+
518+
As with `@CodebaseRoute`, multiple `@CodebaseClient` / `@CodebaseProducer`
519+
annotations on the same method are wrapped in `@CodebaseClients` /
520+
`@CodebaseProducers` automatically. Partial overrides are non-destructive
521+
(see *Caller-side brownfield overrides* above).
522+
373523
Resolution order in code: built-in inference, then config annotation maps,
374524
then meta-annotation walk, then `@CodebaseRole` / `@CodebaseCapability`, then
375525
`role_overrides.fqn` (highest priority for explicit per-type config). Route
@@ -420,10 +570,10 @@ Example: if built-in detection produces `client_kind=rest_template`, `method=GET
420570
`path=/users/{id}`, and an override sets only `path=/users/me`, the final call
421571
keeps `client_kind=rest_template` and `method=GET` while changing only the path.
422572

423-
For source stubs, copy `@CodebaseClient` / `@CodebaseClients` and
424-
`@CodebaseProducer` / `@CodebaseProducers` from
425-
`tests/fixtures/brownfield_client_stubs/` (same "simple-name only" behavior as
426-
`@CodebaseRoute` stubs).
573+
For in-source stubs, see **3c. Clients & producers** above for the full
574+
`@CodebaseClient` / `@CodebaseClients` / `@CodebaseProducer` /
575+
`@CodebaseProducers` `@interface` definitions and usage examples (same
576+
"simple-name only" matching as `@CodebaseRoute` stubs).
427577

428578
**Kuzu vs Lance (Layer A consistency):** both the Kuzu graph writer and Lance
429579
chunk enrichment call **one** function, `graph_enrich.collect_annotation_meta_chain`,
@@ -523,12 +673,18 @@ back to exact-text matching in that case, so re-running the flow fixes it.
523673

524674
## 6. Deferred (beyond static call graph)
525675

526-
**Call graph (static intra-JVM `CALLS` + `DECLARES`) is implemented** — see §5 edge types and
527-
`find_callers` / `find_callees` / `trace_flow(follow_calls)`. Remaining graph work:
676+
**Static intra-JVM `CALLS` / `DECLARES` are shipped** — see §5 edge types
677+
and `find_callers` / `find_callees` / `trace_flow(follow_calls)`.
678+
**Cross-service caller edges (`HTTP_CALLS` / `ASYNC_CALLS`) are shipped
679+
too**, with `find_route_callers`, `trace_request_flow`, and the
680+
brownfield composition layer documented under §5 "Brownfield overrides".
681+
Remaining graph work:
528682

529-
- Cross-service topology tools (`get_service_topology`, `trace_request_flow`) depending on the above.
683+
- `get_service_topology` (microservice-level summary view aggregating `HTTP_CALLS` / `ASYNC_CALLS`).
530684
- Agentic routing layer (query classifier → vector / graph / both) from the DKB paper §4.1.
531-
- Incremental Kuzu updates (per-changed-file) to avoid full rebuild.
685+
- Incremental Kuzu updates (per-changed-file) to avoid full rebuild —
686+
see `propose/TIER2-INCREMENTAL-REBUILD-PROPOSE.md` and
687+
`propose/REFRESH-CODE-INDEX-AUTO-MODE-PROPOSE.md`.
532688
- Optional `codegraph_nodes` LanceDB table embedding symbol summaries so the graph itself is vector-searchable.
533689

534690
## 7. Syncing from the main repo
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)