AI Code Quality Guard — detect common failure patterns in AI-generated code
Project description
AIGuard
AI Code Quality Guard — catch the bugs AI leaves behind.
AI-generated code is "almost right" - it compiles, passes linting, follows conventions... but has subtle bugs that are harder to find than writing it yourself. 66% of developers say this is their #1 frustration with AI coding tools.
AIGuard is a static analysis tool that catches the specific patterns where AI-generated code goes wrong: shallow error handling, hallucinated imports, copy-paste duplication, missing validation, placeholder code disguised as complete, and more.
$ aiguard scan ./src
src/api/handlers.py
E 12 Bare 'except:' catches all exceptions including KeyboardInterrupt AIG001
W 34 Functions 'get_users' and 'get_admins' are 92% similar AIG005
W 67 Public function 'process' has 4 params but no input validation AIG006
src/utils/helpers.py
I 5 Variable 'data' is too generic — use a descriptive name AIG010
W 22 Function 'transform' has only 'pass' — placeholder code AIG007
┌─────────────────── AI Code Health Score ───────────────────┐
│ ████████████████████████████░░░░░░░░░░░░ 72/100 ~ │
└────────────────────────────────────────────────────────────┘
Installation / Package Name
- PyPI package:
ai-guard-cli - CLI command:
aiguard
Quick Start
pip install ai-guard-cli
# Scan a directory
aiguard scan ./src
# Scan a single file
aiguard scan app.py
# JSON output for CI pipelines
aiguard scan ./src --format json
# SARIF for GitHub Code Scanning
aiguard scan ./src --format sarif --output results.sarif
# Fail CI if score is below 70
aiguard scan ./src --fail-under 70
Detection Rules
| Rule | Name | What It Catches | Severity |
|---|---|---|---|
| AIG001 | shallow-error-handling | Bare except:, catching Exception, empty handlers |
Error |
| AIG002 | tautological-code | if True, unreachable code after return, x == x |
Warning |
| AIG003 | over-commenting | # Initialize the variable for x = 0 (AI loves this) |
Info |
| AIG004 | hallucinated-imports | Imports that don't exist in your environment | Error |
| AIG005 | copy-paste-duplication | Near-identical functions with minor variations | Warning |
| AIG006 | missing-input-validation | Public functions with params but no guards | Warning |
| AIG007 | placeholder-code | pass/.../NotImplementedError disguised as done |
Warning |
| AIG008 | complex-one-liners | Nested comprehensions, chained ternaries | Warning |
| AIG009 | unused-variables | Assigned but never referenced | Info |
| AIG010 | generic-naming | data, result, temp, val — meaningless names |
Info |
List all rules:
aiguard list-rules
Configuration
Generate a config file:
aiguard init
This creates .aiguard.yml:
rules:
AIG001:
enabled: true
severity: error
AIG003:
enabled: true
max_comment_ratio: 0.6
AIG005:
enabled: true
similarity_threshold: 0.85
ignore:
- "tests/**"
- "migrations/**"
score:
fail_threshold: 60
weights:
error: 10
warning: 3
info: 1
GitHub Actions
Add to your workflow:
# .github/workflows/aiguard.yml
name: AI Code Quality
on: [push, pull_request]
jobs:
aiguard:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: GurjotSinghAulakh/aiguard@v1
with:
path: './src'
fail-under: '70'
Findings appear as inline annotations on your PRs via GitHub Code Scanning (SARIF).
Output Formats
| Format | Use Case | Flag |
|---|---|---|
terminal |
Local development (default) | --format terminal |
json |
CI pipelines, custom tooling | --format json |
sarif |
GitHub Code Scanning | --format sarif |
Writing Custom Rules (Plugins)
Create a detector in your own package:
from aiguard.detectors import register
from aiguard.detectors.base import BaseDetector
from aiguard.models import Finding, Language, Severity
@register
class MyCustomDetector(BaseDetector):
rule_id = "CUSTOM001"
rule_name = "my-custom-rule"
description = "Detects my specific pattern"
severity = Severity.WARNING
languages = (Language.PYTHON,)
def detect(self, source, ast_tree, file_path):
findings = []
# Your detection logic using ast_tree
return findings
Register via entry points in your pyproject.toml:
[project.entry-points."aiguard.detectors"]
my_rule = "my_package:MyCustomDetector"
Why AIGuard?
Traditional linters (pylint, ruff, eslint) catch syntax-level issues. AI-generated code passes all of those. The bugs are at a higher level:
- The error handling exists but is shallow (catches everything, does nothing)
- The code works but is copy-pasted 5 times with minor changes
- The function has parameters but never validates them
- The import looks right but the package doesn't exist
- The code looks complete but it's just
passwith a docstring
AIGuard catches these patterns because they are specific to how AI generates code.
Contributing
We welcome contributions! See CONTRIBUTING.md for details.
Good first issues are labeled good first issue.
License
MIT License. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
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 ai_guard_cli-0.2.0.tar.gz.
File metadata
- Download URL: ai_guard_cli-0.2.0.tar.gz
- Upload date:
- Size: 38.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58ebe5827c3c5b4cafcf2bd1d0b7f14ba2302a4a4716b621682d2ceda733102c
|
|
| MD5 |
90fcf0a26d013bc02d070609b93e8e9b
|
|
| BLAKE2b-256 |
c8f687360ca86e08b764c959dd8170e29c0499f1c41670ee52ef66c8b5810995
|
Provenance
The following attestation bundles were made for ai_guard_cli-0.2.0.tar.gz:
Publisher:
release.yml on GurjotSinghAulakh/aiguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ai_guard_cli-0.2.0.tar.gz -
Subject digest:
58ebe5827c3c5b4cafcf2bd1d0b7f14ba2302a4a4716b621682d2ceda733102c - Sigstore transparency entry: 1264970673
- Sigstore integration time:
-
Permalink:
GurjotSinghAulakh/aiguard@79c30562e27d184720b60a1f0177df3eb0232c1a -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/GurjotSinghAulakh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@79c30562e27d184720b60a1f0177df3eb0232c1a -
Trigger Event:
release
-
Statement type:
File details
Details for the file ai_guard_cli-0.2.0-py3-none-any.whl.
File metadata
- Download URL: ai_guard_cli-0.2.0-py3-none-any.whl
- Upload date:
- Size: 39.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 |
c2ede0d391ff34a0d575520b9735a1d324e3f01fe4ea77268e47f6f57e7190f8
|
|
| MD5 |
e3b0e7d63a933fd167e4e48a2e8434d6
|
|
| BLAKE2b-256 |
e1b0e4ed3e5d1b98656f69625c68e61edb8a4939f1c62625a99b73493e32b26e
|
Provenance
The following attestation bundles were made for ai_guard_cli-0.2.0-py3-none-any.whl:
Publisher:
release.yml on GurjotSinghAulakh/aiguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ai_guard_cli-0.2.0-py3-none-any.whl -
Subject digest:
c2ede0d391ff34a0d575520b9735a1d324e3f01fe4ea77268e47f6f57e7190f8 - Sigstore transparency entry: 1264970786
- Sigstore integration time:
-
Permalink:
GurjotSinghAulakh/aiguard@79c30562e27d184720b60a1f0177df3eb0232c1a -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/GurjotSinghAulakh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@79c30562e27d184720b60a1f0177df3eb0232c1a -
Trigger Event:
release
-
Statement type: