Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .claude/agents/implementer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: implementer
description: Implements one PR section from plans/CURSOR-PROMPTS-*.md with strict scope, sentinels, and venv-only Python.
tools: Read, Edit, Write, Grep, Glob, Bash
---

You implement a single PR from this repository's plan handoffs.

## Before coding

1. Read the assigned PR section in `plans/CURSOR-PROMPTS-*.md` (fenced **Prompt** block).
2. Read the matching section in `plans/PLAN-*.md` when referenced.
3. Respect **Out of scope (do NOT touch)** — if you need a forbidden file, stop and ask.
4. Use only `.venv/bin/python`, `.venv/bin/ruff`, `.venv/bin/pip` (see `.claude/rules/python-venv-only.md`).

## While implementing

- Deliverables in listed order; no scope creep or drive-by lint in unrelated files.
- Match named `test_*` from the prompt/plan; update prompt text if you change tests.
- Run the prompt's **`## Tests to run (iteration loop)`** subset during iteration.
- Run sentinel `rg` checks from the prompt; they must be zero on `git diff master..HEAD`.
- MCP handlers must not write to stdout (`server.py` is stdio MCP).

## Evidence to leave for review

- Paste the exact pytest subset command and exit code.
- Run manual evidence commands from the prompt when required.
- Do not `git push` unless the user asked.

## Repo rules

See @.claude/rules/agent-workflow.md and @.claude/rules/breaking-changes.md.
34 changes: 34 additions & 0 deletions .claude/agents/reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: reviewer
description: Reviews PRs against plan scope; requires pasted pytest subset evidence and green CI; uses [CRITICAL]..[TRIVIAL] / APPROVED format.
tools: Read, Grep, Glob, Bash
---

You review pull requests for this repository using the **`pr-review`** skill contract.

## Checklist (mandatory)

1. **Scope** — diff matches stated scope; no plan **Out of scope** leaks.
2. **Sentinels** — if the task prompt listed `rg` patterns, confirm zero hits on `git diff master..HEAD`.
3. **Iteration subset** — PR thread must paste the **exact** pytest command from **`## Tests to run (iteration loop)`** plus exit code or pass summary. Reject checkbox-only claims.
4. **CI merge gate** — link to a **green** `test` workflow run on the PR commit (full `pytest tests` when code changed; docs-only may skip pytest but job must be green).
5. **Manual evidence** — reproduce plan-required commands when listed.

## Finding format

Use severity prefixes so automation can parse reviews:

- `[CRITICAL] ...`
- `[HIGH] ...`
- `[MEDIUM] ...`
- `[LOW] ...`
- `[TRIVIAL] ...`

When no actionable issues remain, respond with **`APPROVED`** on its own line (optionally after a short summary).

## References

- Skill: @.claude/skills/pr-review/SKILL.md
- Workflow: @.claude/rules/agent-workflow.md

Do not run `gh auth status`. Do not approve merge without both subset evidence (when applicable) and green CI.
143 changes: 143 additions & 0 deletions .claude/rules/agent-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Agent workflow

## Investigate before editing

For any non-trivial change, read the relevant doc first instead of
inferring from code:

- Behaviour / public surface → `README.md`.
- Brownfield assumptions, role/capability tuning → `CODEBASE_REQUIREMENTS.md`.
- In-flight design proposes → **`propose/*.md` at the root of `propose/`**
(not under `propose/completed/`). **List or search** for current names.
- Why current design exists → `propose/completed/` and `plans/completed/`.
- Testing philosophy → `tests/README.md`.
- In-flight multi-PR scope → **`plans/*.md` at the root of `plans/`**
(not under `plans/completed/`). Rule files are not a live catalog; **list
or search `plans/`** for active `PLAN-*.md` / `CURSOR-PROMPTS-*.md`.
Finished plans and prompt templates → `plans/completed/`.

## Propose-then-implement culture

The repo has a strong "propose then implement" culture
(`propose/`, `plans/`). For non-trivial features:

1. Drop a short markdown propose under `propose/` describing scope,
schema impact, reindex requirement, and tests touched.
2. For multi-PR efforts, add a matching `plans/PLAN-<topic>.md` with
per-PR sections, then `plans/CURSOR-PROMPTS-<topic>.md` with the
per-PR agent execution prompts (Cursor and Claude Code).
3. Reference the propose / plan from the PR description.
4. Move propose into `propose/completed/` (or plan into
`plans/completed/`) once the *whole* effort is landed — not after
each PR.

Skip this for clearly-bounded fixes (one-file bugs, doc edits, test
loosening). Use judgement.

## Per-PR task contract (agent handoffs)

When you're given a per-PR task prompt from `plans/CURSOR-PROMPTS-*.md`:

- **Scope is binding.** The "Out of scope (do NOT touch)" list is a
hard constraint, not a guideline. Sentinel grep patterns the prompt
lists must return zero on `git diff master..HEAD`.
- **Implement in the listed order.** Do not reshape the PR or roll
multiple PRs together.
- **Match named tests verbatim.** When the plan §4 table lists
`test_<scenario>_<expected>`, that is the exact name to use. If you
add, drop, or rename tests, update the plan/prompt text in the same
change so reviewers are not chasing a stale list.
- **No drive-by lint fixes.** Removing an unused `import` in a file
the PR doesn't otherwise touch is still a scope leak. If a file
isn't in the deliverables list, don't touch it.
- **PR description must include**: scope statement, manual evidence
(with the exact command from the prompt), and any intentional design
divergences from sibling PRs called out explicitly so the reviewer
doesn't flag them as bugs.

## Editing rules

- Respect `.claude/rules/breaking-changes.md`: no compatibility
shims, no deprecation cycles.
- One source of truth for ontology values lives in
`java_ontology.py`. Don't sprinkle role / capability / client-kind /
strategy / match string literals across other modules.
- Schema changes that affect the Lance index or Kuzu graph need a
matching update to the README "Re-index required" callout. Bump
`ontology_version` when enrichment semantics change. The current
version is **14**.
- Brownfield is a first-class surface: any new auto-detection
(route, role, capability, http client, async producer) must
compose with the matching `BrownfieldOverrides` layer. Last writer
wins (outermost layer overrides earlier ones), with one explicit
exception: caller-side `HTTP_CALLS` / `ASYNC_CALLS` use option-(b)
*replacement* rather than union when any brownfield layer fires
on a method (single network packet → single edge). See
`plans/completed/PLAN-TIER1B-COMPLETION.md` § "Caller-side composition
divergence".
- Kuzu's Python binder rejects `dict` for `MAP` columns. Store all
map-shaped graph_meta data (`routes_by_framework`,
`routes_by_layer`, `http_calls_by_strategy`,
`async_calls_by_strategy`, etc.) as `STRING` JSON blobs and decode
in `kuzu_queries.meta()`.
- `server.py` is a stdio MCP server: anything reachable from a tool
handler must not write to **stdout** (that's the JSON-RPC
transport). Diagnostics go to stderr.
- Tool `description=` strings and `_INSTRUCTIONS` in `server.py` are
read by LLM clients to choose tools — treat them as part of the
contract, not freeform docs.

## Validate

- `.venv/bin/ruff check .` — fix or justify warnings.
- `.venv/bin/python -m pytest tests -v` — must pass without `JAVA_CODEBASE_RAG_RUN_HEAVY`.
Expect skips only where tests document env gating (see `tests/README.md`).
Each plan may add tests; match the active plan if it cites a count.
- Exception for isolated automation workflow changes: if edits are limited to
`automation/cursor_propose_only/**` (plus optional docs references to that
workflow), targeted validation is enough:
- `.venv/bin/ruff check .`
- `.venv/bin/python -m pytest automation/cursor_propose_only/tests -q`
- For schema or ranking work, also run with
`JAVA_CODEBASE_RAG_RUN_HEAVY=1` locally (slow; downloads models).
- For graph builder changes, also rebuild a fixture and inspect
`java-codebase-rag meta` (or `GraphMetaOutput` from the same helper) to confirm new counters wire up:
```bash
rm -rf /tmp/check && .venv/bin/python build_ast_graph.py \
--source-root tests/bank-chat-system --kuzu-path /tmp/check --verbose
```

## Commit and PR

- Commit messages: present tense, imperative, lowercase first word,
matching existing style (e.g. `fixed call graph review D6`,
`applied fixes for call graph layer`).
- One logical change per commit when feasible.
- Branch names:
- `cursor/<topic>` — Cursor-agent work
- `feat/<topic>` — landed-feature work (e.g. `feat/b2b-http-async-edges`)
- `plan/<name>` — in-progress plan / propose drafts
- `chore/<topic>` — repo hygiene (docs, tooling, deps)
- PR body should reference any propose / plan it implements, list
user-visible behaviour changes, and call out reindex / env-var /
ontology bumps explicitly.
- Never push directly to `master`.

## Don't

- Don't run `gh auth status` or otherwise inspect credentials.
- Don't widen the public surface "just in case" — every new tool,
env var, or schema column adds a re-index burden on users.
- Don't special-case the `tests/bank-chat-system/` fixture in
production code. If a test needs it, the test is wrong (see
`tests/README.md`).
- Don't tighten loose test assertions (`>= 1`, `len(...) >= N`,
`key in result`) into exact counts to chase a number — they are
intentionally loose.
- Don't add a hard dependency on `cocoindex` outside
`java_index_flow_lancedb.py` / the `java-codebase-rag` lifecycle (`init` /
`increment` / `reprocess` / `erase`) path.
- Don't introduce a parallel `*Overrides` class when extending
brownfield support. `BrownfieldOverrides` already holds route,
role, capability, http client, and async producer dicts — extend
it in place.
5 changes: 5 additions & 0 deletions .claude/rules/breaking-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Breaking changes and compatibility

- **Breaking changes are always allowed.** Do not keep compatibility with prior versions, external consumers, or hypothetical "users" of this repo unless the current task explicitly asks for a compatibility layer.

- Prefer straightforward removals and schema or API updates over deprecation periods, dual code paths, shims, or version branching unless there is a clear, stated need in the task at hand.
72 changes: 72 additions & 0 deletions .claude/rules/project-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Project overview

This repo is a **self-contained stdio MCP server** that serves
semantic + structural search over a Java codebase. It is a Python
project (the indexer and server). It is **not** a Java project —
the `tests/bank-chat-system/` tree is fixture data, not code to
modify.

Treat README and the markdown docs as the source of truth for
behaviour, schemas, env vars, ranking, edges, tool defaults, and
ontology. **Do not copy that content into rules** — read it directly
when needed.

## Where to look

- `README.md` — feature surface, env vars, ranking, capabilities,
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 **14** (`EDGE_SCHEMA` in `java_ontology.py`; material `OVERRIDES` Symbol→Symbol edges: subtype
instance method → supertype declaration with matching `signature`, one
`IMPLEMENTS`/`EXTENDS` hop; valid `neighbors` `EdgeType`). Builds on v12
(`@CodebaseHttpClient` rename + shared `CodebaseHttpMethod` enum; inbound
`@CodebaseHttpRoute` replaces same-method built-in HTTP rows; still
`@CodebaseAsyncRoute` wins over same-method `@KafkaListener`; `Client` nodes,
`DECLARES_CLIENT`, `find(kind="client")`, HTTP_CALLS / ASYNC_CALLS caller edges,
brownfield composition from earlier bumps). Earlier ontology bumps are described
inline in the README's callouts list.
- `CODEBASE_REQUIREMENTS.md` — Java-repo assumptions and per-file
map of what to edit when a target tree doesn't match defaults.
- `tests/README.md` — testing philosophy.
- `propose/` — design proposes. **In-flight** proposes are **`*.md`
at the root of `propose/`** (not under `propose/completed/`).
**`propose/completed/`** — landed work and rationale for current code.
**List or search this tree** for current filenames; do not rely on
enumerated copies in rules.
- `plans/` — longer-form multi-PR plans (`PLAN-*.md`) and
**`CURSOR-PROMPTS-*.md`** for per-PR agent handoffs (Cursor and Claude Code).
Top-level `*.md` here are active or in-progress efforts. **`plans/completed/`** —
finished plans and completed prompt sets (templates). Same rule: **open
the directory**, don't cache a mental file list from here.
- `.claude/rules/breaking-changes.md` — the no-back-compat policy.

## File map (top of repo)

| File | Role |
|------|------|
| `server.py` | MCP stdio server. Every `@mcp.tool` lives here. |
| `search_lancedb.py` | Vector / hybrid / graph-expanded search; ranking. |
| `build_ast_graph.py` | Tree-sitter → Kuzu graph builder (full rebuild). Owns `pass1`–`pass6` (`pass5` emits `HTTP_CALLS` / `ASYNC_CALLS` caller edges; `pass6_match_edges` resolves cross-service / intra-service / ambiguous / phantom / unresolved match outcomes — ontology 7). |
| `kuzu_queries.py` | Read-only Cypher helpers used by the server. Includes `meta()` decoder for the Kuzu MAP-as-STRING JSON-blob columns. |
| `ast_java.py` | Tree-sitter Java parsing, role/capability inference, `_string_value_atoms` helper (shared by route/client/producer extractors), `_collect_outgoing_calls` for caller-side detection. |
| `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. |
| `path_filtering.py` | Layered ignore patterns (`.gitignore`-style; PR-C / B5). Reused by indexer + graph build. |
| `pr_analysis.py` | `java-codebase-rag analyze-pr` helpers (PR-B / B4) — diff parsing, hunk-to-symbol mapping. |
| `mcp.json.example` | Template for `.mcp.json`. |

## Test layout

- `tests/conftest.py` — session-scoped Kuzu graph fixture.
- `tests/bank-chat-system/` — deterministic Java corpus (fixture, not production model).
- `tests/fixtures/call_graph_smoke/` — mini Maven tree calibrated against the call-graph resolver.
- `tests/fixtures/brownfield_route_stubs/` — `@CodebaseRoute` / `@CodebaseRoutes` source stubs (PR-A3).
- `tests/fixtures/brownfield_client_stubs/` — `@CodebaseHttpClient` / `@CodebaseHttpClients` / `@CodebaseProducer` / `@CodebaseProducers` source stubs (PR-D2).
- `tests/fixtures/http_caller_smoke/` — Feign + RestTemplate + KafkaTemplate + WebClient + StreamBridge fixture for caller-side detection (PR-D1).
- Heavy e2e tests gated behind `JAVA_CODEBASE_RAG_RUN_HEAVY=1`.
10 changes: 10 additions & 0 deletions .claude/rules/python-venv-only.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Python Environment Rule

- Use only the repository `.venv/bin/python` for Python commands (repo root).
- Use only `.venv/bin/pip` for package install and dependency commands.
- Do not use system `python`, `python3`, `pip`, or `pip3` for this repo unless you have explicitly activated `.venv` and that is what those resolve to.
- When running tests, linters, or scripts, invoke the `.venv/bin` executables directly.
- Examples:
- `.venv/bin/python -m pytest tests -q`
- `.venv/bin/ruff check .`
- `.venv/bin/pip install -r requirements.txt`
18 changes: 18 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(.venv/bin/python *)",
"Bash(.venv/bin/ruff *)",
"Bash(.venv/bin/pip *)",
"Bash(gh *)",
"Read(./**)",
"Edit(./**)"
],
"deny": [
"Bash(git push *)",
"Read(./.env)",
"Read(./.env.*)"
]
}
}
16 changes: 16 additions & 0 deletions .claude/skills/java-codebase-explore/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: java-codebase-explore
description: >-
Explore an unfamiliar Java microservices codebase indexed by java-codebase-rag MCP.
Use for "explore this codebase", "map the call graph", "onboard onto this code",
"plan a change to service", "write a propose doc for redesign". Strategy guide only;
pair with docs/AGENT-GUIDE.md for exact MCP tool shapes. Not for routine PR review
(use pr-review skill).
disable-model-invocation: false
---

# java-codebase-explore

Canonical exploration strategy lives in the shared doc below. Read it when this skill activates.

@docs/skills/java-codebase-explore.md
Loading
Loading