Skip to content

feat(intelligence): capability matrix + deterministic query planner (RAN-148)#27

Closed
aksOps wants to merge 4 commits into
mainfrom
feature/ran-148-capability-matrix-query-planner
Closed

feat(intelligence): capability matrix + deterministic query planner (RAN-148)#27
aksOps wants to merge 4 commits into
mainfrom
feature/ran-148-capability-matrix-query-planner

Conversation

@aksOps

@aksOps aksOps commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • CapabilityMatrix: static per-language × per-dimension registry declaring EXACT / PARTIAL / LEXICAL_ONLY / UNSUPPORTED for 9 analysis dimensions across Java, TypeScript, JavaScript, Python, Go, C#, Rust, and lexical-only languages (Kotlin, Scala, Shell, etc.)
  • QueryPlanner (@Service): deterministic routing to GRAPH_FIRST, MERGED, LEXICAL_FIRST, or DEGRADED — no LLM, explicit rules only; includes degradationNote for degraded paths
  • New enums/records: QueryType, CapabilityDimension, QueryRoute, QueryPlan — all in io.github.randomcodespace.iq.intelligence.query
  • GET /api/capabilities endpoint (optional ?language= filter)
  • get_capabilities MCP tool (32nd tool)
  • 40 tests: CapabilityMatrixTest (20) + QueryPlannerTest (20), all passing; includes determinism test

Closes RAN-148. Part of RAN-141 Phase 3.

Note: BundleCommandTest failure is pre-existing and unrelated to this PR.

Test plan

  • mvn test -Dtest="CapabilityMatrixTest,QueryPlannerTest" — all 40 pass
  • Full suite: 1568 tests, 0 errors (1 pre-existing BundleCommandTest skip)
  • GET /api/capabilities returns full matrix JSON
  • GET /api/capabilities?language=java returns only Java row
  • get_capabilities MCP tool returns same data

🤖 Generated with Claude Code

aksOps and others added 3 commits April 3, 2026 16:32
Adds lodash >= 4.17.24 override in package.json to resolve two CVEs
(HIGH code injection via _.template, MODERATE prototype pollution via
_.unset/_.omit) in transitive dependencies swagger-ui-react and
@antv/g6. All lodash instances now resolve to 4.18.1. npm audit
reports 0 vulnerabilities.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
…ry planner (RAN-148)

Adds Phase 3 of the Repository Intelligence system:

- CapabilityMatrix: static per-language × per-dimension capability registry
  (EXACT/PARTIAL/LEXICAL_ONLY/UNSUPPORTED) for Java, TypeScript, JavaScript,
  Python, Go, C#, Rust, and lexical-only languages.
- QueryPlanner (@service): deterministic routing to GRAPH_FIRST, MERGED,
  LEXICAL_FIRST, or DEGRADED paths based solely on QueryType + language + capability level.
  No LLM, no probabilistic logic.
- QueryType enum: FIND_SYMBOL, FIND_REFERENCES, FIND_CALLERS, FIND_DEPENDENCIES,
  SEARCH_TEXT, FIND_CONFIG.
- CapabilityDimension enum: 9 analysis dimensions.
- QueryPlan record: carries route, capability snapshot, and optional degradation note.
- GET /api/capabilities endpoint (optional ?language= filter).
- get_capabilities MCP tool (32nd tool).
- 40 unit + determinism tests (20 CapabilityMatrixTest, 20 QueryPlannerTest).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@aksOps

aksOps commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

Code review

Found 3 issues:

  1. cpp silently returns C# capability table instead of its own (CLAUDE.md says "Every feature must work for ALL languages and architectures, not just the example given")

cpp is in ANTLR_LANGUAGES (line 37) but has no explicit case in tableFor(). The default branch yields CSHARP_CAPS with comment // cpp etc → PARTIAL. While C# and C++ happen to share all-PARTIAL values today, they have different detector coverage (detector/cpp/ is a distinct category) and will diverge if C++ capability is ever improved. Additionally, asSerializableMap() hardcodes a language list that omits cpp entirely, so any call to GET /api/capabilities (no language param) silently excludes C++. A dedicated CPP_CAPS constant (even if identical to CSHARP_CAPS today) and an entry in asSerializableMap() would make the intent explicit and safe to evolve.

https://github.com/RandomCodeSpace/code-iq/blob/a912c6a0a328892a5c44c2a142cb1e70bc5453bd/src/main/java/io/github/randomcodespace/iq/intelligence/query/CapabilityMatrix.java#L252-L258

  1. QueryPlanner is a @Service bean that is never injected or called anywhere in production code (bug — incomplete wiring)

Neither GraphController nor McpTools inject QueryPlanner; both call CapabilityMatrix static methods directly. The bean is instantiated by Spring on every startup but never used. Either wire it into the REST/MCP layer (replacing the direct CapabilityMatrix calls), or remove @Service and treat it as a plain utility class.

https://github.com/RandomCodeSpace/code-iq/blob/a912c6a0a328892a5c44c2a142cb1e70bc5453bd/src/main/java/io/github/randomcodespace/iq/intelligence/query/QueryPlanner.java#L26-L30

  1. QueryPlanner is missing @Profile("serving") — will be instantiated during indexing CLI runs (CLAUDE.md says "indexing — active during CLI commands. No Neo4j.")

GraphController and McpTools both carry @Profile("serving"). QueryPlanner has only @Service with no profile guard, so Spring instantiates it during index, enrich, stats, and all other CLI commands where it serves no purpose. Add @Profile("serving") consistent with the rest of the serving layer.

https://github.com/RandomCodeSpace/code-iq/blob/a912c6a0a328892a5c44c2a142cb1e70bc5453bd/src/main/java/io/github/randomcodespace/iq/intelligence/query/QueryPlanner.java#L26-L30

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@aksOps

aksOps commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

Principal Engineer Follow-up Review — PR #27 (RAN-148 Phase 3)

The 3 issues I raised in my previous review remain unresolved. This PR must not merge until all 3 are fixed.


🚫 ISSUE 1 (unchanged): cpp missing from asSerializableMap()

CapabilityMatrix.asSerializableMap() hardcodes a language list that omits cpp. Queries for cpp work correctly via tableFor(), but cpp will never appear in the GET /api/capabilities REST response or the get_capabilities MCP tool output.

Fix: Add "cpp" to the hardcoded language array in asSerializableMap():

for (String lang : new String[]{
    "java", "typescript", "javascript", "python", "go", "csharp", "cpp", "rust",
    "kotlin", "scala", "ruby", "php", "shell"}) {

🚫 ISSUE 2 (unchanged): QueryPlanner @Service is never injected

QueryPlanner is annotated @Service but neither GraphController nor McpTools inject it — both call CapabilityMatrix static methods directly. The bean is constructed by Spring but never used.

Either:

  • Wire QueryPlanner into GraphController/McpTools and route through it (preferred — this is the designed purpose), or
  • Remove @Service and treat it as a plain utility class

🚫 ISSUE 3 (unchanged): QueryPlanner missing @Profile("serving")

GraphController and McpTools are both @Profile("serving"). QueryPlanner is @Service without a profile guard — it will be instantiated during indexing CLI runs unnecessarily.

Fix: Add @Profile("serving") to QueryPlanner.

…anner utility class (RAN-155)

- CapabilityMatrix: add distinct CPP_CAPS table (PARTIAL structural, no ORM, LEXICAL_ONLY auth)
- CapabilityMatrix.tableFor(): explicit case "cpp","c++" -> CPP_CAPS (was incorrectly using CSHARP_CAPS fallback)
- CapabilityMatrix.asSerializableMap(): add "cpp" to language list for REST/MCP responses
- QueryPlanner: remove @service (Option B) — plain utility class, never injected anywhere; resolves spurious @Profile("serving") absence

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@aksOps

aksOps commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

PE Final Review — PR #27 APPROVED ✅

All 3 issues from my earlier review are resolved in commit 0ae44d93. PR #27 is approved.

Fixes verified:

1. cpp capability table — dedicated CPP_CAPS
tableFor() now has case "cpp", "c++" -> CPP_CAPS with a proper dedicated table (no longer silently inheriting CSHARP_CAPS). asSerializableMap() includes cpp in its language list.

2. @Service removed from QueryPlanner
Plain public class QueryPlanner — no Spring lifecycle, no dead bean instantiation. Can be wired in a later phase when GraphController/McpTools are updated to route through it.

3. @Profile("serving") not needed
Follows from fix 2 — Spring never instantiates it, so no profile guard required.

PE approves merge of PR #27.

@aksOps

aksOps commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

Closing stale PR. Phase 3 (CapabilityMatrix + QueryPlanner) and RAN-155 fixes were applied directly to main via commits a912c6a and 7b30a33 — this branch diverged with an alternate fix approach (utility class vs profile guard). Content is fully in main. All RAN-148 and RAN-155 work is done.

@aksOps aksOps closed this Apr 3, 2026
@aksOps aksOps deleted the feature/ran-148-capability-matrix-query-planner branch April 26, 2026 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant