From 7d6c651a2b9f1813bddc272bef9a7b20b8fe63c5 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 15 Jun 2026 11:34:48 -0400 Subject: [PATCH 1/2] Enhance prompts, resources, and tool descriptions based on real-world debugging session - data-extension-development prompt: add troubleshooting table (compilation cache, CLI discovery, subtypes on stub types, missing chain hops, column count) and Phase 8 note about when to escalate to QL library changes - csharp_library_modeling resource: add subtypes flag section with caveat about library stub types (matches existing Java modeling resource pattern) - Tool descriptions: clarify register_database (session-scoped validation), codeql_bqrs_decode (array parameter), quick_evaluate (isolation scope) - ql-tdd-basic prompt: add compilation cache pitfall Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../src/prompts/data-extension-development.prompt.md | 12 ++++++++++++ server/src/prompts/ql-tdd-basic.prompt.md | 1 + .../resources/languages/csharp_library_modeling.md | 7 +++++++ server/src/tools/codeql/bqrs-decode.ts | 2 +- server/src/tools/codeql/quick-evaluate.ts | 3 ++- server/src/tools/codeql/register-database.ts | 3 ++- 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/server/src/prompts/data-extension-development.prompt.md b/server/src/prompts/data-extension-development.prompt.md index 01a6fbf3..600e10cb 100644 --- a/server/src/prompts/data-extension-development.prompt.md +++ b/server/src/prompts/data-extension-development.prompt.md @@ -132,6 +132,8 @@ Validate the model against a real database: - If the `.model.yml` lives under `.github/codeql/extensions/` of the consuming repo, you are **done** — Code Scanning will load it on the next analysis. - If you authored a reusable model pack and want it to apply across an organization, publish it to GHCR with `codeql pack publish` and configure it under org Code security → Global settings → CodeQL analysis → Model packs. +> **When data extensions aren't enough**: If `subtypes: True` fails to match subclasses (common when the base type is a library stub not present in the database), or the detection logic cannot be expressed as a source/sink/summary tuple, a QL library change (`.qll`) is needed instead. Use the `codeql://prompts/ql-tdd-basic` workflow to develop and test the fix, then contribute it upstream to `github/codeql`. + ## Validation Checklist - [ ] Correct tuple format for the language (API Graph vs MaD) @@ -147,3 +149,13 @@ Validate the model against a real database: - `codeql://languages/{{language}}/library-modeling` — Language-specific library modeling guide - `codeql://templates/security` — Security query templates - `codeql://learning/test-driven-development` — TDD workflow for CodeQL queries + +## Troubleshooting + +| Issue | Likely Cause | Resolution | +| ----- | ------------ | ---------- | +| Extension not found by `codeql query run` | `.github/codeql/extensions/` is only auto-loaded by Code Scanning (GitHub Actions), not the CLI | Move `.model.yml` into the pack's `ext/` directory (e.g., `csharp/ql/lib/ext/`) or pass the directory via `--additional-packs` | +| Stale results after adding/changing `.model.yml` | Compilation cache is returning previously cached results | Use `--no-default-compilation-cache` with a fresh `--compilation-cache=` to force recompilation | +| `subtypes: True` not matching subclass methods | The base type only exists as a library stub in the database, not as extracted source | `subtypes` resolution requires the declaring type to be in the database. For framework base types (e.g., `PageModel`, `ControllerBase`) that are only stubs, use a QL-based source/sink class instead of a data extension | +| Extension loads but produces no findings | Missing link in the source → summary → sink chain | Verify all hops are modeled — a single missing `summaryModel` between source and sink will break the chain | +| YAML parse error or silent failure | Wrong column count for the extensible predicate | Double-check the exact column count for your language's format (MaD vs API Graph) — extra or missing columns fail silently | diff --git a/server/src/prompts/ql-tdd-basic.prompt.md b/server/src/prompts/ql-tdd-basic.prompt.md index 44c909f1..8b7be49e 100644 --- a/server/src/prompts/ql-tdd-basic.prompt.md +++ b/server/src/prompts/ql-tdd-basic.prompt.md @@ -214,6 +214,7 @@ codeql_test_accept: { - ❌ Not using #codeql_lsp_completion to discover available types - ❌ Not setting `workspace_uri` when using LSP tools (completions will be empty) - ❌ Creating tests that are too complex +- ❌ Not clearing compilation cache after adding data extensions (stale cached results hide new models) - ❌ Ignoring false positives in results - ❌ Not refactoring after tests pass diff --git a/server/src/resources/languages/csharp_library_modeling.md b/server/src/resources/languages/csharp_library_modeling.md index f62ac567..95863949 100644 --- a/server/src/resources/languages/csharp_library_modeling.md +++ b/server/src/resources/languages/csharp_library_modeling.md @@ -58,6 +58,13 @@ C# uses a **MaD (Models as Data)** format with **9–10 column tuples** that ide | `kind` | Source/sink/summary kind | `"sql-injection"`, `"taint"` | | `provenance` | Origin of the model | `"manual"` | +### Important: `subtypes` Flag + +- `True` — the model applies to the method **and all overrides** in subclasses and implementing classes +- `False` — only applies to the exact class specified + +> **Caveat**: `subtypes: True` requires the base type to be **present in the CodeQL database** as extracted source or a resolved reference. For framework base types that exist only as library stubs (e.g., `Microsoft.AspNetCore.Mvc.RazorPages.PageModel`), subtypes resolution may silently fail to match subclass methods. In these cases, model each concrete class explicitly or implement a QL-based source/sink class instead. + ### Important: C#-Specific Signature Rules - Type names must be **fully qualified**: `System.String`, not `string` diff --git a/server/src/tools/codeql/bqrs-decode.ts b/server/src/tools/codeql/bqrs-decode.ts index 568c6a24..7a6f2b9d 100644 --- a/server/src/tools/codeql/bqrs-decode.ts +++ b/server/src/tools/codeql/bqrs-decode.ts @@ -23,7 +23,7 @@ export const codeqlBqrsDecodeTool: CLIToolDefinition = { command: 'codeql', subcommand: 'bqrs decode', inputSchema: { - files: z.array(z.string()).describe('BQRS file(s) to decode'), + files: z.array(z.string()).describe('Array of BQRS file path(s) to decode. Pass an array even for a single file, e.g. ["/path/to/results.bqrs"]'), output: createCodeQLSchemas.output(), format: z.enum(['csv', 'json', 'text', 'bqrs']).optional() .describe('Output format: text (human-readable table, default), csv, json (streaming JSON), or bqrs (binary, requires --output)'), diff --git a/server/src/tools/codeql/quick-evaluate.ts b/server/src/tools/codeql/quick-evaluate.ts index 5d908b44..1730c8cd 100644 --- a/server/src/tools/codeql/quick-evaluate.ts +++ b/server/src/tools/codeql/quick-evaluate.ts @@ -60,7 +60,8 @@ export async function quickEvaluate({ export function registerQuickEvaluateTool(server: McpServer): void { server.tool( 'quick_evaluate', - 'Quick evaluate either a class or a predicate in a CodeQL query for debugging', + 'Quick evaluate a single class or predicate in isolation from a CodeQL query file. ' + + 'Useful for debugging — evaluates just the named symbol against the database without running the full query.', { file: z.string().describe('Path to the .ql file containing the symbol'), db: z.string().describe('Path to the CodeQL database'), diff --git a/server/src/tools/codeql/register-database.ts b/server/src/tools/codeql/register-database.ts index 018783f8..cf8f77c5 100644 --- a/server/src/tools/codeql/register-database.ts +++ b/server/src/tools/codeql/register-database.ts @@ -90,7 +90,8 @@ export async function registerDatabase(dbPath: string): Promise { export function registerRegisterDatabaseTool(server: McpServer): void { server.tool( 'register_database', - 'Register a CodeQL database given a local path to the database directory', + 'Register a CodeQL database for use by other MCP tools in this session. ' + + 'Validates the database directory exists, contains codeql-database.yml, and has source files (src.zip or src/).', { db_path: z.string().describe('Path to the CodeQL database directory'), }, From 87a8e23280879a15a41177171d129d1aa0c32a44 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:49:14 -0400 Subject: [PATCH 2/2] Address PR review: fix tool description accuracy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - register_database: remove 'in this session' claim — tool only validates, does not persist session state. Clarify it's a preflight check. - quick_evaluate: remove claim that it evaluates against the database — current implementation only resolves symbol position. Note that codeql_query_run should be used for full evaluation. - codeql_bqrs_decode: fix 'path(s)' to 'paths' per grammar feedback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- server/src/tools/codeql/bqrs-decode.ts | 2 +- server/src/tools/codeql/quick-evaluate.ts | 6 ++++-- server/src/tools/codeql/register-database.ts | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/server/src/tools/codeql/bqrs-decode.ts b/server/src/tools/codeql/bqrs-decode.ts index 7a6f2b9d..2e406c00 100644 --- a/server/src/tools/codeql/bqrs-decode.ts +++ b/server/src/tools/codeql/bqrs-decode.ts @@ -23,7 +23,7 @@ export const codeqlBqrsDecodeTool: CLIToolDefinition = { command: 'codeql', subcommand: 'bqrs decode', inputSchema: { - files: z.array(z.string()).describe('Array of BQRS file path(s) to decode. Pass an array even for a single file, e.g. ["/path/to/results.bqrs"]'), + files: z.array(z.string()).describe('Array of BQRS file paths to decode. Pass an array even for a single file, e.g. ["/path/to/results.bqrs"]'), output: createCodeQLSchemas.output(), format: z.enum(['csv', 'json', 'text', 'bqrs']).optional() .describe('Output format: text (human-readable table, default), csv, json (streaming JSON), or bqrs (binary, requires --output)'), diff --git a/server/src/tools/codeql/quick-evaluate.ts b/server/src/tools/codeql/quick-evaluate.ts index 1730c8cd..c5c69c5d 100644 --- a/server/src/tools/codeql/quick-evaluate.ts +++ b/server/src/tools/codeql/quick-evaluate.ts @@ -60,8 +60,10 @@ export async function quickEvaluate({ export function registerQuickEvaluateTool(server: McpServer): void { server.tool( 'quick_evaluate', - 'Quick evaluate a single class or predicate in isolation from a CodeQL query file. ' + - 'Useful for debugging — evaluates just the named symbol against the database without running the full query.', + 'Resolve a class or predicate symbol in a CodeQL query file for quick evaluation. ' + + 'Locates the symbol position and returns an output path for results. ' + + 'Note: this tool validates the symbol exists but does not yet execute the evaluation — ' + + 'use codeql_query_run for full evaluation.', { file: z.string().describe('Path to the .ql file containing the symbol'), db: z.string().describe('Path to the CodeQL database'), diff --git a/server/src/tools/codeql/register-database.ts b/server/src/tools/codeql/register-database.ts index cf8f77c5..7a2fd4e0 100644 --- a/server/src/tools/codeql/register-database.ts +++ b/server/src/tools/codeql/register-database.ts @@ -90,8 +90,9 @@ export async function registerDatabase(dbPath: string): Promise { export function registerRegisterDatabaseTool(server: McpServer): void { server.tool( 'register_database', - 'Register a CodeQL database for use by other MCP tools in this session. ' + - 'Validates the database directory exists, contains codeql-database.yml, and has source files (src.zip or src/).', + 'Register a CodeQL database for use by other MCP tools. ' + + 'Validates that the database directory exists, contains codeql-database.yml, and has source files (src.zip or src/). ' + + 'Does not persist any session state — acts as a preflight check before using other database tools.', { db_path: z.string().describe('Path to the CodeQL database directory'), },