# Semgrep registry coverage
> Status: 2026-07-05. Generated by `cargo run --release --bin registry_coverage -- .registry-snapshot`.
> Living document — regenerate after loader changes.
Measures how well foxguard's existing Semgrep-compat YAML loader (`src/rules/semgrep_compat.rs`) handles a snapshot of the real [semgrep-rules](https://github.com/semgrep/semgrep-rules) registry. Each rule is classified by whether the loader produces a live matcher, and skips are attributed to the single unsupported operator/key that blocks them. This drives the parity roadmap: build the operator at the top of the priority list to unlock the most rules.
## Overall
| Rule files scanned | 2070 |
| Files with YAML parse errors | 0 |
| Total rules | 2144 |
| Rules loaded OK | 2106 (98.2%) |
| Rules skipped | 38 (1.8%) |
**Headline load rate: 98.2%** (2106 / 2144 rules).
## Skip-reason histogram
Sorted by frequency. The reason names the operator/key that blocks the rule today.
| `mode: taint (unsupported shape)` | 37 | 97.4% | 1.7% |
| `generic mode (languages: [generic])` | 1 | 2.6% | 0.0% |
## Priority order — operator/feature backlog
Matcher capabilities (implementable in `semgrep_compat.rs` / `semgrep_taint.rs`) ranked by how many registry rules each would unlock. These are independent of adding new language grammars. Build top-down.
| 1 | `mode: taint (unsupported shape)` | 37 |
Operator/feature gaps account for **37 rules** (1.7% of all rules). Closing the top of this list is the highest-leverage parity work that does not require a new parser.
## Priority order — missing language grammars
Rules foxguard cannot run because it has no tree-sitter grammar for the target language (a separate, heavier lift than matcher operators).
| 1 | `generic mode (languages: [generic])` | 1 |
Missing-grammar gaps account for **1 rules** (0.0% of all rules).
## Per-language breakdown
Language is the rule's first declared language (js/ts/jsx/tsx collapsed to `javascript`, matching the loader).
| python | 423 | 417 | 6 | 98.6% |
| hcl | 359 | 359 | 0 | 100.0% |
| javascript | 243 | 232 | 11 | 95.5% |
| regex | 237 | 237 | 0 | 100.0% |
| java | 131 | 127 | 4 | 96.9% |
| generic | 103 | 102 | 1 | 99.0% |
| yaml | 100 | 100 | 0 | 100.0% |
| go | 97 | 95 | 2 | 97.9% |
| ruby | 92 | 87 | 5 | 94.6% |
| php | 63 | 59 | 4 | 93.7% |
| solidity | 50 | 49 | 1 | 98.0% |
| csharp | 48 | 45 | 3 | 93.8% |
| dockerfile | 39 | 39 | 0 | 100.0% |
| ocaml | 34 | 34 | 0 | 100.0% |
| scala | 23 | 23 | 0 | 100.0% |
| c | 16 | 16 | 0 | 100.0% |
| kotlin | 15 | 15 | 0 | 100.0% |
| bash | 13 | 13 | 0 | 100.0% |
| apex | 12 | 11 | 1 | 91.7% |
| rust | 10 | 10 | 0 | 100.0% |
| elixir | 7 | 7 | 0 | 100.0% |
| json | 7 | 7 | 0 | 100.0% |
| swift | 6 | 6 | 0 | 100.0% |
| clojure | 5 | 5 | 0 | 100.0% |
| terraform | 5 | 5 | 0 | 100.0% |
| html | 4 | 4 | 0 | 100.0% |
| dart | 1 | 1 | 0 | 100.0% |
| xml | 1 | 1 | 0 | 100.0% |
## Top skip reasons per language
- **apex**: `mode: taint (unsupported shape)` (1)
- **csharp**: `mode: taint (unsupported shape)` (3)
- **generic**: `generic mode (languages: [generic])` (1)
- **go**: `mode: taint (unsupported shape)` (2)
- **java**: `mode: taint (unsupported shape)` (4)
- **javascript**: `mode: taint (unsupported shape)` (11)
- **php**: `mode: taint (unsupported shape)` (4)
- **python**: `mode: taint (unsupported shape)` (6)
- **ruby**: `mode: taint (unsupported shape)` (5)
- **solidity**: `mode: taint (unsupported shape)` (1)
---
Regenerate with `cargo run --release --bin registry_coverage -- <registry-dir>`. The registry snapshot is gitignored (`.registry-snapshot/`) and never committed.