* rust-review: add Rust security review plugin Add the rust-review plugin: a comprehensive Rust security review skill with clustered finders covering memory safety, concurrency/data races, panic-induced DoS, FFI/cross-language boundaries, error handling, resource handling, async runtime, and static hygiene. Includes worker, dedup-judge, fp-judge, and planner agents, SARIF generation with rule descriptions and regression tests, deterministic cluster chunking, and Codex skills mapping. Versioned at 1.0.0 and registered in the marketplace, CODEOWNERS, and root README. * c-review: backport rust-review protocol fixes and planner chunking Port the language-agnostic fixes made while building rust-review (which was ported from c-review) back into c-review: - worker/fp-judge: force findings, coverage gate, and REPORT.md to disk via Write instead of returning content in the reply (orchestrator context-bloat hardening); add a pre-complete file-existence check. - worker: move the cache-primer block below the normal self-check and pre-work budget so a non-primer worker does not start under a global "no tool calls" rule. - planner: add --max-passes-per-worker (default 4) with deterministic split_oversized_clusters chunking; skill passes the flag and documents the chunked-subset worker rule. - scripts: add test_split.py and test_generate_sarif.py regression tests. The SARIF test caught a missing RULE_DESCRIPTIONS entry for uninitialized-data, now added. Bump c-review to 1.2.0. * c-review/rust-review: validate artifacts, index-aware SARIF, protocol cleanups - Add validate_artifacts.py (+ tests) to both plugins to check worker shard, coverage, and finding files before accepting completions. - generate_sarif.py now reads the canonical findings-index.txt when present, falling back to findings/*.md only if the index is absent. - Merge the worker step-6 verification paragraphs and drop orchestrator -internal Phase 7 / plan.json jargon in favor of worker-facing stakes. - Tighten uninitialized-read-finder guidance: primitive integers still require initialization. * rust-review/c-review: per-cluster max_passes_per_worker override Lets output-heavy clusters declare a smaller manifest-level max_passes_per_worker so each expensive pass group gets its own worker, validated by a single shared cluster_max_passes_per_worker helper and honored by split_oversized_clusters via an explicit override (0 is rejected rather than silently falling back to the global cap). rust-review opts in concurrency-locking and recursion-dos; c-review ports the capability for parity. validate_artifacts now accepts grouped or repeated --claimed-count values. * rust-review: broaden bug-class coverage with capability-gated clusters Add layout-safety, input-os-safety, and info-disclosure clusters behind new has_packed_repr / has_fs_io capability gates so packed-repr, path, and pointer-exposure passes only run where they apply, and gate unsafe-only passes behind has_unsafe to cut noise on safe crates. Extend existing clusters with new bug classes: RefCell double-borrow panics, unflushed BufWriter, string-comparison bypasses, serialize_struct mismatches, nondeterminism, in-collection key mutation, and destructor-skip cleanup leaks. Fix detector regexes that missed or over-matched real Rust (packed-field borrows, RefCell try_borrow_mut, HashMap substrings, path push, packed inner attrs, fs/path probes) and add a regression test pinning them to snippets. * fix dedup * safety-net check for REPORT.md * on-disk data -> shards reconciliation * on-disk data -> shards reconciliation - v2 * ls -> glob * memory-safety gate * path validation * fix numbers/counting * rm PACKEDREF from FFI cluster prompt, it is in layout-safety * fix unsafe-boundary count * minor fixes for prompts * do not filter unknown-severity findings, just mark them as such * fix minor behavior changes in worker * Correctness: - generate_sarif: clamp startLine >=1 (`:0` produced schema-invalid SARIF) - generate_sarif: don't drop a judged survivor with blank severity - dedup-judge: Tier-2 carry-forward so a primary can't be demoted/orphaned - dedup-judge: crash-recovery unions shards with findings/*.md (empty-shard trap) Robustness: - generate_sarif: skip frontmatter-less files; add originalUriBaseIds Contracts: - SKILL: gate dedup-judge before fp-judge (prevent concurrent-spawn race) - worker: verbatim coverage cells; sub_prompt_paths omitted-not-empty; skip_subclasses reserved; Codebase comma format * improve prompts regexes, add missing deconflictions * prompt factual fixes * fix dozen of small prompt inconsistencies and add missing sections * more prompt fixes, fix retry guard in SKILL, small fixes in agents * dozen more small fixes * final regex fixes * fixes from rust to c-review * agents cannot use write tool for reports (strange cc limitation) - bypass via bash * spawnings agents is capped to 20 - explicit handling for that * fix glob -> read (glob is blocked for agents that has also bash) * fix regex patterns to work with grep * soften output requirements - they were violated anyway * consolidated clusters are no longer chunked — one worker owns the whole cluster, builds its shared Phase-A inventory once, and runs every phase * fix judge finding counting and low-severity guidance * fix metadata * small fix for skipped findings * Carry forward guard for `also_known_as` bucket * Gracefully handle parse_frontmatter error * Extend has_ffi coverage * Broader gate for has_concurrency * Update FFI-safe layout regex to support C, C+packed, and C+u32 in unsafe-boundary and dyn-trait-ffi-finder prompts * Small refine of regex patterns * Improve regex patterns for recursive type detection to include Mutex and RwLock * rm global .codex/rust-review * backport fixes to c-review * merge changes * Backport SARIF merge-survivor + malformed-frontmatter guards to c-review, mark missing locations, fix prompt-regex test extractor, and harden planner/validator scripts across both review plugins * fix pytest * fix global gitignore, adds / and ruff_cache * small fixes from pr-review * small fixes from pr-review - 2 * fix copilot finding --------- Co-authored-by: GrosQuildu <e2.8a.95@gmail.com>
c-review
C/C++ security code review plugin. Based on Trail of Bits Testing Handbook
Usage
Invoke with /c-review:c-review. The skill will prompt for:
- Threat model (
REMOTE/LOCAL_UNPRIVILEGED/BOTH) - Worker model (
haiku/sonnet/opus) - Severity filter (
all/medium/high) - Scope subpath (optional — defaults to whole repo)
Findings + SARIF are written to $(pwd)/.c-review-results/<iso-timestamp>/.
Overview
The skill takes the following inputs (collected via AskUserQuestion):
- Threat model —
REMOTE,LOCAL_UNPRIVILEGED, orBOTH. Drives which passes are in scope (e.g.privilege-dropis skipped underREMOTE). - Scope subpath — optional path under the repo root; defaults to the whole repo. Ambiguous scope requests are clarified.
- Worker model —
haiku/sonnet/opusfor the parallel worker agents. - Severity filter —
all/medium/high; controls what lands inREPORT.mdandREPORT.sarif.
From these inputs the orchestrator detects platform/language flags (is_cpp, is_posix, is_windows) over the scope and selects clusters from prompts/clusters/manifest.json. Each cluster groups related bug classes — based on C/C++ chapters of appsec.guide — and runs as one parallel worker.
The planner caps each non-consolidated worker at four passes, splitting larger clusters into -1/-2/… chunks; output-heavy clusters can declare a smaller manifest-level max_passes_per_worker override for finer-grained workers. The consolidated cluster buffer-write-sinks (13 passes) is never chunked — one worker builds its shared inventory once and runs every phase (chunking would force each chunk to rebuild that inventory, which workers skip in practice), making it the heaviest worker in the fan-out.
Always-on clusters:
- buffer-write-sinks — banned/unsafe stdlib calls, format strings,
snprintfretval, overlapping buffers,memcpy/strncpy/strncatsize and termination,strlen/strcpypairs, scanf-uninit, flexible arrays, generic string-handling issues, buffer overflows. - object-lifecycle — uninitialized data, NULL deref, use-after-free, memory leaks.
- arithmetic-type — operator precedence, integer overflow, OOB comparisons, NULL/zero conflation, type confusion, undefined behavior, compiler bugs.
- syscall-retval — error /
errno/EINTRhandling, negative retval,open()issues, socket disconnect, half-closed sockets. - concurrency — spinlock init, thread safety, race conditions, signal-handler safety.
- ambient-state — filesystem issues, access control, privilege drop, env vars, time-of-check, DoS.
- static-hygiene — exploit mitigations,
printfattribute,va_start/va_end, regex,inet_aton,qsort.
Conditional clusters:
- cpp-semantics (
is_cpp) — init order, virtual functions, smart pointers, move semantics, iterator invalidation, lambda captures, exception safety. - windows-process (
is_windows) —CreateProcess, cross-process access, token privileges, service security. - windows-fs-path (
is_windows) — DLL planting, Windows path handling, installer races. - windows-ipc-crypto (
is_windows) — named pipes, Windows crypto, Windows allocators.
Each worker inventories candidate sites once for its cluster (Phase A), then runs that cluster's focused passes and writes one markdown-with-YAML-frontmatter finding file per issue into a shared findings/ directory. After workers exit, two judges run sequentially: a dedup judge merges duplicates, then an FP + severity judge assigns fp_verdict / severity / attack_vector / exploitability and writes REPORT.md. The orchestrator then runs scripts/generate_sarif.py (Phase 8b safety net) to emit REPORT.sarif (SARIF 2.1.0) from the same frontmatter — idempotent, runs unconditionally so a crashed fp-judge can't leave a corrupt or stale SARIF on disk. The same phase also guarantees REPORT.md: if the fp-judge crashed or returned the report as chat text instead of writing it, the orchestrator writes REPORT.md from the finding files.
Architecture
/c-review:c-review (skill entry point — no command wrapper)
└── Main conversation coordinates:
├── Phase 0: AskUserQuestion — collects required params, plus scope_subpath only when ambiguous
├── Phase 1: Detect is_cpp / is_posix / is_windows (scope-scoped)
├── Phase 2-3: Output directory + context.md
├── Phase 4: Select clusters from prompts/clusters/manifest.json
├── Phase 5: TaskCreate M cluster tasks (orchestrator-internal bookkeeping; workers
│ have no Task tools and never read or write the ledger)
├── Phase 6: Phase 6a cache primer (foreground, gated on plan.run.cache_primer);
│ Phase 6b spawns M workers foreground, one message per wave of ≤16
│ (parallel Agent calls, subagent_type="c-review:c-review-worker")
│ └── Each worker: validate spawn prompt (self-check) →
│ run assigned cluster prompt
│ (Phase A inventory + focused passes) →
│ write finding files + per-worker shard
│ under findings-index.d/ → exit
├── Phase 7: Wait until all workers complete; build findings-index.txt from findings/ on disk,
│ reconciled against the findings-index.d/ shards
├── Phase 8: Judges sequentially — Dedup → FP+Severity
│ ├── Dedup-judge: reads ALL findings, merges duplicates (Tier 1 exact loc+class,
│ │ Tier 2 same-function snippet, Tier 3 cross-class same-bug;
│ │ Tier 4 = related, not merged), writes dedup-summary.md
│ └── FP+Severity: reads primaries only, assigns fp_verdict + (for survivors)
│ severity / attack_vector / exploitability, writes
│ fp-summary.md + REPORT.md (and REPORT.sarif on the happy path)
├── Phase 8b: report safety net — orchestrator unconditionally runs generate_sarif.py
│ whenever findings/ exists (idempotent), and writes REPORT.md itself if the fp-judge didn't
└── Phase 9: Return REPORT.md + artifact list
Output directory layout
${output_dir}/
├── context.md # threat model, scope, codebase summary
├── plan.json # build_run_plan.py output: cluster selection, worker assignments
├── worker-prompts/ # build_run_plan.py output: one .txt per worker plus optional cache-primer.txt
│ ├── worker-1.txt
│ ├── worker-2.txt
│ └── cache-primer.txt # only when plan.run.cache_primer=true
├── findings/
│ ├── BOF-001.md # worker-written; judges add merged_into / fp_verdict / severity
│ ├── UAF-001.md
│ └── …
├── findings-index.d/ # per-worker shards (each worker writes its own paths here)
│ ├── worker-1.txt
│ └── …
├── findings-index.txt # sorted, de-duplicated list of finding files on disk, reconciled vs shards (canonical manifest)
├── run-summary.md # orchestrator-written: resolved params, worker outcomes, judge status
├── dedup-summary.md # dedup-judge output (minimal no-op summary on zero findings)
├── fp-summary.md # fp+severity-judge output
├── REPORT.md # severity-filtered human-facing report
└── REPORT.sarif # SARIF 2.1.0, generated from finding frontmatter
Default output_dir: $(pwd)/.c-review-results/<iso-timestamp>/.
Communication format
Markdown-with-YAML-frontmatter everywhere except the SARIF export:
- Finding files — worker writes prose + code + data flow; judges add
merged_into/fp_verdict/severityfields to the frontmatter viaEdit. - Summary files (
dedup-summary.md,fp-summary.md) — markdown tables of counts and per-finding annotations. - Final report (
REPORT.md) — severity-grouped markdown, filtered perseverity_filter. - SARIF export (
REPORT.sarif) — SARIF 2.1.0 JSON, covering the same reported findings asREPORT.md.
Clusters
The authoritative list of clusters, pass ordering, gates, prefixes, and per-class prompt paths is prompts/clusters/manifest.json. Always-on coverage is 47 passes across 7 clusters. Conditional clusters add up to 17 more passes.
Not for
- Windows or Linux/macOS kernel drivers / modules
- Managed languages (Java, C#, Python)