diff --git a/.cursor/rules/project-overview.mdc b/.cursor/rules/project-overview.mdc index e61576f..ff1d9e1 100644 --- a/.cursor/rules/project-overview.mdc +++ b/.cursor/rules/project-overview.mdc @@ -19,7 +19,8 @@ when needed. ## Where to look - `README.md` — feature surface, env vars, ranking, capabilities, - MCP tools (`search` / `find` / `describe` / `neighbors` / `resolve`), `java-codebase-rag` CLI, + MCP tools (`search` / `find` / `describe` / `neighbors` / `resolve`; response + `hints` + pagination echo on locate tools — see README), `java-codebase-rag` CLI, "Re-index required" callouts. The current `ontology_version` is **13** (material `OVERRIDES` Symbol→Symbol edges: subtype instance method → supertype declaration with matching `signature`, one @@ -57,6 +58,7 @@ when needed. | `graph_enrich.py` | `module` / `microservice` resolution, `BrownfieldOverrides` (route + role + capability + http client + async producer), meta-annotation walk, `resolve_routes_for_method` / `resolve_http_client_for_method` / `resolve_async_producer_for_method`. | | `java_ontology.py` | Source of truth for `VALID_ROLES`, `VALID_CAPABILITIES`, `VALID_CLIENT_KINDS`, `VALID_HTTP_CALL_STRATEGIES`, `VALID_ASYNC_CALL_STRATEGIES`, `VALID_HTTP_CALL_MATCHES`. | | `chunk_heuristics.py` | Query-time chunk hints (no AST / no re-index). | +| `mcp_hints.py` | MCP v2 road-sign `hints` catalog (`generate_hints`; locked v1 templates in `propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md`). | | `index_common.py` | Embedding config (no CocoIndex dep). | | `java_index_flow_lancedb.py` | CocoIndex flow (used by `java-codebase-rag init` / `increment` / `reprocess` / `erase`). | | `java_index_v1_common.py` | Shared file walker / exclude patterns. | diff --git a/AGENTS.md b/AGENTS.md index 0e466ac..d27f47e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,7 +8,8 @@ for tools that don't read `.cursor/rules/`. ## Where to look - `README.md` — feature surface, env vars, ranking, capabilities, - MCP tool list (`search` / `find` / `describe` / `neighbors` / `resolve`), + MCP tool list (`search` / `find` / `describe` / `neighbors` / `resolve`; + response `hints` + pagination echo — see README), CLI ops (`java-codebase-rag --help`), and "Re-index required" callouts. **`ontology_version` is currently 13** (stored `OVERRIDES` method→method edges traversable via `neighbors`; plus v12 HTTP brownfield rename, `CodebaseHttpMethod` enum, inbound HTTP layer-C replace — see README graph section). - [`docs/JAVA-CODEBASE-RAG-CLI.md`](./docs/JAVA-CODEBASE-RAG-CLI.md) — operator guide for the `java-codebase-rag` CLI (`init` / `increment` / `reprocess` / `erase`, `meta`, `tables`, `diagnose-ignore`, `analyze-pr`; hidden `refresh` alias → `reprocess` — see that doc). diff --git a/README.md b/README.md index 2e95a37..ad582d9 100644 --- a/README.md +++ b/README.md @@ -261,7 +261,7 @@ Example: {"kind":"symbol","filter":{"microservice":"chat-core","symbol_kind":"interface"}} ``` -**MCP v2 response extras (`hints`, pagination echo):** On success, `search`, `find`, `describe`, and `neighbors` return a `hints` field (`list[str]`, capped at five unique strings) with short, templated suggestions for likely next tool calls; hints are advisory. `hints` is always empty when `success` is false. `search` and `find` additionally echo the request’s `limit` and `offset` on success; on failure those echoed fields are omitted (`null` in JSON). The find page-full hint fires only when another page may exist (handler over-fetches by one row; not exposed on the output model). `neighbors` echoes `requested_edge_types` (deduped edge labels from the request) on success for empty-result hints and diagnostics. See [`propose/HINTS-ROAD-SIGNS-PROPOSE.md`](./propose/HINTS-ROAD-SIGNS-PROPOSE.md) Appendix A for the locked v1 template catalog. +**MCP v2 response extras (`hints`, pagination echo):** On success, `search`, `find`, `describe`, and `neighbors` return a `hints` field (`list[str]`, capped at five unique strings) with short, templated suggestions for likely next tool calls; hints are advisory. `hints` is always empty when `success` is false. `search` and `find` additionally echo the request’s `limit` and `offset` on success; on failure those echoed fields are omitted (`null` in JSON). The find page-full hint fires only when another page may exist (handler over-fetches by one row; not exposed on the output model). `neighbors` echoes `requested_edge_types` (deduped edge labels from the request) on success for empty-result hints and diagnostics. See [`propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md`](./propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md) Appendix A for the locked v1 template catalog. --- diff --git a/docs/AGENT-GUIDE.md b/docs/AGENT-GUIDE.md index ff8b5d1..6244f7d 100644 --- a/docs/AGENT-GUIDE.md +++ b/docs/AGENT-GUIDE.md @@ -20,7 +20,7 @@ > replace same-method built-in rows). **Design rationale:** navigation surface and tools — > [`propose/completed/MCP-API-V2-REDESIGN-PROPOSE.md`](../propose/completed/MCP-API-V2-REDESIGN-PROPOSE.md); > HTTP brownfield rename, `CodebaseHttpMethod`, and exclusivity — -> [`propose/HTTP-ROUTE-METHOD-ENUM-PROPOSE.md`](../propose/HTTP-ROUTE-METHOD-ENUM-PROPOSE.md). +> [`propose/completed/HTTP-ROUTE-METHOD-ENUM-PROPOSE.md`](../propose/completed/HTTP-ROUTE-METHOD-ENUM-PROPOSE.md). --- @@ -35,6 +35,8 @@ This MCP indexes Java enterprise projects into two stores: **MCP surface (navigation only):** `search`, `find`, `describe`, `neighbors`, `resolve`. +**Response extras (advisory):** On success, `search`, `find`, `describe`, and `neighbors` include a top-level `hints` list (≤5 templated next-call strings). `search` and `find` also echo `limit` / `offset`. Hints are safe to ignore; they are empty when `success` is false. Locked catalog: [`propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md`](../propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md) Appendix A. + **Operator / diagnostics (not MCP):** use the **`java-codebase-rag`** CLI — lifecycle (`init`, `increment`, `reprocess`, `erase`) plus `meta`, `tables`, `diagnose-ignore`, `analyze-pr`. Rebuilds are slow; the coding agent should not pretend it can reindex via MCP. For lifecycle commands, subprocess progress is written to **stderr** (use **`--quiet`** to suppress it); **stdout** is only the structured result payload. **Use this MCP when** you need whole-codebase context: who calls what, what handles a route, what a method invokes, where clients point, or fuzzy “where is concept X” entry points. diff --git a/docs/MANUAL-VERIFICATION-CHECKLIST.md b/docs/MANUAL-VERIFICATION-CHECKLIST.md index f753c8c..09c0cb8 100644 --- a/docs/MANUAL-VERIFICATION-CHECKLIST.md +++ b/docs/MANUAL-VERIFICATION-CHECKLIST.md @@ -13,15 +13,15 @@ Each item has: - a **Verification prompt** — paste verbatim into your agent (or run the shell snippet yourself) - **Expected (calibration)** — what the same prompt produces on - `tests/bank-chat-system` (ontology **11**). If your numbers diverge wildly, + `tests/bank-chat-system` (ontology **13**). If your numbers diverge wildly, that's a signal, not a verdict — what matters is the **shape** (proportions, error rates, presence of expected edges). - **If failing → fix** — concrete next step Calibration was captured against `tests/bank-chat-system` on -`master @ e90cbecc` (ontology version **11**): 84 files, 92 types, 474 -members, 0 parse errors, 17 routes, 11 `EXPOSES`, 793 `CALLS`, 2 `HTTP_CALLS`, -5 `ASYNC_CALLS`, 2 `Client` rows, microservices = `chat-core` + `chat-assign`. +`chore/docs-sync @ 1fa1b28` (ontology version **13**): 84 files, 92 types, 474 +members, 0 parse errors, 17 routes, 11 `EXPOSES`, 793 `CALLS`, 24 `OVERRIDES`, +2 `HTTP_CALLS`, 5 `ASYNC_CALLS`, 2 `Client` rows, microservices = `chat-core` + `chat-assign`. **Convention:** Graph ops use MCP. Index health / rebuild / PR analysis use **`java-codebase-rag`** (see README **CLI reference**). Example: @@ -83,16 +83,16 @@ export JAVA_CODEBASE_RAG_INDEX_DIR=/tmp/verify_index ## Phase 1 — Index health (4 items) -### 1.1 ☐ Ontology version is 11 +### 1.1 ☐ Ontology version is 13 **Verification prompt:** > In a shell with `JAVA_CODEBASE_RAG_INDEX_DIR` and `JAVA_CODEBASE_RAG_SOURCE_ROOT` > set for your graph, run `java-codebase-rag meta` (JSON output if piped). Report > `ontology_version`, `built_at`, `source_root`, and `parse_errors`. Does -> `ontology_version` equal `11`? +> `ontology_version` equal `13`? -**Expected (calibration):** `ontology_version: 11`, +**Expected (calibration):** `ontology_version: 13`, `parse_errors: 0`. **If failing → fix:** older ontology means a stale graph file. Re-pull the @@ -313,7 +313,7 @@ exact count. > with `{"kind":"client","filter":{},"limit":200}`. Rows should include > `client_kind`, `target_service`, paths, `source_layer`. -**Expected (calibration):** `ontology_version=11`, `counts.clients=2`, both +**Expected (calibration):** `ontology_version=13`, `counts.clients=2`, both `rest_template` in the fixture. **If failing → fix:** ontology < 10 → full rebuild. Zero clients when you @@ -496,7 +496,7 @@ expect Feign → README §3c brownfield. If everything is green: - Commit `.java-codebase-rag.yml` and `@Codebase*` stubs. -- Record **ontology 11** (or current `java-codebase-rag meta` value) in your team docs. +- Record **ontology 13** (or current `java-codebase-rag meta` value) in your team docs. - Periodically diff `java-codebase-rag meta` `counts` after large refactors. If something is red: @@ -522,4 +522,4 @@ java-codebase-rag meta --source-root tests/bank-chat-system --index-dir /tmp/cal `build_ast_graph.py` still takes `--kuzu-path` (the Kuzu file). Point it at `/code_graph.kuzu` so it matches the layout `java-codebase-rag meta --index-dir` expects under that directory. -Current snapshot: `tests/bank-chat-system`, `master @ e90cbecc`, ontology **11**. +Current snapshot: `tests/bank-chat-system`, `chore/docs-sync @ 1fa1b28`, ontology **13**. diff --git a/docs/paper/README.md b/docs/paper/README.md index dd65bce..c9802a8 100644 --- a/docs/paper/README.md +++ b/docs/paper/README.md @@ -8,8 +8,9 @@ architecture report: > May 2026. The paper describes the three-layer architecture (Extract \& Store / Navigate / -Reason), the four-tool MCP surface, the GPS metaphor (locate \-- inspect \-- walk), -the design principles that drove a v1\->v2 collapse from 9 tools to 4, and what +Reason), the five-tool MCP surface, the GPS metaphor (locate \-- inspect \-- walk), +the design principles that drove a v1\->v2 collapse from 9 tools to a small fixed +set (currently five navigation tools), and what the system deliberately does not do. It contains no empirical evaluation; testing on real legacy codebases is in progress and the data is not yet ready to publish. @@ -19,7 +20,7 @@ to publish. | File | Purpose | |---|---| | `paper.tex` | Main LaTeX source. Single-file paper, ~320 lines. | -| `references.bib` | BibTeX bibliography (13 entries). | +| `references.bib` | BibTeX bibliography. | | `figures/layers.tex` | TikZ source: three-layer architecture diagram. | | `figures/gps.tex` | TikZ source: GPS-metaphor / three-primitive diagram. | | `figures/workflow.tex` | TikZ source: canonical agent-interaction trace. | diff --git a/docs/paper/figures/gps.tex b/docs/paper/figures/gps.tex index 418941a..31f043f 100644 --- a/docs/paper/figures/gps.tex +++ b/docs/paper/figures/gps.tex @@ -24,14 +24,16 @@ \node[prim, walk, right=of inspect] (walk) {WALK\\ \footnotesize\itshape where can I go?}; % --- Tools above each primitive --- -\node[tool, above=0.7cm of locate, xshift=-0.85cm] (s) {search}; -\node[tool, above=0.7cm of locate, xshift=0.85cm] (f) {find}; -\node[tool, above=0.7cm of inspect] (d) {describe}; -\node[tool, above=0.7cm of walk] (n) {neighbors}; +\node[tool, above=0.7cm of locate, xshift=-1.15cm] (s) {search}; +\node[tool, above=0.7cm of locate, xshift=0cm] (f) {find}; +\node[tool, above=0.7cm of locate, xshift=1.15cm] (r) {resolve}; +\node[tool, above=0.7cm of inspect] (d) {describe}; +\node[tool, above=0.7cm of walk] (n) {neighbors}; % --- Connections tools -> primitives --- \draw[arr] (s) -- (locate.north -| s); \draw[arr] (f) -- (locate.north -| f); +\draw[arr] (r) -- (locate.north -| r); \draw[arr] (d) -- (inspect); \draw[arr] (n) -- (walk); diff --git a/docs/paper/paper.pdf b/docs/paper/paper.pdf index 68b7bad..14d6fcd 100644 Binary files a/docs/paper/paper.pdf and b/docs/paper/paper.pdf differ diff --git a/docs/paper/paper.tex b/docs/paper/paper.tex index 121a103..df71efa 100644 --- a/docs/paper/paper.tex +++ b/docs/paper/paper.tex @@ -78,7 +78,7 @@ % ============================================================================= \begin{abstract} \noindent -Large language model agents reason poorly about codebases the moment the codebase no longer fits in their context window. The standard remedy --- chunked retrieval-augmented generation over source files \cite{lewis2020rag} --- treats source code as prose and produces irrelevant or contradictory chunks for non-trivial questions ("who calls this method", "what HTTP routes does this microservice expose", "if I change this DTO, what breaks"). \textbf{java-codebase-rag} is a graph-native code intelligence layer that replaces chunk retrieval with deterministic graph navigation. It exposes a deliberately small Model Context Protocol (MCP) surface --- four tools: \texttt{search}, \texttt{find}, \texttt{describe}, \texttt{neighbors} --- backed by a typed property graph extracted from Java microservice source via tree-sitter \cite{treesitter}. The four tools collapse onto three primitive operations the agent actually performs: \emph{locate} a starting node (\texttt{search}, \texttt{find}); \emph{inspect} a node's full record (\texttt{describe}); \emph{walk} edges in the graph (\texttt{neighbors}). We call this metaphor \emph{a GPS for the agent}: the agent always knows where it is in the codebase, what is adjacent, and how to move. This report describes the architecture, the inspirations (GraphRAG \cite{edge2024graphrag}, context engineering \cite{karpathy2025context}, the MCP standard \cite{anthropic2024mcp}, and the broader AST-graph-RAG line), and the design principles that shaped a v2 redesign from a 9-tool surface into the current 4-tool surface plus eight operator CLI subcommands grouped as lifecycle (\texttt{init}, \texttt{increment}, \texttt{reprocess}, \texttt{erase}), introspection (\texttt{meta}, \texttt{tables}, \texttt{diagnose-ignore}), and analysis (\texttt{analyze-pr}) (Section~\ref{sec:layer3} discusses the CLI briefly; full reference in \texttt{docs/JAVA-CODEBASE-RAG-CLI.md}). We do not include empirical evaluation: testing on real legacy codebases is in progress and the data is not yet ready to publish. The contribution of this report is conceptual: it argues for a particular shape of code-intelligence layer --- minimal, typed, graph-native, agent-shaped --- and shows the architecture in enough detail that a reader could rebuild it for another language ecosystem. +Large language model agents reason poorly about codebases the moment the codebase no longer fits in their context window. The standard remedy --- chunked retrieval-augmented generation over source files \cite{lewis2020rag} --- treats source code as prose and produces irrelevant or contradictory chunks for non-trivial questions ("who calls this method", "what HTTP routes does this microservice expose", "if I change this DTO, what breaks"). \textbf{java-codebase-rag} is a graph-native code intelligence layer that replaces chunk retrieval with deterministic graph navigation. It exposes a deliberately small Model Context Protocol (MCP) surface --- five tools: \texttt{search}, \texttt{find}, \texttt{describe}, \texttt{neighbors}, \texttt{resolve} --- backed by a typed property graph extracted from Java microservice source via tree-sitter \cite{treesitter}. The five tools collapse onto three primitive operations the agent actually performs: \emph{locate} a starting node (\texttt{search}, \texttt{find}, \texttt{resolve}); \emph{inspect} a node's full record (\texttt{describe}); \emph{walk} edges in the graph (\texttt{neighbors}). We call this metaphor \emph{a GPS for the agent}: the agent always knows where it is in the codebase, what is adjacent, and how to move. This report describes the architecture, the inspirations (GraphRAG \cite{edge2024graphrag}, the MCP standard \cite{anthropic2024mcp}, and the broader AST-graph-RAG line), and the design principles that shaped a v2 redesign from a 9-tool surface into the current 5-tool surface plus eight operator CLI subcommands grouped as lifecycle (\texttt{init}, \texttt{increment}, \texttt{reprocess}, \texttt{erase}), introspection (\texttt{meta}, \texttt{tables}, \texttt{diagnose-ignore}), and analysis (\texttt{analyze-pr}) (Section~\ref{sec:layer3} discusses the CLI briefly; full reference in \texttt{docs/JAVA-CODEBASE-RAG-CLI.md}). We do not include empirical evaluation: testing on real legacy codebases is in progress and the data is not yet ready to publish. The contribution of this report is conceptual: it argues for a particular shape of code-intelligence layer --- minimal, typed, graph-native, agent-shaped --- and shows the architecture in enough detail that a reader could rebuild it for another language ecosystem. \end{abstract} \vspace{0.6em} @@ -103,11 +103,11 @@ \section{Inspirations} \paragraph{GraphRAG and AST-graph retrieval.} Microsoft's GraphRAG \cite{edge2024graphrag} demonstrated that constructing a knowledge graph from source documents and retrieving over the graph --- with community detection for global summarisation and hierarchical context for local queries --- substantially outperforms flat vector retrieval for query-focused summarisation. The lesson generalises beyond text: \emph{any} corpus with strong relational structure benefits from extracting that structure once and querying it as a graph. Source code has the strongest relational structure of any corpus we routinely retrieve over (compilers extract it for free); not exploiting it is a missed opportunity. Subsequent work in the AST-graph-RAG line \cite{guo2024lightrag} reinforces the pattern: lighter, simpler graph backends with cleaner ontologies often beat heavyweight ones for retrieval quality. -\paragraph{Context engineering.} Karpathy's \cite{karpathy2025context} framing of context engineering --- the delicate art of filling the context window with the right information at the right time --- shifted our thinking on tool design. A tool that returns 5\,KB of plausibly-relevant text is not equivalent to a tool that returns 200 bytes of structured truth; the second is far more useful. Lost-in-the-middle effects \cite{liu2023lostmiddle} mean that long noisy contexts actively hurt downstream reasoning. The correct response is not "retrieve better" but "retrieve less, with type guarantees". Every tool in the java-codebase-rag surface returns small, typed, deterministic JSON. The agent never has to decide whether what it received is signal or noise. +\paragraph{Context engineering.} Context engineering --- filling the context window with the right information at the right time --- shaped our tool design. A tool that returns 5\,KB of plausibly-relevant text is not equivalent to a tool that returns 200 bytes of structured truth; the second is far more useful. Lost-in-the-middle effects \cite{liu2023lostmiddle} mean that long noisy contexts actively hurt downstream reasoning. The correct response is not "retrieve better" but "retrieve less, with type guarantees". Every tool in the java-codebase-rag surface returns small, typed, deterministic JSON. The agent never has to decide whether what it received is signal or noise. \paragraph{Model Context Protocol.} The MCP standard \cite{anthropic2024mcp} fixed the impedance mismatch between agents and tools: a single transport, a single way to declare schemas, and a single way to bind tools to hosts (Claude Code, Cursor, Qwen Code, and others). Without MCP this report would describe a Claude-Code-only system. With MCP, a single Python server reaches every host the user already prefers. The standard does one thing well and stops. -\paragraph{The agent-skills layer.} Anthropic's agent skills \cite{anthropic2025skills} provided the missing piece between raw tool calls and agent reasoning: a skill is a slash-invokable, declaratively-described chain of tool calls that encodes a recurring intent ("trace this request flow", "show me callers of this method"). Skills are how a 4-tool MCP grows into hundreds of usable agent intents without growing the tool surface. We describe the planned skills layer briefly in \S\ref{sec:future} and defer its specification to a separate document; empirical testing showed that a comprehensive prose guide (mirrored as \texttt{AGENT-GUIDE.md} and \texttt{QWEN.md}) is sufficient for current weak-model performance, so the skills layer is not yet on the critical path. +\paragraph{The agent-skills layer.} Anthropic's agent skills \cite{anthropic2025skills} provided the missing piece between raw tool calls and agent reasoning: a skill is a slash-invokable, declaratively-described chain of tool calls that encodes a recurring intent ("trace this request flow", "show me callers of this method"). Skills are how a small fixed MCP surface grows into hundreds of usable agent intents without growing the tool count. We describe the planned skills layer briefly in \S\ref{sec:future} and defer its specification to a separate document; empirical testing showed that a comprehensive prose guide (mirrored as \texttt{docs/AGENT-GUIDE.md}) is sufficient for current weak-model performance, so the skills layer is not yet on the critical path. \paragraph{What we are not.} We do not claim novelty over GraphRAG, LightRAG, or LSP-backed tooling. We claim that a particular synthesis --- minimal MCP surface, typed property graph, three-primitive navigation model, agent-shaped affordances --- is the right shape for code intelligence at the agentic-development layer. The synthesis is the contribution. @@ -120,7 +120,7 @@ \section{Architecture: three layers} \begin{figure}[H] \centering \input{figures/layers.tex} -\caption{Three-layer architecture. \textbf{Layer 1 (Extract \& Store)} ingests Java source via tree-sitter and emits nodes and edges into an embedded property graph. \textbf{Layer 2 (Navigate)} exposes four MCP tools collapsing onto three primitive operations: locate, inspect, walk. \textbf{Layer 3 (Reason)} is the agent host (Claude Code, Qwen Code, or any MCP-compatible runtime) plus optional skills. Each layer is replaceable: swap the extractor for another language, swap the graph backend, swap the agent host --- contracts hold.} +\caption{Three-layer architecture. \textbf{Layer 1 (Extract \& Store)} ingests Java source via tree-sitter and emits nodes and edges into an embedded property graph. \textbf{Layer 2 (Navigate)} exposes five MCP tools collapsing onto three primitive operations: locate, inspect, walk. \textbf{Layer 3 (Reason)} is the agent host (Claude Code, Qwen Code, or any MCP-compatible runtime) plus optional skills. Each layer is replaceable: swap the extractor for another language, swap the graph backend, swap the agent host --- contracts hold.} \label{fig:layers} \end{figure} @@ -131,7 +131,7 @@ \subsection{Layer 1: extract and store} The graph is stored in K\`uzu \cite{kuzu2023}, an embedded property-graph database with a Cypher-style query language. K\`uzu was chosen over Neo4j for two pragmatic reasons: it embeds in-process (no separate database server to operate), and it has zero ongoing cost for a developer-side tool. Cocoindex \cite{cocoindex2024} drives the indexing pipeline (incremental rebuilds, dependency tracking, change detection on source files). -The ontology is small by design (Table~\ref{tab:ontology}). Three node kinds (\textsc{symbol}, \textsc{route}, \textsc{client}) cover everything an agent realistically asks about; nine edge types cover every relation we have found load-bearing in practice. The ontology version is currently 11; the discipline is that no edge type ships unless at least three realistic agent questions in our use-case backlog require it. +The ontology is small by design (Table~\ref{tab:ontology}). Three node kinds (\textsc{symbol}, \textsc{route}, \textsc{client}) cover everything an agent realistically asks about; ten edge types cover every relation we have found load-bearing in practice. The ontology version is currently 13; the discipline is that no edge type ships unless at least three realistic agent questions in our use-case backlog require it. \begin{table}[H] \centering @@ -147,10 +147,11 @@ \subsection{Layer 1: extract and store} \textsc{route} & An HTTP-exposed endpoint (Spring \texttt{@RequestMapping}, JAX-RS \texttt{@Path}, etc.). One per HTTP method + path. \\ \textsc{client} & A typed reference to an external service: declared HTTP client (Feign, OpenFeign, REST clients) or messaging client. \\ \midrule -\multicolumn{2}{l}{\emph{Edge types (9)}} \\ +\multicolumn{2}{l}{\emph{Edge types (10)}} \\ \textsc{extends} & Class- or interface-inheritance edge (Java \texttt{extends}). \\ \textsc{implements} & Interface-implementation edge (Java \texttt{implements}). \\ \textsc{injects} & Dependency-injection edge: a symbol receives another via constructor, field, or setter injection. \\ +\textsc{overrides} & Subtype method overrides a supertype declaration with the same signature. \\ \textsc{declares} & Container declares a member: class \textsc{declares} method, package \textsc{declares} class, etc. \\ \textsc{declares\_client} & Module declares a typed external-service client. \\ \textsc{calls} & In-process method call. The work-horse edge. \\ @@ -164,12 +165,12 @@ \subsection{Layer 1: extract and store} \subsection{Layer 2: navigate (the MCP)} \label{sec:layer2} -Layer 2 is the public surface of the system. Four tools, three primitive operations (Figure~\ref{fig:gps}). Every tool returns small, typed JSON; no tool returns more than a single page of results without explicit pagination. +Layer 2 is the public surface of the system. Five tools, three primitive operations (Figure~\ref{fig:gps}). Every tool returns small, typed JSON; no tool returns more than a single page of results without explicit pagination. Successful outputs may also carry advisory \texttt{hints} (templated next-call strings) and pagination echoes on \texttt{search} / \texttt{find}. \begin{figure}[H] \centering \input{figures/gps.tex} -\caption{The GPS metaphor. Four MCP tools collapse onto three primitive operations: \emph{locate} (where am I?), \emph{inspect} (what is here?), \emph{walk} (where can I go?). Every realistic agent question decomposes into a chain over these three primitives. The agent supplies the reasoning; the graph supplies the geometry.} +\caption{The GPS metaphor. Five MCP tools collapse onto three primitive operations: \emph{locate} (where am I?), \emph{inspect} (what is here?), \emph{walk} (where can I go?). Every realistic agent question decomposes into a chain over these three primitives. The agent supplies the reasoning; the graph supplies the geometry.} \label{fig:gps} \end{figure} @@ -191,7 +192,7 @@ \subsection{Layer 2: navigate (the MCP)} \subsection{Layer 3: reason (the agent)} \label{sec:layer3} -Layer 3 is whatever MCP-compatible host the developer prefers --- Claude Code, Qwen Code, Cursor, or another runtime. The host loads the java-codebase-rag MCP server, sees the four tools, and the agent reasons over them. There is no logic in this layer that is specific to java-codebase-rag; the entire affordance is the four tools and a prose agent guide (\texttt{docs/AGENT-GUIDE.md}, with a Qwen-specific mirror at \texttt{QWEN.md}) that documents the canonical workflows --- forced reasoning preamble, decision tree, edge taxonomy, worked examples. +Layer 3 is whatever MCP-compatible host the developer prefers --- Claude Code, Qwen Code, Cursor, or another runtime. The host loads the java-codebase-rag MCP server, sees the five tools, and the agent reasons over them. There is no logic in this layer that is specific to java-codebase-rag; the entire affordance is the five tools and a prose agent guide (\texttt{docs/AGENT-GUIDE.md}) that documents the canonical workflows --- forced reasoning preamble, decision tree, edge taxonomy, worked examples. A planned addition (deferred) is a thin skills layer that turns recurring intents (\texttt{/callers}, \texttt{/routes}, \texttt{/explain-feature}) into one-line slash invocations that compile to MCP-call chains. Empirical testing on the target codebase showed that the prose guide alone is sufficient for current weak-model accuracy, so the skills layer is not yet implemented. @@ -208,7 +209,7 @@ \section{Agent workflow} \label{fig:workflow} \end{figure} -The workflow is general. The java-codebase-rag agent guide enumerates 15+ canonical intents, each decomposing into 2--5 tool calls over the same four tools. New intents are new chains, not new tools. +The workflow is general. The java-codebase-rag agent guide enumerates 15+ canonical intents, each decomposing into 2--5 tool calls over the same five tools. New intents are new chains, not new tools. A subtle point worth surfacing: the agent's first move is almost always \texttt{search}, not \texttt{find}. Natural-language questions arrive fuzzy; \texttt{search} is the cheapest way to get from "fuzzy English" to "candidate node ids". Once the agent has an id, all subsequent navigation is deterministic. This shape --- semantic at the boundary, structural in the interior --- is the practical reconciliation between vector retrieval and graph navigation. We do not need hybrid retrieval (parallel vector $+$ graph fusion) for most questions; we need \emph{sequential} retrieval, with the vector step strictly outside the graph step. @@ -216,13 +217,13 @@ \section{Agent workflow} \section{Design principles} \label{sec:principles} -The architecture above did not arrive in one step. It arrived after a v1 surface of nine MCP tools collapsed --- in design review --- into four. Five design principles guided the collapse, and they remain binding for any future surface change. +The architecture above did not arrive in one step. It arrived after a v1 surface of nine MCP tools collapsed --- in design review --- into a small fixed set (currently five navigation tools). Five design principles guided the collapse, and they remain binding for any future surface change. \begin{enumerate} \item \textbf{The MCP is a graph navigator, not a reasoning engine.} If a tool's job is to combine results, summarise across nodes, or rank candidates, the tool belongs in the agent's reasoning, not the MCP. Move it to a skill or to a CLI subcommand. \item \textbf{Every tool has a single primitive operation.} If a tool does two things ("search and describe", "find and walk"), it should be two tools or one tool with a strict contract. Composite tools confuse weak models and double the failure surface. \item \textbf{Schemas are closed where finite.} Every parameter that takes one of $N$ known values is a \texttt{Literal}-typed enumeration. The agent gets explicit affordances; the server gets free input validation. -\item \textbf{Operational surface is human-shaped, not agent-shaped.} {\sloppy Tools the agent does not call belong in a CLI (\texttt{java-codebase-rag} lifecycle and introspection subcommands --- \texttt{init}, \texttt{increment}, \texttt{reprocess}, \texttt{erase}, \texttt{meta}, \texttt{tables}, \texttt{diagnose-ignore}, \texttt{analyze-pr}), not the MCP. The MCP surface stays at four tools forever.\par} +\item \textbf{Operational surface is human-shaped, not agent-shaped.} {\sloppy Tools the agent does not call belong in a CLI (\texttt{java-codebase-rag} lifecycle and introspection subcommands --- \texttt{init}, \texttt{increment}, \texttt{reprocess}, \texttt{erase}, \texttt{meta}, \texttt{tables}, \texttt{diagnose-ignore}, \texttt{analyze-pr}), not the MCP. The MCP navigation surface stays small and fixed; new agent intents are new chains over the existing tools, not new tools.\par} \item \textbf{Walks are explicit, not silent.} The system never multi-hops without the agent asking. Multi-hop intents become multi-call chains. The agent always knows what edges it walked, and the user always can audit. \end{enumerate} @@ -247,10 +248,10 @@ \section{Future work} \label{sec:future} {\sloppy -Three threads are open and prioritised. \textbf{(1) Real-codebase evaluation.} Testing on a large legacy Java microservice estate is in progress; once stable, we expect to publish accuracy numbers (intent $\to$ correct-tool-chain rate, end-to-end answer correctness against human labels) for the four-tool surface against weak (Qwen) and strong (Claude Sonnet 4.5) hosts. \textbf{(2) Skills layer.} A 13-skill set --- 10 single-call navigation skills (\texttt{/callers}, \texttt{/callees}, \texttt{/routes}, \texttt{/controllers}, \ldots) and 3 multi-step workflow skills (\texttt{/explain-feature}, \texttt{/impact-of}, \texttt{/trace-request-flow}) --- is designed and on hold until the prose-guide approach shows insufficient. \textbf{(3) Tier-2 incremental rebuilds.} Today the index rebuilds the affected modules; we want commit-level incremental rebuilds for sub-second index updates on large monorepos. +Three threads are open and prioritised. \textbf{(1) Real-codebase evaluation.} Testing on a large legacy Java microservice estate is in progress; once stable, we expect to publish accuracy numbers (intent $\to$ correct-tool-chain rate, end-to-end answer correctness against human labels) for the five-tool surface against weak (Qwen) and strong (Claude Sonnet 4.5) hosts. \textbf{(2) Skills layer.} A 13-skill set --- 10 single-call navigation skills (\texttt{/callers}, \texttt{/callees}, \texttt{/routes}, \texttt{/controllers}, \ldots) and 3 multi-step workflow skills (\texttt{/explain-feature}, \texttt{/impact-of}, \texttt{/trace-request-flow}) --- is designed and on hold until the prose-guide approach shows insufficient. \textbf{(3) Tier-2 incremental rebuilds.} Today the index rebuilds the affected modules; we want commit-level incremental rebuilds for sub-second index updates on large monorepos. \par} -We deliberately list \emph{no} item that would grow the MCP tool count. The four-tool surface is a load-bearing commitment; it will not be revisited without proof that it cannot accommodate a real intent. +We deliberately list \emph{no} item that would grow the MCP tool count without proof that the existing five tools cannot accommodate a real intent. % ============================================================================= \section*{Acknowledgements} @@ -265,7 +266,7 @@ \section*{Acknowledgements} \section{Tool signatures (verbatim)} \label{app:tools} -The four MCP tools have the following Python (Pydantic) signatures, simplified for readability. The full source lives at \texttt{mcp\_v2.py} in the repository. +The five MCP tools have the following Python (Pydantic) signatures, simplified for readability. The full source lives at \texttt{mcp\_v2.py} in the repository. \begin{lstlisting}[language=Python] DeclarationSymbolKind = Literal[ @@ -274,7 +275,7 @@ \section{Tool signatures (verbatim)} ] EdgeType = Literal[ - "EXTENDS", "IMPLEMENTS", "INJECTS", "DECLARES", + "EXTENDS", "IMPLEMENTS", "INJECTS", "OVERRIDES", "DECLARES", "DECLARES_CLIENT", "CALLS", "EXPOSES", "HTTP_CALLS", "ASYNC_CALLS" ] @@ -308,6 +309,8 @@ \section{Tool signatures (verbatim)} def describe(id: str) -> DescribeOutput: ... +def resolve(identifier: str, hint_kind: str | None = None) -> ResolveOutput: ... + def neighbors( id: str, direction: Literal["in", "out"], diff --git a/docs/paper/references.bib b/docs/paper/references.bib index 08c6530..634455e 100644 --- a/docs/paper/references.bib +++ b/docs/paper/references.bib @@ -28,15 +28,6 @@ @misc{lewis2020rag url = {https://arxiv.org/abs/2005.11401} } -@misc{karpathy2025context, - author = {Karpathy, Andrej}, - title = {Context engineering: the delicate art of filling the context window}, - howpublished = {Online essay}, - year = {2025}, - url = {https://x.com/karpathy/status/1937902205765607626}, - note = {Accessed 2026-05-08} -} - @misc{anthropic2025skills, author = {Anthropic}, title = {Agent Skills}, diff --git a/docs/skills/java-codebase-explore.md b/docs/skills/java-codebase-explore.md index 1b0b3fa..f55eaec 100644 --- a/docs/skills/java-codebase-explore.md +++ b/docs/skills/java-codebase-explore.md @@ -205,7 +205,7 @@ disagreement as evidence of staleness, not as a contradiction. - **Wire fields:** Cross-service and resolver-heavy edges carry **`edge.attrs`** (same map surfaced as `attrs` in payloads). Treat **`attrs.confidence`**, **`attrs.strategy`**, and **`attrs.match`** as structured hints: low confidence means “resolver could not pin this cleanly,” not “definitely false.” - **MCP vs editor:** If the open buffer contradicts graph edges (deleted method, renamed class), **trust the file** and treat MCP as stale until **`reprocess`** (or at least acknowledge incremental lag after **`increment`**). -- **Operational check:** Use **`java-codebase-rag meta`** to compare index health, ontology version (currently **v11** in this repo’s README), and recency signals—then decide whether to re-run **`reprocess`** before continuing a mission. +- **Operational check:** Use **`java-codebase-rag meta`** to compare index health, ontology version (currently **13** in this repo’s README), and recency signals—then decide whether to re-run **`reprocess`** before continuing a mission. ## Anti-patterns @@ -234,12 +234,13 @@ Five MCP tools: Three node kinds: `symbol`, `route`, `client`. Ids carry a prefix (`sym:`, `route:` / `r:`, `client:` / `c:`). -Nine edge types: +Ten edge types: | Group | Edges | | ----- | ----- | | Type wiring | `EXTENDS`, `IMPLEMENTS`, `INJECTS` | | Containment | `DECLARES`, `DECLARES_CLIENT` | +| Method overrides | `OVERRIDES` | | Method calls | `CALLS` | | Service boundary | `EXPOSES` | | Cross-service | `HTTP_CALLS`, `ASYNC_CALLS` | diff --git a/mcp_hints.py b/mcp_hints.py index 72e3f06..ee2f43b 100644 --- a/mcp_hints.py +++ b/mcp_hints.py @@ -1,7 +1,7 @@ """Pure MCP v2 road-sign hint generation (no graph I/O, no search, no LLM). -Locked v1 catalog: ``propose/HINTS-ROAD-SIGNS-PROPOSE.md`` Appendix A. -Priority cap: same propose §7.12 / ``plans/PLAN-HINTS.md`` principles. +Locked v1 catalog: ``propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md`` Appendix A. +Priority cap: same propose §7.12 / ``plans/completed/PLAN-HINTS.md`` principles. """ from __future__ import annotations diff --git a/plans/CURSOR-PROMPTS-HINTS.md b/plans/completed/CURSOR-PROMPTS-HINTS.md similarity index 89% rename from plans/CURSOR-PROMPTS-HINTS.md rename to plans/completed/CURSOR-PROMPTS-HINTS.md index ff1806d..7e5c8ad 100644 --- a/plans/CURSOR-PROMPTS-HINTS.md +++ b/plans/completed/CURSOR-PROMPTS-HINTS.md @@ -1,7 +1,7 @@ # Cursor task prompts — Hints (road signs) + stored `OVERRIDES` -Status: **active**. Plan: [`plans/PLAN-HINTS.md`](./PLAN-HINTS.md). Propose: -[`propose/HINTS-ROAD-SIGNS-PROPOSE.md`](../propose/HINTS-ROAD-SIGNS-PROPOSE.md). +Status: **completed** (landed). Plan: [`plans/completed/PLAN-HINTS.md`](./PLAN-HINTS.md). Propose: +[`propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md`](../propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md). One prompt per PR. Copy the fenced **Prompt** block into Cursor agent mode with the listed `@-files` attached. @@ -22,13 +22,13 @@ is merged to `master`. **Branch:** `feat/hints-stored-overrides` off `master`. **Base:** `master`. -**Plan section:** [`plans/PLAN-HINTS.md`](./PLAN-HINTS.md) § PR-A — Stored `OVERRIDES` edges + ontology bump. +**Plan section:** [`plans/completed/PLAN-HINTS.md`](./PLAN-HINTS.md) § PR-A — Stored `OVERRIDES` edges + ontology bump. **PR title:** `materialize OVERRIDES rel and bump ontology to 13` **Attach (`@-files`):** -- `@plans/PLAN-HINTS.md` (PR-A section + principles + cross-PR risks) -- `@propose/HINTS-ROAD-SIGNS-PROPOSE.md` (§6 PR-A, §7.17) +- `@plans/completed/PLAN-HINTS.md` (PR-A section + principles + cross-PR risks) +- `@propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md` (§6 PR-A, §7.17) - `@build_ast_graph.py` - `@ast_java.py` - `@kuzu_queries.py` (`override_axis_rollup_for` — reference only unless optional hygiene is justified) @@ -43,7 +43,7 @@ is merged to `master`. **Prompt:** ```` -You are implementing PR-HINTS-A from `plans/PLAN-HINTS.md` (the **PR-A** section). +You are implementing PR-HINTS-A from `plans/completed/PLAN-HINTS.md` (the **PR-A** section). Read the PR-A **File-by-file changes** and **Tests for PR-A** before coding. If this prompt and the plan disagree, the plan wins; the propose fills background only. @@ -125,7 +125,7 @@ present; server `describe` text must **not** claim stored `OVERRIDES` is unusabl `neighbors` (rollup/dot-key carve-out may remain for virtual keys). ```bash -# Allowed paths for PR-A (see `plans/PLAN-HINTS.md` PR-A file-by-file). Anything +# Allowed paths for PR-A (see `plans/completed/PLAN-HINTS.md` PR-A file-by-file). Anything # else printed here is a red flag — confirm against that list or trim scope before merge. git diff master..HEAD --name-only | rg -v '^(tests/|build_ast_graph\.py|ast_java\.py|java_index_flow_lancedb\.py|kuzu_queries\.py|mcp_v2\.py|server\.py|README\.md)$' || true ``` @@ -153,7 +153,7 @@ fixture expects overrides; paste command + key line in the PR body. ## Definition of Done -- [ ] PR-A plan definition of done satisfied (`plans/PLAN-HINTS.md`). +- [ ] PR-A plan definition of done satisfied (`plans/completed/PLAN-HINTS.md`). - [ ] `.venv/bin/ruff check .` and `.venv/bin/python -m pytest tests -v` green. - [ ] PR title: `materialize OVERRIDES rel and bump ontology to 13` - [ ] Branch: `feat/hints-stored-overrides` @@ -166,13 +166,13 @@ fixture expects overrides; paste command + key line in the PR body. **Branch:** `feat/mcp-v2-hints` off `master` **after PR-HINTS-A is merged**. **Base:** `master` at merge commit of PR-HINTS-A. -**Plan section:** [`plans/PLAN-HINTS.md`](./PLAN-HINTS.md) § PR-B — `hints`, pagination echo, `mcp_hints.py` catalog. +**Plan section:** [`plans/completed/PLAN-HINTS.md`](./PLAN-HINTS.md) § PR-B — `hints`, pagination echo, `mcp_hints.py` catalog. **PR title:** `add MCP v2 hints and find/search pagination echo` **Attach (`@-files`):** -- `@plans/PLAN-HINTS.md` (PR-B section + principles §7.12 priority) -- `@propose/HINTS-ROAD-SIGNS-PROPOSE.md` (§3, Appendix A — canonical template strings) +- `@plans/completed/PLAN-HINTS.md` (PR-B section + principles §7.12 priority) +- `@propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md` (§3, Appendix A — canonical template strings) - `@mcp_hints.py` (create) - `@mcp_v2.py` (outputs + handler wiring) - `@server.py` (optional: tool `description=` updates for `hints` / pagination — minimal) @@ -182,12 +182,12 @@ fixture expects overrides; paste command + key line in the PR body. **Prompt:** ```` -You are implementing PR-HINTS-B from `plans/PLAN-HINTS.md` (the **PR-B** section). +You are implementing PR-HINTS-B from `plans/completed/PLAN-HINTS.md` (the **PR-B** section). PR-HINTS-A is already on `master` (stored `OVERRIDES`, `EdgeType` includes it, ontology 13). Do not re-land builder/schema work here. -Read **Appendix A** in `propose/HINTS-ROAD-SIGNS-PROPOSE.md` for verbatim v1 template +Read **Appendix A** in `propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md` for verbatim v1 template strings. If §3.3 and Appendix A disagree, Appendix A wins; if you change strings, update the propose in the same PR. @@ -206,7 +206,7 @@ update the propose in the same PR. 3. **`README.md`** — Document `hints` and pagination echo briefly under MCP v2. 4. **`server.py`** — Only if needed for LLM-facing tool descriptions; keep stdout clean. 5. **Tests** — Implement **all** `test_*` names listed under **Tests for PR-B** in - `plans/PLAN-HINTS.md` (verbatim names). Prefer crafted pydantic payloads where the + `plans/completed/PLAN-HINTS.md` (verbatim names). Prefer crafted pydantic payloads where the scenario does not need a DB; use `kuzu_graph` / fixtures where integration is required. diff --git a/plans/PLAN-HINTS.md b/plans/completed/PLAN-HINTS.md similarity index 98% rename from plans/PLAN-HINTS.md rename to plans/completed/PLAN-HINTS.md index 333351a..b8d3f50 100644 --- a/plans/PLAN-HINTS.md +++ b/plans/completed/PLAN-HINTS.md @@ -1,7 +1,7 @@ # Plan: Hints (road signs) + stored `OVERRIDES` edges -Status: **active (planning)**. This plan implements -[`propose/HINTS-ROAD-SIGNS-PROPOSE.md`](../propose/HINTS-ROAD-SIGNS-PROPOSE.md). +Status: **completed** (landed). This plan implemented +[`propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md`](../propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md). Depends on: **none** (strict `find` frame and `resolve` tool are already landed per the propose open-links section). @@ -219,5 +219,5 @@ Use **verbatim** names below (adjust only if pytest collection would collide; if ## Cursor handoff -Per-PR execution prompts: [`plans/CURSOR-PROMPTS-HINTS.md`](CURSOR-PROMPTS-HINTS.md) +Per-PR execution prompts: [`plans/completed/CURSOR-PROMPTS-HINTS.md`](CURSOR-PROMPTS-HINTS.md) (structure aligned with completed `plans/completed/CURSOR-PROMPTS-*.md` handoffs). diff --git a/propose/HINTS-ROAD-SIGNS-PROPOSE.md b/propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md similarity index 99% rename from propose/HINTS-ROAD-SIGNS-PROPOSE.md rename to propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md index 855cd93..64d1080 100644 --- a/propose/HINTS-ROAD-SIGNS-PROPOSE.md +++ b/propose/completed/HINTS-ROAD-SIGNS-PROPOSE.md @@ -1,6 +1,6 @@ # HINTS-ROAD-SIGNS — machine-readable next-action signals on MCP V2 outputs -**Status**: under review +**Status**: completed (landed: stored `OVERRIDES` edges + MCP `hints` catalog; plan: [`plans/completed/PLAN-HINTS.md`](../plans/completed/PLAN-HINTS.md)) **Author**: Dmitriy Teriaev + Perplexity Computer **Date**: 2026-05-14 (revised 2026-05-15) @@ -269,7 +269,7 @@ results==[] and edge_types non-empty → "0 results — check if the requested len(results)==limit and (max_score - min_score) < 0.1*max_score → "results look weak — narrow the query or try find(role=…)" # requires SearchOutput.limit echo, see §3.1 ``` -File placement (`mcp_hints.py`), function decomposition, integration points in `mcp_v2.py`, and test file names go in `plans/PLAN-HINTS.md` — not in this propose. +File placement (`mcp_hints.py`), function decomposition, integration points in `mcp_v2.py`, and test file names go in `plans/completed/PLAN-HINTS.md` — not in this propose. ## Appendix B — What changed (traceability) @@ -291,7 +291,7 @@ File placement (`mcp_hints.py`), function decomposition, integration points in ` 7. Old decision §7.14 (no hints for `find` when no filter was passed) dropped. In the post-#117 strict-frame world, `find()` without a filter is a contract error that fails loud — the carve-out was solving a problem the strict frame already solved. 8. New decision §7.15 added: hints are documentation-grade, not programmatic-dispatch. Locks the consumer model so future readers don't relitigate it. 9. New decision §7.16 added: cross-tool hints allowed at v1, scoped to the one row pointing at `resolve(…)`. Other cross-tool templates need their own amendment per §7.11. -10. Appendix A trimmed from a `mcp_hints.py` skeleton with function bodies to a verbatim template catalog. Function decomposition is plan-level work and belongs in `plans/PLAN-HINTS.md`. +10. Appendix A trimmed from a `mcp_hints.py` skeleton with function bodies to a verbatim template catalog. Function decomposition is plan-level work and belongs in `plans/completed/PLAN-HINTS.md`. 11. Open-links section rewritten: #117 landed, `resolve` shipped, #118 is a partial overlap (documentation-grade only) not a resolution. Misleading "locking hints here mostly resolves #118" claim removed. **What changed after the fourth review pass (2026-05-15, PR-A builder sharpening)**