deslop is a Rust-based static analyzer for Go, Python, and Rust repositories that focuses on signals commonly associated with low-context AI-generated code. It currently scans a repository, parses Go, Python, and Rust files with tree-sitter, extracts structural fingerprints for each function, builds a lightweight local package index, runs early heuristic checks, and can benchmark the pipeline against real repositories.
Run a scan against a target path:
cargo run -- scan /path/to/repodeslop auto-detects supported source files under that path. The same command works for Go-only repositories, Python-only repositories, Rust-only repositories, and mixed-language repositories.
By default, scan output prints the scan summary plus the standard finding set. Pass --details when you want the per-function fingerprint breakdown alongside the normal findings.
Repository-local scan behavior can be tuned with a .deslop.toml file at the scan root:
go_semantic_experimental = true
rust_async_experimental = true
disabled_rules = ["panic_macro_leftover"]
suppressed_paths = ["tests/fixtures"]
[severity_overrides]
expect_in_non_test_code = "error"go_semantic_experimental = true enables the deeper semantic Go heuristics such as nested-loop allocation/string-build checks and stronger nested N+1 escalation.
rust_async_experimental = true keeps the Rust async rule pack enabled for that repository.
disabled_rules removes matching rule ids entirely,
suppressed_paths filters findings under matching relative path prefixes after analysis, and
severity_overrides rewrites the emitted severity after analysis.
You can also ignore rule ids for a single scan invocation without changing repository config:
cargo run -- scan --ignore hallucinated_import_call,hallucinated_local_call /path/to/repo--ignore applies after analysis and only affects the emitted findings for that command.
Run the same scan with JSON output:
cargo run -- scan --json /path/to/repoEnable the deeper semantic Go checks for a single run:
cargo run -- scan --enable-semantic /path/to/go-repoShow full per-function fingerprint details in either text or JSON output:
cargo run -- scan --details /path/to/repo
cargo run -- scan --json --details /path/to/repoBy default, scan also exports review-ready function context files and batched chunk files:
cargo run -- scan /path/to/repo --no-failOutput locations (created automatically):
scripts/findings/functions/1.txt,2.txt, ...scripts/chunks/Chunk_1_25.txt,Chunk_26_50.txt, ...
Opt out of export:
cargo run -- scan /path/to/repo --no-context --no-chunksCustomize chunk size or output directories:
cargo run -- scan /path/to/repo --no-fail --chunk-size 50
cargo run -- scan /path/to/repo --context-output-dir /tmp/functions --chunks-output-dir /tmp/chunksWrite scan output directly to a file:
cargo run -- scan /path/to/repo > results.txt
cargo run -- scan /home/chinmay/ChinmayPersonalProjects/gopdfsuit > gopdfsuit_results.txt
cargo run -- scan /home/chinmay/ChinmayPersonalProjects/SnapBack > snapback_results.txt
cargo run -- scan --json /path/to/repo > results.txtRun a scan without .gitignore filtering:
cargo run -- scan --no-ignore /path/to/repoBenchmark the current pipeline against a real local repository:
cargo run -- bench /path/to/repoBenchmark with explicit repeats and warmups:
cargo run -- bench --warmups 2 --repeats 5 /path/to/repoBenchmark with JSON output:
cargo run -- bench --json /path/to/repoList rules from the central registry:
cargo run -- rules
cargo run -- rules --language go
cargo run -- rules --status experimental --jsondeslop now publishes a central rule registry that drives the CLI and the synced docs surfaces.
| Language | Stable | Experimental | Research | Total |
|---|---|---|---|---|
| common | 11 | 0 | 0 | 11 |
| go | 751 | 2 | 0 | 753 |
| python | 691 | 0 | 0 | 691 |
| rust | 338 | 12 | 0 | 350 |
| total | 1791 | 14 | 0 | 1805 |
The totals above are language-scoped rule entries, so a shared rule ID implemented in more than one backend appears in each relevant language bucket.
The registry is now the source of truth for deslop rules, the frontend rule catalog, and the generated detection inventory guide.
Use deslop directly in GitHub Actions without installing Rust. The action downloads the matching release binary for the current runner, adds it to the PATH, and runs either deslop scan or deslop bench.
Scan the checked out repository with the defaults:
name: Deslop
on:
pull_request:
push:
branches:
- main
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chinmay-sawant/deslop@v0.2.0
with:
path: .Emit JSON and include per-function fingerprint details:
- uses: actions/checkout@v4
- uses: chinmay-sawant/deslop@v0.2.0
with:
path: .
json: 'true'
details: 'true'
fail-on-findings: 'false'Run a benchmark job instead of a scan:
- uses: actions/checkout@v4
- uses: chinmay-sawant/deslop@v0.2.0
with:
command: bench
path: .
repeats: '10'
warmups: '2'Inputs:
version: Release tag to install, for example v0.1.0. Defaults to the current action ref when it is a full release tag, otherwise latest. Optional.command: Subcommand to run. Supported values are scan and bench. Defaults toscan. Optional.path: Path to the repository to analyze. Defaults to.. Optional.json: Emit JSON output. Defaults tofalse. Optional.details: Include full per-function fingerprint details in scan output. Applies only to the scan command. Defaults tofalse. Optional.no-ignore: Scan without respecting .gitignore. Defaults tofalse. Optional.enable-semantic: Enable the opt-in deeper semantic Go heuristics. Defaults tofalse. Optional.fail-on-findings: Exit with a non-zero status code when scan findings are present. Applies only to the scan command. Defaults totrue. Optional.repeats: Benchmark repeat count. Applies only to the bench command. Defaults to5. Optional.warmups: Benchmark warmup count. Applies only to the bench command. Defaults to1. Optional.
- Wrapper propagation now covers receiver-field clients, local wrapper chains, and
QueryversusQueryContext-style mismatches when a function already acceptscontext.Context. - Functions that intentionally detach from request context can document that boundary and avoid the propagation warning.
- The semantic Go pack adds
likely_n_squared_allocation,likely_n_squared_string_concat, and stronger nested-loop correlation forn_plus_one_query.
Run the test suite:
cargo testValidate the documentation sync and corpus manifest:
python3 scripts/sync_docs.py --check
python3 scripts/corpus_harness.py validateList or run the real-repository evaluation corpus:
python3 scripts/corpus_harness.py list
python3 scripts/corpus_harness.py run --target gopdfsuit --scan
python3 scripts/corpus_harness.py run --target gopdfsuit --benchExpand a saved findings report into review-ready function context:
cargo run -- scan /path/to/repo --no-failEach exported block includes Source, Rule, Rule description, Auto triage note, and the full enclosing Function. Pass --details for richer metadata blocks.
cargo run -- scan /path/to/repo --no-fail > temp.txt
python3 scripts/extract_function_context_json.py temp.txt \
--output-dir frontend/public/findings \
--include-function-textFunction context files and chunks are written automatically during the scan step above. Only the JSON dataset step still uses Python.
If you run the temp workflow above, make sure you start the frontend server from the frontend folder:
cd frontend
npm run devThose commands read the path:line entries from temp.txt and rewrite the generated findings data under frontend/public/findings. The scan step also writes per-finding review files under scripts/findings/functions/ and batched chunks under scripts/chunks/. By default each exported block includes:
SourceRule descriptionAuto triage noteFunction
If you want the full metadata-rich output again, pass --details to scan:
cargo run -- scan /path/to/repo --no-fail --detailsRun the repo-local scripts through one shared entrypoint:
make run-scriptsrun-scripts executes the normal repo-local utility scripts and validates installer scripts in a safe non-installing mode.
Build release executables for your current platform or cross-compile for other supported platforms:
cargo build --release
cargo build --release --target x86_64-pc-windows-gnu
cargo build --release --target x86_64-apple-darwin
cargo build --release --target x86_64-unknown-linux-gnuIf you are cross-compiling, make sure the matching Rust target is installed first. Adjust the target triple to match the architecture you want to ship:
rustup target add x86_64-pc-windows-gnu x86_64-apple-darwin x86_64-unknown-linux-gnuThe native release binary is written to target/release/. Cross-compiled binaries are written under target/<target-triple>/release/ and are named deslop on Unix-like systems and deslop.exe on Windows.
If you review deslop scan output in Visual Studio Code, the vscode-finding-opener helper provides a small extension and scripts to open findings directly in the editor for quick triage. See vscode-finding-opener for installation, usage, and troubleshooting notes.
For a detailed architecture and roadmap guide, see guides/implementation-guide.md.
For the corpus workflow and promotion contract, see guides/evaluation-and-promotion-policy.md.
For a detector-oriented overview, see guides/features-and-detections.md.
Library code uses typed errors internally and keeps anyhow at the CLI edge. The scanner also uses bounded file reads by default so repository scans do not rely on unbounded read_to_string calls.
Rust scan hardening now also canonicalizes the scan root, rejects symlinked file reads, and compares the generated Rust security baseline report against the committed baseline in CI.