Skip to content

Commit 42717a7

Browse files
address pr 155 review: lock traversals and member_only contracts
Clarify role-keyed typical_traversals vs SCHEMA appendix tuples, split member_only across PR-A/PR-C, update PROPOSES-ORDER phase 2, and align prompts with pr_analysis and compose test coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent fd1996e commit 42717a7

5 files changed

Lines changed: 32 additions & 23 deletions

File tree

docs/PROPOSES-ORDER.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ When two or more proposes touch overlapping subsystems, the order they lock and
1313

1414
1. **SCHEMA-V2**`propose/SCHEMA-V2-PROPOSE.md` (propose merged via [#151](https://github.com/HumanBean17/java-codebase-rag/pull/151); treat as locked for sequencing)
1515
- 4 code PRs: PR-A (`EDGE_SCHEMA` + ontology v14 bump), PR-B (`HTTP_CALLS` flip + downstream API), PR-C (`Producer` node + `ASYNC_CALLS` flip + GraphMeta + MCP parity), PR-D (hints v3).
16-
2. **HINTS-V3**`propose/HINTS-V3-PROPOSE.md` ([#154](https://github.com/HumanBean17/java-codebase-rag/pull/154), draft)
16+
2. **HINTS-V3**`propose/HINTS-V3-PROPOSE.md` (merged [#154](https://github.com/HumanBean17/java-codebase-rag/pull/154); set `Status: locked` before PR-D)
1717
- Implementation = SCHEMA-V2 PR-D (same PR).
1818

1919
No other proposes are in flight.
@@ -35,17 +35,17 @@ HINTS-V3-PROPOSE.md [draft PR #154 — SCHEMA-V2 Decision 30]
3535
### Phase 2 — plan + cursor-prompt artefacts
3636

3737
```
38-
plans/PLAN-SCHEMA-V2.md [not started]
38+
plans/PLAN-SCHEMA-V2.md [landed #155]
3939
plans/CURSOR-PROMPTS-SCHEMA-V2.md
4040
plans/PLAN-HINTS-V3.md
4141
plans/CURSOR-PROMPTS-HINTS-V3.md
4242
```
4343

44-
SCHEMA-V2 Decision 29: `PLAN-SCHEMA-V2.md` + `CURSOR-PROMPTS-SCHEMA-V2.md` are merge gates for **PR-A**.
44+
SCHEMA-V2 Decision 29: `PLAN-SCHEMA-V2.md` + `CURSOR-PROMPTS-SCHEMA-V2.md` are merge gates for **PR-A** (satisfied when [#155](https://github.com/HumanBean17/java-codebase-rag/pull/155) is on `master`).
4545

46-
By analogy: `PLAN-HINTS-V3.md` + `CURSOR-PROMPTS-HINTS-V3.md` are merge gates for **PR-D**.
46+
By analogy: `PLAN-HINTS-V3.md` + `CURSOR-PROMPTS-HINTS-V3.md` are merge gates for **PR-D** (same PR).
4747

48-
Plans and prompts may be drafted in parallel with each other; each pair must land before its code PR.
48+
Plans and prompts may be drafted in parallel with each other; each pair must land before its code PR. **Code PRs (Phase 3) are not started** until Phase 2 is on `master`.
4949

5050
### Phase 3 — code PRs (merge order)
5151

plans/CURSOR-PROMPTS-SCHEMA-V2.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Read PR-A **File-by-file changes** and **Tests for PR-A** before coding. Plan wi
4848
4949
## Scope
5050
51-
1. **`java_ontology.py`** — `EdgeAttr`, `EdgeSpec`, `EDGE_SCHEMA` for **10 edges** with **pre-flip** `HTTP_CALLS`/`ASYNC_CALLS` (`Symbol→Route`). Include `brownfield_resolver_sourced`, role-keyed `typical_traversals`, `member_only` per HINTS-V3 §3.4. Add `BROWNFIELD_RESOLVER_STRATEGY_SET` (union of `FUZZY_STRATEGY_SET` + resolver strategies used on edges today).
51+
1. **`java_ontology.py`** — `EdgeAttr`, `EdgeSpec`, `EDGE_SCHEMA` for **10 edges** with **pre-flip** `HTTP_CALLS`/`ASYNC_CALLS` (`Symbol→Route`). Include `brownfield_resolver_sourced`; **`typical_traversals: dict[str, str]`** per HINTS-V3 §3.5 (SCHEMA propose Appendix A tuples are illustrative only). **`member_only`:** set `True` on `DECLARES_CLIENT`, `EXPOSES`, `OVERRIDES`, `CALLS` only — **not** `DECLARES_PRODUCER` (PR-C). Add `BROWNFIELD_RESOLVER_STRATEGY_SET` (union of `FUZZY_STRATEGY_SET` + resolver strategies used on edges today); **enumerate every member in the PR body**.
5252
2. **`scripts/generate_edge_navigation.py`** + committed **`docs/EDGE-NAVIGATION.md`** with `--check` mode.
5353
3. **`ast_java.py`** — `ONTOLOGY_VERSION = 14`.
5454
4. **`README.md`** + **`docs/AGENT-GUIDE.md`** — v14 re-index callout (PR-B/C consequences one sentence each).
@@ -125,6 +125,7 @@ Before PR open:
125125
- `@tests/test_pr_analysis.py`
126126
- `@tests/test_brownfield_clients.py`
127127
- `@tests/test_mcp_v2.py`
128+
- `@tests/test_mcp_v2_compose.py`
128129
- `@tests/test_client_hint_recovery.py`
129130

130131
**Prompt:**
@@ -196,6 +197,7 @@ Before PR open: `.venv/bin/ruff check .` and `.venv/bin/python -m pytest tests -
196197
- `@java_ontology.py`
197198
- `@build_ast_graph.py`
198199
- `@kuzu_queries.py`
200+
- `@pr_analysis.py`
199201
- `@mcp_v2.py`
200202
- `@server.py`
201203
- `@tests/test_call_edges_e2e.py`
@@ -217,10 +219,12 @@ PR-B is on `master` (HTTP_CALLS from Client). Do not revert HTTP shape.
217219
2. **`AsyncCallRow.producer_id`**; Producer fields from `AsyncProducerHint` / dispatch metadata (propose §3.2 table — no HTTP-only copy-paste).
218220
3. **`GraphMeta`**: `producers_total`, `declares_producer_total`; wire `server.py` meta output if applicable.
219221
4. **`kuzu_queries.py`**: async two-hop in `find_route_callers`, `trace_request_flow`, impact analysis; producer branch on `RouteCaller`.
220-
5. **`mcp_v2.py`**: `find(kind="producer")`, `resolve(hint_kind="producer")`, `_load_node_record` for Producer.
221-
6. **Type-level `describe` rollups**: `DECLARES.DECLARES_PRODUCER`, `OVERRIDDEN_BY.DECLARES_PRODUCER`.
222-
7. **Async doc sweep** + regenerate `docs/EDGE-NAVIGATION.md` (11 edges).
223-
8. **Tests** — All **Tests for PR-C** in the plan (verbatim).
222+
5. **`pr_analysis.py`**: async two-hop route reachability (`DECLARES_PRODUCER` + `ASYNC_CALLS`; HTTP already two-hop from PR-B).
223+
6. **`mcp_v2.py`**: `find(kind="producer")`, `resolve(hint_kind="producer")`, `_load_node_record` for Producer.
224+
7. **`java_ontology.py`**: `DECLARES_PRODUCER` in `EDGE_SCHEMA` with `member_only=True`.
225+
8. **Type-level `describe` rollups**: `DECLARES.DECLARES_PRODUCER`, `OVERRIDDEN_BY.DECLARES_PRODUCER`.
226+
9. **Async doc sweep** + regenerate `docs/EDGE-NAVIGATION.md` (11 edges).
227+
10. **Tests** — All **Tests for PR-C** in the plan (verbatim).
224228
225229
## Out of scope (do NOT touch)
226230

plans/PLAN-HINTS-V3.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ Name tests `test_hints_hv{N}_*` matching propose §6 / §4 rows:
130130
19. `test_hints_hv19_edge_schema_coverage_exists_trigger_per_edge`
131131
20. `test_hints_hv20_no_dotkey_edge_labels_in_rendered_neighbors_hints`
132132
21. `test_hints_neighbors_empty_kind_check_template_removed` — grep/template absent
133-
22. `test_hints_neighbors_v2_empty_post_flip_method_http_calls` — integration (optional if graph fixture available)
133+
22. `test_hints_neighbors_v2_empty_post_flip_method_http_calls` — integration round-trip on post-flip graph (**required** once SCHEMA PR-C is on `master`; fail loud if session fixture lacks Client→Route shape)
134134

135135
**Regression:** `test_hints_neighbors_fuzzy_strategy_*` and v1 neighbors tests still pass; update `test_hints_neighbors_empty_with_edge_types_emits_kind_check` → expect new template family (rename to reflect v3 behavior).
136136

plans/PLAN-SCHEMA-V2.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ Depends on:
4545
| Topic | Decision |
4646
| --- | --- |
4747
| `EDGE_SCHEMA` size in v2 | **11** entries after PR-C (`DECLARES_PRODUCER` added); PR-A ships **10** (no Producer table yet). |
48-
| `typical_traversals` | Role-keyed `dict[str, str]` (`type_subject`, `member_subject`, `alien_subject`, …) finalized in PR-A; hints v3 consumes in PR-D. |
49-
| `member_only` on `EdgeSpec` | Prefer PR-A; if omitted, PR-D adds (hint-only field; not in DDL CI). |
48+
| `typical_traversals` | **PR-A contract:** role-keyed `dict[str, str]` per HINTS-V3 §3.5 (`type_subject`, `member_subject`, `alien_subject`, …). SCHEMA-V2 propose Appendix A `tuple[str, …]` examples are **illustrative only** — implementation and hints v3 use the dict shape. |
49+
| `member_only` on `EdgeSpec` | Hint-only (not in DDL CI). **PR-A:** `True` on `DECLARES_CLIENT`, `EXPOSES`, `OVERRIDES`, `CALLS` only (10-edge schema). **PR-C:** add `DECLARES_PRODUCER` to `EDGE_SCHEMA` and set `member_only=True` when that edge lands. If PR-A omits the field entirely, PR-D may add it. |
5050
| `brownfield_resolver_sourced` | Renamed from `brownfield_sourced`; True iff edge carries resolver `strategy``BROWNFIELD_RESOLVER_STRATEGY_SET`. |
5151
| `BROWNFIELD_RESOLVER_STRATEGY_SET` | `FUZZY_STRATEGY_SET` ∪ non-fuzzy resolver strategies used on edges today (`codebase_route`, `codebase_client`, `codebase_producer`, `layer_*`, pass5/6 HTTP/async strategy literals — lock members in PR-A from `grep` of `strategy=` / ontology sets). |
5252
| `HttpCallRow` / `AsyncCallRow` | PR-B: `client_id` replaces `symbol_id` on HTTP rows. PR-C: `producer_id` replaces `symbol_id` on async rows. |
@@ -70,8 +70,8 @@ Depends on:
7070
- `ASYNC_CALLS`: `Symbol → Route` (pre-flip)
7171
- No `DECLARES_PRODUCER` entry yet (PR-C).
7272
- Add `brownfield_resolver_sourced: bool` on `EdgeSpec`.
73-
- Add `member_only: bool = False` on `EdgeSpec` (default False); set True on `DECLARES_CLIENT`, `EXPOSES`, `OVERRIDES`, `CALLS` per HINTS-V3 §3.4 (PR-D depends on this).
74-
- Add `typical_traversals: dict[str, str]` per edge (role keys; post-flip traversals for HTTP/ASYNC may describe **target** shapeupdate strings again in PR-B/C when endpoints flip).
73+
- Add `member_only: bool = False` on `EdgeSpec` (default False). **PR-A only:** set `True` on `DECLARES_CLIENT`, `EXPOSES`, `OVERRIDES`, `CALLS` (not `DECLARES_PRODUCER` — that edge does not exist until PR-C).
74+
- Add `typical_traversals: dict[str, str]` per edge (role keys per HINTS-V3 §3.5 — **not** the tuple shape in SCHEMA propose Appendix A). Post-flip traversals for HTTP/ASYNC may describe target shape; update strings again in PR-B/C when endpoints flip.
7575
- Add `BROWNFIELD_RESOLVER_STRATEGY_SET: frozenset[str]` (Decision 28).
7676
- Export new symbols in `__all__`.
7777

@@ -136,7 +136,7 @@ Depends on:
136136
4. `test_edge_navigation_doc_matches_generator_output`
137137
5. `test_edge_navigation_doc_check_mode_detects_drift`
138138
6. `test_kuzu_graph_refuses_ontology_version_below_required`
139-
7. `test_edge_schema_member_only_flags_on_method_level_edges``DECLARES_CLIENT`, `EXPOSES`, `OVERRIDES`, `CALLS` True; `HTTP_CALLS`/`ASYNC_CALLS` False at pre-flip.
139+
7. `test_edge_schema_member_only_flags_on_method_level_edges``DECLARES_CLIENT`, `EXPOSES`, `OVERRIDES`, `CALLS` True; no `DECLARES_PRODUCER` key in PR-A schema; `HTTP_CALLS`/`ASYNC_CALLS` False at pre-flip.
140140

141141
## Definition of done (PR-A)
142142

@@ -184,7 +184,7 @@ Depends on:
184184
- `find_route_callers`: two-hop Cypher
185185
`MATCH (s:Symbol)-[:DECLARES_CLIENT]->(c:Client)-[e:HTTP_CALLS]->(r:Route …)`.
186186
- `trace_request_flow` inbound: two-hop via Client; output rows include `caller_node_id`, `caller_node_kind`, `declaring_symbol_id`, `declaring_symbol_fqn`.
187-
- Impact-analysis expansion (~line 1335): three-hop through Client; surface caller node id on impacted route rows.
187+
- Impact-analysis expansion in `KuzuGraph` cross-service flow stage (Cypher using `HTTP_CALLS|ASYNC_CALLS` on changed symbols): three-hop through Client; surface caller node id on impacted route rows. Locate via `grep HTTP_CALLS|ASYNC_CALLS` in `kuzu_queries.py` — do not rely on line numbers.
188188
- Remove all `Symbol-[HTTP_CALLS]->Route` patterns.
189189

190190
### 4. `pr_analysis.py`
@@ -257,6 +257,7 @@ with every hit accounted for (fixed or justified).
257257

258258
- Add `Producer` to `NodeKind`.
259259
- Add `EDGE_SCHEMA["DECLARES_PRODUCER"]`, update `ASYNC_CALLS` to `Producer → Route`.
260+
- Set `member_only=True` on `DECLARES_PRODUCER` (edge lands in this PR).
260261
- `typical_traversals` for async edges/post-flip producer traversals.
261262

262263
### 2. `build_ast_graph.py`
@@ -275,27 +276,31 @@ with every hit accounted for (fixed or justified).
275276
- `find_route_callers` / `trace_request_flow` / impact analysis: include `DECLARES_PRODUCER` + `ASYNC_CALLS` two-hop branch; `caller_node_kind="producer"` with `topic`/`broker` from node.
276277
- `find` producers query helper (parallel `find_clients`).
277278

278-
### 4. `mcp_v2.py`
279+
### 4. `pr_analysis.py`
280+
281+
- Extend route reachability for changed symbols: async leg uses `DECLARES_PRODUCER` + `ASYNC_CALLS` two-hop (HTTP leg already two-hop from PR-B).
282+
283+
### 5. `mcp_v2.py`
279284

280285
- Extend `Literal` unions: `"producer"` on `find`, `resolve`, `_node_kind_from_id`, filters.
281286
- `find_v2(kind="producer")`, `resolve(..., hint_kind="producer")` using `VALID_PRODUCER_KINDS`.
282287
- `_load_node_record` for Producer.
283288

284-
### 5. `server.py`
289+
### 6. `server.py`
285290

286291
- `GraphMetaOutput`: optional `producers_total` / `declares_producer_total` if exposed in meta tool (match `build_ast_graph` counters).
287292

288-
### 6. `kuzu_queries.py``describe` rollups (~625, ~681)
293+
### 7. `kuzu_queries.py``describe` rollups (type-level `edge_summary` path)
289294

290295
- Add `("DECLARES.DECLARES_PRODUCER", "DECLARES_PRODUCER")` to type rollup set.
291296
- Add `OVERRIDDEN_BY.DECLARES_PRODUCER` parallel to client axis.
292297

293-
### 7. Docs (async sweep)
298+
### 8. Docs (async sweep)
294299

295300
- `README.md`, `docs/AGENT-GUIDE.md`, exploration skill — ASYNC_CALLS / Producer navigation.
296301
- Regenerate `docs/EDGE-NAVIGATION.md` (11 edges).
297302

298-
### 8. Tests / fixtures
303+
### 9. Tests / fixtures
299304

300305
- `tests/test_call_edges_e2e.py`, `tests/test_brownfield_clients.py` (producer stubs), `tests/test_mcp_v2.py`, `tests/test_ast_graph_build.py`, `tests/test_client_node_extraction.py` (meta counters pattern).
301306

propose/HINTS-V3-PROPOSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# HINTS-V3 — kind- and direction-aware empty-result hints driven by EDGE_SCHEMA
22

3-
**Status**: draft
3+
**Status**: merged
44
**Author**: Dmitriy Teriaev
55
**Date**: 2026-05-16
66

0 commit comments

Comments
 (0)