Skip to main content

Catches structural erosion from AI-generated code — the bugs that pass all your tests

Project description

drift — steer your agent before it ships

Drift

AI writes the code. Drift keeps the architecture honest.

CI codecov PyPI PyPI Downloads Python versions GitHub Stars License Discussions

Docs · Quick Start · Benchmarking · Trust & Limitations


🤔 Why drift?

Most linters catch single-file style issues. Drift catches what they miss: cross-file structural drift that accumulates silently during AI-assisted development.

Without DriftWith Drift
  • Agent duplicates a helper in 3 modules — tests pass
  • Layer boundary violated in a refactor — CI green
  • Auth middleware reimplemented 4 ways — linter silent
  • Score degrades over weeks — nobody notices
  • drift brief injects structural guardrails before the agent writes code
  • drift nudge flags new violations in real-time during the session
  • drift check blocks the commit on high-severity findings
  • drift trend tracks score evolution — regressions are visible

🔍 Beforedrift brief analyses your repo scope and generates structural constraints ready to paste into your agent prompt
🚦 Afterdrift check runs 20+ cross-file signals and exits 1 on violations — CI, SARIF, and pre-commit ready
🧠 Over time — Bayesian calibration reweights signals via feedback, git outcome correlation, and GitHub label correlation


⚡ Quick Install

pip install drift-analyzer

Python 3.11+. Also available via pipx, Homebrew, Docker, GitHub Action, pre-commit →


⚙️ How it works

Before a session — generate guardrails:

drift brief --task "refactor the auth service" --format markdown
# → paste output into your agent prompt before delegation

After a session — enforce structure:

drift check --fail-on high         # local or CI gate
drift check --fail-on none         # pre-commit hook (advisory, report-only)
drift analyze --repo . --format json  # full report
drift analyze terminal demo

📖 Full workflow guide →

[!TIP] Best fit: Python repos with 20+ files and active AI-assisted development.
Tiny repos produce noisy scores. Drift does not replace your linter, type checker, or security scanner — it covers the layer they cannot: cross-file structural coherence over time.


🔌 Integrations

# GitHub Actions — start report-only, tighten once you trust the output
- uses: mick-gsk/drift@v1
  with:
    fail-on: none               # report findings without blocking
    upload-sarif: "true"        # findings appear as PR annotations

MCP / AI Tools: Cursor, Claude Code, and Copilot call drift directly via MCP server — the agent runs a full session loop:

Phase MCP Tool What it does
Plan drift_brief Scope-aware guardrails injected into the agent prompt
Code drift_nudge Real-time safe_to_commit check after each edit
Verify drift_diff Full before/after comparison before push
Learn drift_feedback Mark findings as TP/FP — calibrates signal weights

📖 MCP setup guide →

pre-commit: Add drift diff --staged-only as a hook — findings block the commit before they reach CI.

📖 Full integration guide →


Advanced: Adaptive learning, Negative context library, Guided mode

Adaptive learning & calibration

Drift does not treat all signals equally forever. It maintains a per-repo profile:

  • Bayesian calibration engine combines three evidence sources: explicit drift feedback mark, git outcome correlation, and GitHub issue/PR label correlation.
  • Feedback events are stored as structured FeedbackEvent records and can be reloaded and replayed across versions (record_feedback, load_feedback).
  • Profile builder (build_profile) produces a calibrated weight profile that drift check and drift brief use to focus on the most trusted signals in your codebase.

CLI surface: drift feedback, drift calibrate, drift precision (for your own ground-truth checks).

Negative context library for agents

Drift can turn findings into a structured "what NOT to do" library for coding agents:

  • Per-signal generators map each signal (PFS, MDS, AVS, BEM, TPD, …) to one or more NegativeContext items with category, scope, rationale, and confidence.
  • Anti-pattern IDs like neg-MDS-… are deterministic and stable — ideal for referencing in policies and prompts.
  • Forbidden vs. canonical patterns: each item includes a concrete anti-pattern code block and a canonical alternative, often tagged with CWE and FMEA RPN.
  • Security-aware: mappings for MISSING_AUTHORIZATION, HARDCODED_SECRET, and INSECURE_DEFAULT generate explicit security guardrails for agents.

API: findings_to_negative_context() and negative_context_to_dict() deliver agent-consumable JSON for drift_nudge, drift brief, and other tools.

Guided mode for vibe-coding teams

If your team ships most changes via AI coding tools (Copilot, Cursor, Claude), drift includes a guided mode:

  • CLI guide: drift start prints the three-command journey for new users: analyze → fix-plan → check with safe defaults.
  • Vibe-coding playbook: examples/vibe-coding/README.md documents a 30-day rollout plan (IDE → commit → PR → merge → trend) with concrete scripts and metrics.
  • Problem-to-signal map: maps typical vibe-coding issues (duplicate helpers, boundary erosion, happy-path-only tests, type-ignore buildup) directly to signals like MDS, PFS, AVS, TPD, BAT, CIR, CCC.
  • Baseline + ratchet: ready-made drift.yaml, CI gate, pre-push hook and weekly scripts implement a ratcheting quality gate over time.

📖 Start here if you are a heavy AI-coding user: Vibe-coding technical debt solution →


🔄 Coming from another tool?

From Ruff / pylint: Drift operates one layer above single-file style. It detects when AI generates the same error handler four different ways across modules — something no linter sees.

From SonarQube: Drift runs locally with zero server setup and produces deterministic, reproducible findings per signal. Add it alongside SonarQube — not instead.

From jscpd / CPD: Drift's duplicate detection is AST-level, not text-level. It finds near-duplicates that text diff misses and places them in architectural context.

Full capability comparison
Capability drift SonarQube pylint / mypy jscpd / CPD
Pattern Fragmentation across modules
Near-Duplicate Detection (AST-level) Partial (text) ✔ (text)
Architecture Violation signals Partial
Temporal / change-history signals
GitHub Code Scanning via SARIF
Zero server setup Partial
TypeScript support Experimental ¹

✔ = within primary design scope · — = not a primary design target · Partial = limited coverage

¹ Via drift-analyzer[typescript]. Python is the primary analysis target.

Comparison reflects primary design scope per STUDY.md §9.


[!NOTE] Drift analyzes its own source code on every release — same input, same output, reproducible in CI. Results: benchmark_results/drift_self.json

drift self   # or: drift analyze --repo https://github.com/mick-gsk/drift

📚 Documentation

Topic Description
Quick Start Install → first findings in 2 minutes
Brief & Guardrails Pre-task agent workflow
CI Integration GitHub Action, SARIF, pre-commit, progressive rollout
Signal Reference All 25 signals with detection logic
Benchmarking & Trust Precision/Recall, methodology, artifacts
MCP & AI Tools Cursor, Claude Code, Copilot, HTTP API
Configuration drift.yaml, layer boundaries, signal weights
Calibration & Feedback Bayesian signal reweighting, feedback workflow
Vibe-coding Playbook 30-day rollout guide for AI-heavy teams
Contributing Dev setup, FP/FN reporting, signal development

🤝 Contributing

Drift's biggest blind spots are found by people running it on codebases the maintainers have never seen. A well-documented false positive can be more valuable than a new feature.

I want to… Go here
Ask a usage question Discussions
Report a false positive / false negative FP/FN template
Report a bug Bug report
Suggest a feature Feature request
Propose a contribution before coding Contribution proposal
Report a security vulnerability SECURITY.md — not a public issue
git clone https://github.com/mick-gsk/drift.git && cd drift && make install
make test-fast

See CONTRIBUTING.md · ROADMAP.md


🔒 Trust and limitations

Drift's pipeline is deterministic and benchmark artifacts are published in the repository — claims can be inspected, not just trusted.

Metric Value Artifact
Ground-truth precision 100 % (47 TP, 0 FP) v2.7.0 baseline
Ground-truth recall 100 % (0 FN across 114 fixtures) v2.7.0 baseline
Mutation recall 100 % (25/25 injected patterns) mutation benchmark
Wild-repo precision 77 % strict / 95 % lenient (5 repos) study §5
  • No LLM in detection. Same input, same output. Reproducible in CI and auditable.
  • Single-rater caveat: ground-truth classification is not yet independently replicated.
  • Small-repo noise: repositories with few files can produce noisy scores. Calibration mitigates but does not eliminate this.
  • Temporal signals depend on clone depth and git history quality.
  • The composite score is orientation, not a verdict. Interpret deltas via drift trend, not isolated snapshots.

Full methodology: Benchmarking & Trust · Full Study


⭐ Star History

Star History Chart


📄 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

drift_analyzer-2.9.1.tar.gz (1.5 MB view details)

Uploaded Source

Built Distribution

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

drift_analyzer-2.9.1-py3-none-any.whl (525.6 kB view details)

Uploaded Python 3

File details

Details for the file drift_analyzer-2.9.1.tar.gz.

File metadata

  • Download URL: drift_analyzer-2.9.1.tar.gz
  • Upload date:
  • Size: 1.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for drift_analyzer-2.9.1.tar.gz
Algorithm Hash digest
SHA256 726688ac0a024472c32c4570dc8275ce9abe61aa24bd58ab73397ceebaf18b97
MD5 82f31839420dcc2dfef228d316876baf
BLAKE2b-256 f9f0fc5efb31d532b363fd7c88ed4ac4aabc4545ecc498d1824b4cd8b8c2fa00

See more details on using hashes here.

File details

Details for the file drift_analyzer-2.9.1-py3-none-any.whl.

File metadata

  • Download URL: drift_analyzer-2.9.1-py3-none-any.whl
  • Upload date:
  • Size: 525.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for drift_analyzer-2.9.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f5ac5e243e4eab4fbb905c315cada349835c4b4499d2fa87e5c3352bf25fb06a
MD5 40562bfd4da1e8b768ac15f5c9051518
BLAKE2b-256 55cc311738996fc5f23237e46bdb676d193d6f5a8605c9b6efd6511630e93137

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