CodeQL Analysis Supported languages: Python, JavaScript/TypeScript, Go, Java/Kotlin, C/C++, C#, Ruby, Swift. Skill resources: Reference files and templates are located at and . Essential Principles 1. Database quality is non-negotiable. A database that builds is not automatically good — a cached build extracts nothing while reporting success. 2. Data extensions catch what CodeQL misses. Django, Spring, and Express projects still wrap database calls, request parsing, and shell execution in project-specific APIs that no shipped model covers. 3. Explicit suite references prevent silent query dro…

. --exclude 'static_analysis_codeql_*' --exclude 'codeql_*.db' | while read -r f; do\n if grep -q 'dataExtensions' \"$f\"; then\n echo \"MODEL PACK: $(dirname \"$f\") - $(grep '^name:' \"$f\")\"\n fi\ndone\n\n# 2. Standalone data extension files\nrg -l '^extensions:' --glob '*.yml' --glob '!static_analysis_codeql_*/**' --glob '!codeql_*.db/**' | head -20\n\n# 3. Installed model packs\ncodeql resolve qlpacks 2>/dev/null | grep -iE 'model|extension'\n```\n\n**If any found:** Report to user and finish. These will be picked up by the run-analysis workflow.\n\n**If none found:** Proceed to Step 2.\n\n---\n\n### Step 2: Query Known Sources and Sinks\n\n**Entry:** Step 1 found no existing extensions; database and language identified\n**Exit:** `sources.csv` and `sinks.csv` exist in `$DIAG_DIR` with enumerated source/sink locations\n\nRun custom QL queries against the database to enumerate all sources and sinks CodeQL currently recognizes.\n\n#### 2a: Select Database and Language\n\n`$DB_NAME` may already be set by the parent skill. If not, discover with `find_databases.sh`,\nwhich filters candidates through `codeql resolve database`. Do not use a bare `find` for the\nmarker file: `codeql database create` writes `codeql-database.yml` before the build finishes, so\na run killed mid-build leaves one behind. Selecting it here makes `list-sources.ql` and\n`list-sinks.ql` return nothing, `sources.csv` and `sinks.csv` come back empty, and Step 3's\n\"no missing models identified\" early exit reports coverage as adequate for a database that was\nnever finalized.\n\n```bash\nif [ -z \"$DB_NAME\" ]; then\n # Discovery and selection share a block: an array built in an earlier Bash call is gone by\n # this one, and an empty FOUND_DBS reads as \"no database\".\n # Command substitution, not `done \u003c \u003c(...)`: a process substitution discards the script's\n # exit status, so exit 2 (\"codeql not on this shell's PATH\") would arrive as an empty list\n # and be reported below as \"No CodeQL database found\".\n if ! DB_LIST=$(\"{baseDir}/scripts/find_databases.sh\" \"${OUTPUT_DIR:-.}\" .); then\n echo \"ERROR: database discovery failed — see the message above\" >&2\n exit 1\n fi\n\n FOUND_DBS=()\n while IFS= read -r db; do\n [ -n \"$db\" ] || continue\n FOUND_DBS+=(\"$db\")\n done \u003c\u003c\u003c\"$DB_LIST\"\n\n if [ ${#FOUND_DBS[@]} -eq 0 ]; then\n echo \"ERROR: No CodeQL database found in $OUTPUT_DIR\"; exit 1\n elif [ ${#FOUND_DBS[@]} -eq 1 ]; then\n DB_NAME=\"${FOUND_DBS[0]}\"\n else\n # Multiple databases. Use AskUserQuestion to select, or skip the prompt if the user\n # already named one. The `:` is required: an else branch containing only comments is\n # a bash syntax error and the block will not parse.\n :\n fi\nfi\n\nCODEQL_LANG=$(codeql resolve database --format=json -- \"$DB_NAME\" | jq -r '.languages[0]')\nDIAG_DIR=\"$OUTPUT_DIR/diagnostics\"\nmkdir -p \"$DIAG_DIR\"\n```\n\n#### 2b: Write Source Enumeration Query\n\nUse the `Write` tool to create `$DIAG_DIR/list-sources.ql` using the source template from [diagnostic-query-templates.md](../references/diagnostic-query-templates.md#source-enumeration-query). Pick the correct import block for `$CODEQL_LANG`.\n\n#### 2c: Write Sink Enumeration Query\n\nUse the `Write` tool to create `$DIAG_DIR/list-sinks.ql` using the language-specific sink template from [diagnostic-query-templates.md](../references/diagnostic-query-templates.md#sink-enumeration-queries).\n\n**For Java:** Also create `$DIAG_DIR/qlpack.yml` with a `codeql/java-all` dependency and run `codeql pack install` before executing queries.\n\n#### 2d: Run Queries\n\n```bash\ncodeql query run --database=\"$DB_NAME\" --output=\"$DIAG_DIR/sources.bqrs\" -- \"$DIAG_DIR/list-sources.ql\"\ncodeql bqrs decode --format=csv --output=\"$DIAG_DIR/sources.csv\" -- \"$DIAG_DIR/sources.bqrs\"\n\ncodeql query run --database=\"$DB_NAME\" --output=\"$DIAG_DIR/sinks.bqrs\" -- \"$DIAG_DIR/list-sinks.ql\"\ncodeql bqrs decode --format=csv --output=\"$DIAG_DIR/sinks.csv\" -- \"$DIAG_DIR/sinks.bqrs\"\n```\n\n#### 2e: Summarize Results\n\nRead both CSV files and present a summary showing source types and sink kinds with counts.\n\n---\n\n### Step 3: Identify Missing Sources and Sinks\n\n**Entry:** Step 2 complete (`sources.csv` and `sinks.csv` available)\n**Exit:** Either no gaps found (report adequate coverage and finish) OR user confirms which gaps to model (proceed to Step 4)\n\nCross-reference the project's API surface against CodeQL's known models.\n\n#### 3a: Map the Project's API Surface\n\nRead source code to identify security-relevant patterns:\n\n| Pattern | What To Find | Likely Model Type |\n|---------|-------------|-------------------|\n| HTTP/request handlers | Custom request parsing | `sourceModel` (kind: `remote`) |\n| Database layers | Custom ORM, raw query wrappers | `sinkModel` (kind: `sql-injection`) |\n| Command execution | Shell wrappers, process spawners | `sinkModel` (kind: `command-injection`) |\n| File operations | Custom file read/write | `sinkModel` (kind: `path-injection`) |\n| Template rendering | HTML output, response builders | `sinkModel` (kind: `xss`) |\n| Deserialization | Custom deserializers | `sinkModel` (kind: `unsafe-deserialization`) |\n| HTTP clients | URL construction | `sinkModel` (kind: `ssrf`) |\n| Sanitizers | Input validation, escaping | `neutralModel` |\n| Pass-through wrappers | Logging, caching, encoding | `summaryModel` (kind: `taint`) |\n\nUse `Grep` to search for these patterns in source code (adapt per language).\n\n#### 3b: Cross-Reference Against Known Sources and Sinks\n\nFor each API pattern found, check if it appears in `sources.csv` or `sinks.csv` from Step 2.\n\n**An API is \"missing\" if:**\n- It handles user input but does not appear in `sources.csv`\n- It performs a dangerous operation but does not appear in `sinks.csv`\n- It wraps tainted data but has no summary model\n\n#### 3c: Report Gaps\n\nPresent findings and use `AskUserQuestion`:\n\n```\nheader: \"Extensions\"\nquestion: \"Create data extension files for the identified gaps?\"\noptions:\n - label: \"Create all (Recommended)\"\n description: \"Generate extensions for all identified gaps\"\n - label: \"Select individually\"\n description: \"Choose which gaps to model\"\n - label: \"Skip\"\n description: \"No extensions needed, proceed to analysis\"\n```\n\n---\n\n### Step 4: Create Data Extension Files\n\n**Entry:** Step 3 identified gaps and user confirmed which to model\n**Exit:** YAML extension files created in `$OUTPUT_DIR/extensions/` and deployed to `\u003clang>-all` ext/ directory\n\nGenerate YAML data extension files for the gaps confirmed by the user.\n\n#### File Structure\n\nCreate files in `$OUTPUT_DIR/extensions/`:\n\n```\n$OUTPUT_DIR/extensions/\n sources.yml # sourceModel entries\n sinks.yml # sinkModel entries\n summaries.yml # summaryModel and neutralModel entries\n```\n\n#### YAML Format and Deployment\n\nSee [extension-yaml-format.md](../references/extension-yaml-format.md) for column definitions, per-language examples (Python, Java, JS, Go, C/C++), and the deployment workaround for pre-compiled query packs.\n\nUse the `Write` tool to create each file. Only create files that have entries — skip empty categories.\n\n---\n\n### Step 5: Validate with Re-Analysis\n\n**Entry:** Step 4 complete (extension files deployed)\n**Exit:** Finding delta measured (with-extensions count >= baseline count); extensions validated as loading correctly\n\nRun a full security analysis with and without extensions to measure the finding delta.\n\n#### 5a: Run Baseline Analysis (without extensions)\n\nValidation artifacts go in `$DIAG_DIR` (not `results/`) since these are intermediate comparisons, not the final analysis output.\n\n```bash\ncodeql database analyze \"$DB_NAME\" \\\n --format=sarif-latest --output=\"$DIAG_DIR/baseline.sarif\" --threads=0 \\\n -- codeql/\u003clang>-queries:codeql-suites/\u003clang>-security-extended.qls\n```\n\n#### 5b: Run Analysis with Extensions\n\n```bash\ncodeql database cleanup \"$DB_NAME\"\ncodeql database analyze \"$DB_NAME\" \\\n --format=sarif-latest --output=\"$DIAG_DIR/with-extensions.sarif\" --threads=0 --rerun \\\n -- codeql/\u003clang>-queries:codeql-suites/\u003clang>-security-extended.qls\n```\n\nUse `-vvv` flag to verify extensions are being loaded.\n\n#### 5c: Compare Findings\n\n```bash\nBASELINE=$(python3 -c \"import json; print(sum(len(r.get('results',[])) for r in json.load(open('$DIAG_DIR/baseline.sarif')).get('runs',[])))\")\nWITH_EXT=$(python3 -c \"import json; print(sum(len(r.get('results',[])) for r in json.load(open('$DIAG_DIR/with-extensions.sarif')).get('runs',[])))\")\necho \"Findings: $BASELINE → $WITH_EXT (+$((WITH_EXT - BASELINE)))\"\n```\n\n**If counts did not increase:** Check extension loading (`-vvv`), pre-compiled pack workaround, Java `True`/`False` capitalization, column value accuracy.\n\n---\n\n## Final Output\n\n```\n## Data Extensions Created\n\n**Output directory:** $OUTPUT_DIR\n**Database:** $DB_NAME\n**Language:** \u003cLANG>\n\n### Files Created:\n- $OUTPUT_DIR/extensions/sources.yml — \u003cN> source models\n- $OUTPUT_DIR/extensions/sinks.yml — \u003cN> sink models\n- $OUTPUT_DIR/extensions/summaries.yml — \u003cN> summary/neutral models\n\n### Model Coverage:\n- Sources: \u003cBEFORE> → \u003cAFTER> (+\u003cDELTA>)\n- Sinks: \u003cBEFORE> → \u003cAFTER> (+\u003cDELTA>)\n\n### Usage:\nExtensions deployed to `\u003clang>-all` ext/ directory (auto-loaded).\nSource files in `$OUTPUT_DIR/extensions/` for version control.\nRun the run-analysis workflow to use them.\n```\n\n## References\n\n- [Threat models reference](../references/threat-models.md) — control which source categories are active during analysis\n- [CodeQL data extensions](https://codeql.github.com/docs/codeql-cli/using-custom-queries-with-the-codeql-cli/#using-extension-packs)\n- [Customizing library models](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-python/)\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":10555,"content_sha256":"f3643e4916e7586c7738c14f781e3919bce35129d75beb00812b963efbbc4673"},{"filename":"workflows/run-analysis.md","content":"# Run Analysis Workflow\n\nExecute CodeQL security queries on an existing database with ruleset selection and result formatting.\n\n## Scan Modes\n\nTwo modes control analysis scope. Both use all installed packs — the difference is filtering.\n\n| Mode | Description | Suite Reference |\n|------|-------------|-----------------|\n| **Run all** | The `security-and-quality` + `security-experimental` suites from every installed pack. Not literally every query in the packs — see [run-all-suite.md](../references/run-all-suite.md) | [run-all-suite.md](../references/run-all-suite.md) |\n| **Important only** | Security queries filtered by precision and security-severity threshold | [important-only-suite.md](../references/important-only-suite.md) |\n\n> **WARNING:** Do NOT pass pack names directly to `codeql database analyze` (e.g., `-- codeql/cpp-queries`). Each pack's `defaultSuiteFile` silently applies strict filters and can produce zero results. Always use an explicit suite reference.\n\n---\n\n## The one gate\n\nAsk once, in Step 3, and present everything the run depends on together: scan mode, query\npacks, model packs, and threat model.\n\nLet the user change any part, then proceed. If the user already specified something in\ntheir prompt, show it as chosen rather than asking again.\n\n---\n\n## Steps\n\n### Step 1: Select Database and Detect Language\n\n**Entry:** `$OUTPUT_DIR` is set (from parent skill). `$DB_NAME` may already be set if the parent skill resolved database selection.\n**Exit:** `DB_NAME` and `CODEQL_LANG` variables set; database resolves successfully.\n\n**If `$DB_NAME` is already set** (parent skill handled database selection): validate it and proceed.\n\n**If `$DB_NAME` is not set:** discover databases with `find_databases.sh`, which filters\ncandidates through `codeql resolve database` so a marker file left behind by a failed\nbuild cannot be selected as though it were a database.\n\n```bash\n# Discovery and selection must share a block: an array built in an earlier Bash call is\n# gone by this one, and an empty FOUND_DBS reads as \"no database\" for a project that has\n# one. The script is what SKILL.md's Database Discovery section calls too, so the search\n# depth and the validity filter are defined once.\nif [ -z \"${DB_NAME:-}\" ]; then\n # Command substitution, not `done \u003c \u003c(...)`: a process substitution discards the script's\n # exit status, so exit 2 (\"codeql not on this shell's PATH\" — a fresh shell each block,\n # so the preflight's PATH does not carry) would arrive here as an empty list and be\n # reported as \"No CodeQL database found\" for a project that has several.\n if ! DB_LIST=$(\"{baseDir}/scripts/find_databases.sh\" \"${OUTPUT_DIR:-.}\" .); then\n echo \"ERROR: database discovery failed — see the message above\" >&2\n exit 1\n fi\n\n FOUND_DBS=()\n while IFS= read -r db; do\n [ -n \"$db\" ] || continue\n FOUND_DBS+=(\"$db\")\n done \u003c\u003c\u003c\"$DB_LIST\"\n\n if [ \"${#FOUND_DBS[@]}\" -eq 0 ]; then\n echo \"ERROR: No CodeQL database found in $OUTPUT_DIR or project root\" >&2\n exit 1\n elif [ \"${#FOUND_DBS[@]}\" -eq 1 ]; then\n DB_NAME=\"${FOUND_DBS[0]}\"\n else\n # More than one: select with AskUserQuestion, at most four options — the three most\n # recent plus \"Build a new database\", the rest named in the prompt text. Skip the\n # prompt when the user already said which database to use.\n #\n # DB_NAME stays unset here on purpose, and the check below turns that into an error.\n # Falling through to FOUND_DBS[0] would analyse whichever database `find` happened to\n # return first — a different language or a stale build, chosen without the user ever\n # being told there was a choice. The `:` is required: an else branch of only comments\n # is a bash syntax error.\n :\n fi\nfi\n\nif [ -z \"${DB_NAME:-}\" ]; then\n echo \"ERROR: more than one database found. Ask which one, then re-run this block with DB_NAME set.\" >&2\n exit 1\nfi\n\nCODEQL_LANG=$(codeql resolve database --format=json -- \"$DB_NAME\" | jq -r '.languages[0]')\necho \"Using: $DB_NAME (language: $CODEQL_LANG)\"\n```\n\nIf the database holds more than one language, ask which to analyze.\n\n---\n\n### Step 2: Gather What the Run Depends On\n\n**Entry:** Step 1 complete (`DB_NAME` and `CODEQL_LANG` set)\n**Exit:** Scan mode, installed packs, and model packs determined. Nothing presented to the user yet.\n\nCollect everything here and present it as one plan in Step 3. Default the scan mode to\n**run all** unless the user's prompt says otherwise.\n\n#### 2a: Query Packs\n\nFor each pack available for the detected language (see [ruleset-catalog.md](../references/ruleset-catalog.md)):\n\n| Language | Trail of Bits | Community Pack |\n|----------|---------------|----------------|\n| C/C++ | `trailofbits/cpp-queries` | `GitHubSecurityLab/CodeQL-Community-Packs-CPP` |\n| Go | `trailofbits/go-queries` | `GitHubSecurityLab/CodeQL-Community-Packs-Go` |\n| Java | `trailofbits/java-queries` | `GitHubSecurityLab/CodeQL-Community-Packs-Java` |\n| JavaScript | — | `GitHubSecurityLab/CodeQL-Community-Packs-JavaScript` |\n| Python | — | `GitHubSecurityLab/CodeQL-Community-Packs-Python` |\n| C# | — | `GitHubSecurityLab/CodeQL-Community-Packs-CSharp` |\n| Ruby | — | `GitHubSecurityLab/CodeQL-Community-Packs-Ruby` |\n\nCheck if installed (`codeql resolve qlpacks | grep -i \"\u003cPACK_NAME>\"`). If not, ask user to install or ignore.\n\n#### 2b: Detect Model Packs\n\nSearch three locations for data extension model packs:\n1. **In-repo model packs** — `qlpack.yml`/`codeql-pack.yml` with `dataExtensions`\n2. **In-repo standalone data extensions** — `.yml` files with `extensions:` key\n3. **Installed model packs** — resolved by CodeQL\n\nRecord all detected packs for Step 3.\n\n---\n\n### Step 3: Confirm the Plan\n\n**Entry:** Step 2 complete (mode, pack availability, and model packs all determined)\n**Exit:** User confirmed; flag arrays built (`THREAT_MODEL_FLAGS`, `MODEL_PACK_FLAGS`, `ADDITIONAL_PACK_FLAGS`)\n\nPresent the whole plan in one `AskUserQuestion`, defaults filled in, and let the user\nchange any part before proceeding:\n\n```\n## CodeQL Analysis Plan\n\n**Database:** $DB_NAME (language: $CODEQL_LANG)\n**Scan mode:** Run all | Important only\n**Query packs:** \u003cinstalled packs — official, Trail of Bits, Community>\n**Model packs:** \u003cdetected packs, or \"None\">\n**Threat model:** Remote only (default) | + Local | All sources\n\nChange anything, or say proceed.\n```\n\nDefaults, all overridable: **run all**, every installed pack, every detected model pack,\nand **remote-only** threat models. Remote-only matches CodeQL's default. Widen it for CLI\ntools, file parsers, and config readers, where the sources are `local` rather than\n`remote`. See [threat-models.md](../references/threat-models.md).\n\nBuild the flags from the answer as arrays: `THREAT_MODEL_FLAGS=()` for remote-only,\n`THREAT_MODEL_FLAGS=(--threat-model local)`, and so on. See Step 4 for why arrays rather\nthan strings.\n\n**Model pack flags:**\n- In-repo standalone extensions (`.yml`) are auto-discovered — pass source directory via `--additional-packs`\n- In-repo model packs (with `qlpack.yml`) need parent directory via `--additional-packs`\n- Installed model packs use `--model-packs`\n\n---\n\n### Step 4: Execute Analysis\n\n**Entry:** Step 3 complete (all flags and pack selections finalized)\n**Exit:** `$RAW_DIR/results.sarif` exists and contains valid SARIF output\n\n#### Log selected query packs\n\nWrite the selected query packs, model packs, and threat models to `$OUTPUT_DIR/rulesets.txt`:\n\n```bash\ncat > \"$OUTPUT_DIR/rulesets.txt\" \u003c\u003c RULESETS\n# CodeQL Analysis — Selected Query Packs\n# Generated: $(date -Iseconds)\n# Scan mode: \u003crun-all|important-only>\n# Database: $DB_NAME\n# Language: $CODEQL_LANG\n\n## Query packs:\n\u003cone pack per line>\n\n## Model packs:\n\u003cone pack per line, or \"None\">\n\n## Threat models:\n\u003cthreat model selection, or \"default (remote)\">\nRULESETS\n```\n\n#### Generate custom suite\n\n**Important-only mode:** Generate the custom `.qls` suite using the template and script in [important-only-suite.md](../references/important-only-suite.md).\n\n**Run-all mode:** Generate the custom `.qls` suite using the template in [run-all-suite.md](../references/run-all-suite.md).\n\n```bash\nset -euo pipefail\n\nRAW_DIR=\"$OUTPUT_DIR/raw\"\nRESULTS_DIR=\"$OUTPUT_DIR/results\"\nmkdir -p \"$RAW_DIR\" \"$RESULTS_DIR\"\n# SCAN_MODE is \"run-all\" or \"important-only\", chosen in Step 3.\nSUITE_FILE=\"$RAW_DIR/${SCAN_MODE}.qls\"\n```\n\nThe generation scripts above end by running `verify_query_suite.py`, so a suite produced\nhere is already checked. **Run it explicitly only if the suite came from somewhere else** —\nreused from a previous run, or hand-edited:\n\n```bash\nuv run {baseDir}/scripts/verify_query_suite.py \"$SUITE_FILE\"\n```\n\n#### Run analysis\n\nOutput goes to `$RAW_DIR/results.sarif` (unfiltered). The final results are produced in Step 5.\n\nBuild the optional flags as **arrays**, not strings. A quoted empty string becomes an\nempty argument that CodeQL rejects, and leaving a string unquoted so it can be empty also\nlets `$DB_NAME` split on spaces. An array expands to nothing when empty and to each\nelement intact otherwise.\n\nExpand them as `\"${ARRAY[@]+\"${ARRAY[@]}\"}\"`, not `\"${ARRAY[@]}\"`. Before bash 4.4 an\nempty array under `set -u` is an unbound variable, so on macOS's `/bin/bash` 3.2 the plain\nform aborts with `THREAT_MODEL_FLAGS[@]: unbound variable` before CodeQL runs — for the\ndocumented default, a user who selected no threat models and no model packs.\n\n**Declare the three arrays and the scalars in this block, filled in with the choices from\nStep 3.** Nothing survives from Step 3 — see\n[Each Bash call is a fresh shell](../SKILL.md#each-bash-call-is-a-fresh-shell). Leaving an\narray empty is correct only when Step 3 selected nothing for it.\n\n```bash\nset -euo pipefail\n\nDB_NAME=\"${DB_NAME:?set this to the database selected in Step 1}\"\nRAW_DIR=\"${RAW_DIR:-$OUTPUT_DIR/raw}\"\nSUITE_FILE=\"${SUITE_FILE:?set this to the .qls written in Step 2}\"\nmkdir -p \"$RAW_DIR\"\n\n# Fill these from the Step 3 answers. Empty means \"the user chose none\".\nTHREAT_MODEL_FLAGS=() # e.g. (--threat-model local --threat-model environment)\nMODEL_PACK_FLAGS=() # e.g. (--model-packs myorg/java-models)\nADDITIONAL_PACK_FLAGS=() # e.g. (--additional-packs ./codeql-extensions)\n\ncodeql database analyze \"$DB_NAME\" \\\n --format=sarif-latest \\\n --output=\"$RAW_DIR/results.sarif\" \\\n --threads=0 \\\n ${THREAT_MODEL_FLAGS[@]+\"${THREAT_MODEL_FLAGS[@]}\"} \\\n ${MODEL_PACK_FLAGS[@]+\"${MODEL_PACK_FLAGS[@]}\"} \\\n ${ADDITIONAL_PACK_FLAGS[@]+\"${ADDITIONAL_PACK_FLAGS[@]}\"} \\\n -- \"$SUITE_FILE\"\n```\n\n`set -e` matters here: a failed analysis (out of memory, an unresolvable model pack) leaves\n`raw/results.sarif` truncated or absent, and without it Step 5 copies that file forward and\nthe report prints \"Total findings: 0\" for a scan that never completed.\n\n**Flag reference for model packs:**\n\n| Source | Flag | Example |\n|--------|------|---------|\n| Installed model packs | `--model-packs` | `--model-packs=myorg/java-models` |\n| In-repo model packs | `--additional-packs` | `--additional-packs=./lib/codeql-models` |\n| In-repo standalone extensions | `--additional-packs` | `--additional-packs=.` |\n\n### Performance\n\nIf codebase is large, read [performance-tuning.md](../references/performance-tuning.md) and apply relevant optimizations.\n\n---\n\n### Step 5: Process and Report Results\n\n**Entry:** Step 4 complete (`$RAW_DIR/results.sarif` exists)\n**Exit:** `$RESULTS_DIR/results.sarif` contains final results; findings summarized by severity, rule, and location; zero-finding results investigated; final report presented to user\n\n#### Produce final results\n\n- **Run-all mode:** Copy unfiltered results to the final location:\n ```bash\n cp \"$RAW_DIR/results.sarif\" \"$RESULTS_DIR/results.sarif\"\n ```\n\n- **Important-only mode:** Apply the post-analysis filter from [sarif-processing.md](../references/sarif-processing.md#important-only-post-filter) to remove medium-precision results with `security-severity` \u003c 6.0. The filter reads from `$RAW_DIR/results.sarif` and writes to `$RESULTS_DIR/results.sarif`, preserving the unfiltered original.\n\nProcess the final SARIF output (`$RESULTS_DIR/results.sarif`) using the jq commands in [sarif-processing.md](../references/sarif-processing.md): count findings, summarize by level, summarize by security severity, summarize by rule.\n\n---\n\n## Final Output\n\nReport to user:\n\n```\n## CodeQL Analysis Complete\n\n**Output directory:** $OUTPUT_DIR\n**Database:** $DB_NAME\n**Language:** \u003cLANG>\n**Scan mode:** Run all | Important only\n**Query packs:** \u003clist of query packs used>\n**Model packs:** \u003clist of model packs used, or \"None\">\n**Threat models:** \u003clist of threat models, or \"default (remote)\">\n**Extraction:** \u003cbuildMode from $DB_NAME/codeql-database.yml: autobuild | manual | none>\n\n### Results Summary:\n- Total findings: \u003cN>\n- Error: \u003cN>\n- Warning: \u003cN>\n- Note: \u003cN>\n\n### Coverage Note:\n[compiled languages only (cpp, csharp, go, java, kotlin, rust); omit for python, js/ts, ruby]\n- Coverage depends on the Extraction mode above. autobuild/manual captures only compiled code —\n unbuilt files and disabled `#ifdef`/`cfg` branches are absent. `none` extracts source without a\n build, so it reaches unbuilt files, but still drops disabled branches and gives weaker dataflow.\n If the finding count is low or zero, suspect incomplete extraction rather than clean code:\n broaden the build and rebuild; don't substitute another analyzer.\n\n### Output Files:\n- SARIF (final): $OUTPUT_DIR/results/results.sarif\n- SARIF (unfiltered): $OUTPUT_DIR/raw/results.sarif\n- Rulesets: $OUTPUT_DIR/rulesets.txt\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":13598,"content_sha256":"83b0e0bccdb7f9f3962022b4477bcc888a6728eebcd25495378a860da72930c6"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"CodeQL Analysis","type":"text"}]},{"type":"paragraph","content":[{"text":"Supported languages: Python, JavaScript/TypeScript, Go, Java/Kotlin, C/C++, C#, Ruby, Swift.","type":"text"}]},{"type":"paragraph","content":[{"text":"Skill resources:","type":"text","marks":[{"type":"strong"}]},{"text":" Reference files and templates are located at ","type":"text"},{"text":"{baseDir}/references/","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"{baseDir}/workflows/","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Essential Principles","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Database quality is non-negotiable.","type":"text","marks":[{"type":"strong"}]},{"text":" A database that builds is not automatically good — a cached build extracts nothing while reporting success.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Data extensions catch what CodeQL misses.","type":"text","marks":[{"type":"strong"}]},{"text":" Django, Spring, and Express projects still wrap database calls, request parsing, and shell execution in project-specific APIs that no shipped model covers.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Explicit suite references prevent silent query dropping.","type":"text","marks":[{"type":"strong"}]},{"text":" Never pass pack names to ","type":"text"},{"text":"codeql database analyze","type":"text","marks":[{"type":"code_inline"}]},{"text":" — each pack's ","type":"text"},{"text":"defaultSuiteFile","type":"text","marks":[{"type":"code_inline"}]},{"text":" applies hidden filters that can produce zero results. Always generate a ","type":"text"},{"text":".qls","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Zero findings needs investigation, not celebration.","type":"text","marks":[{"type":"strong"}]},{"text":" It can mean poor extraction, missing models, the wrong packs, or suite filtering. Run ","type":"text"},{"text":"{baseDir}/scripts/check_db_quality.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" after the build, confirm ","type":"text"},{"text":"{baseDir}/scripts/verify_query_suite.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" exited zero for the suite in use — the generation scripts run it, so invoke it by hand only for a reused or hand-edited suite — and say in the report that both passed.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"macOS Apple Silicon requires workarounds for compiled languages.","type":"text","marks":[{"type":"strong"}]},{"text":" Exit code 137 is an ","type":"text"},{"text":"arm64e","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"arm64","type":"text","marks":[{"type":"code_inline"}]},{"text":" mismatch, not a build failure. Try Homebrew arm64 tools or Rosetta before falling back to ","type":"text"},{"text":"build-mode=none","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Follow workflows step by step.","type":"text","marks":[{"type":"strong"}]},{"text":" Each phase gates the next; skipping quality assessment or data extensions leaves the gap invisible in the results.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Each Bash call is a fresh shell","type":"text"}]},{"type":"paragraph","content":[{"text":"Nothing carries across a Bash call: not variables, not arrays, not functions sourced from ","type":"text"},{"text":"build_log.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":". Every block below that uses a value must re-establish it in the same block. The workflows point back here rather than repeating it; what they do state is the specific damage at that site, because each one fails differently and silently:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"a lost ","type":"text"},{"text":"function","type":"text","marks":[{"type":"strong"}]},{"text":" makes ","type":"text"},{"text":"run_logged","type":"text","marks":[{"type":"code_inline"}]},{"text":" exit 127, which the build ladder reads as a failed method and walks down to ","type":"text"},{"text":"--build-mode=none","type":"text","marks":[{"type":"code_inline"}]},{"text":", never having invoked CodeQL","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"a lost ","type":"text"},{"text":"array","type":"text","marks":[{"type":"strong"}]},{"text":" expands to nothing, so every ","type":"text"},{"text":"--threat-model","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"--model-packs","type":"text","marks":[{"type":"code_inline"}]},{"text":" the user chose is dropped while the final report still lists them as used","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"a lost ","type":"text"},{"text":"scalar","type":"text","marks":[{"type":"strong"}]},{"text":" under ","type":"text"},{"text":"set -u","type":"text","marks":[{"type":"code_inline"}]},{"text":" aborts the block with ","type":"text"},{"text":"unbound variable","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Directory","type":"text"}]},{"type":"paragraph","content":[{"text":"All generated files (database, build logs, diagnostics, extensions, results) are stored in a single output directory.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If the user specifies an output directory","type":"text","marks":[{"type":"strong"}]},{"text":" in their prompt, use it as ","type":"text"},{"text":"OUTPUT_DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If not specified","type":"text","marks":[{"type":"strong"}]},{"text":", default to ","type":"text"},{"text":"./static_analysis_codeql_1","type":"text","marks":[{"type":"code_inline"}]},{"text":". If that already exists, increment to ","type":"text"},{"text":"_2","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"_3","type":"text","marks":[{"type":"code_inline"}]},{"text":", etc.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"In both cases, ","type":"text"},{"text":"always create the directory","type":"text","marks":[{"type":"strong"}]},{"text":" with ","type":"text"},{"text":"mkdir -p","type":"text","marks":[{"type":"code_inline"}]},{"text":" before writing any files.","type":"text"}]},{"type":"paragraph","content":[{"text":"Set ","type":"text"},{"text":"USER_SPECIFIED_DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":" to the literal path from the user's prompt before running this, or leave it unset to auto-increment. Nothing else assigns it.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Resolve output directory\nUSER_SPECIFIED_DIR=\"${USER_SPECIFIED_DIR:-}\" # substitute the user's path here, if any\nif [ -n \"$USER_SPECIFIED_DIR\" ]; then\n OUTPUT_DIR=\"$USER_SPECIFIED_DIR\"\nelse\n BASE=\"static_analysis_codeql\"\n N=1\n while [ -e \"${BASE}_${N}\" ]; do\n N=$((N + 1))\n done\n OUTPUT_DIR=\"${BASE}_${N}\"\nfi\nmkdir -p \"$OUTPUT_DIR\"","type":"text"}]},{"type":"paragraph","content":[{"text":"The output directory is resolved ","type":"text"},{"text":"once","type":"text","marks":[{"type":"strong"}]},{"text":" at the start before any workflow executes. All workflows receive ","type":"text"},{"text":"$OUTPUT_DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":" and store their artifacts there:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"$OUTPUT_DIR/\n├── rulesets.txt # Selected query packs (logged after Step 3)\n├── codeql.db/ # CodeQL database (dir containing codeql-database.yml)\n├── build.log # Build log\n├── codeql-config.yml # Exclusion config (interpreted languages)\n├── diagnostics/ # Diagnostic queries and CSVs\n├── extensions/ # Data extension YAMLs\n├── raw/ # Unfiltered analysis output\n│ ├── results.sarif\n│ └── run-all.qls | important-only.qls\n└── results/ # Final results (filtered for important-only, copied for run-all)\n └── results.sarif","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Database Discovery","type":"text"}]},{"type":"paragraph","content":[{"text":"A CodeQL database is identified by the presence of a ","type":"text"},{"text":"codeql-database.yml","type":"text","marks":[{"type":"code_inline"}]},{"text":" marker file inside its directory. When searching for existing databases, ","type":"text"},{"text":"always collect all matches","type":"text","marks":[{"type":"strong"}]},{"text":" — there may be multiple databases from previous runs or for different languages.","type":"text"}]},{"type":"paragraph","content":[{"text":"Discovery command.","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"find_databases.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" prints one database path per line, filtering out the marker files a failed build leaves behind. Build the array ","type":"text"},{"text":"in the same block that selects from it","type":"text","marks":[{"type":"strong"}]},{"text":" — each Bash call is a fresh shell, so an array built here is empty by the next call, and the run concludes there is no database:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Command substitution, not `done \u003c \u003c(...)`: a process substitution discards the script's\n# exit status, so \"codeql is not on this shell's PATH\" (exit 2) would arrive as an empty\n# list and route to \"build a new database\" with three good ones sitting on disk.\nif ! DB_LIST=$(\"{baseDir}/scripts/find_databases.sh\" \"${OUTPUT_DIR:-.}\" .); then\n echo \"ERROR: database discovery failed — see the message above\" >&2\n exit 1\nfi\n\nFOUND_DBS=()\nwhile IFS= read -r db; do\n [ -n \"$db\" ] || continue\n FOUND_DBS+=(\"$db\")\ndone \u003c\u003c\u003c\"$DB_LIST\"\n\necho \"Found ${#FOUND_DBS[@]} existing database(s)\"\n\n# The metadata the selection prompt needs, collected here rather than in a block of its\n# own: FOUND_DBS is gone by the next Bash call, and a loop over an array that no longer\n# exists prints nothing and reports success.\nfor db in \"${FOUND_DBS[@]}\"; do\n CODEQL_LANG=$(codeql resolve database --format=json -- \"$db\" 2>/dev/null | jq -r '.languages[0]')\n CREATED=$(grep '^creationMetadata:' -A5 \"$db/codeql-database.yml\" 2>/dev/null | grep 'creationTime' | awk '{print $2}')\n echo \"$db — language: $CODEQL_LANG, created: $CREATED\"\ndone","type":"text"}]},{"type":"paragraph","content":[{"text":"Never assume a database is named ","type":"text"},{"text":"codeql.db","type":"text","marks":[{"type":"code_inline"}]},{"text":" — discover it by its marker file.","type":"text"}]},{"type":"paragraph","content":[{"text":"When multiple databases are found:","type":"text","marks":[{"type":"strong"}]},{"text":" use ","type":"text"},{"text":"AskUserQuestion","type":"text","marks":[{"type":"code_inline"}]},{"text":" to let the user select which database to use, or to build a new one, from the language and creation time printed above. ","type":"text"},{"text":"AskUserQuestion","type":"text","marks":[{"type":"code_inline"}]},{"text":" takes at most four options, so with more databases than that, offer the three most recent plus \"Build a new database\" and list the rest in the prompt text. ","type":"text"},{"text":"Skip ","type":"text","marks":[{"type":"strong"}]},{"text":"AskUserQuestion","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" if the user explicitly stated which database to use or to build a new one in their prompt.","type":"text","marks":[{"type":"strong"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Start","type":"text"}]},{"type":"paragraph","content":[{"text":"For the common case (\"scan this codebase for vulnerabilities\"):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Verify CodeQL is installed. Stop here if it is not — every later command fails with\n# a less informative error, and the run wastes a build cycle before saying why.\nif ! command -v codeql >/dev/null 2>&1; then\n echo \"ERROR: codeql not found on PATH. Install it with one of:\" >&2\n echo \" gh extension install github/gh-codeql # then: gh codeql install-stub\" >&2\n echo \" brew install --cask codeql\" >&2\n echo \" https://github.com/github/codeql-action/releases (codeql-bundle)\" >&2\n exit 1\nfi\n\n# jq parses `codeql resolve database --format=json` in the very next step. Without it\n# CODEQL_LANG comes back empty and the run continues against the wrong language.\nif ! command -v jq >/dev/null 2>&1; then\n echo \"ERROR: jq not found on PATH (brew install jq / apt install jq)\" >&2\n exit 1\nfi\n\n# uv runs both guard scripts and both suite generators. Check it here rather than at\n# suite generation, which is after the build — otherwise a machine without uv spends\n# the whole build before failing.\nif ! command -v uv >/dev/null 2>&1; then\n echo \"ERROR: uv not found on PATH (https://docs.astral.sh/uv/getting-started/)\" >&2\n exit 1\nfi\n\ncodeql --version","type":"text"}]},{"type":"paragraph","content":[{"text":"Then resolve ","type":"text"},{"text":"OUTPUT_DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":" using the block in ","type":"text"},{"text":"Output Directory","type":"text","marks":[{"type":"link","attrs":{"href":"#output-directory","title":null}}]},{"text":" above — it honours a user-specified directory, which a bare auto-increment does not.","type":"text"}]},{"type":"paragraph","content":[{"text":"Then execute the full pipeline: ","type":"text"},{"text":"build database → create data extensions → run analysis","type":"text","marks":[{"type":"strong"}]},{"text":" using the workflows below.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Rationalizations to Reject","type":"text"}]},{"type":"paragraph","content":[{"text":"These shortcuts lead to missed findings. Do not accept them:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"security-extended is enough\"","type":"text","marks":[{"type":"strong"}]},{"text":" - It is the baseline. Always check if Trail of Bits packs and Community Packs are available for the language. They catch categories ","type":"text"},{"text":"security-extended","type":"text","marks":[{"type":"code_inline"}]},{"text":" misses entirely.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"security-and-quality is the broadest suite\"","type":"text","marks":[{"type":"strong"}]},{"text":" - ","type":"text"},{"text":"security-and-quality","type":"text","marks":[{"type":"code_inline"}]},{"text":" excludes all ","type":"text"},{"text":"experimental/","type":"text","marks":[{"type":"code_inline"}]},{"text":" query paths. For run-all mode, import both ","type":"text"},{"text":"security-and-quality","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"security-experimental","type":"text","marks":[{"type":"code_inline"}]},{"text":". The delta is 1–52 queries depending on the language.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"The database built, so it's good\"","type":"text","marks":[{"type":"strong"}]},{"text":" - A database that builds does not mean it extracted well. Always run quality assessment and check file counts against expected source files.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"Data extensions aren't needed for standard frameworks\"","type":"text","marks":[{"type":"strong"}]},{"text":" - Even Django/Spring apps have custom wrappers that CodeQL does not model. Skipping extensions means missing vulnerabilities.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"build-mode=none is fine for compiled languages\"","type":"text","marks":[{"type":"strong"}]},{"text":" - It produces severely incomplete analysis. Only use as an absolute last resort. On macOS, try the arm64 toolchain workaround or Rosetta first.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"The build fails on macOS, just use build-mode=none\"","type":"text","marks":[{"type":"strong"}]},{"text":" - Exit code 137 is caused by ","type":"text"},{"text":"arm64e","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"arm64","type":"text","marks":[{"type":"code_inline"}]},{"text":" mismatch, not a fundamental build failure. See ","type":"text"},{"text":"macos-arm64e-workaround.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/macos-arm64e-workaround.md","title":null}}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"No findings means the code is secure\"","type":"text","marks":[{"type":"strong"}]},{"text":" - Run ","type":"text"},{"text":"check_db_quality.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"verify_query_suite.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" and report that they passed. Without them, zero findings and a database that extracted nothing are the same output.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"I'll just run the default suite\"","type":"text","marks":[{"type":"strong"}]},{"text":" / ","type":"text"},{"text":"\"I'll just pass the pack names directly\"","type":"text","marks":[{"type":"strong"}]},{"text":" - Each pack's ","type":"text"},{"text":"defaultSuiteFile","type":"text","marks":[{"type":"code_inline"}]},{"text":" applies hidden filters and can produce zero results. Always use an explicit suite reference.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"I'll put files in the current directory\"","type":"text","marks":[{"type":"strong"}]},{"text":" - All generated files must go in ","type":"text"},{"text":"$OUTPUT_DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":". Scattering files in the working directory makes cleanup impossible and risks overwriting previous runs.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"Just use the first database I find\"","type":"text","marks":[{"type":"strong"}]},{"text":" - Multiple databases may exist for different languages or from previous runs. When more than one is found, present all options to the user. Only skip the prompt when the user already specified which database to use.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"The user said 'scan', that means they want me to pick a database\"","type":"text","marks":[{"type":"strong"}]},{"text":" - \"Scan\" is not database selection. If multiple databases exist and the user didn't name one, ask.","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow Selection","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill has three workflows. ","type":"text"},{"text":"Once a workflow is selected, execute it step by step without skipping phases.","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"These runs are long. A database build has four fallback methods, so use the task tools to track progress. Decide which steps are worth tracking based on the run.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Workflow","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"build-database","type":"text","marks":[{"type":"link","attrs":{"href":"workflows/build-database.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Create CodeQL database using build methods in sequence","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"create-data-extensions","type":"text","marks":[{"type":"link","attrs":{"href":"workflows/create-data-extensions.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Detect or generate data extension models for project APIs","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"run-analysis","type":"text","marks":[{"type":"link","attrs":{"href":"workflows/run-analysis.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Select rulesets, execute queries, process results","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Building unattended","type":"text"}]},{"type":"paragraph","content":[{"text":"This plugin ships ","type":"text"},{"text":"/static-analysis:codeql-build","type":"text","marks":[{"type":"code_inline"}]},{"text":", which runs the build-database steps end to end: detect the language and toolchain, walk the method ladder applying fixes from ","type":"text"},{"text":"build-fixes.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/build-fixes.md","title":null}}]},{"text":" between rungs, and enforce the quality gate.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"/static-analysis:codeql-build {\"target\": \"/abs/path\", \"lang\": \"cpp\"}","type":"text"}]},{"type":"paragraph","content":[{"text":"It asks nothing. Every method failing, and a database that built but sits below the quality threshold, come back as statuses — ","type":"text"},{"text":"no-method-succeeded","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"built-below-threshold","type":"text","marks":[{"type":"code_inline"}]},{"text":" — for you to act on here, because whether the remaining extractor errors are confined to code nobody needs analysed is a judgement call the run cannot make.","type":"text"}]},{"type":"paragraph","content":[{"text":"Use it when the build is the long, uncertain part and you want it driven to a conclusion. Work ","type":"text"},{"text":"build-database.md","type":"text","marks":[{"type":"link","attrs":{"href":"workflows/build-database.md","title":null}}]},{"text":" by hand when you want a say in which method is tried, or when a build failure needs interpreting as it happens.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Auto-Detection Logic","type":"text"}]},{"type":"paragraph","content":[{"text":"If user explicitly specifies","type":"text","marks":[{"type":"strong"}]},{"text":" what to do (e.g., \"build a database\", \"run analysis on ./my-db\"), execute that workflow directly. ","type":"text"},{"text":"Do NOT call ","type":"text","marks":[{"type":"strong"}]},{"text":"AskUserQuestion","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" for database selection if the user's prompt already makes their intent clear","type":"text","marks":[{"type":"strong"}]},{"text":" — e.g., \"build a new database\", \"analyze the codeql database in static_analysis_codeql_2\", \"run a full scan from scratch\".","type":"text"}]},{"type":"paragraph","content":[{"text":"Default pipeline for \"test\", \"scan\", \"analyze\", or similar:","type":"text","marks":[{"type":"strong"}]},{"text":" Discover existing databases using the command in ","type":"text"},{"text":"Database Discovery","type":"text","marks":[{"type":"link","attrs":{"href":"#database-discovery","title":null}}]},{"text":" above, then decide.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Condition","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Action","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No databases found","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Resolve new ","type":"text"},{"text":"$OUTPUT_DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":", execute build → extensions → analysis (full pipeline)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"One database found","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"AskUserQuestion","type":"text","marks":[{"type":"code_inline"}]},{"text":": reuse it or build new?","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multiple databases found","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"AskUserQuestion","type":"text","marks":[{"type":"code_inline"}]},{"text":", capped at four options — see ","type":"text"},{"text":"Database Discovery","type":"text","marks":[{"type":"link","attrs":{"href":"#database-discovery","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"User explicitly stated intent","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skip ","type":"text"},{"text":"AskUserQuestion","type":"text","marks":[{"type":"code_inline"}]},{"text":", act on their instructions directly","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Database Selection Prompt","type":"text"}]},{"type":"paragraph","content":[{"text":"When existing databases are found ","type":"text"},{"text":"and the user did not explicitly specify which to use","type":"text","marks":[{"type":"strong"}]},{"text":", present them via ","type":"text"},{"text":"AskUserQuestion","type":"text","marks":[{"type":"code_inline"}]},{"text":" under the header \"Existing CodeQL Databases\". Label each option with the path, language, and creation time collected above — ","type":"text"},{"text":"./static_analysis_codeql_1/codeql.db (language: python, created: 2026-02-24)","type":"text","marks":[{"type":"code_inline"}]},{"text":" — and make the last option \"Build a new database\".","type":"text"}]},{"type":"paragraph","content":[{"text":"After selection:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If user picks an existing database:","type":"text","marks":[{"type":"strong"}]},{"text":" Set ","type":"text"},{"text":"$OUTPUT_DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":" to its parent directory (or the directory containing it), set ","type":"text"},{"text":"$DB_NAME","type":"text","marks":[{"type":"code_inline"}]},{"text":" to the selected path, then proceed to extensions → analysis.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If user picks \"Build new\":","type":"text","marks":[{"type":"strong"}]},{"text":" Resolve a new ","type":"text"},{"text":"$OUTPUT_DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":", execute build → extensions → analysis.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"General Decision Prompt","type":"text"}]},{"type":"paragraph","content":[{"text":"If neither the database nor the workflow is clear from the prompt, offer the four workflows via ","type":"text"},{"text":"AskUserQuestion","type":"text","marks":[{"type":"code_inline"}]},{"text":" — full scan (recommended), build database, create data extensions, run analysis — naming any databases found and the resolved ","type":"text"},{"text":"$OUTPUT_DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Index","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"File","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Content","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Scripts","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/verify_query_suite.py","type":"text","marks":[{"type":"link","attrs":{"href":"scripts/verify_query_suite.py","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fails a suite that resolves to zero queries. The generation scripts run it; invoke by hand only for a reused or hand-edited suite","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/check_db_quality.py","type":"text","marks":[{"type":"link","attrs":{"href":"scripts/check_db_quality.py","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fails a database with no analysable source. Run after every build","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/build_log.sh","type":"text","marks":[{"type":"link","attrs":{"href":"scripts/build_log.sh","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"log_step","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"run_logged","type":"text","marks":[{"type":"code_inline"}]},{"text":" helpers; source before any build step","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/find_databases.sh","type":"text","marks":[{"type":"link","attrs":{"href":"scripts/find_databases.sh","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Prints every database that ","type":"text"},{"text":"codeql resolve database","type":"text","marks":[{"type":"code_inline"}]},{"text":" accepts, one per line. Build your array from it in the block that reads it","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/generate_suite.sh","type":"text","marks":[{"type":"link","attrs":{"href":"scripts/generate_suite.sh","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Writes the run-all or important-only ","type":"text"},{"text":".qls","type":"text","marks":[{"type":"code_inline"}]},{"text":" and verifies it resolves to a non-zero query count","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"References","type":"text","marks":[{"type":"strong"}]},{"text":" — the three workflows are listed under ","type":"text"},{"text":"Workflow Selection","type":"text","marks":[{"type":"link","attrs":{"href":"#workflow-selection","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/macos-arm64e-workaround.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/macos-arm64e-workaround.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Apple Silicon build tracing workarounds","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/build-fixes.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/build-fixes.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Build failure fix catalog","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/quality-assessment.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/quality-assessment.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Database quality metrics and improvements","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/extension-yaml-format.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/extension-yaml-format.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Data extension YAML column definitions and examples","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/sarif-processing.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/sarif-processing.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"jq commands for SARIF output processing","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/diagnostic-query-templates.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/diagnostic-query-templates.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"QL queries for source/sink enumeration","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/important-only-suite.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/important-only-suite.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Important-only suite template and generation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/run-all-suite.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/run-all-suite.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Run-all suite template","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/ruleset-catalog.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/ruleset-catalog.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Available query packs by language","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/threat-models.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/threat-models.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Threat model configuration","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/language-details.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/language-details.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Language-specific build and extraction details","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/performance-tuning.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/performance-tuning.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Memory, threading, and timeout configuration","type":"text"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Success Criteria","type":"text"}]},{"type":"paragraph","content":[{"text":"A complete CodeQL analysis run should satisfy:","type":"text"}]},{"type":"checkbox_list","attrs":{"id":null},"content":[{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Output directory resolved (user-specified or auto-incremented default)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"All generated files stored inside ","type":"text"},{"text":"$OUTPUT_DIR","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Database built (discovered via ","type":"text"},{"text":"codeql-database.yml","type":"text","marks":[{"type":"code_inline"}]},{"text":" marker) and ","type":"text"},{"text":"{baseDir}/scripts/check_db_quality.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" exited zero","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Data extensions evaluated — either created in ","type":"text"},{"text":"$OUTPUT_DIR/extensions/","type":"text","marks":[{"type":"code_inline"}]},{"text":" or explicitly skipped with justification","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Analysis run with explicit suite reference (not default pack suite), and ","type":"text"},{"text":"{baseDir}/scripts/verify_query_suite.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" exited zero for it","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"All installed query packs (official + Trail of Bits + Community) used or explicitly excluded","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Selected query packs logged to ","type":"text"},{"text":"$OUTPUT_DIR/rulesets.txt","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Unfiltered results preserved in ","type":"text"},{"text":"$OUTPUT_DIR/raw/results.sarif","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Final results in ","type":"text"},{"text":"$OUTPUT_DIR/results/results.sarif","type":"text","marks":[{"type":"code_inline"}]},{"text":" (filtered for important-only, copied for run-all)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Zero-finding results investigated (database quality, model coverage, suite selection)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Build log preserved at ","type":"text"},{"text":"$OUTPUT_DIR/build.log","type":"text","marks":[{"type":"code_inline"}]},{"text":" with all commands, fixes, and quality assessments","type":"text"}]}]}]}]},"metadata":{"date":"2026-11-02","name":"codeql","author":"@skillopedia","source":{"stars":7957,"repo_name":"skills","origin_url":"https://github.com/trailofbits/skills/blob/HEAD/plugins/static-analysis/skills/codeql/SKILL.md","repo_owner":"trailofbits","body_sha256":"1a6d919ff80f83b262daf650552af6eb6d2c32b19d0c529b70efe0c116b675cf","cluster_key":"34e7bc39f0d68f9877016103433f0697c4fd0a6cd9549f14f2490c1b1126eea7","clean_bundle":{"format":"clean-skill-bundle-v1","source":"trailofbits/skills/plugins/static-analysis/skills/codeql/SKILL.md","text_bytes":224389,"source_commit":"d016e08cc7408ecb1853a299d06d4a56e363ad5e","skills_sh_rank":2903,"attachment_count":32,"text_attachments":32,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"plugins/static-analysis/skills/codeql/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"security","category_label":"Security"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"security","import_tag":"skills-sh-top20k-2026-11","description":"Scans a codebase for security vulnerabilities using CodeQL's interprocedural data flow and taint tracking analysis. Triggers on \"run codeql\", \"codeql scan\", \"build codeql database\", \"SAST scan\", \"taint analysis\", \"dataflow analysis\", or \"find vulnerabilities in this repo\". Covers Python, JavaScript/TypeScript, Go, Java/Kotlin, C/C++, C#, Ruby, and Swift. Supports \"run all\" (security-and-quality + security-experimental) and \"important only\" (high-precision) scan modes, and creates data extension models for project-specific sources and sinks. For fast single-file pattern matching, or when no build is available for a compiled language, use the semgrep skill; to parse SARIF that already exists rather than produce it, use the sarif-parsing skill.","allowed-tools":"Bash Read Write Edit Glob Grep AskUserQuestion TaskCreate TaskList TaskUpdate TaskGet"}},"renderedAt":1793665865910}

CodeQL Analysis Supported languages: Python, JavaScript/TypeScript, Go, Java/Kotlin, C/C++, C#, Ruby, Swift. Skill resources: Reference files and templates are located at and . Essential Principles 1. Database quality is non-negotiable. A database that builds is not automatically good — a cached build extracts nothing while reporting success. 2. Data extensions catch what CodeQL misses. Django, Spring, and Express projects still wrap database calls, request parsing, and shell execution in project-specific APIs that no shipped model covers. 3. Explicit suite references prevent silent query dro…