Code quality drift monitor for AI-generated code
Project description
DriftLens
AI coding agents make you faster. DriftLens makes sure they don't make your code worse.
AI agents write code at superhuman speed — but SlopCodeBench (arXiv:2603.24755) shows they produce 2.2x more verbose code than humans, and code quality degrades in 80% of agentic trajectories. DriftLens catches this drift before it ships: baseline your codebase, then score every change against it.
Quick start (30 seconds)
pip install driftlens
cd your-project
driftlens init # snapshot current state as baseline
driftlens report # score drift since baseline
What it measures
DriftLens tracks four structural signals, all computed from the AST — no regex, no LLM calls.
| Metric | What it captures |
|---|---|
| Verbosity ratio | Lines per logical operation — AI agents pad code with redundant assignments, dead branches, and over-commented obvious logic |
| Structural similarity | Cosine distance between AST fingerprints — catches wholesale rewrites that preserve behavior but destroy architecture |
| Complexity concentration | Gini coefficient over cyclomatic complexity — flags when complexity pools into a few giant functions instead of staying distributed |
| Naming consistency | Identifier entropy and length distribution — detects drift toward generic names (data, result, tmp) or absurdly verbose ones |
These four signals are combined into a single composite drift score (0–100). Higher = more drift from your baseline.
CLI commands
| Command | Description |
|---|---|
driftlens init |
Snapshot the current codebase as the baseline |
driftlens score |
Print the composite drift score (0–100) |
driftlens report |
Full breakdown — per-metric scores with Rich table output |
driftlens ci |
Exit 1 if drift score exceeds threshold (for CI gates) |
CI/CD integration
Drop this into any GitHub Actions workflow to gate PRs on drift:
- uses: Su760/driftlens@main
with:
threshold: "40"
DriftLens will fail the job if the composite drift score exceeds the threshold, printing a breakdown so you know exactly which metric regressed.
Full workflow example:
name: Drift check
on: [pull_request]
jobs:
drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: Su760/driftlens@main
with:
threshold: "40"
Severity levels
| Score | Severity | Meaning |
|---|---|---|
| 0–15 | Healthy | Code is consistent with baseline |
| 16–35 | Mild | Minor drift; worth a second look |
| 36–60 | Significant | Structural changes detected; review carefully |
| 61–100 | Critical | Major drift; likely AI-introduced degradation |
How it works
Step 1 — Baseline. driftlens init walks your source tree, computes the four metrics for every Python file, and saves a JSON snapshot in .driftlens/baseline.json. This snapshot is your ground truth.
Step 2 — Drift detection. On every subsequent run, DriftLens recomputes the same metrics and compares them against the snapshot. Each metric returns a normalized delta (0–1), where 0 means identical and 1 means maximum measurable deviation.
Step 3 — Scoring. The four deltas are combined into a composite score using fixed weights:
score = 0.30 × verbosity + 0.30 × structure + 0.25 × complexity + 0.15 × naming
The result is scaled to 0–100. Verbosity and structure carry the most weight because they are the primary failure modes documented in SlopCodeBench.
All metrics are AST-based. DriftLens never calls an LLM, never sends your code anywhere, and produces deterministic results. A CI run that passes locally will pass remotely.
Contributing
Pull requests are welcome. Before opening one:
- Run
pytest tests/ -v— all tests must pass - Do not modify files in
tests/fixtures/— they are calibrated ground truth - New metrics follow the same pattern:
analyze_*→compute_*→compare_*
See CONTRIBUTING.md for more detail.
License
MIT — see LICENSE.
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 driftlens_ai-0.1.0.tar.gz.
File metadata
- Download URL: driftlens_ai-0.1.0.tar.gz
- Upload date:
- Size: 22.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
504b4f57d7fb021c7f48971c063ea0c9d787d65b5d0bf68325df9bff3dc784bf
|
|
| MD5 |
b21434a58a9afa5c5008aaa996610f3d
|
|
| BLAKE2b-256 |
f4b38c53bb17dea672ba212e17f7568fc48917b8d48f87a479ffd3ad516c68dd
|
Provenance
The following attestation bundles were made for driftlens_ai-0.1.0.tar.gz:
Publisher:
publish.yml on Su760/driftlens
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
driftlens_ai-0.1.0.tar.gz -
Subject digest:
504b4f57d7fb021c7f48971c063ea0c9d787d65b5d0bf68325df9bff3dc784bf - Sigstore transparency entry: 1242065895
- Sigstore integration time:
-
Permalink:
Su760/driftlens@7bb9919a40a4312ecc2f4646a3a8a94bd432b1a4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Su760
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7bb9919a40a4312ecc2f4646a3a8a94bd432b1a4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file driftlens_ai-0.1.0-py3-none-any.whl.
File metadata
- Download URL: driftlens_ai-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5971a715f3344b00d5c745bff3450457fc7c554d4f06cc4e637606300bd16fb2
|
|
| MD5 |
35450487fd0f232229f3fd902a9f05c4
|
|
| BLAKE2b-256 |
0b4f9a7a7a4583688e4c1735f327f832465c8a898178801c376e35ea39c37174
|
Provenance
The following attestation bundles were made for driftlens_ai-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Su760/driftlens
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
driftlens_ai-0.1.0-py3-none-any.whl -
Subject digest:
5971a715f3344b00d5c745bff3450457fc7c554d4f06cc4e637606300bd16fb2 - Sigstore transparency entry: 1242065931
- Sigstore integration time:
-
Permalink:
Su760/driftlens@7bb9919a40a4312ecc2f4646a3a8a94bd432b1a4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Su760
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7bb9919a40a4312ecc2f4646a3a8a94bd432b1a4 -
Trigger Event:
push
-
Statement type: