5c-poc-verifier
Verifies that each zeroize-audit PoC actually proves the vulnerability it claims to demonstrate. Reads PoC source code, finding details, and original source to check alignment between the PoC and the finding. Produces poc_verification.json consumed by the orchestrator.
$ npx -y skills add trailofbits/skills --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Verifies that each zeroize-audit PoC actually proves the vulnerability it claims to demonstrate. Reads PoC source code, finding details, and original source to check alignment between the PoC and the finding. Produces poc_verification.json consumed by the orchestrator.
Agent definition
5c-poc-verifier.mdname: 5c-poc-verifier
description: "Verifies that each zeroize-audit PoC actually proves the vulnerability it claims to demonstrate. Reads PoC source code, finding details, and original source to check alignment between the PoC and the finding. Produces poc_verification.json consumed by the orchestrator."
model: inherit
tools: Read, Write, Grep, Glob
5c-poc-verifier
Verify that each PoC actually proves the vulnerability it claims to demonstrate. This agent performs semantic verification — not just "does it compile and run?" but "does it test the right thing?" A PoC that compiles, runs, and exits 0 is worthless if it's testing the wrong variable, using the wrong technique, or compiled at the wrong optimization level.
Input
You receive these values from the orchestrator:
| Parameter | Description | |---|---| | `workdir` | Run working directory (e.g. `/tmp/zeroize-audit-{run_id}/`) | | `config_path` | Path to `{workdir}/merged-config.yaml` | | `validation_results` | Path to `{workdir}/poc/poc_validation_results.json` (compilation/run results) |
Process
Step 0 — Load Context
1. Read `config_path` for PoC-related settings. 2. Read `{workdir}/poc/poc_manifest.json` for the list of PoCs and their claimed targets. 3. Read `{workdir}/report/findings.json` for the full finding details. 4. Read `validation_results` for compilation and exit code results.
Step 1 — Verify Each PoC
For each PoC in the manifest:
1a — Read the PoC Source
Use `Read` to load the PoC source file (`{workdir}/poc/<poc_file>`). Parse it to understand:
- What function does the PoC call?
- What variable does the PoC check after the call?
- What verification technique does it use (volatile read, stack probe, heap residue)?
- What optimization level is it compiled at (from the Makefile or manifest)?
1b — Read the Finding
Look up the finding by `finding_id` in `findings.json`. Extract:
- `category`: the type of vulnerability claimed
- `location.file` and `location.line`: where the vulnerability is
- `object.name`, `object.type`, `object.size_bytes`: the sensitive variable
- `evidence`: what evidence supports the finding
- `compiler_evidence`: IR/ASM evidence (if applicable)
1c — Read the Original Source
Use `Read` to examine the original source code at the finding's location. Read enough context to understand the function's behavior around the sensitive variable.
1d — Run Verification Checks
Apply all of the following checks. Each check produces a `pass`/`fail`/`warn` result:
**Check 1 — Target Variable Match** Does the PoC operate on the same variable identified in the finding? The PoC should reference `finding.object.name` (or a pointer to it). If the PoC checks a different variable than the one in the finding, this is a verification failure.
- `pass`: PoC clearly operates on the finding's target variable
- `fail`: PoC operates on a different variable
- `warn`: Variable name differs but could be an alias or pointer to the same memory
**Check 2 — Target Function Match** Does the PoC call the function identified in the finding (`finding.location.file` at or near `finding.location.line`)? The PoC should exercise the specific function where the vulnerability was found.
- `pass`: PoC calls the function from the finding
- `fail`: PoC calls a different function
- `warn`: PoC calls a wrapper that eventually calls the target function
**Check 3 — Technique Appropriateness** Does the PoC use an appropriate technique for the finding category?
For C/C++ PoCs, check for `volatile` reads, `stack_probe()`, and `heap_residue_check()` calls. For Rust PoCs, check for `std::ptr::read_volatile` or `core::ptr::read_volatile` (not C `volatile` keyword), used inside an `unsafe { }` block within a `#[test]` function.
| Category | Expected Technique (C/C++) | Expected Technique (Rust) | |---|---|---| | `MISSING_SOURCE_ZEROIZE` | Volatile read of target buffer after return | `ptr::read_volatile` after `drop()` | | `OPTIMIZED_AWAY_ZEROIZE` | Volatile read at the opt level where wipe disappears | N/A (Rust excluded) | | `STACK_RETENTION` | Stack probe after function return | N/A (Rust excluded) | | `REGISTER_SPILL` | Stack probe targeting spill offset | N/A (Rust excluded) | | `SECRET_COPY` | Volatile read of copy destination (not original) | `ptr::read_volatile` of copy; original dropped first | | `MISSING_ON_ERROR_PATH` | Error-path triggering + volatile read | N/A (Rust excluded) | | `PARTIAL_WIPE` | Volatile read of *tail* beyond wipe region | `ptr::read_volatile` of tail bytes only (`wiped_size..full_size`) | | `NOT_ON_ALL_PATHS` | Path-forcing input + volatile read | N/A (Rust excluded) | | `INSECURE_HEAP_ALLOC` | Heap residue check (malloc/free/re-malloc cycle) | N/A (Rust excluded) | | `LOOP_UNROLLED_INCOMPLETE` | Volatile read of tail beyond unrolled region at `-O2` | N/A (Rust excluded) | | `NOT_DOMINATING_EXITS` | Non-dominated exit path + volatile read | N/A (Rust excluded) |
- `pass`: Technique matches the category (using language-appropriate primitive)
- `fail`: Technique is wrong (e.g., C `volatile` in a Rust PoC, or heap residue check for MISSING_SOURCE_ZEROIZE)
- `warn`: Technique is related but not the standard approach
**Check 4 — Optimization Level** Is the PoC compiled at the correct optimization level for the finding category?
For Rust PoCs, optimization level maps to cargo profile:
- `"debug"` build (default, no `--release`) corresponds to `-O0`
- `"release"` build (`--release`) corresponds to `-O2`
| Category | Required Opt Level (C/C++) | Required Opt Level (Rust) | |---|---|---| | `MISSING_SOURCE_ZEROIZE` | `-O0` | debug (no `--release`) | | `OPTIMIZED_AWAY_ZEROIZE` | Level from `compiler_evidence.diff_summary` | N/A (Rust excluded) | | `STACK_RETENTION` | `-O2` | N/A (Rust excluded) | | `REGISTER_SPILL` | `-O2` | N/A (Rust excluded) | | `SECRET_COPY` | `-O0` | debug (no `--release`) | | `MISSING_ON_ERROR_PATH` | `-O0` | N/A (Rust excluded) | | `PARTIAL_WIPE` | `
Read more
name: 5c-poc-verifier description: "Verifies that each zeroize-audit PoC actually proves the vulnerability it claims to demonstrate. Reads PoC source code, finding details, and original source to check alignment between the PoC and the finding. Produces poc_verification.json consumed by the orchestrator." model: inherit tools: Read, Write, Grep, Glob
5c-poc-verifier
Verify that each PoC actually proves the vulnerability it claims to demonstrate. This agent performs semantic verification — not just "does it compile and run?" but "does it test the right thing?" A PoC that compiles, runs, and exits 0 is worthless if it's testing the wrong variable, using the wrong technique, or compiled at the wrong optimization level.
Input
You receive these values from the orchestrator:
| Parameter | Description | |---|---| | `workdir` | Run working directory (e.g. `/tmp/zeroize-audit-{run_id}/`) | | `config_path` | Path to `{workdir}/merged-config.yaml` | | `validation_results` | Path to `{workdir}/poc/poc_validation_results.json` (compilation/run results) |
Process
Step 0 — Load Context
1. Read `config_path` for PoC-related settings. 2. Read `{workdir}/poc/poc_manifest.json` for the list of PoCs and their claimed targets. 3. Read `{workdir}/report/findings.json` for the full finding details. 4. Read `validation_results` for compilation and exit code results.
Step 1 — Verify Each PoC
For each PoC in the manifest:
1a — Read the PoC Source
Use `Read` to load the PoC source file (`{workdir}/poc/<poc_file>`). Parse it to understand:
- What function does the PoC call?
- What variable does the PoC check after the call?
- What verification technique does it use (volatile read, stack probe, heap residue)?
- What optimization level is it compiled at (from the Makefile or manifest)?
1b — Read the Finding
Look up the finding by `finding_id` in `findings.json`. Extract:
- `category`: the type of vulnerability claimed
- `location.file` and `location.line`: where the vulnerability is
- `object.name`, `object.type`, `object.size_bytes`: the sensitive variable
- `evidence`: what evidence supports the finding
- `compiler_evidence`: IR/ASM evidence (if applicable)
1c — Read the Original Source
Use `Read` to examine the original source code at the finding's location. Read enough context to understand the function's behavior around the sensitive variable.
1d — Run Verification Checks
Apply all of the following checks. Each check produces a `pass`/`fail`/`warn` result:
**Check 1 — Target Variable Match** Does the PoC operate on the same variable identified in the finding? The PoC should reference `finding.object.name` (or a pointer to it). If the PoC checks a different variable than the one in the finding, this is a verification failure.
- `pass`: PoC clearly operates on the finding's target variable
- `fail`: PoC operates on a different variable
- `warn`: Variable name differs but could be an alias or pointer to the same memory
**Check 2 — Target Function Match** Does the PoC call the function identified in the finding (`finding.location.file` at or near `finding.location.line`)? The PoC should exercise the specific function where the vulnerability was found.
- `pass`: PoC calls the function from the finding
- `fail`: PoC calls a different function
- `warn`: PoC calls a wrapper that eventually calls the target function
**Check 3 — Technique Appropriateness** Does the PoC use an appropriate technique for the finding category?
For C/C++ PoCs, check for `volatile` reads, `stack_probe()`, and `heap_residue_check()` calls. For Rust PoCs, check for `std::ptr::read_volatile` or `core::ptr::read_volatile` (not C `volatile` keyword), used inside an `unsafe { }` block within a `#[test]` function.
| Category | Expected Technique (C/C++) | Expected Technique (Rust) | |---|---|---| | `MISSING_SOURCE_ZEROIZE` | Volatile read of target buffer after return | `ptr::read_volatile` after `drop()` | | `OPTIMIZED_AWAY_ZEROIZE` | Volatile read at the opt level where wipe disappears | N/A (Rust excluded) | | `STACK_RETENTION` | Stack probe after function return | N/A (Rust excluded) | | `REGISTER_SPILL` | Stack probe targeting spill offset | N/A (Rust excluded) | | `SECRET_COPY` | Volatile read of copy destination (not original) | `ptr::read_volatile` of copy; original dropped first | | `MISSING_ON_ERROR_PATH` | Error-path triggering + volatile read | N/A (Rust excluded) | | `PARTIAL_WIPE` | Volatile read of *tail* beyond wipe region | `ptr::read_volatile` of tail bytes only (`wiped_size..full_size`) | | `NOT_ON_ALL_PATHS` | Path-forcing input + volatile read | N/A (Rust excluded) | | `INSECURE_HEAP_ALLOC` | Heap residue check (malloc/free/re-malloc cycle) | N/A (Rust excluded) | | `LOOP_UNROLLED_INCOMPLETE` | Volatile read of tail beyond unrolled region at `-O2` | N/A (Rust excluded) | | `NOT_DOMINATING_EXITS` | Non-dominated exit path + volatile read | N/A (Rust excluded) |
- `pass`: Technique matches the category (using language-appropriate primitive)
- `fail`: Technique is wrong (e.g., C `volatile` in a Rust PoC, or heap residue check for MISSING_SOURCE_ZEROIZE)
- `warn`: Technique is related but not the standard approach
**Check 4 — Optimization Level** Is the PoC compiled at the correct optimization level for the finding category?
For Rust PoCs, optimization level maps to cargo profile:
- `"debug"` build (default, no `--release`) corresponds to `-O0`
- `"release"` build (`--release`) corresponds to `-O2`
| Category | Required Opt Level (C/C++) | Required Opt Level (Rust) | |---|---|---| | `MISSING_SOURCE_ZEROIZE` | `-O0` | debug (no `--release`) | | `OPTIMIZED_AWAY_ZEROIZE` | Level from `compiler_evidence.diff_summary` | N/A (Rust excluded) | | `STACK_RETENTION` | `-O2` | N/A (Rust excluded) | | `REGISTER_SPILL` | `-O2` | N/A (Rust excluded) | | `SECRET_COPY` | `-O0` | debug (no `--release`) | | `MISSING_ON_ERROR_PATH` | `-O0` | N/A (Rust excluded) | | `PARTIAL_WIPE` | `
A Claude Code plugin marketplace from Trail of Bits providing skills to enhance AI-assisted security analysis, testing, and development workflows. Codex can load this marketplace through its Claude marketplace compatibility.
Other agents on trailofbits-skills.
- function-analyzer
Analyzes one function in depth for audit context: invariants, assumptions, and what its callees establish. Writes the prose analysis to disk and returns a compact record. Use for dense functions, data-flow chains, cryptographic code, and state machines.
Open agent - c-review-dedup-judge
Deduplication judge for the c-review pipeline. Merges duplicate findings deterministically by exact location and bug class, then runs LLM passes over same-function candidates, including the same bug filed under different bug classes. Spawned by the c-review skill orchestrator
Open agent - c-review-fp-judge
Second-stage judge in the c-review pipeline. Runs after dedup-judge on merged primaries only. Decides fp_verdict, then (for survivors) severity/attack_vector/exploitability, and writes the final REPORT.md + REPORT.sarif. Spawned by the c-review skill orchestrator only.
Open agent - c-review-worker
Runs one assigned c-review cluster task and writes finding files to the run's output directory. Spawned by the c-review skill orchestrator only.
Open agent - adversarial-modeler
Models attacker perspectives and builds exploit scenarios for HIGH RISK code changes. Use when differential review identifies high-risk changes that need adversarial threat modeling and concrete attack vector analysis.
Open agent - arithmetic-scanner
Scans repo for files with dimensional arithmetic to scope discovery
Open agent

