# Saf Checker Dev

> Use when creating new SAF bug-finding checkers, taint analysis rules, resource leak detectors, or typestate specifications

- Skill: `tomevault-io/saf-checker-dev` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/saf-checker-dev`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/saf-checker-dev/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/saf-checker-dev

---


# SAF Checker Development Skill

Guides spec-first development of bug-finding checkers in SAF. Checkers are classified into three tiers -- try declarative first, escalate only when needed.

## Checker Tier Routing

| Tier | When to Use | What You Write |
|---|---|---|
| **1 - Declarative** | Source/sink/sanitizer expressible with existing `SitePattern` variants | `CheckerSpec` only (no Rust code) |
| **2 - Typestate** | Bug involves ordered state transitions (open->use->close) | `TypestateSpec` with state machine |
| **3 - Custom** | Need new `SitePattern` variant or `CustomPredicate` | Rust code changes in `spec.rs`, `site_classifier.rs`, solver |

All 9 built-in checkers are Tier 1. Start there.

## Workflow Phases

### Phase 1: Understand the Bug Pattern
Ask the user for: source (where bad values originate), sink (where the bug manifests), sanitizer (what prevents it), CWE number, and severity.

### Phase 2: Classify Tier
Load `references/checker-types-guide.md` with Read. Use the decision tree and `SitePattern` catalog to determine if existing patterns suffice (Tier 1), a state machine is needed (Tier 2), or new Rust code is required (Tier 3).

### Phase 3: Explore Existing Checkers
Read `crates/saf-analysis/src/checkers/spec.rs` to find the closest built-in checker. Use Grep to search for similar `SitePattern` usage across `checkers/`. Reuse patterns where possible.

### Phase 4: Write the Spec
Load `references/spec-authoring-guide.md` with Read. For Tier 1: compose a `CheckerSpec` with the right `ReachabilityMode`, sources, sinks, and sanitizers. For Tier 2: define a `TypestateSpec`. For Tier 3: implement new `SitePattern` variants in Rust.

### Phase 5: Create Test Cases
Load `references/test-case-guide.md` with Read. Write paired C programs (bad variant with the bug, good variant without). Compile to LLVM IR inside Docker via Bash:
```
docker compose run --rm dev sh -c 'clang -S -emit-llvm -g -O0 tests/programs/c/<name>.c -o tests/fixtures/llvm/e2e/<name>.ll'
```
Write e2e tests asserting bad variant produces findings and good variant produces none.

### Phase 6: Run and Debug
Run tests via Bash: `make fmt && make test 2>&1 | tee /tmp/test-output.txt`. On failures, enable debug logging:
```
docker compose run --rm -e SAF_LOG="checker[reasoning,path,result]" dev sh -c 'cargo nextest run <test_name>'
```
Load `references/saf-log-guide.md` for log DSL details.

### Phase 7: Refine
Iterate: fix false positives by adding sanitizers, fix false negatives by broadening sources/sinks. Re-run tests after each change. Use `SAF_LOG=pta::solve[pts]` for pointer analysis issues.

### Phase 8: Export and Register
For built-in checkers: Edit `spec.rs` to add to `builtin_checkers()` and `builtin_checker_names()`. For YAML-based: write spec file to `share/saf/specs/`. Update any relevant documentation.

## Key Reminders

- **Spec-first**: Always try Tier 1 declarative before writing Rust code.
- **Docker only**: All builds and tests run inside Docker (`make test`, `make shell`).
- **SAF_LOG**: Use `checker[reasoning,path,result]` to trace checker decisions.
- **Paired tests**: Every checker needs both bad and good variant test programs.
- **Shared references** available in `references/`: `saf-invariants.md`, `saf-log-guide.md`, `e2e-testing-guide.md`.

---
> Source: [Static-Analyzer-Factory/static-analyzer-factory](https://github.com/Static-Analyzer-Factory/static-analyzer-factory) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-06-18 -->

