Skip to main content

Deterministic linter for AI-generated Python code

Project description

wraith

PyPI CI License: MIT

An extremely fast AI code linter, written in Rust.

Catches what your AI forgot to check — hallucinated APIs, phantom packages, hardcoded secrets, AI artifacts, and supply chain risks. 20 rules, zero config.

wraith demo

$ wraith check .

src/api/handler.py:42:5  AG001 pandas.read_csv: unknown parameter "fast_mode"
                               → did you mean "mode"? (auto-fixable)
src/api/handler.py:78:1  PH001 import "ai-utils-secure": package not found on PyPI
                               → possible slopsquatting target
src/utils/auth.py:15:0   VC001 hardcoded secret: API_KEY = "sk-proj-..."
                               → known secret prefix; use os.environ["API_KEY"] instead (auto-fixable)
src/utils/auth.py:89:4   VC011 potential secret leak: 'api_key' passed to print()
                               → avoid logging or printing secret variable 'api_key'

Found 4 issues (2 auto-fixable). Run with --fix to apply.
Checked 128 files in 0.34s

Why wraith?

AI code generators hallucinate APIs, invent packages, and leave secrets in your code. Traditional linters don't catch any of it.

wraith vs other linters

Scans 1121 files (FastAPI) in 350ms. Zero config, zero dependencies.


Install

pip install wraith

Quick start

wraith check .                       # scan current directory
wraith check . --fix --diff          # preview fixes as unified diff
wraith check . --fix                 # apply fixes
wraith rules                         # list all 20 rules

Features

  • Hallucinated API detection — catches non-existent functions, kwargs, and deprecated calls via Python introspection
  • Phantom package detection — validates imports against PyPI, catches typosquatting and slopsquatting
  • Secret detection — layered analysis: known prefixes (sk-, ghp_, AKIA), Shannon entropy, bigram name classification, character class filtering
  • Taint analysis — tracks data flow from os.environ to print()/logging sinks
  • Supply chain checks — unpinned dependencies, missing lockfiles, dangerous files
  • AI artifact cleanup — removes # Generated by Claude comments, debug code, pdb imports
  • # noqa suppression — industry-standard inline suppression, Ruff/flake8 compatible
  • SARIF output--format sarif for GitHub Code Scanning and VS Code integration
  • Confidence scoring--min-confidence 0.8 to filter noise, every finding has a confidence score

Rules

AG — API Guard

Code Name Fix Description
AG001 non-existent-attribute yes os.path.joinn() → did you mean join?
AG002 non-existent-kwarg yes makedirs(exst_ok=True)exist_ok
AG003 deprecated-api PEP 702 + source analysis, zero false positives
AG004 bare-call yes read_csv()pd.read_csv()
AG005 missing-import yes np.array() without import numpy
AG006 contextual-mismatch yes pd.read_excel("data.csv") → wrong extension

PH — Phantom

Code Name Description
PH001 package-not-found Package doesn't exist on PyPI (slopsquatting risk)
PH002 package-not-installed Package exists but not in current environment
PH003 suspicious-package Typosquat name, new package, low downloads

VC — Vibe Check

Code Name Fix Description
VC001 hardcoded-secret yes Entropy + prefix + bigram analysis
VC002 ai-artifact-comment yes # Generated by Claude, # Copilot
VC003 debug-code yes print/breakpoint (pedantic, off by default)
VC004 pdb-import yes import pdb / import ipdb
VC005 source-map-exposure sourceMappingURL references
VC006 suspicious-endpoint /debug/, /admin/ without auth
VC007 dangerous-file .env, .pem, credentials in project
VC008 unpinned-dependency No version pin in requirements.txt
VC009 missing-lockfile No poetry.lock / uv.lock
VC010 source-map-full-source .map with sourcesContent
VC011 secret-leak Secret variable → print/logging sink

Configuration

# Select specific rules
wraith check . --select AG,VC001

# Skip PyPI checks (offline)
wraith check . --offline

# Include test files (excluded by default)
wraith check . --include-tests

# Enable pedantic rules (VC003 print detection)
wraith check . --pedantic

# Only high-confidence findings
wraith check . --min-confidence 0.8

# CI/CD integration
wraith check . --strict --format sarif > wraith.sarif

Inline suppression

print("debug")           # noqa: VC003
API_KEY = "sk-secret"    # noqa: VC001
import pdb               # noqa

Python API

import wraith

results = wraith.check_source('API_KEY = "sk-secret"')
fixed = wraith.fix('import pdb\nbreakpoint()')

How it works

Component What How
Parser AST extraction tree-sitter-python, not regex
Symbol table Name resolution PEP 227 LEGB, scope-aware
Introspection API validation Python subprocess, inspect.signature()
Secret detection 4-layer Prefix → entropy → bigram → character class
Taint analysis Source → sink Intraprocedural, name-based
Package check PyPI validation HTTP + SQLite cache (24h TTL)

Research

Built on peer-reviewed research:

Contributing

Found a false positive? Missing a rule? Open an issue — bug reports with code samples are the fastest way to improve wraith.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wraith-0.2.0.tar.gz (72.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wraith-0.2.0-py3-none-macosx_11_0_arm64.whl (3.5 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file wraith-0.2.0.tar.gz.

File metadata

  • Download URL: wraith-0.2.0.tar.gz
  • Upload date:
  • Size: 72.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for wraith-0.2.0.tar.gz
Algorithm Hash digest
SHA256 09e8924d37b1924fe5b8a04890e1217018b8986d7beec91c9c081954f51925ea
MD5 f3655e6c5b6b24ba9c7e049fe68fe3cc
BLAKE2b-256 d6c467ee2fa102fcf6ec04610281ce39b136246ed083a175afd79402cd91f29c

See more details on using hashes here.

File details

Details for the file wraith-0.2.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for wraith-0.2.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 66b8b11b42b642d7922f7be871911565d4bf27ed9f6bac87e561847482127a5c
MD5 65e334d721eb2cc09542a85b720cbb64
BLAKE2b-256 586111db8d800eca4934cf954ebbb4e4d19e2cf74848fd0396ef01225abfdd13

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page