[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7151M2N4TETJP1MPWW0AAGF":3,"skill-same:01M7151M2N4TETJP1MPWW0AAGF":80},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":14,"repositoryHtmlUrl":63,"repositoryHomepageUrl":6,"ownerHtmlUrl":64,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":65,"install":66,"resources":79},"01M7151M2N4TETJP1MPWW0AAGF","zeroize-audit",null,"Detects missing zeroization of sensitive data in source code and identifies zeroization removed by compiler optimizations, with assembly-level analysis, and control-flow verification. Use for auditing C\u002FC++\u002FRust code handling secrets, keys, passwords, or other sensitive data.","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcopilot\u002Fzeroize-audit\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"zeroize audit","audit","read","serena","unknown","get","project","activate","community","assembly","write","MCP","Bash","secrets","analysis","data","flow","verification","code","rust","2026-11-10 10:12:30",false,"---\nname: zeroize-audit\ndescription: \"Detects missing zeroization of sensitive data in source code and identifies zeroization removed by compiler optimizations, with assembly-level analysis, and control-flow verification. Use for auditing C\u002FC++\u002FRust code handling secrets, keys, passwords, or other sensitive data.\"\nallowed-tools:\n  - Read\n  - Grep\n  - Glob\n  - Bash\n  - Write\n  - Task\n  - AskUserQuestion\n  - mcp__serena__activate_project\n  - mcp__serena__find_symbol\n  - mcp__serena__find_referencing_symbols\n  - mcp__serena__get_symbols_overview\nrisk: unknown\nsource: community\n---\n\n# zeroize-audit — Claude Skill\n\n## When to Use\n- Auditing cryptographic implementations (keys, seeds, nonces, secrets)\n- Reviewing authentication systems (passwords, tokens, session data)\n- Analyzing code that handles PII or sensitive credentials\n- Verifying secure cleanup in security-critical codebases\n- Investigating memory safety of sensitive data handling\n\n## When NOT to Use\n- General code review without security focus\n- Performance optimization (unless related to secure wiping)\n- Refactoring tasks not related to sensitive data\n- Code without identifiable secrets or sensitive values\n\n---\n\n## Purpose\nDetect missing zeroization of sensitive data in source code and identify zeroization that is removed or weakened by compiler optimizations (e.g., dead-store elimination), with mandatory LLVM IR\u002Fasm evidence. Capabilities include:\n- Assembly-level analysis for register spills and stack retention\n- Data-flow tracking for secret copies\n- Heap allocator security warnings\n- Semantic IR analysis for loop unrolling and SSA form\n- Control-flow graph analysis for path coverage verification\n- Runtime validation test generation\n\n## Scope\n- Read-only against the target codebase (does not modify audited code; writes analysis artifacts to a temporary working directory).\n- Produces a structured report (JSON).\n- Requires valid build context (`compile_commands.json`) and compilable translation units.\n- \"Optimized away\" findings only allowed with compiler evidence (IR\u002Fasm diff).\n\n---\n\n## Inputs\n\nSee `{baseDir}\u002Fschemas\u002Finput.json` for the full schema. Key fields:\n\n| Field | Required | Default | Description |\n|---|---|---|---|\n| `path` | yes | — | Repo root |\n| `compile_db` | no | `null` | Path to `compile_commands.json` for C\u002FC++ analysis. Required if `cargo_manifest` is not set. |\n| `cargo_manifest` | no | `null` | Path to `Cargo.toml` for Rust crate analysis. Required if `compile_db` is not set. |\n| `config` | no | — | YAML defining heuristics and approved wipes |\n| `opt_levels` | no | `[\"O0\",\"O1\",\"O2\"]` | Optimization levels for IR comparison. O1 is the diagnostic level: if a wipe disappears at O1 it is simple DSE; O2 catches more aggressive eliminations. |\n| `languages` | no | `[\"c\",\"cpp\",\"rust\"]` | Languages to analyze |\n| `max_tus` | no | — | Limit on translation units processed from compile DB |\n| `mcp_mode` | no | `prefer` | `off`, `prefer`, or `require` — controls Serena MCP usage |\n| `mcp_required_for_advanced` | no | `true` | Downgrade `SECRET_COPY`, `MISSING_ON_ERROR_PATH`, and `NOT_DOMINATING_EXITS` to `needs_review` when MCP is unavailable |\n| `mcp_timeout_ms` | no | — | Timeout budget for MCP semantic queries |\n| `poc_categories` | no | all 11 exploitable | Finding categories for which to generate PoCs. C\u002FC++ findings: all 11 categories supported. Rust findings: only `MISSING_SOURCE_ZEROIZE`, `SECRET_COPY`, and `PARTIAL_WIPE` are supported; other Rust categories are marked `poc_supported=false`. |\n| `poc_output_dir` | no | `generated_pocs\u002F` | Output directory for generated PoCs |\n| `enable_asm` | no | `true` | Enable assembly emission and analysis (Step 8); produces `STACK_RETENTION`, `REGISTER_SPILL`. Auto-disabled if `emit_asm.sh` is missing. |\n| `enable_semantic_ir` | no | `false` | Enable semantic LLVM IR analysis (Step 9); produces `LOOP_UNROLLED_INCOMPLETE` |\n| `enable_cfg` | no | `false` | Enable control-flow graph analysis (Step 10); produces `MISSING_ON_ERROR_PATH`, `NOT_DOMINATING_EXITS` |\n| `enable_runtime_tests` | no | `false` | Enable runtime test harness generation (Step 11) |\n\n---\n\n## Prerequisites\n\nBefore running, verify the following. Each has a defined failure mode.\n\n**C\u002FC++ prerequisites:**\n\n| Prerequisite | Failure mode if missing |\n|---|---|\n| `compile_commands.json` at `compile_db` path | Fail fast — do not proceed |\n| `clang` on PATH | Fail fast — IR\u002FASM analysis impossible |\n| `uvx` on PATH (for Serena) | If `mcp_mode=require`: fail. If `mcp_mode=prefer`: continue without MCP; downgrade affected findings per Confidence Gating rules. |\n| `{baseDir}\u002Ftools\u002Fextract_compile_flags.py` | Fail fast — cannot extract per-TU flags |\n| `{baseDir}\u002Ftools\u002Femit_ir.sh` | Fail fast — IR analysis impossible |\n| `{baseDir}\u002Ftools\u002Femit_asm.sh` | Warn and skip assembly findings (STACK_RETENTION, REGISTER_SPILL) |\n| `{baseDir}\u002Ftools\u002Fmcp\u002Fcheck_mcp.sh` | Warn and treat as MCP unavailable |\n| `{baseDir}\u002Ftools\u002Fmcp\u002Fnormalize_mcp_evidence.py` | Warn and use raw MCP output |\n\n**Rust prerequisites:**\n\n| Prerequisite | Failure mode if missing |\n|---|---|\n| `Cargo.toml` at `cargo_manifest` path | Fail fast — do not proceed |\n| `cargo check` passes | Fail fast — crate must be buildable |\n| `cargo +nightly` on PATH | Fail fast — nightly required for MIR and LLVM IR emission |\n| `uv` on PATH | Fail fast — required to run Python analysis scripts |\n| `{baseDir}\u002Ftools\u002Fvalidate_rust_toolchain.sh` | Warn — run preflight manually. Checks all tools, scripts, nightly, and optionally `cargo check`. Use `--json` for machine-readable output, `--manifest` to also validate the crate builds. |\n| `{baseDir}\u002Ftools\u002Femit_rust_mir.sh` | Fail fast — MIR analysis impossible (`--opt`, `--crate`, `--bin\u002F--lib` supported; `--out` can be file or directory) |\n| `{baseDir}\u002Ftools\u002Femit_rust_ir.sh` | Fail fast — LLVM IR analysis impossible (`--opt` required; `--crate`, `--bin\u002F--lib` supported; `--out` must be `.ll`) |\n| `{baseDir}\u002Ftools\u002Femit_rust_asm.sh` | Warn and skip assembly findings (`STACK_RETENTION`, `REGISTER_SPILL`). Supports `--opt`, `--crate`, `--bin\u002F--lib`, `--target`, `--intel-syntax`; `--out` can be `.s` file or directory. |\n| `{baseDir}\u002Ftools\u002Fdiff_rust_mir.sh` | Warn and skip MIR-level optimization comparison. Accepts 2+ MIR files, normalizes, diffs pairwise, and reports first opt level where zeroize\u002Fdrop-glue patterns disappear. |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fsemantic_audit.py` | Warn and skip semantic source analysis |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Ffind_dangerous_apis.py` | Warn and skip dangerous API scan |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_mir_patterns.py` | Warn and skip MIR analysis |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_llvm_patterns.py` | Warn and skip LLVM IR analysis |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_rust_asm.py` | Warn and skip Rust assembly analysis (`STACK_RETENTION`, `REGISTER_SPILL`, drop-glue checks). Dispatches to `check_rust_asm_x86.py` (production) or `check_rust_asm_aarch64.py` (**EXPERIMENTAL** — AArch64 findings require manual verification). |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_rust_asm_x86.py` | Required by `check_rust_asm.py` for x86-64 analysis; warn and skip if missing |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_rust_asm_aarch64.py` | Required by `check_rust_asm.py` for AArch64 analysis (**EXPERIMENTAL**); warn and skip if missing |\n\n**Common prerequisite:**\n\n| Prerequisite | Failure mode if missing |\n|---|---|\n| `{baseDir}\u002Ftools\u002Fgenerate_poc.py` | Fail fast — PoC generation is mandatory |\n\n---\n\n## Approved Wipe APIs\n\nThe following are recognized as valid zeroization. Configure additional entries in `{baseDir}\u002Fconfigs\u002F`.\n\n**C\u002FC++**\n- `explicit_bzero`\n- `memset_s`\n- `SecureZeroMemory`\n- `OPENSSL_cleanse`\n- `sodium_memzero`\n- Volatile wipe loops (pattern-based; see `volatile_wipe_patterns` in `{baseDir}\u002Fconfigs\u002Fdefault.yaml`)\n- In IR: `llvm.memset` with volatile flag, volatile stores, or non-elidable wipe call\n\n**Rust**\n- `zeroize::Zeroize` trait (`zeroize()` method)\n- `Zeroizing\u003CT>` wrapper (drop-based)\n- `ZeroizeOnDrop` derive macro\n\n---\n\n## Finding Capabilities\n\nFindings are grouped by required evidence. Only attempt findings for which the required tooling is available.\n\n| Finding ID | Description | Requires | PoC Support |\n|---|---|---|---|\n| `MISSING_SOURCE_ZEROIZE` | No zeroization found in source | Source only | Yes (C\u002FC++ + Rust) |\n| `PARTIAL_WIPE` | Incorrect size or incomplete wipe | Source only | Yes (C\u002FC++ + Rust) |\n| `NOT_ON_ALL_PATHS` | Zeroization missing on some control-flow paths (heuristic) | Source only | Yes (C\u002FC++ only) |\n| `SECRET_COPY` | Sensitive data copied without zeroization tracking | Source + MCP preferred | Yes (C\u002FC++ + Rust) |\n| `INSECURE_HEAP_ALLOC` | Secret uses insecure allocator (malloc vs. secure_malloc) | Source only | Yes (C\u002FC++ only) |\n| `OPTIMIZED_AWAY_ZEROIZE` | Compiler removed zeroization | IR diff required (never source-only) | Yes |\n| `STACK_RETENTION` | Stack frame may retain secrets after return | Assembly required (C\u002FC++); LLVM IR `alloca`+`lifetime.end` evidence (Rust); assembly corroboration upgrades to `confirmed` | Yes (C\u002FC++ only) |\n| `REGISTER_SPILL` | Secrets spilled from registers to stack | Assembly required (C\u002FC++); LLVM IR `load`+call-site evidence (Rust); assembly corroboration upgrades to `confirmed` | Yes (C\u002FC++ only) |\n| `MISSING_ON_ERROR_PATH` | Error-handling paths lack cleanup | CFG or MCP required | Yes |\n| `NOT_DOMINATING_EXITS` | Wipe doesn't dominate all exits | CFG or MCP required | Yes |\n| `LOOP_UNROLLED_INCOMPLETE` | Unrolled loop wipe is incomplete | Semantic IR required | Yes |\n\n---\n\n## Agent Architecture\n\nThe analysis pipeline uses 11 agents across 8 phases, invoked by the orchestrator (`{baseDir}\u002Fprompts\u002Ftask.md`) via `Task`. Agents write persistent finding files to a shared working directory (`\u002Ftmp\u002Fzeroize-audit-{run_id}\u002F`), enabling parallel execution and protecting against context pressure.\n\n| Agent | Phase | Purpose | Output Directory |\n|---|---|---|---|\n| `0-preflight` | Phase 0 | Preflight checks (tools, toolchain, compile DB, crate build), config merge, workdir creation, TU enumeration | `{workdir}\u002F` |\n| `1-mcp-resolver` | Phase 1, Wave 1 (C\u002FC++ only) | Resolve symbols, types, and cross-file references via Serena MCP | `mcp-evidence\u002F` |\n| `2-source-analyzer` | Phase 1, Wave 2a (C\u002FC++ only) | Identify sensitive objects, detect wipes, validate correctness, data-flow\u002Fheap | `source-analysis\u002F` |\n| `2b-rust-source-analyzer` | Phase 1, Wave 2b (Rust only, parallel with 2a) | Rustdoc JSON trait-aware analysis + dangerous API grep | `source-analysis\u002F` |\n| `3-tu-compiler-analyzer` | Phase 2, Wave 3 (C\u002FC++ only, N parallel) | Per-TU IR diff, assembly, semantic IR, CFG analysis | `compiler-analysis\u002F{tu_hash}\u002F` |\n| `3b-rust-compiler-analyzer` | Phase 2, Wave 3R (Rust only, single agent) | Crate-level MIR, LLVM IR, and assembly analysis | `rust-compiler-analysis\u002F` |\n| `4-report-assembler` | Phase 3 (interim) + Phase 6 (final) | Collect findings from all agents, apply confidence gates; merge PoC results and produce final report | `report\u002F` |\n| `5-poc-generator` | Phase 4 | Craft bespoke proof-of-concept programs (C\u002FC++: all categories; Rust: MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE) | `poc\u002F` |\n| `5b-poc-validator` | Phase 5 | Compile and run all PoCs | `poc\u002F` |\n| `5c-poc-verifier` | Phase 5 | Verify each PoC proves its claimed finding | `poc\u002F` |\n| `6-test-generator` | Phase 7 (optional) | Generate runtime validation test harnesses | `tests\u002F` |\n\nThe orchestrator reads one per-phase workflow file from `{baseDir}\u002Fworkflows\u002F` at a time, and maintains `orchestrator-state.json` for recovery after context compression. Agents receive configuration by file path (`config_path`), not by value.\n\n### Execution flow\n\n```\nPhase 0: 0-preflight agent — Preflight + config + create workdir + enumerate TUs\n           → writes orchestrator-state.json, merged-config.yaml, preflight.json\nPhase 1: Wave 1:  1-mcp-resolver              (skip if mcp_mode=off OR language_mode=rust)\n         Wave 2a: 2-source-analyzer           (C\u002FC++ only; skip if no compile_db)  ─┐ parallel\n         Wave 2b: 2b-rust-source-analyzer     (Rust only; skip if no cargo_manifest) ─┘\nPhase 2: Wave 3:  3-tu-compiler-analyzer x N  (C\u002FC++ only; parallel per TU)\n         Wave 3R: 3b-rust-compiler-analyzer   (Rust only; single crate-level agent)\nPhase 3: Wave 4:  4-report-assembler          (mode=interim → findings.json; reads all agent outputs)\nPhase 4: Wave 5:  5-poc-generator             (C\u002FC++: all categories; Rust: MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE; other Rust findings: poc_supported=false)\nPhase 5: PoC Validation & Verification\n           Step 1: 5b-poc-validator agent      (compile and run all PoCs)\n           Step 2: 5c-poc-verifier agent       (verify each PoC proves its claimed finding)\n           Step 3: Orchestrator presents verification failures to user via AskUserQuestion\n           Step 4: Orchestrator merges all results into poc_final_results.json\nPhase 6: Wave 6: 4-report-assembler           (mode=final → merge PoC results, final-report.md)\nPhase 7: Wave 7: 6-test-generator             (optional)\nPhase 8: Orchestrator — Return final-report.md\n```\n\n## Cross-Reference Convention\n\nIDs are namespaced per agent to prevent collisions during parallel execution:\n\n| Entity | Pattern | Assigned By |\n|---|---|---|\n| Sensitive object (C\u002FC++) | `SO-0001`–`SO-4999` | `2-source-analyzer` |\n| Sensitive object (Rust) | `SO-5000`–`SO-9999` (Rust namespace) | `2b-rust-source-analyzer` |\n| Source finding (C\u002FC++) | `F-SRC-NNNN` | `2-source-analyzer` |\n| Source finding (Rust) | `F-RUST-SRC-NNNN` | `2b-rust-source-analyzer` |\n| IR finding (C\u002FC++) | `F-IR-{tu_hash}-NNNN` | `3-tu-compiler-analyzer` |\n| ASM finding (C\u002FC++) | `F-ASM-{tu_hash}-NNNN` | `3-tu-compiler-analyzer` |\n| CFG finding | `F-CFG-{tu_hash}-NNNN` | `3-tu-compiler-analyzer` |\n| Semantic IR finding | `F-SIR-{tu_hash}-NNNN` | `3-tu-compiler-analyzer` |\n| Rust MIR finding | `F-RUST-MIR-NNNN` | `3b-rust-compiler-analyzer` |\n| Rust LLVM IR finding | `F-RUST-IR-NNNN` | `3b-rust-compiler-analyzer` |\n| Rust assembly finding | `F-RUST-ASM-NNNN` | `3b-rust-compiler-analyzer` |\n| Translation unit | `TU-{hash}` | Orchestrator |\n| Final finding | `ZA-NNNN` | `4-report-assembler` |\n\nEvery finding JSON object includes `related_objects`, `related_findings`, and `evidence_files` fields for cross-referencing between agents.\n\n---\n\n## Detection Strategy\n\nAnalysis runs in two phases. For complete step-by-step guidance, see `{baseDir}\u002Freferences\u002Fdetection-strategy.md`.\n\n| Phase | Steps | Findings produced | Required tooling |\n|---|---|---|---|\n| Phase 1 (Source) | 1–6 | `MISSING_SOURCE_ZEROIZE`, `PARTIAL_WIPE`, `NOT_ON_ALL_PATHS`, `SECRET_COPY`, `INSECURE_HEAP_ALLOC` | Source + compile DB |\n| Phase 2 (Compiler) | 7–12 | `OPTIMIZED_AWAY_ZEROIZE`, `STACK_RETENTION`*, `REGISTER_SPILL`*, `LOOP_UNROLLED_INCOMPLETE`†, `MISSING_ON_ERROR_PATH`‡, `NOT_DOMINATING_EXITS`‡ | `clang`, IR\u002FASM tools |\n\n\\* requires `enable_asm=true` (default)\n† requires `enable_semantic_ir=true`\n‡ requires `enable_cfg=true`\n\n---\n\n\n## Output Format\n\nEach run produces two outputs:\n\n1. **`final-report.md`** — Comprehensive markdown report (primary human-readable output)\n2. **`findings.json`** — Structured JSON matching `{baseDir}\u002Fschemas\u002Foutput.json` (for machine consumption and downstream tools)\n\n### Markdown Report Structure\n\nThe markdown report (`final-report.md`) contains these sections:\n\n- **Header**: Run metadata (run_id, timestamp, repo, compile_db, config summary)\n- **Executive Summary**: Finding counts by severity, confidence, and category\n- **Sensitive Objects Inventory**: Table of all identified objects with IDs, types, locations\n- **Findings**: Grouped by severity then confidence. Each finding includes location, object, all evidence (source\u002FIR\u002FASM\u002FCFG), compiler evidence details, and recommended fix\n- **Superseded Findings**: Source findings replaced by CFG-backed findings\n- **Confidence Gate Summary**: Downgrades applied and overrides rejected\n- **Analysis Coverage**: TUs analyzed, agent success\u002Ffailure, features enabled\n- **Appendix: Evidence Files**: Mapping of finding IDs to evidence file paths\n\n### Structured JSON\n\nThe `findings.json` file follows the schema in `{baseDir}\u002Fschemas\u002Foutput.json`. Each `Finding` object:\n\n```json\n{\n  \"id\": \"ZA-0001\",\n  \"category\": \"OPTIMIZED_AWAY_ZEROIZE\",\n  \"severity\": \"high\",\n  \"confidence\": \"confirmed\",\n  \"language\": \"c\",\n  \"file\": \"src\u002Fcrypto.c\",\n  \"line\": 42,\n  \"symbol\": \"key_buf\",\n  \"evidence\": \"store volatile i8 0 count: O0=32, O2=0 — wipe eliminated by DSE\",\n  \"compiler_evidence\": {\n    \"opt_levels\": [\"O0\", \"O2\"],\n    \"o0\": \"32 volatile stores targeting key_buf\",\n    \"o2\": \"0 volatile stores (all eliminated)\",\n    \"diff_summary\": \"All volatile wipe stores removed at O2 — classic DSE pattern\"\n  },\n  \"suggested_fix\": \"Replace memset with explicit_bzero or add compiler_fence(SeqCst) after the wipe\",\n  \"poc\": {\n    \"file\": \"generated_pocs\u002FZA-0001.c\",\n    \"makefile_target\": \"ZA-0001\",\n    \"compile_opt\": \"-O2\",\n    \"requires_manual_adjustment\": false,\n    \"validated\": true,\n    \"validation_result\": \"exploitable\"\n  }\n}\n```\n\nSee `{baseDir}\u002Fschemas\u002Foutput.json` for the full schema and enum values.\n\n---\n\n## Confidence Gating\n\n### Evidence thresholds\n\nA finding requires at least **2 independent signals** to be marked `confirmed`. With 1 signal, mark `likely`. With 0 strong signals (name-pattern match only), mark `needs_review`.\n\nSignals include: name pattern match, type hint match, explicit annotation, IR evidence, ASM evidence, MCP cross-reference, CFG evidence, PoC validation.\n\n### PoC validation as evidence signal\n\nEvery finding is validated against a bespoke PoC. After compilation and execution, each PoC is also verified to ensure it actually tests the claimed vulnerability. The combined result is an evidence signal:\n\n| PoC Result | Verified | Impact |\n|---|---|---|\n| Exit 0 (exploitable) | Yes | Strong signal — can upgrade `likely` to `confirmed` |\n| Exit 1 (not exploitable) | Yes | Downgrade severity to `low` (informational); retain in report |\n| Exit 0 or 1 | No (user accepted) | Weaker signal — note verification failure in evidence |\n| Exit 0 or 1 | No (user rejected) | No confidence change; annotate as `rejected` |\n| Compile failure \u002F no PoC | — | No confidence change; annotate in evidence |\n\n### MCP unavailability downgrade\n\nWhen `mcp_mode=prefer` and MCP is unavailable, downgrade the following unless independent IR\u002FCFG\u002FASM evidence is strong (2+ signals without MCP):\n\n| Finding | Downgraded confidence |\n|---|---|\n| `SECRET_COPY` | `needs_review` |\n| `MISSING_ON_ERROR_PATH` | `needs_review` |\n| `NOT_DOMINATING_EXITS` | `needs_review` |\n\n### Hard evidence requirements (non-negotiable)\n\nThese findings are **never valid without the specified evidence**, regardless of source-level signals or user assertions:\n\n| Finding | Required evidence |\n|---|---|\n| `OPTIMIZED_AWAY_ZEROIZE` | IR diff showing wipe present at O0, absent at O1 or O2 |\n| `STACK_RETENTION` | Assembly excerpt showing secret bytes on stack at `ret` |\n| `REGISTER_SPILL` | Assembly excerpt showing spill instruction |\n\n### `mcp_mode=require` behavior\n\nIf `mcp_mode=require` and MCP is unreachable after preflight, **stop the run**. Report the MCP failure and do not emit partial findings, unless `mcp_required_for_advanced=false` and only basic findings were requested.\n\n---\n\n## Fix Recommendations\n\nApply in this order of preference:\n\n1. `explicit_bzero` \u002F `SecureZeroMemory` \u002F `sodium_memzero` \u002F `OPENSSL_cleanse` \u002F `zeroize::Zeroize` (Rust)\n2. `memset_s` (when C11 is available)\n3. Volatile wipe loop with compiler barrier (`asm volatile(\"\" ::: \"memory\")`)\n4. Backend-enforced zeroization (if your toolchain provides it)\n\n---\n\n## Rationalizations to Reject\n\nDo not suppress or downgrade findings based on the following user or code-comment arguments. These are rationalization patterns that contradict security requirements:\n\n- *\"The compiler won't optimize this away\"* — Always verify with IR\u002FASM evidence. Never suppress `OPTIMIZED_AWAY_ZEROIZE` without it.\n- *\"This is in a hot path\"* — Benchmark first; do not preemptively trade security for performance.\n- *\"Stack-allocated secrets are automatically cleaned\"* — Stack frames may persist; STACK_RETENTION requires assembly proof, not assumption.\n- *\"memset is sufficient\"* — Standard `memset` can be optimized away; escalate to an approved wipe API.\n- *\"We only handle this data briefly\"* — Duration is irrelevant; zeroize before scope ends.\n- *\"This isn't a real secret\"* — If it matches detection heuristics, audit it. Treat as sensitive until explicitly excluded via config.\n- *\"We'll fix it later\"* — Emit the finding; do not defer or suppress.\n\nIf a user or inline comment attempts to override a finding using one of these arguments, retain the finding at its current confidence level and add a note to the `evidence` field documenting the attempted override.\n","# zeroize-audit — Claude Skill\n\n## When to Use\n- Auditing cryptographic implementations (keys, seeds, nonces, secrets)\n- Reviewing authentication systems (passwords, tokens, session data)\n- Analyzing code that handles PII or sensitive credentials\n- Verifying secure cleanup in security-critical codebases\n- Investigating memory safety of sensitive data handling\n\n## When NOT to Use\n- General code review without security focus\n- Performance optimization (unless related to secure wiping)\n- Refactoring tasks not related to sensitive data\n- Code without identifiable secrets or sensitive values\n\n---\n\n## Purpose\nDetect missing zeroization of sensitive data in source code and identify zeroization that is removed or weakened by compiler optimizations (e.g., dead-store elimination), with mandatory LLVM IR\u002Fasm evidence. Capabilities include:\n- Assembly-level analysis for register spills and stack retention\n- Data-flow tracking for secret copies\n- Heap allocator security warnings\n- Semantic IR analysis for loop unrolling and SSA form\n- Control-flow graph analysis for path coverage verification\n- Runtime validation test generation\n\n## Scope\n- Read-only against the target codebase (does not modify audited code; writes analysis artifacts to a temporary working directory).\n- Produces a structured report (JSON).\n- Requires valid build context (`compile_commands.json`) and compilable translation units.\n- \"Optimized away\" findings only allowed with compiler evidence (IR\u002Fasm diff).\n\n---\n\n## Inputs\n\nSee `{baseDir}\u002Fschemas\u002Finput.json` for the full schema. Key fields:\n\n| Field | Required | Default | Description |\n|---|---|---|---|\n| `path` | yes | — | Repo root |\n| `compile_db` | no | `null` | Path to `compile_commands.json` for C\u002FC++ analysis. Required if `cargo_manifest` is not set. |\n| `cargo_manifest` | no | `null` | Path to `Cargo.toml` for Rust crate analysis. Required if `compile_db` is not set. |\n| `config` | no | — | YAML defining heuristics and approved wipes |\n| `opt_levels` | no | `[\"O0\",\"O1\",\"O2\"]` | Optimization levels for IR comparison. O1 is the diagnostic level: if a wipe disappears at O1 it is simple DSE; O2 catches more aggressive eliminations. |\n| `languages` | no | `[\"c\",\"cpp\",\"rust\"]` | Languages to analyze |\n| `max_tus` | no | — | Limit on translation units processed from compile DB |\n| `mcp_mode` | no | `prefer` | `off`, `prefer`, or `require` — controls Serena MCP usage |\n| `mcp_required_for_advanced` | no | `true` | Downgrade `SECRET_COPY`, `MISSING_ON_ERROR_PATH`, and `NOT_DOMINATING_EXITS` to `needs_review` when MCP is unavailable |\n| `mcp_timeout_ms` | no | — | Timeout budget for MCP semantic queries |\n| `poc_categories` | no | all 11 exploitable | Finding categories for which to generate PoCs. C\u002FC++ findings: all 11 categories supported. Rust findings: only `MISSING_SOURCE_ZEROIZE`, `SECRET_COPY`, and `PARTIAL_WIPE` are supported; other Rust categories are marked `poc_supported=false`. |\n| `poc_output_dir` | no | `generated_pocs\u002F` | Output directory for generated PoCs |\n| `enable_asm` | no | `true` | Enable assembly emission and analysis (Step 8); produces `STACK_RETENTION`, `REGISTER_SPILL`. Auto-disabled if `emit_asm.sh` is missing. |\n| `enable_semantic_ir` | no | `false` | Enable semantic LLVM IR analysis (Step 9); produces `LOOP_UNROLLED_INCOMPLETE` |\n| `enable_cfg` | no | `false` | Enable control-flow graph analysis (Step 10); produces `MISSING_ON_ERROR_PATH`, `NOT_DOMINATING_EXITS` |\n| `enable_runtime_tests` | no | `false` | Enable runtime test harness generation (Step 11) |\n\n---\n\n## Prerequisites\n\nBefore running, verify the following. Each has a defined failure mode.\n\n**C\u002FC++ prerequisites:**\n\n| Prerequisite | Failure mode if missing |\n|---|---|\n| `compile_commands.json` at `compile_db` path | Fail fast — do not proceed |\n| `clang` on PATH | Fail fast — IR\u002FASM analysis impossible |\n| `uvx` on PATH (for Serena) | If `mcp_mode=require`: fail. If `mcp_mode=prefer`: continue without MCP; downgrade affected findings per Confidence Gating rules. |\n| `{baseDir}\u002Ftools\u002Fextract_compile_flags.py` | Fail fast — cannot extract per-TU flags |\n| `{baseDir}\u002Ftools\u002Femit_ir.sh` | Fail fast — IR analysis impossible |\n| `{baseDir}\u002Ftools\u002Femit_asm.sh` | Warn and skip assembly findings (STACK_RETENTION, REGISTER_SPILL) |\n| `{baseDir}\u002Ftools\u002Fmcp\u002Fcheck_mcp.sh` | Warn and treat as MCP unavailable |\n| `{baseDir}\u002Ftools\u002Fmcp\u002Fnormalize_mcp_evidence.py` | Warn and use raw MCP output |\n\n**Rust prerequisites:**\n\n| Prerequisite | Failure mode if missing |\n|---|---|\n| `Cargo.toml` at `cargo_manifest` path | Fail fast — do not proceed |\n| `cargo check` passes | Fail fast — crate must be buildable |\n| `cargo +nightly` on PATH | Fail fast — nightly required for MIR and LLVM IR emission |\n| `uv` on PATH | Fail fast — required to run Python analysis scripts |\n| `{baseDir}\u002Ftools\u002Fvalidate_rust_toolchain.sh` | Warn — run preflight manually. Checks all tools, scripts, nightly, and optionally `cargo check`. Use `--json` for machine-readable output, `--manifest` to also validate the crate builds. |\n| `{baseDir}\u002Ftools\u002Femit_rust_mir.sh` | Fail fast — MIR analysis impossible (`--opt`, `--crate`, `--bin\u002F--lib` supported; `--out` can be file or directory) |\n| `{baseDir}\u002Ftools\u002Femit_rust_ir.sh` | Fail fast — LLVM IR analysis impossible (`--opt` required; `--crate`, `--bin\u002F--lib` supported; `--out` must be `.ll`) |\n| `{baseDir}\u002Ftools\u002Femit_rust_asm.sh` | Warn and skip assembly findings (`STACK_RETENTION`, `REGISTER_SPILL`). Supports `--opt`, `--crate`, `--bin\u002F--lib`, `--target`, `--intel-syntax`; `--out` can be `.s` file or directory. |\n| `{baseDir}\u002Ftools\u002Fdiff_rust_mir.sh` | Warn and skip MIR-level optimization comparison. Accepts 2+ MIR files, normalizes, diffs pairwise, and reports first opt level where zeroize\u002Fdrop-glue patterns disappear. |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fsemantic_audit.py` | Warn and skip semantic source analysis |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Ffind_dangerous_apis.py` | Warn and skip dangerous API scan |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_mir_patterns.py` | Warn and skip MIR analysis |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_llvm_patterns.py` | Warn and skip LLVM IR analysis |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_rust_asm.py` | Warn and skip Rust assembly analysis (`STACK_RETENTION`, `REGISTER_SPILL`, drop-glue checks). Dispatches to `check_rust_asm_x86.py` (production) or `check_rust_asm_aarch64.py` (**EXPERIMENTAL** — AArch64 findings require manual verification). |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_rust_asm_x86.py` | Required by `check_rust_asm.py` for x86-64 analysis; warn and skip if missing |\n| `{baseDir}\u002Ftools\u002Fscripts\u002Fcheck_rust_asm_aarch64.py` | Required by `check_rust_asm.py` for AArch64 analysis (**EXPERIMENTAL**); warn and skip if missing |\n\n**Common prerequisite:**\n\n| Prerequisite | Failure mode if missing |\n|---|---|\n| `{baseDir}\u002Ftools\u002Fgenerate_poc.py` | Fail fast — PoC generation is mandatory |\n\n---\n\n## Approved Wipe APIs\n\nThe following are recognized as valid zeroization. Configure additional entries in `{baseDir}\u002Fconfigs\u002F`.\n\n**C\u002FC++**\n- `explicit_bzero`\n- `memset_s`\n- `SecureZeroMemory`\n- `OPENSSL_cleanse`\n- `sodium_memzero`\n- Volatile wipe loops (pattern-based; see `volatile_wipe_patterns` in `{baseDir}\u002Fconfigs\u002Fdefault.yaml`)\n- In IR: `llvm.memset` with volatile flag, volatile stores, or non-elidable wipe call\n\n**Rust**\n- `zeroize::Zeroize` trait (`zeroize()` method)\n- `Zeroizing\u003CT>` wrapper (drop-based)\n- `ZeroizeOnDrop` derive macro\n\n---\n\n## Finding Capabilities\n\nFindings are grouped by required evidence. Only attempt findings for which the required tooling is available.\n\n| Finding ID | Description | Requires | PoC Support |\n|---|---|---|---|\n| `MISSING_SOURCE_ZEROIZE` | No zeroization found in source | Source only | Yes (C\u002FC++ + Rust) |\n| `PARTIAL_WIPE` | Incorrect size or incomplete wipe | Source only | Yes (C\u002FC++ + Rust) |\n| `NOT_ON_ALL_PATHS` | Zeroization missing on some control-flow paths (heuristic) | Source only | Yes (C\u002FC++ only) |\n| `SECRET_COPY` | Sensitive data copied without zeroization tracking | Source + MCP preferred | Yes (C\u002FC++ + Rust) |\n| `INSECURE_HEAP_ALLOC` | Secret uses insecure allocator (malloc vs. secure_malloc) | Source only | Yes (C\u002FC++ only) |\n| `OPTIMIZED_AWAY_ZEROIZE` | Compiler removed zeroization | IR diff required (never source-only) | Yes |\n| `STACK_RETENTION` | Stack frame may retain secrets after return | Assembly required (C\u002FC++); LLVM IR `alloca`+`lifetime.end` evidence (Rust); assembly corroboration upgrades to `confirmed` | Yes (C\u002FC++ only) |\n| `REGISTER_SPILL` | Secrets spilled from registers to stack | Assembly required (C\u002FC++); LLVM IR `load`+call-site evidence (Rust); assembly corroboration upgrades to `confirmed` | Yes (C\u002FC++ only) |\n| `MISSING_ON_ERROR_PATH` | Error-handling paths lack cleanup | CFG or MCP required | Yes |\n| `NOT_DOMINATING_EXITS` | Wipe doesn't dominate all exits | CFG or MCP required | Yes |\n| `LOOP_UNROLLED_INCOMPLETE` | Unrolled loop wipe is incomplete | Semantic IR required | Yes |\n\n---\n\n## Agent Architecture\n\nThe analysis pipeline uses 11 agents across 8 phases, invoked by the orchestrator (`{baseDir}\u002Fprompts\u002Ftask.md`) via `Task`. Agents write persistent finding files to a shared working directory (`\u002Ftmp\u002Fzeroize-audit-{run_id}\u002F`), enabling parallel execution and protecting against context pressure.\n\n| Agent | Phase | Purpose | Output Directory |\n|---|---|---|---|\n| `0-preflight` | Phase 0 | Preflight checks (tools, toolchain, compile DB, crate build), config merge, workdir creation, TU enumeration | `{workdir}\u002F` |\n| `1-mcp-resolver` | Phase 1, Wave 1 (C\u002FC++ only) | Resolve symbols, types, and cross-file references via Serena MCP | `mcp-evidence\u002F` |\n| `2-source-analyzer` | Phase 1, Wave 2a (C\u002FC++ only) | Identify sensitive objects, detect wipes, validate correctness, data-flow\u002Fheap | `source-analysis\u002F` |\n| `2b-rust-source-analyzer` | Phase 1, Wave 2b (Rust only, parallel with 2a) | Rustdoc JSON trait-aware analysis + dangerous API grep | `source-analysis\u002F` |\n| `3-tu-compiler-analyzer` | Phase 2, Wave 3 (C\u002FC++ only, N parallel) | Per-TU IR diff, assembly, semantic IR, CFG analysis | `compiler-analysis\u002F{tu_hash}\u002F` |\n| `3b-rust-compiler-analyzer` | Phase 2, Wave 3R (Rust only, single agent) | Crate-level MIR, LLVM IR, and assembly analysis | `rust-compiler-analysis\u002F` |\n| `4-report-assembler` | Phase 3 (interim) + Phase 6 (final) | Collect findings from all agents, apply confidence gates; merge PoC results and produce final report | `report\u002F` |\n| `5-poc-generator` | Phase 4 | Craft bespoke proof-of-concept programs (C\u002FC++: all categories; Rust: MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE) | `poc\u002F` |\n| `5b-poc-validator` | Phase 5 | Compile and run all PoCs | `poc\u002F` |\n| `5c-poc-verifier` | Phase 5 | Verify each PoC proves its claimed finding | `poc\u002F` |\n| `6-test-generator` | Phase 7 (optional) | Generate runtime validation test harnesses | `tests\u002F` |\n\nThe orchestrator reads one per-phase workflow file from `{baseDir}\u002Fworkflows\u002F` at a time, and maintains `orchestrator-state.json` for recovery after context compression. Agents receive configuration by file path (`config_path`), not by value.\n\n### Execution flow\n\n```\nPhase 0: 0-preflight agent — Preflight + config + create workdir + enumerate TUs\n           → writes orchestrator-state.json, merged-config.yaml, preflight.json\nPhase 1: Wave 1:  1-mcp-resolver              (skip if mcp_mode=off OR language_mode=rust)\n         Wave 2a: 2-source-analyzer           (C\u002FC++ only; skip if no compile_db)  ─┐ parallel\n         Wave 2b: 2b-rust-source-analyzer     (Rust only; skip if no cargo_manifest) ─┘\nPhase 2: Wave 3:  3-tu-compiler-analyzer x N  (C\u002FC++ only; parallel per TU)\n         Wave 3R: 3b-rust-compiler-analyzer   (Rust only; single crate-level agent)\nPhase 3: Wave 4:  4-report-assembler          (mode=interim → findings.json; reads all agent outputs)\nPhase 4: Wave 5:  5-poc-generator             (C\u002FC++: all categories; Rust: MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE; other Rust findings: poc_supported=false)\nPhase 5: PoC Validation & Verification\n           Step 1: 5b-poc-validator agent      (compile and run all PoCs)\n           Step 2: 5c-poc-verifier agent       (verify each PoC proves its claimed finding)\n           Step 3: Orchestrator presents verification failures to user via AskUserQuestion\n           Step 4: Orchestrator merges all results into poc_final_results.json\nPhase 6: Wave 6: 4-report-assembler           (mode=final → merge PoC results, final-report.md)\nPhase 7: Wave 7: 6-test-generator             (optional)\nPhase 8: Orchestrator — Return final-report.md\n```\n\n## Cross-Reference Convention\n\nIDs are namespaced per agent to prevent collisions during parallel execution:\n\n| Entity | Pattern | Assigned By |\n|---|---|---|\n| Sensitive object (C\u002FC++) | `SO-0001`–`SO-4999` | `2-source-analyzer` |\n| Sensitive object (Rust) | `SO-5000`–`SO-9999` (Rust namespace) | `2b-rust-source-analyzer` |\n| Source finding (C\u002FC++) | `F-SRC-NNNN` | `2-source-analyzer` |\n| Source finding (Rust) | `F-RUST-SRC-NNNN` | `2b-rust-source-analyzer` |\n| IR finding (C\u002FC++) | `F-IR-{tu_hash}-NNNN` | `3-tu-compiler-analyzer` |\n| ASM finding (C\u002FC++) | `F-ASM-{tu_hash}-NNNN` | `3-tu-compiler-analyzer` |\n| CFG finding | `F-CFG-{tu_hash}-NNNN` | `3-tu-compiler-analyzer` |\n| Semantic IR finding | `F-SIR-{tu_hash}-NNNN` | `3-tu-compiler-analyzer` |\n| Rust MIR finding | `F-RUST-MIR-NNNN` | `3b-rust-compiler-analyzer` |\n| Rust LLVM IR finding | `F-RUST-IR-NNNN` | `3b-rust-compiler-analyzer` |\n| Rust assembly finding | `F-RUST-ASM-NNNN` | `3b-rust-compiler-analyzer` |\n| Translation unit | `TU-{hash}` | Orchestrator |\n| Final finding | `ZA-NNNN` | `4-report-assembler` |\n\nEvery finding JSON object includes `related_objects`, `related_findings`, and `evidence_files` fields for cross-referencing between agents.\n\n---\n\n## Detection Strategy\n\nAnalysis runs in two phases. For complete step-by-step guidance, see `{baseDir}\u002Freferences\u002Fdetection-strategy.md`.\n\n| Phase | Steps | Findings produced | Required tooling |\n|---|---|---|---|\n| Phase 1 (Source) | 1–6 | `MISSING_SOURCE_ZEROIZE`, `PARTIAL_WIPE`, `NOT_ON_ALL_PATHS`, `SECRET_COPY`, `INSECURE_HEAP_ALLOC` | Source + compile DB |\n| Phase 2 (Compiler) | 7–12 | `OPTIMIZED_AWAY_ZEROIZE`, `STACK_RETENTION`*, `REGISTER_SPILL`*, `LOOP_UNROLLED_INCOMPLETE`†, `MISSING_ON_ERROR_PATH`‡, `NOT_DOMINATING_EXITS`‡ | `clang`, IR\u002FASM tools |\n\n\\* requires `enable_asm=true` (default)\n† requires `enable_semantic_ir=true`\n‡ requires `enable_cfg=true`\n\n---\n\n\n## Output Format\n\nEach run produces two outputs:\n\n1. **`final-report.md`** — Comprehensive markdown report (primary human-readable output)\n2. **`findings.json`** — Structured JSON matching `{baseDir}\u002Fschemas\u002Foutput.json` (for machine consumption and downstream tools)\n\n### Markdown Report Structure\n\nThe markdown report (`final-report.md`) contains these sections:\n\n- **Header**: Run metadata (run_id, timestamp, repo, compile_db, config summary)\n- **Executive Summary**: Finding counts by severity, confidence, and category\n- **Sensitive Objects Inventory**: Table of all identified objects with IDs, types, locations\n- **Findings**: Grouped by severity then confidence. Each finding includes location, object, all evidence (source\u002FIR\u002FASM\u002FCFG), compiler evidence details, and recommended fix\n- **Superseded Findings**: Source findings replaced by CFG-backed findings\n- **Confidence Gate Summary**: Downgrades applied and overrides rejected\n- **Analysis Coverage**: TUs analyzed, agent success\u002Ffailure, features enabled\n- **Appendix: Evidence Files**: Mapping of finding IDs to evidence file paths\n\n### Structured JSON\n\nThe `findings.json` file follows the schema in `{baseDir}\u002Fschemas\u002Foutput.json`. Each `Finding` object:\n\n```json\n{\n  \"id\": \"ZA-0001\",\n  \"category\": \"OPTIMIZED_AWAY_ZEROIZE\",\n  \"severity\": \"high\",\n  \"confidence\": \"confirmed\",\n  \"language\": \"c\",\n  \"file\": \"src\u002Fcrypto.c\",\n  \"line\": 42,\n  \"symbol\": \"key_buf\",\n  \"evidence\": \"store volatile i8 0 count: O0=32, O2=0 — wipe eliminated by DSE\",\n  \"compiler_evidence\": {\n    \"opt_levels\": [\"O0\", \"O2\"],\n    \"o0\": \"32 volatile stores targeting key_buf\",\n    \"o2\": \"0 volatile stores (all eliminated)\",\n    \"diff_summary\": \"All volatile wipe stores removed at O2 — classic DSE pattern\"\n  },\n  \"suggested_fix\": \"Replace memset with explicit_bzero or add compiler_fence(SeqCst) after the wipe\",\n  \"poc\": {\n    \"file\": \"generated_pocs\u002FZA-0001.c\",\n    \"makefile_target\": \"ZA-0001\",\n    \"compile_opt\": \"-O2\",\n    \"requires_manual_adjustment\": false,\n    \"validated\": true,\n    \"validation_result\": \"exploitable\"\n  }\n}\n```\n\nSee `{baseDir}\u002Fschemas\u002Foutput.json` for the full schema and enum values.\n\n---\n\n## Confidence Gating\n\n### Evidence thresholds\n\nA finding requires at least **2 independent signals** to be marked `confirmed`. With 1 signal, mark `likely`. With 0 strong signals (name-pattern match only), mark `needs_review`.\n\nSignals include: name pattern match, type hint match, explicit annotation, IR evidence, ASM evidence, MCP cross-reference, CFG evidence, PoC validation.\n\n### PoC validation as evidence signal\n\nEvery finding is validated against a bespoke PoC. After compilation and execution, each PoC is also verified to ensure it actually tests the claimed vulnerability. The combined result is an evidence signal:\n\n| PoC Result | Verified | Impact |\n|---|---|---|\n| Exit 0 (exploitable) | Yes | Strong signal — can upgrade `likely` to `confirmed` |\n| Exit 1 (not exploitable) | Yes | Downgrade severity to `low` (informational); retain in report |\n| Exit 0 or 1 | No (user accepted) | Weaker signal — note verification failure in evidence |\n| Exit 0 or 1 | No (user rejected) | No confidence change; annotate as `rejected` |\n| Compile failure \u002F no PoC | — | No confidence change; annotate in evidence |\n\n### MCP unavailability downgrade\n\nWhen `mcp_mode=prefer` and MCP is unavailable, downgrade the following unless independent IR\u002FCFG\u002FASM evidence is strong (2+ signals without MCP):\n\n| Finding | Downgraded confidence |\n|---|---|\n| `SECRET_COPY` | `needs_review` |\n| `MISSING_ON_ERROR_PATH` | `needs_review` |\n| `NOT_DOMINATING_EXITS` | `needs_review` |\n\n### Hard evidence requirements (non-negotiable)\n\nThese findings are **never valid without the specified evidence**, regardless of source-level signals or user assertions:\n\n| Finding | Required evidence |\n|---|---|\n| `OPTIMIZED_AWAY_ZEROIZE` | IR diff showing wipe present at O0, absent at O1 or O2 |\n| `STACK_RETENTION` | Assembly excerpt showing secret bytes on stack at `ret` |\n| `REGISTER_SPILL` | Assembly excerpt showing spill instruction |\n\n### `mcp_mode=require` behavior\n\nIf `mcp_mode=require` and MCP is unreachable after preflight, **stop the run**. Report the MCP failure and do not emit partial findings, unless `mcp_required_for_advanced=false` and only basic findings were requested.\n\n---\n\n## Fix Recommendations\n\nApply in this order of preference:\n\n1. `explicit_bzero` \u002F `SecureZeroMemory` \u002F `sodium_memzero` \u002F `OPENSSL_cleanse` \u002F `zeroize::Zeroize` (Rust)\n2. `memset_s` (when C11 is available)\n3. Volatile wipe loop with compiler barrier (`asm volatile(\"\" ::: \"memory\")`)\n4. Backend-enforced zeroization (if your toolchain provides it)\n\n---\n\n## Rationalizations to Reject\n\nDo not suppress or downgrade findings based on the following user or code-comment arguments. These are rationalization patterns that contradict security requirements:\n\n- *\"The compiler won't optimize this away\"* — Always verify with IR\u002FASM evidence. Never suppress `OPTIMIZED_AWAY_ZEROIZE` without it.\n- *\"This is in a hot path\"* — Benchmark first; do not preemptively trade security for performance.\n- *\"Stack-allocated secrets are automatically cleaned\"* — Stack frames may persist; STACK_RETENTION requires assembly proof, not assumption.\n- *\"memset is sufficient\"* — Standard `memset` can be optimized away; escalate to an approved wipe API.\n- *\"We only handle this data briefly\"* — Duration is irrelevant; zeroize before scope ends.\n- *\"This isn't a real secret\"* — If it matches detection heuristics, audit it. Treat as sensitive until explicitly excluded via config.\n- *\"We'll fix it later\"* — Emit the finding; do not defer or suppress.\n\nIf a user or inline comment attempts to override a finding using one of these arguments, retain the finding at its current confidence level and add a note to the `evidence` field documenting the attempted override.\n",{"name":5,"risk":28,"source":32,"description":7,"allowed-tools":49},[50,51,52,36,53,54,55,56,57,58,59],"Read","Grep","Glob","Write","Task","AskUserQuestion","mcp__serena__activate_project","mcp__serena__find_symbol","mcp__serena__find_referencing_symbols","mcp__serena__get_symbols_overview","main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fcopilot\u002Fzeroize-audit","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":67,"prompt":77,"zipAvailable":78},[68,71,74],{"tool":69,"command":70},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill zeroize-audit",{"tool":72,"command":73},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill zeroize-audit",{"tool":75,"command":76},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill zeroize-audit","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcopilot\u002Fzeroize-audit\u002FSKILL.md",true,[],[81,105,128,138,151,168],{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":92,"publishedAt":44},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[87],{"categoryNo":88,"categoryName":89,"taxonomyType":90,"taxonomyTypeDesc":91},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[93,94,95,96,97,98,99,100,101,102,103,104],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch","with",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":111,"publishedAt":44},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[112,113,114,115,36,116,95,117,118,119,120,121,122,123,39,124,125,26,126,127],"trend","trend tap","tap","api keys","time","trending","hacker","aggregator","do","when","brew","live","google","install","across","api",{"skillNo":129,"name":130,"nameZh":6,"description":131,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":134,"publishedAt":44},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[135,136,112,122,123,39,124,36,95,26,137,126,127,121,119,118,117,125,116,115],"trend radar","radar","pulse",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":144,"publishedAt":44},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[145,146,147,148,149,150],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":152,"name":153,"nameZh":6,"description":154,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":155,"categories":156,"keywords":160,"publishedAt":44},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[157],{"categoryNo":158,"categoryName":159,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究",[153,101,161,162,163,104,122,164,165,166,114,167,125],"Audio","cli","youtube","images","https","files","pdfs",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":174,"publishedAt":44},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[170,175,176,177,125,178,165,179,180,181,182,183],"status","play","go","latest","github","discover","control","cmd","volume"]