Hybrid static + LLM codebase bug detector for Python projects.
Project description
testx
testx is a hybrid codebase auditing engine for teams that need deeper bug discovery than linting alone.
It combines deterministic static analysis with optional AI reasoning, then emits structured, actionable reports.
For a deep system breakdown, see ARCHITECTURE.md.
Table of Contents
- Why testx
- Core Capabilities
- Architecture at a Glance
- Installation
- Quick Start
- Configuration
- CLI Reference
- Output Model
- How Analysis Works
- Operational Guidance
- Testing
- Release / Publish
- Security Practices
- Roadmap
Why testx
Traditional static tools often miss contextual or cross-language risks. testx is designed to:
- detect high-signal bug/security/reliability risks quickly
- operate fully offline (
--ai none) for restricted environments - scale analysis depth with AI providers when allowed
- track cost and avoid repeated spend through chunk-level caching
- produce readable audits for engineers, leads, and reviewers
Core Capabilities
- Hybrid analysis pipeline
- Python AST rules for semantic checks
- Generic analyzer for cross-language heuristics
- Optional AI deep analysis over code chunks
- One-library integration SDK
- importable API for embedding audits into your app/CI
- severity gating for release policies
- extension and directory scan controls
- Multi-language scanning
- Python, JS/TS/React, Java, Go, Rust, C/C++, C#, Ruby, PHP, SQL, shell, YAML, JSON
- Cost and throughput controls
- rate limiter for AI calls
- hard cap with
--max-cost - SQLite cache keyed by provider/model/file/content hash
- Audit-focused reporting
- text, JSON, and HTML outputs
- severity/type/source counts and risk hotspots
- concrete fix guidance per issue
Architecture at a Glance
Execution pipeline:
- CLI parses command options and loads config.
- Scanner enumerates supported source files.
- Static analyzers execute per file.
- If AI is enabled, files are chunked and analyzed with provider client.
- Results are deduplicated and aggregated.
- Reporter renders final output.
Primary modules:
bugfinder/cli.py- command interfacebugfinder/config.py- environment and TOML config mergebugfinder/scanner.py- file discovery + chunkingbugfinder/analyzer/ast_analyzer.py- Python semantic checksbugfinder/analyzer/generic_analyzer.py- non-Python heuristicsbugfinder/analyzer/hybrid_analyzer.py- orchestration layerbugfinder/ai/*_client.py- provider adaptersbugfinder/cache/cache_manager.py- SQLite cachebugfinder/reporters.py- renderersbugfinder/models.py- issue/report data models
Detailed architecture and data flow are documented in ARCHITECTURE.md.
Installation
Runtime install
pip install testx
Local development install
pip install -e ".[dev]"
Quick Start
1) Static-only audit (fastest and offline)
testx scan . --ai none --output text
1b) Programmatic integration (all in one library)
from bugfinder import AuditOptions, render_report, run_audit, should_fail_ci
report = run_audit(
".",
AuditOptions(
ai_provider="none",
include_extensions={".py", ".ts", ".tsx"},
exclude_dirs={"dist", "build"},
min_severity="medium",
),
)
print(render_report(report, output="text"))
if should_fail_ci(report, "high"):
raise SystemExit("High severity issues detected")
2) Deep audit with OpenAI
testx scan . \
--ai openai \
--model gpt-4o-mini \
--max-cost 2.50 \
--output html \
--output-file audit.html
3) Deep audit with Claude
testx scan . \
--ai claude \
--model claude-3-5-sonnet-latest \
--max-cost 2.50 \
--output json \
--output-file audit.json
Configuration
Configuration resolution order:
- Environment variables
.bugfinder.toml(or--configpath)
Supported environment variables:
OPENAI_API_KEYANTHROPIC_API_KEY
Example .bugfinder.toml:
[ai]
openai_api_key = "sk-..."
anthropic_api_key = "sk-ant-..."
default_provider = "none"
default_model = "gpt-4o-mini"
max_cost = 5.0
rate_limit_per_minute = 30
CLI Reference
Command:
testx scan <path> [options]
Options:
--ai:openai | claude | none--model: provider model override--max-cost: max estimated AI spend in USD--output:text | json | html--output-file: write report to file path--config: explicit TOML config path--cache-db: SQLite cache path (default.bugfinder_cache.sqlite3)--exclude-dir: directory name to exclude (repeatable)--include-ext: only analyze listed extensions (repeatable)--min-severity: only include findings at or above threshold--fail-on-severity: non-zero exit for CI policy enforcement
Output Model
Each issue includes:
type:bug | security | performance | code_smellseverity:low | medium | highdescription: actionable risk statementfileand optionallinefix: concrete remediation guidancesource:static,ai:<provider>, orsystem
Report summary includes:
- total issue count
- severity/type/source distribution
- top risky files by issue density
- scan metadata (
files_scanned,chunks_analyzed, provider/model, estimated cost)
How Analysis Works
Static analysis layer
-
AST analyzer (
.py)- dynamic execution risks (
eval,exec) - broad exception handling (
except,except Exception) - mutable defaults
- unreachable code patterns
- unsafe subprocess usage (
shell=True) - unsafe YAML loading patterns
- runtime
assertmisuse warnings
- dynamic execution risks (
-
Generic analyzer (other languages + text patterns)
- TODO/FIXME/HACK risk markers
- debug statements (
console.log,debugger) - hardcoded secrets/tokens/password-like assignments
- private key marker detection
AI analysis layer (optional)
- file chunks are generated
- prompt includes language + line range context
- provider returns strict JSON
- parsed issues are normalized into shared model
- responses are cached by file content hash + provider + model
Merge and dedup
Issues are deduplicated on type, severity, description, file path, and line.
Operational Guidance
- Start with
--ai nonein CI for fast deterministic checks. - Run AI scans on main branch nightly or pre-release for deeper coverage.
- Use
--max-costaggressively in shared environments. - Persist report artifacts as CI artifacts, not committed source files.
- Rotate API keys immediately if accidentally exposed.
Testing
Run unit tests:
pytest -q
Tests cover:
- scanner chunking behavior
- cache read/write semantics
- issue deduplication
- deep-audit regression rules (security detection + report summary structure)
Release / Publish
python -m pip install --upgrade build twine
python -m build
twine check dist/*
twine upload --repository testpypi dist/*
twine upload dist/*
Trusted Publishing with GitHub Actions (recommended)
testx includes .github/workflows/publish.yml for OIDC-based PyPI publishing.
PyPI Trusted Publisher settings:
- Project name:
testx - Owner:
Najeebullah3124 - Repository:
testx - Workflow:
publish.yml - Environment:
pypi
Workflow behavior:
- triggers automatically when a GitHub Release is published
- also supports manual run via
workflow_dispatch - builds wheel + sdist, then publishes via
pypa/gh-action-pypi-publish
Security Practices
- never commit secrets or API keys
- prefer environment variables for credentials
- keep AI optional in sensitive environments
- use dedicated CI environments for publishing permissions
- rotate credentials after any accidental exposure
Roadmap
- incremental and diff-only scans
- pluggable custom rule packs
- SARIF output for security tooling integration
- confidence scoring calibration and false-positive suppression
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file testx-0.1.1.tar.gz.
File metadata
- Download URL: testx-0.1.1.tar.gz
- Upload date:
- Size: 23.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d95872d4f42194d81f2a0be11740152083d7bf5c907d282819b809d9b73c564
|
|
| MD5 |
d941b7cc904f8a0117936962210481fc
|
|
| BLAKE2b-256 |
857126cde4b4422df5031d41af5095aed04d528bb71c470f867eea588a3f52ab
|
Provenance
The following attestation bundles were made for testx-0.1.1.tar.gz:
Publisher:
publish.yml on Najeebullah3124/testx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
testx-0.1.1.tar.gz -
Subject digest:
5d95872d4f42194d81f2a0be11740152083d7bf5c907d282819b809d9b73c564 - Sigstore transparency entry: 1310310103
- Sigstore integration time:
-
Permalink:
Najeebullah3124/testx@a8eb8693cb3e3a65c9f64c1d70d0f429c93c56fd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Najeebullah3124
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a8eb8693cb3e3a65c9f64c1d70d0f429c93c56fd -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file testx-0.1.1-py3-none-any.whl.
File metadata
- Download URL: testx-0.1.1-py3-none-any.whl
- Upload date:
- Size: 22.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8230fb6bad02639493d24ea501ea10a92aeef6d1574c1704041cda81e7d4665
|
|
| MD5 |
1fcf15ad636e27da4d1ea10240268fe4
|
|
| BLAKE2b-256 |
8f76704f2eda2fed50d630b91bd9f22167ac48ec2591145504796d6d75c29d0e
|
Provenance
The following attestation bundles were made for testx-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on Najeebullah3124/testx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
testx-0.1.1-py3-none-any.whl -
Subject digest:
a8230fb6bad02639493d24ea501ea10a92aeef6d1574c1704041cda81e7d4665 - Sigstore transparency entry: 1310310156
- Sigstore integration time:
-
Permalink:
Najeebullah3124/testx@a8eb8693cb3e3a65c9f64c1d70d0f429c93c56fd -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Najeebullah3124
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a8eb8693cb3e3a65c9f64c1d70d0f429c93c56fd -
Trigger Event:
workflow_dispatch
-
Statement type: