feat(query): GraphRAG prompt compiler — cgis context <fqn> (#19)#219
Conversation
New agent-facing context compiler: feeds an LLM a compact, XML-tagged package about a focal node (source snippet, enclosing class, domain boundary, callers, callees) in place of raw file dumps. - query/snippet.py: extract_snippet (linecache, graceful on missing/EOF) - query/prompt.py: pure compile_context — Hybrid XML, adaptive code-fence anti-injection, graceful degradation, L3 <domain> boundary block - query/context_service.py: orchestration — CALLS-filtered direct neighbours, INTERNAL-only (builtins/third-party dropped as noise), structural-parent class context, unresolved raw_call list - cli.py `cgis context` (clean stdout payload, stderr resolve notes, --source-root to locate snippets after `ingest ./src`) - mcp_server.py cgis_context tool (MCP_REFERENCE left to the autodoc sync) Mermaid is a visual format an LLM parses at several times the token cost, so adjacency is rendered as FQN+location bullet lists; only the focal node's source is inlined, never whole files. Dogfooded via cgis MCP + CLI (which caught two noise bugs: junk domain block from the structural ontology_class fallback, and builtin callees — both fixed). Incorporates @kehansama's two-layer-context insight: the <domain> block surfaces the focal node's architectural boundary so agents respect it during refactoring. Adaptive depth + centrality token-budgeting deferred to a follow-up. Closes #19 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
/guardian review |
There was a problem hiding this comment.
Summary: Found 3 real defects: (1) unresolved callees logic misses incoming unresolved calls, (2) structural parent lookup may return incorrect parent, (3) domain section may emit for structural ontology_class without domains. All other changes appear correct and well-tested.
🤖 mistral-medium-latest · 15,503 prompt + 711 completion = 16,214 tokens · graph 5/10 files (50%)
There was a problem hiding this comment.
Code Review
This pull request introduces a new feature to compile an agent-facing GraphRAG context package for a focal FQN, adding a new MCP tool, a CLI command, and dedicated services for context orchestration, prompt compilation, and source snippet extraction. The code review feedback suggests several key improvements: normalizing file paths to ensure cross-platform compatibility on POSIX systems, escaping source code to prevent XML injection vulnerabilities, and improving robustness when resolving structural parent nodes by continuing the search if a node is missing from the database.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
… parent preference - prompt.py: neutralize `</` in source so a file containing `</source>`/`</context>` can't close the prompt's own XML tags (gemini SEC-HIGH). Surgical `</`-escape keeps `->` return arrows, generics and comparisons readable, unlike a blanket `<`/`>` escape (verified by dogfood: `def f() -> Node` stays intact). - context_service.py: normalize Windows backslash file_paths before locating the snippet so Windows-ingested graphs still read source on POSIX (gemini HIGH). - context_service.py: `_structural_parent` now skips parents missing from the store and prefers the enclosing CLASS over a FILE/MODULE so a method's class context is never lost to an earlier file-level edge (gemini MEDIUM + guardian). Rejected (guardian, empirically): the unresolved-callee `edge.target` "fix" — callees come from get_flow_graph (outgoing), so `edge.source == focus` is correct and a raw_call target is never the focus; and the domain-block claim — already gated on `focus.domains`, the finder reviewed a pre-fix hunk. 5 new regression tests. 902 pass, mypy strict, doc 99.6%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new feature to compile and output an agent-facing GraphRAG context package for a focal FQN, adding a new CLI command, an MCP tool, and supporting orchestration, prompt compilation, and snippet extraction services along with comprehensive unit tests. The code review feedback is highly constructive, suggesting an optimization in the snippet extractor to break early on EOF to avoid performance bottlenecks, and recommending the escaping of special characters in XML attributes to prevent malformed XML generation.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Code review —
|
…tr-escape Addresses the colleague cross-review + gemini round 2 on #219. - depth default 1 (was 2): callers/callees lists are now *direct* by default, so the `_collect_*` data and the section notes are honest. `--depth N` still pulls transitive neighbours, but the note states the hop bound ("callers within N hops …") instead of mislabeling them "direct" (colleague 🔴 #1). - unresolved callees collected across the whole traversal, not just the focal node's own edges — symmetric with the resolved set at depth>1 (colleague 🟠 #2). - `_neutralize_closing_tags` now escapes only the closing tags THIS module emits (regex over source/context/class/domain/callers/callees), so TS/JSX `</div>` and generics reach the agent verbatim while injection is still blocked (colleague 🟡 #3). - `_escape_xml_attr` helper applied to every XML attribute (focal id/file, class name/file, domain ontology/domains) so `&`/`"`/`<`/`>` can't malform the tags (gemini MEDIUM ×4). - snippet: break on linecache EOF ("" sentinel) so a corrupt/huge end_line can't spin millions of empty reads; a blank middle line ("\n") is still preserved (gemini MEDIUM). CLI/MCP `cgis context` depth default → 1 to match. 8 new/updated tests, 908 pass, mypy strict, doc 99.6%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks for the cross-review — all three addressed in d61be5c. 🔴 1. depth labeling. You nailed the real defect: the lists were honest only at depth 1, but the default was 2, so transitive neighbours rode under a "direct" note. Fixed by making depth default 1 (the 🟠 2. unresolved asymmetry. 🟡 3. TS/JSX mangling. Also took gemini's round-2 attribute-escaping ( |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements a GraphRAG context compiler feature that generates XML-tagged prompt contexts for focal FQNs, including their source snippets, enclosing classes, and call relationships. The changes introduce a new CLI command, an MCP tool, and supporting services for context orchestration, snippet extraction, and prompt rendering, backed by comprehensive unit tests. The review feedback suggests refactoring the structural parent resolution logic in context_service.py to avoid variable leakage caused by using an assignment expression inside a list comprehension.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Round 2 — fixes verified ✅Re-reviewed
Two unprompted hardenings I'll call out as good catches:
No regressions spotted in the round-2 changes. Optional micro-nit (non-blocking): LGTM to merge. 🚢 🤖 via |
…alrus leak - prompt.py: `_OWN_CLOSING_TAG` now allows whitespace before `>` (`</source >`), the only injection variant the exact match missed (colleague non-blocking nit). Case stays sensitive — tags are lowercase and XML end-tags are case-sensitive, so `</SOURCE>` can't close `<source>` anyway. - context_service.py: `_structural_parent` rebuilt as a generator + filter comprehension instead of a `:=` walrus inside the list comp (which leaked `parent` to the function scope) — same behaviour, cleaner (gemini MEDIUM). 909 tests, mypy strict, doc 99.6%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks for the 🚢 — and good eye on the whitespace nit. Took it anyway in 8889a38: |
|



What
Implements #19 — a GraphRAG prompt compiler that feeds an LLM coding agent a compact, structured context package about the node it's about to edit, in place of raw file dumps.
New
cgis context <fqn>CLI +cgis_contextMCP tool emit an XML-tagged package:Design decisions
trace/impact/structure(Rich trees) + Mermaid. Socontextoptimises for LLM token-efficiency + parseability.--format mermaidis a possible follow-up.)linecache), with an adaptive code-fence guard against</source>/backtick prompt-injection.len,ValueError,pathlib.Path) are dropped as noise; truly-unknown calls still surface via the unresolvedraw_call:list.<domain>block (from @kehansama's two-layer-context insight) — surfaces the focal node's architectural boundary, gated on realdomainstags (not the structuralontology_classfallback).Architecture (Lane B, zero-conflict)
Mirrors the
drift_service+graph_jsonsplit:query/snippet.py— pure-ish I/O leaf (extract_snippet)query/prompt.py— purecompile_context(TDD'd in isolation)query/context_service.py— orchestration (resolve → CALLS-filtered neighbours → class context → assemble)cli.py/mcp_server.py— thin append-only wrappersDogfooding
Built and verified end-to-end via the cgis MCP +
cgis contexton its own code — which caught two noise bugs (junk<domain>block from the structuralontology_classfallback; builtin callees) that are fixed here.Deferred (follow-up issue, crediting @kehansama)
depth ≈ log(out_degree+1); leaf→1, hub→3+)Verification
make format lint type-check pytest doc-coverageall green — 898 unit + 48 self-parsing, mypy strict, doc 99.6%. No self-drift re-baseline (new modules fit thecgis.querypattern). MCP_REFERENCE intentionally left to the autodoc sync.Closes #19
🤖 Generated with Claude Code