Skip to main content

Deterministic-first decision governance — codify architecture decisions as enforceable rules

Project description

DecisionDrift

Deterministic-first decision governance. Codify architecture decisions as enforceable rules, detect drift before it reaches production, and keep your codebase aligned with documented decisions.

Repository ADRs (docs/adr/)
         │
    ┌────┴────┐
    │         │
 enforce    review
(determi-  (LLM-based
nistic)    classification)
    │         │
    └────┬────┘
         │
   PR comment / CLI report

How It Works

  1. Bootstrap scans your repository structure, detects technologies and patterns, and proposes candidate ADRs (Architecture Decision Records).
  2. You approve the ADRs that reflect real team decisions. Each ADR can express prohibitions (e.g., "don't add Flask alongside FastAPI").
  3. The deterministic rule engine (enforce) converts accepted ADRs into dependency, import, path, API, and config rules — with zero LLM cost.
  4. On every change, enforce checks the diff or full repo against active rules. Detected violations exit non-zero, suitable for CI gating.
  5. The LLM classifier (review) optionally provides semantic analysis for complex cases beyond simple rule matching.
  6. Audit periodically checks ADR health: drift detection, stale/expired ADRs, quality scores, and coverage gaps.

Example

Given this ADR:

id: ADR-0001
title: Use Flask as Web Framework
status: accepted
prohibitions: [fastapi, django]

The rule engine generates two rules:

  • Dependency rule: BLOCK if fastapi or django appears in dependency files
  • Import rule: BLOCK if fastapi or django is imported anywhere

Running decisiondrift enforce against a diff that adds fastapi to requirements.txt:

  [BLOCK] ADR-0001 (dependency)
           Match: fastapi
           File: requirements.txt

Quickstart

1. Install

pip install decisiondrift

Or from source:

git clone https://github.com/yourorg/decisiondrift
cd decisiondrift
pip install -e .

2. Bootstrap ADRs from your repo structure

# Scan the repo and propose candidate ADRs (dry-run by default)
decisiondrift bootstrap .

# Review what was generated
decisiondrift adr list --status proposed

# Approve the ones that reflect real team decisions
decisiondrift adr approve ADR-0001

3. Enforce rules against a diff or full repo

# Check unstaged changes against accepted ADRs
decisiondrift enforce --from-git

# Full repository scan (for CI or audit)
decisiondrift enforce .

# Fail CI on any rule violation (not just BLOCK-level)
decisiondrift enforce --from-git --fail-on warn

4. Run an ADR health audit

decisiondrift audit

Shows expired/stale ADRs, drift detection (rules violated by current codebase), technology coverage gaps, and ADR quality scores.

5. Install as a pre-commit hook

decisiondrift guard --install

This installs a hook that runs decisiondrift enforce --from-git before every commit.

6. Run an LLM-based review (optional)

# Requires DECISIONDRIFT_LLM_API_KEY
decisiondrift review --from-git

7. Ingest decisions from free-text notes

decisiondrift ingest meeting-notes.md

Extracts candidate decisions from RFCs, meeting notes, or chat transcripts.


CLI Reference

Command Description
decisiondrift bootstrap <path> Generate candidate ADRs from repository structure (V3 deterministic)
decisiondrift enforce [diff] Enforce ADR rules against a diff or full repo (exit code: violations)
decisiondrift audit ADR health audit: drift, stale/expired, quality, coverage
decisiondrift review [diff] LLM-based semantic violation classification
decisiondrift impact [diff] Analyze diff for impacted symbols (AST-based diagnostic)
decisiondrift ingest <file> Extract candidate ADRs from free-text notes (LLM required)
decisiondrift adr list List ADRs (filter by --status, --source)
decisiondrift adr approve ADR-XXXX Approve a proposed ADR
decisiondrift adr reject ADR-XXXX Reject a proposed ADR
decisiondrift guard Pre-commit hook runner (--install to set up)

Key Options

Option Applies To Description
--from-git enforce, review, impact Read diff from git diff
--fail-on [level] enforce Minimum severity that causes non-zero exit (block, require_approval, warn, info)
--dry-run / --apply bootstrap Preview candidates or write them to disk
--min-confidence bootstrap Minimum evidence level for candidates
--repo <path> enforce, review, audit, impact Repository root (default: .)
--adr-dir <path> All ADR commands ADR directory (default: docs/adr)

ADR Lifecycle

Status Meaning Enforced?
proposed Generated but unreviewed No
accepted Approved by a maintainer Yes
rejected Declined; kept for dedup No
deprecated No longer valid No
superseded Replaced by a newer ADR No

Only accepted ADRs participate in enforcement. Generated candidates can never silently block a PR.


Deterministic Rule Engine

The rule engine (decisiondrift enforce) is the core of DecisionDrift's governance model. It operates without any LLM dependency:

  • Dependency rules: Check requirements.txt, pyproject.toml, package.json, go.mod, Cargo.toml for prohibited packages
  • Import rules: Scan Python AST for prohibited imports
  • Path rules: Regex-match file paths against patterns
  • API rules: Detect prohibited function/method calls in Python files
  • Config rules: Scan config files (YAML, JSON, TOML, INI) for matching key-value patterns

Rules are generated automatically from ADR prohibitions field. Confidence levels (high/medium/low) control enforcement severity: low-confidence rules downgrade BLOCK to INFO.


LLM Configuration (Optional)

For the review and ingest commands, set via environment variables or decisiondrift.yml:

DECISIONDRIFT_LLM_API_KEY=sk-...
DECISIONDRIFT_LLM_MODEL=gpt-4o
DECISIONDRIFT_LLM_BASE_URL=https://api.openai.com/v1

Without an API key, review falls back to non-functional output and enforce (deterministic) is recommended instead.


GitHub Action

Add .github/workflows/decisiondrift.yml:

name: DecisionDrift
on: pull_request
permissions:
  pull-requests: write
  contents: read
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: yourorg/decisiondrift@v1
        with:
          llm-api-key: ${{ secrets.DECISIONDRIFT_LLM_KEY }}

Project Structure

src/decisiondrift/
  cli.py                     # CLI entrypoint (Click)
  config.py                  # Config loader (YAML + .env)
  models/schema.py           # Pydantic models
  adr/                       # ADR loader, parser, writer, supersession
  adr_manager/               # adr list/approve/reject commands
  bootstrap/                 # V3 structure scanner + candidate generation
  rules/                     # Deterministic rule engine (5 rule types)
  classification/            # LLM classifier
  github/                    # GitHub Action adapter
  impact/                    # Diff parser + AST extraction (Python + Tree-sitter)
  ingest/                    # Free-text → ADR pipeline
  report/                    # Text + GitHub comment formatters
  retrieval/                 # Keyword-based ADR retrieval
  review/                    # Orchestrator pipeline

Evaluation

Metric Score
Retrieval Recall@5 95.2% (20/21 patches)
Retrieval Recall@1 85.7% (18/21 patches)
Classification Requires LLM API key; see docs/evaluation.md

Tested against 21 labeled patches (13 violations, 8 non-violations) across 12 architecture decisions.


Limitations

  • Python-focused AST analysis. Tree-sitter support exists for JS, TS, Go, Java, Rust but requires pip install decisiondrift[ast]. Non-Python files in the rule engine still work for dependency and path rules.
  • Keyword-only retrieval. May miss ADRs when symbol/file-path terms don't match (embedding-based hybrid retrieval in [embeddings] extras).
  • Ollama CPU-bound on large models. ~17s/pair with qwen2.5-coder:7b; use Groq/OpenAI for ~1s latency.
  • Bootstrap is heuristic. Directory-naming detection is not architectural understanding — generated ADRs require human approval.

Development

pip install -e ".[embeddings,ast]"
python -m pytest tests/

See docs/plan.md for the full design document and docs/progress.md for current status.

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

decisiondrift-1.0.0b2.tar.gz (76.0 kB view details)

Uploaded Source

Built Distribution

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

decisiondrift-1.0.0b2-py3-none-any.whl (75.5 kB view details)

Uploaded Python 3

File details

Details for the file decisiondrift-1.0.0b2.tar.gz.

File metadata

  • Download URL: decisiondrift-1.0.0b2.tar.gz
  • Upload date:
  • Size: 76.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for decisiondrift-1.0.0b2.tar.gz
Algorithm Hash digest
SHA256 df578d754102f3d4a7ac3859fd7bf14b3a2ce554afb68f88e23756e379ef7b6a
MD5 6e54b25d80f2fce1f04378348ae155c8
BLAKE2b-256 38348be3e2ceef30a8fb503e7ca114275532acdcfe71cbd65ea284f3f6423bf8

See more details on using hashes here.

File details

Details for the file decisiondrift-1.0.0b2-py3-none-any.whl.

File metadata

File hashes

Hashes for decisiondrift-1.0.0b2-py3-none-any.whl
Algorithm Hash digest
SHA256 7ea492a2a220c969ff1ca80fbd2e7fcda1fc88e8b2e7495c21a56f37b6c7e1e8
MD5 95a819c59ced47814ad530f82428dc1b
BLAKE2b-256 0e490cbf605b0b46d26cb89eabfdc895418e8145db7efc403ec62061d343b781

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