Dimensions
How findings are categorized. Read more
When you run unfault review, everything happens locally. There is no API, no cloud analysis, no data leaving your machine. Understanding this helps explain why Unfault behaves the way it does.
unfault-analysis engine runs rules against the graph and produces findings.Most analysis tools either send your source code to a server or require heavy language servers. Unfault does neither.
Parsing and analysis run in the same process as the CLI, using the same code your project runs with. This means:
When Unfault parses your code, it builds a graph with nodes and edges:
Nodes represent things in your code:
Edges represent relationships:
This graph captures the structure of your code without the content. The analysis engine can reason about “function fetch_user calls requests.get with no timeout” without touching the actual URL or request body.
Here’s what happens when you run a review:
Unfault scans your project to understand what it’s looking at:
For each source file, Unfault:
Individual file semantics get merged into a unified graph. This is where Unfault resolves:
The unfault-analysis engine runs rules against the graph. Rules are organized by framework profile (e.g., python_fastapi_backend, go_gin_service) and dimension (stability, correctness, performance, scalability).
Each rule produces findings: observations about your code. A finding includes what was detected, where it is, why it matters, and a suggested fix when possible.
If you have observability integrations configured (GCP Cloud Monitoring, Datadog, Dynatrace), Unfault can fetch SLO data and enrich findings with production context: which routes have SLO coverage and which don’t. This step is skipped with --offline.
Results are formatted for your chosen output mode and printed to stdout.
To be concrete, if you have this code:
def fetch_user(user_id: str) -> dict: response = requests.get(f"https://api.example.com/users/{user_id}") return response.json()The analysis sees something like:
{ "functions": [{ "name": "fetch_user", "file": "users.py", "calls": [{"target": "requests.get", "has_timeout": false}] }]}No URL. No variable names beyond what’s needed for the graph. No string literals. Just enough structure to identify the pattern.
Dimensions
How findings are categorized. Read more
Explore the Code Graph
Impact analysis, dependency queries, critical files. Read more
Quick Start
Run your first review. Get started
CLI Reference
All commands and flags. Read more