
Differential Fuzzer
Run Turso’s differential oracle fuzzer so generated SQL is checked against SQLite before you ship database correctness fixes.
Overview
Differential-fuzzer is an agent skill for the Ship phase that teaches how to run Turso’s differential fuzzer so generated SQL is oracle-checked against SQLite.
Install
npx skills add https://github.com/tursodatabase/turso --skill differential-fuzzerWhat is this skill?
- Documents `cargo run --bin differential_fuzzer` with seed, statement count, table/column knobs, verbose and keep-files f
- Supports continuous `loop` mode and a Docker runner path for CI-style runs
- Compares Turso results to SQLite for generated statements to surface correctness mismatches
- Points to the repo’s Debugging skill as required context when triaging failures
- Default run uses 100 statements with configurable tables (default 2) and columns (default 5)
- Default 100 statements per run (`-n`, tables default 2, columns default 5)
- Supports `loop` mode for open-ended or N-iteration continuous fuzzing
- Optional `--keep-files` persists `.db` files for post-run debugging
Adoption & trust: 686 installs on skills.sh; 19.1k GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are changing Turso’s SQL engine and need a deterministic, high-volume way to catch result mismatches versus SQLite without hand-writing thousands of queries.
Who is it for?
Turso repo contributors running local or CI differential oracle fuzzing after engine or planner changes.
Skip if: Application-level integration tests, UI QA, or teams without the Turso source tree and Rust/Cargo environment.
When should I use this skill?
Always load this skill when running the differential fuzzer tool.
What do I get? / Deliverables
You can launch seeded or looped fuzz runs (optionally in Docker), reproduce failures with kept database files, and triage with the Debugging skill workflow.
- Reproducible fuzz run logs and optional on-disk `.db` artifacts
- Identified Turso-vs-SQLite correctness divergences for debugging
Recommended Skills
Journey fit
Fuzzing and oracle comparison are pre-release quality gates for the database engine, not feature design work. Differential fuzzing is an automated correctness test harness—canonical home is Ship → testing alongside other regression tooling.
How it compares
Use for engine-level differential testing—not as a substitute for application test suites or manual SQL notebooks.
Common Questions / FAQ
Who is differential-fuzzer for?
Database engine contributors and advanced solo builders who clone Turso and need automated SQLite-oracle fuzzing during development.
When should I use differential-fuzzer?
During Ship → testing when you run or debug `differential_fuzzer`, before merging risky SQL/storage changes, or when setting up loop/Docker fuzz jobs in CI.
Is differential-fuzzer safe to install?
It is documentation for running local Rust binaries that generate databases and SQL; review the Security Audits panel on this page and treat fuzz artifacts and shell commands as trusted-only in your own repo.
Workflow Chain
Requires first: debugging
SKILL.md
READMESKILL.md - Differential Fuzzer
# Differential Fuzzer Always load [Debugging skill for reference](../debugging/) The differential fuzzer compares Turso results against SQLite for generated SQL statements to find correctness bugs. ## Location `testing/differential-oracle/fuzzer/` ## Running the Fuzzer ### Single Run ```bash # Basic run (100 statements, random seed) cargo run --bin differential_fuzzer # With specific seed for reproducibility cargo run --bin differential_fuzzer -- --seed 12345 # More statements with verbose output cargo run --bin differential_fuzzer -- -n 1000 --verbose # Keep database files after run (for debugging) cargo run --bin differential_fuzzer -- --seed 12345 --keep-files # All options cargo run --bin differential_fuzzer -- \ --seed <SEED> # Deterministic seed -n <NUM> # Number of statements (default: 100) -t <NUM> # Number of tables (default: 2) -c <NUM> # Columns per table (default: 5) --verbose # Print each SQL statement --keep-files # Persist .db files to disk ``` ### Continuous Fuzzing (Loop Mode) ```bash # Run forever with random seeds cargo run --bin differential_fuzzer -- loop # Run 50 iterations cargo run --bin differential_fuzzer -- loop 50 ``` ### Docker Runner (CI/Production) ```bash # Build and run from repo root docker build -f testing/differential-oracle/fuzzer/docker-runner/Dockerfile -t fuzzer . docker run -e GITHUB_TOKEN=xxx -e SLACK_WEBHOOK_URL=xxx fuzzer ``` Environment variables for docker-runner: - `TIME_LIMIT_MINUTES` - Total runtime (default: 1440 = 24h) - `PER_RUN_TIMEOUT_SECONDS` - Per-run timeout (default: 1200 = 20min) - `NUM_STATEMENTS` - Statements per run (default: 1000) - `LOG_TO_STDOUT` - Print fuzzer output (default: false) - `GITHUB_TOKEN` - For auto-filing issues - `SLACK_WEBHOOK_URL` - For notifications ## Output Files All output goes to `simulator-output/` directory: | File | Description | |------|-------------| | `test.sql` | All executed SQL statements. Failed statements prefixed with `-- FAILED:`, errors with `-- ERROR:` | | `schema.json` | Database schema at end of run (or at failure) | | `test.db` | Turso database file (only with `--keep-files`) | | `test-sqlite.db` | SQLite database file (only with `--keep-files`) | ## Reproducing Errors Always follow these steps 1. **Find the seed** in the error output: ``` INFO: Starting differential_fuzzer with config: SimConfig { seed: 12345, ... } ``` 2. **Re-run with that seed**: ```bash cargo run --bin differential_fuzzer -- --seed 12345 --verbose --keep-files ``` 3. **Check output files**: - `simulator-output/test.sql` - Find the failing statement (look for `-- FAILED:`) - `simulator-output/schema.json` - Check table structure at failure time 4. **Create a minimal reproducer** - Create reproducer in `.sqltest` or in `.rs` always load [Debugging skill for reference](../debugging/) 5. **Compare behavior manually**: If needed try to compare the behaviour and produce a report in the end. Always write to a tmp file first with Edit tool to test the sql and then pass it to the binaries. ```bash # Run failing SQL against SQLite sqlite3 :memory: < simulator-output/test.sql # Run against tursodb CLI tursodb :memory: < simulator-output/test.sql ``` ## Understanding Failures ### Oracle Failure Types 1. **Row set mismatch** - Turso returned different rows than SQLite 2. **Turso errored but SQLite succeeded** - Turso rejected valid SQL 3. **SQLite errored but Turso succeeded** - Turso accepted invalid SQL 4. **Schema mismatch** - Tables/columns differ after DDL ### Warning (non-fatal) - **Unordered LIMIT mismatch** - LIMIT without ORDER BY may return different valid rows ## Key Source Files | File | Purpos