From 57f66570c698bd4359d56c8ec4771b1a5528fd13 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 07:42:18 +0000 Subject: [PATCH 1/2] Rewrite README.md with comprehensive documentation Co-Authored-By: unknown <> --- README.md | 560 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 423 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 75178db..7c3d48b 100644 --- a/README.md +++ b/README.md @@ -1,188 +1,419 @@ -# Docs Drift Guard – Demo +# Docs Drift Guard -> A 3-layer automation that keeps your API, its documentation, and its -> consumers in sync — and alerts your team on Slack when they aren't. +> A 3-layer automation that keeps your API, its documentation, and its consumers in sync -- and alerts your team on Slack when they drift apart. -This repository demonstrates three complementary guards for enterprise APIs: +[![Drift Guard](https://github.com/justinemach/DevinTestRepo/actions/workflows/drift-guard.yml/badge.svg)](https://github.com/justinemach/DevinTestRepo/actions/workflows/drift-guard.yml) -| Layer | What it catches | How | +--- + +## Table of Contents + +- [Overview](#overview) +- [How It Works](#how-it-works) +- [Getting Started](#getting-started) + - [Prerequisites](#prerequisites) + - [Installation](#installation) + - [Starting the API Server](#starting-the-api-server) +- [The Three Guard Layers](#the-three-guard-layers) + - [Layer 1: Code-vs-Docs Drift Detection](#layer-1-code-vs-docs-drift-detection) + - [Layer 2: Runtime API Call Guard](#layer-2-runtime-api-call-guard) + - [Layer 3: Contract Tests](#layer-3-contract-tests) +- [CLI Reference](#cli-reference) + - [Commands](#commands) + - [Exit Codes](#exit-codes) + - [Options](#options) +- [API Endpoints](#api-endpoints) + - [Health](#health) + - [Employees](#employees) + - [Reports](#reports) + - [Audit](#audit) +- [Severity Classification](#severity-classification) +- [Slack Notifications](#slack-notifications) +- [CI/CD Integration](#cicd-integration) +- [Pre-Commit Hook](#pre-commit-hook) +- [Demo Walkthrough](#demo-walkthrough) +- [Project Structure](#project-structure) +- [Tech Stack](#tech-stack) +- [Wiki](#wiki) +- [License](#license) + +--- + +## Overview + +Enterprise APIs evolve constantly -- new fields get added, endpoints get renamed, schemas change. When documentation doesn't keep up, clients break. **Docs Drift Guard** solves this with three complementary layers of protection: + +| Layer | What It Catches | How | |-------|----------------|-----| -| **Code-vs-Docs Drift** | Developer changes the API but forgets to update the docs | Compares live OpenAPI to a stored baseline | -| **Runtime Call Guard** | Clients call the API with wrong field names or hit nonexistent endpoints | FastAPI middleware validates every request against the OpenAPI spec | +| **Code-vs-Docs Drift Detection** | Developer changes the API but forgets to update the docs | Compares the live OpenAPI spec to a stored baseline | +| **Runtime API Call Guard** | Clients call the API with wrong field names or nonexistent endpoints | FastAPI middleware validates every request against the OpenAPI spec | | **Contract Tests** | Accumulated mismatches from clients built against stale docs | pytest suite replays "old client" calls and reports what breaks | -All three feed into Slack notifications so the team knows what to fix. +All three layers feed into **Slack notifications** so the team knows what to fix, and results are published as **CI artifacts** on every push and pull request. + +--- + +## How It Works + +``` ++-----------------------+ +| API Source Code | +| (app/main.py) | ++-----------+-----------+ + | + generates live OpenAPI spec + | ++-----------v-----------+ ++-------> OpenAPI Spec <-------+ +| | (/openapi.json) | | +| +-----------+-----------+ | +| | | +Layer 1: Drift Layer 2: Runtime Layer 3: Contract +Detection Call Guard Tests +| | | +compares to validates every replays stale +stored baseline incoming request client scenarios +| | | +v v v ++--------------+ +---------------+ +---------------+ +| drift_guard/ | | app/middleware | | tests/ | +| guard.py | | | | test_contract | +| check cmd | | APICallGuard | | | ++--------------+ | Middleware | +---------------+ + | +-------+-------+ | + | | | + +--------+-----------+--------------------+ + | + v + Slack Notifications + + Audit Reports + + Generated Docs +``` + +**Key design principle:** The live OpenAPI spec (generated by FastAPI from code) is always the single source of truth. Documentation is derived from it, never the other way around. --- -## Quick Start +## Getting Started + +### Prerequisites + +- **Python 3.11+** +- **pip** (included with Python) +- **Git** + +### Installation + +**Option A: One-command setup** ```bash -# 1. Clone & setup -git clone && cd docs-drift-guard-demo -python3 -m venv .venv && source .venv/bin/activate +git clone https://github.com/justinemach/DevinTestRepo.git +cd DevinTestRepo +bash scripts/bootstrap.sh +``` + +**Option B: Manual setup** + +```bash +git clone https://github.com/justinemach/DevinTestRepo.git +cd DevinTestRepo +python3 -m venv .venv +source .venv/bin/activate pip install -r requirements.txt +``` + +### Starting the API Server -# 2. Start the API server (in a separate terminal) +```bash +source .venv/bin/activate uvicorn app.main:app --reload ``` +The server starts at `http://localhost:8000`. Verify it's running: + +```bash +curl -s http://localhost:8000/health | python -m json.tool +``` + +Expected response: + +```json +{ + "status": "ok", + "version": "1.0.0" +} +``` + +**Interactive docs** are available at: + +| URL | Format | +|-----|--------| +| http://localhost:8000/docs | Swagger UI (interactive) | +| http://localhost:8000/redoc | ReDoc (read-only) | +| http://localhost:8000/openapi.json | Raw OpenAPI spec (JSON) | + --- -## Demo Part 1: Code-vs-Docs Drift Detection +## The Three Guard Layers -Detect when a developer changes the API code but doesn't update the docs. +### Layer 1: Code-vs-Docs Drift Detection + +**Problem:** A developer changes the API code (adds a field, removes an endpoint) but forgets to update the documentation. + +**Module:** `drift_guard/guard.py` + `drift_guard/drift_detect.py` + +**How it works:** + +1. A baseline OpenAPI spec is saved to `artifacts/openapi_baseline.json` +2. When `check` is run, it loads the current OpenAPI spec (by importing the FastAPI app directly -- no running server needed) +3. The two specs are compared field-by-field and endpoint-by-endpoint +4. Changes are classified by severity: GREEN (non-breaking), YELLOW (potentially breaking), RED (breaking) +5. `docs/api_reference.md` is auto-regenerated from the current spec +6. A Slack notification is sent for YELLOW and RED changes (GREEN is silent to avoid noise) +7. The baseline is updated and the drift summary is written to `artifacts/drift_summary.md` ```bash # Save the current API as the baseline python -m drift_guard.guard baseline -# Introduce a code change (adds 'role' field + GET /v1/users endpoint) +# Introduce a code change (replaces app/main.py with a different API) bash scripts/demo_drift.sh # Detect the drift python -m drift_guard.guard check -# → "Added endpoint: GET /v1/users" -# → "Schema change: User gained field role" -# → Regenerates docs/api_reference.md -# → Posts to Slack (if SLACK_WEBHOOK_URL is set) -# → Exits with code 2 ``` ---- +### Layer 2: Runtime API Call Guard + +**Problem:** Clients built from stale documentation send requests with wrong field names or call endpoints that no longer exist. -## Demo Part 2: Runtime API Call Guard +**Module:** `app/middleware.py` + +**How it works:** -Catch clients that are calling the API using field names from the stale -manual docs (e.g. `username` instead of `name`). +1. A FastAPI middleware (`APICallGuardMiddleware`) intercepts every incoming request +2. It checks the request path against the OpenAPI spec -- unknown endpoints are flagged +3. For POST/PUT/PATCH requests, it compares request body field names against the schema -- extra/unknown fields are flagged +4. Mismatches are logged to an in-memory audit log (the request is **never blocked** -- observe-only) +5. An `X-API-Mismatch: true` header is added to responses when issues are found +6. The audit log is queryable via `GET /v1/audit` and clearable via `DELETE /v1/audit` ```bash -# Simulate a client built from the stale docs +# Simulate a client built from stale docs bash scripts/demo_bad_client.sh -# → Sends POST with "username" (wrong) instead of "name" (correct) -# → Sends GET to /v1/teams (doesn't exist) -# → Each mismatch is logged by the middleware # View the audit log curl -s http://localhost:8000/v1/audit | python -m json.tool -# Get a Slack summary +# Get a Slack summary of all runtime mismatches python -m drift_guard.guard audit -# → Summarises all runtime mismatches -# → Posts to Slack -# → Exits with code 3 ``` -The middleware runs on every request but never blocks — it logs issues -and adds an `X-API-Mismatch: true` response header so callers know -something was off. +### Layer 3: Contract Tests ---- +**Problem:** Over time, multiple clients accumulate mismatches against the API. You need a systematic way to find and report all of them. + +**Module:** `tests/test_contract.py` -## Demo Part 3: Contract Tests (Clean Up the Mess) +**How it works:** -Run a test suite that replays how a client built from the stale manual -docs would call the API, and get a clear report of what's broken. +1. A pytest suite makes real HTTP calls against the running server +2. Tests cover correct calls, stale field names, nonexistent endpoints, and cross-API consistency +3. Each test validates response codes, field names, and types +4. The audit log is checked to confirm the middleware caught all issues + +The test suite includes 12 test classes covering: + +| Test Class | What It Validates | +|-----------|-------------------| +| `TestHealthContract` | Health endpoint returns `status` and `version` | +| `TestGetEmployeeContract` | GET single employee returns correct fields and types; legacy `name` field is absent | +| `TestListEmployeesContract` | List employees works with `department` and `status` filters | +| `TestCreateEmployeeContract` | POST with correct fields succeeds (201); POST with stale `name` field fails (422) | +| `TestUpdateEmployeeContract` | PATCH partial updates work; nonexistent employee returns 404 | +| `TestAPITruthLoop` | Full truth loop: POST -> verify schema -> cross-check OpenAPI spec | +| `TestAuditEndpoint` | Audit endpoint records mismatches from bad calls | +| `TestHeadcountReportContract` | Headcount report structure, field types, and totals consistency | +| `TestDepartmentsContract` | Departments list is sorted, matches employee data, and exists in OpenAPI spec | +| `TestCrossAPIConsistency` | Filtered employee counts match headcount report; all endpoints exist in OpenAPI | +| `TestStaleClientScenarios` | Old `/v1/users` and `/v1/teams` endpoints return 404 | ```bash -# Run the contract tests +# Run the contract tests (requires a running server) pytest tests/test_contract.py -v # Or run the full cleanup script (tests + audit report) bash scripts/demo_cleanup.sh ``` -The tests cover: -- Correct calls (should pass) -- Calls using `username` instead of `name` (should fail with 422) -- Calls to nonexistent endpoints (should get 404) -- Validation that the middleware flags all issues in the audit log - --- -## Full Demo Flow (for a Loom recording) - -```bash -# Setup -source .venv/bin/activate -uvicorn app.main:app --reload # separate terminal - -# Part 1: Show the stale manual docs -cat docs/api_manual.md # note: says "username", API uses "name" - -# Part 2: Baseline + drift detection -python -m drift_guard.guard baseline -bash scripts/demo_drift.sh -python -m drift_guard.guard check # drift detected! - -# Part 3: Bad client calls + audit -bash scripts/demo_bad_client.sh # middleware catches mismatches -python -m drift_guard.guard audit # Slack summary - -# Part 4: Contract tests -pytest tests/test_contract.py -v # shows exactly what's broken -``` +## CLI Reference ---- +### Commands -## CLI Reference +All commands are run via: -``` +```bash python -m drift_guard.guard [--url URL] ``` -| Command | What it does | +| Command | What It Does | |---------|-------------| -| `baseline` | Fetch OpenAPI, save snapshot, generate `docs/api_reference.md` | -| `check` | Compare to baseline, report drift, regenerate docs, notify Slack | -| `audit` | Fetch runtime mismatch log, summarise, notify Slack | +| `baseline` | Load the current OpenAPI spec (direct import), save snapshot to `artifacts/openapi_baseline.json`, generate `docs/api_reference.md` | +| `check` | Compare current spec to baseline, classify drift by severity, regenerate docs, update baseline, notify Slack (YELLOW/RED only) | +| `audit` | Fetch runtime mismatch log from `GET /v1/audit`, summarize, append to `docs/api_reference.md`, write `artifacts/audit_report.md`, notify Slack | ### Exit Codes | Code | Meaning | |------|---------| -| 0 | Success / no drift / no mismatches | -| 1 | Runtime error (server down, missing baseline, etc.) | -| 2 | Drift detected | -| 3 | Runtime mismatches found | +| `0` | Success / no drift / no mismatches | +| `1` | Runtime error (server down, missing baseline, import failure) | +| `2` | Breaking (RED) drift detected | +| `3` | Runtime mismatches found | +| `10` | Non-breaking (GREEN) drift detected | +| `11` | Potentially breaking (YELLOW) drift detected | + +### Options + +| Flag | Default | Description | +|------|---------|-------------| +| `--url URL` | *(direct import)* | Fetch OpenAPI spec via HTTP instead of importing the app directly. Only needed if you want to check a remote server. The `audit` command always uses HTTP (`http://localhost:8000/v1/audit` by default). | --- -## Automation: CI Gate (GitHub Action) +## API Endpoints + +The DataStack Platform API powers an internal employee management platform. All endpoints are versioned under `/v1`. + +### Health + +| Method | Path | Summary | +|--------|------|---------| +| GET | `/health` | Health check -- returns `{"status": "ok", "version": "1.0.0"}` | + +### Employees + +| Method | Path | Summary | +|--------|------|---------| +| GET | `/v1/employees` | List employees (optional `?department=` and `?status=` filters) | +| GET | `/v1/employees/{employee_id}` | Get an employee by ID | +| POST | `/v1/employees` | Onboard a new employee | +| PATCH | `/v1/employees/{employee_id}` | Update an employee (partial update) | + +**POST /v1/employees -- Request Body:** -A GitHub Action runs on every push and PR to `main`. It automatically: +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `first_name` | string | Yes | Employee first name | +| `last_name` | string | Yes | Employee last name | +| `email` | string | Yes | Corporate email address | +| `department` | string | Yes | Department (e.g. Engineering, Sales, HR) | +| `title` | string | Yes | Job title | +| `role` | string | No | Access role: `member` (default), `manager`, `admin` | -1. Starts the API server -2. Runs `drift_guard check` — fails if the OpenAPI spec drifted from the baseline -3. Runs `pytest tests/test_contract.py` — fails if any contract tests break -4. Runs `drift_guard audit` — summarises runtime mismatches -5. Uploads `artifacts/drift_summary.md` and `artifacts/audit_report.md` as build artifacts -6. Posts to Slack if `SLACK_WEBHOOK_URL` is set as a repository secret +**PATCH /v1/employees/{id} -- Request Body** (all fields optional): -**To enable Slack in CI:** Add `SLACK_WEBHOOK_URL` as a repository secret in -Settings > Secrets and variables > Actions. +`first_name`, `last_name`, `email`, `department`, `title`, `role`, `status` -If drift is detected, the PR will show a failing check with a clear message -telling the developer to run `python -m drift_guard.guard baseline` and commit -the updated files. +**Employee Response Fields:** + +`id`, `first_name`, `last_name`, `email`, `department`, `title`, `role`, `status`, `hired_at`, `bio`, `dob`, `language` + +### Reports + +| Method | Path | Summary | +|--------|------|---------| +| GET | `/v1/reports/headcount` | Headcount report broken down by department (returns `generated_at`, `total_employees`, `departments[]`) | +| GET | `/v1/departments` | Sorted list of all unique department names | + +### Audit + +| Method | Path | Summary | +|--------|------|---------| +| GET | `/v1/audit` | View all API call mismatches recorded by the middleware | +| DELETE | `/v1/audit` | Clear the audit log | + +**Seed data:** The API starts with 5 pre-loaded employees (Sarah Chen, Marcus Johnson, Priya Patel, James Wright, Lisa Kim). The in-memory store resets every time the server restarts. + +**Authentication:** None currently required. No authentication middleware is configured. --- -## Automation: Pre-Commit Hook +## Severity Classification + +Drift events are classified into three severity levels that drive automation behavior: + +| Severity | What Triggers It | Exit Code | Pre-Commit Behavior | CI Behavior | +|----------|-----------------|-----------|---------------------|-------------| +| **GREEN** (non-breaking) | New optional field, new endpoint, description change, enum constraint relaxed, required field becomes optional | `10` | Auto-update baseline + docs, commit proceeds | Auto-update baseline, add GitHub notice, **pass** | +| **YELLOW** (potentially breaking) | Type change, required flag toggled, enum values removed or added | `11` | Auto-update baseline + docs, commit proceeds | Add GitHub warning, **fail** -- requires PR review | +| **RED** (breaking) | Required field added, field removed, endpoint removed | `2` | **Block commit** -- requires human review | Add GitHub error, **fail** -- must be resolved | -Catch drift before code even gets pushed. Two ways to install: +**Slack notifications** are only sent for YELLOW and RED severity. GREEN changes produce only local CLI output to avoid noise. -**Option A: Using the `pre-commit` framework (recommended)** +--- + +## Slack Notifications + +Set the `SLACK_WEBHOOK_URL` environment variable to enable Slack notifications: ```bash -pip install pre-commit -pre-commit install +export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/T.../B.../xxx" ``` -This uses `.pre-commit-config.yaml` to run the drift check only when files -under `app/` are staged. It also runs `ruff` for linting. +If the variable is not set, the tool prints the JSON payload that would have been sent so you can verify the format. + +**Notification types:** + +| Trigger | Content | +|---------|---------| +| Drift detected (YELLOW/RED) | Change summary, impact assessment, docs status, action items, review links | +| Runtime mismatches found | Mismatch details, affected endpoints, context | + +**Slack message structure** (Block Kit format): + +1. **Header** -- severity emoji + label (e.g. "Breaking") +2. **Change Summary** -- list of added/removed endpoints and schema changes +3. **Impact** -- what this means for clients +4. **Docs Status** -- which files were regenerated +5. **Files Changed** -- list of modified artifact files +6. **Action** -- what the reader needs to do +7. **Review Links** -- direct links to docs, drift summary, and Devin + +--- + +## CI/CD Integration + +A GitHub Actions workflow (`.github/workflows/drift-guard.yml`) runs on every push to `main` and every pull request targeting `main`. + +**Pipeline phases:** + +| Phase | What It Does | +|-------|-------------| +| **1. Drift Detection** | Starts the API server, saves baseline if none exists, runs `drift_guard check`, captures severity | +| **2. Contract Tests** | Runs `pytest tests/test_contract.py -v --tb=short` | +| **3. Audit Summary** | Runs `drift_guard audit` to fetch runtime mismatches | +| **4. Artifacts** | Uploads `artifacts/drift_summary.md` and `artifacts/audit_report.md` (even on failure) | +| **5. Final Verdict** | Fails if YELLOW/RED drift detected OR contract tests failed | + +**To enable Slack in CI:** Add `SLACK_WEBHOOK_URL` as a repository secret in Settings > Secrets and variables > Actions. -**Option B: Manual git hook** +**To fix a failing CI check:** + +1. Download `artifacts/drift_summary.md` from the Actions tab +2. Run `python -m drift_guard.guard baseline` locally +3. Commit the updated `artifacts/openapi_baseline.json` and `docs/api_reference.md` +4. Push to the PR branch + +--- + +## Pre-Commit Hook + +Catch drift before code gets pushed. The hook only triggers when files under `app/` are staged. + +**Install the hook:** ```bash cp scripts/pre-commit-drift-check.sh .git/hooks/pre-commit @@ -190,74 +421,129 @@ chmod +x .git/hooks/pre-commit ``` **How it works:** -- Only triggers when you stage changes to files in `app/` -- Starts a temporary server, compares the live OpenAPI to the baseline -- If drift is found, the commit is blocked with instructions on how to fix it -- To skip once (not recommended): `git commit --no-verify` + +1. Detects staged changes in `app/` +2. Imports the FastAPI app directly and compares the OpenAPI spec to the baseline (no server needed) +3. **GREEN or YELLOW drift:** Auto-updates baseline and docs, stages the updated files, commit proceeds +4. **RED drift:** Blocks the commit with instructions on how to fix it +5. **Error (exit 1):** Warns but allows the commit to proceed + +To skip once (not recommended): `git commit --no-verify` + +**Linting with pre-commit framework:** + +The `.pre-commit-config.yaml` is configured for Ruff linting only. To use it: + +```bash +pip install pre-commit +pre-commit install +``` --- -## Slack Notifications +## Demo Walkthrough -Set the `SLACK_WEBHOOK_URL` environment variable: +Run through the full Docs Drift Guard demo in four parts: ```bash -export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/T.../B.../xxx" +# Setup +source .venv/bin/activate +uvicorn app.main:app --reload # in a separate terminal + +# Part 1: Show the stale manual docs +cat docs/api_manual.md # note: says "username", API uses "first_name" + "last_name" + +# Part 2: Baseline + drift detection +python -m drift_guard.guard baseline +bash scripts/demo_drift.sh # replaces app/main.py with a different API +python -m drift_guard.guard check # drift detected! + +# Part 3: Bad client calls + audit +bash scripts/demo_bad_client.sh # middleware catches mismatches +python -m drift_guard.guard audit # Slack summary + +# Part 4: Contract tests +pytest tests/test_contract.py -v # shows exactly what's broken ``` -If the variable is not set, the tool prints the JSON payload that would -have been sent so you can verify the format. +**What `demo_drift.sh` does:** Replaces `app/main.py` with a simplified User API that has a `role` field on User/UserCreate models and a new `GET /v1/users` endpoint. This creates detectable drift against the original Employee API baseline. + +**What `demo_bad_client.sh` does:** Sends API calls using wrong field names from the stale manual docs (e.g. `username` instead of `name`) and calls nonexistent endpoints (e.g. `/v1/teams`). The middleware logs every mismatch. --- ## Project Structure ``` -docs-drift-guard-demo/ +DevinTestRepo/ app/ - main.py # FastAPI application + audit endpoint - middleware.py # API Call Guard middleware - audit_log.py # In-memory audit log + main.py # FastAPI application (employees, reports, audit endpoints) + middleware.py # API Call Guard middleware (validates requests against OpenAPI) + audit_log.py # In-memory audit log (records mismatches) docs/ - api_reference.md # Auto-generated (by drift_guard) - api_manual.md # Hand-written – intentionally stale + api_reference.md # Auto-generated Markdown API reference (by drift_guard) + api_manual.md # Hand-written docs -- intentionally stale for demo purposes + wiki/ # Comprehensive wiki documentation (15 pages) drift_guard/ - guard.py # CLI entrypoint (baseline, check, audit) - openapi_to_md.py # OpenAPI JSON → Markdown converter - drift_detect.py # Compares two OpenAPI snapshots - slack_notify.py # Slack Incoming Webhook integration + guard.py # CLI entrypoint (baseline, check, audit commands) + drift_detect.py # Compares two OpenAPI snapshots, classifies severity + openapi_to_md.py # OpenAPI JSON -> Markdown converter + slack_notify.py # Slack Incoming Webhook integration (Block Kit format) tests/ - test_contract.py # Contract test suite + test_contract.py # Contract test suite (12 test classes, ~30 tests) artifacts/ - openapi_baseline.json # Stored OpenAPI snapshot - drift_summary.md # Generated change summary + openapi_baseline.json # Stored OpenAPI snapshot (with metadata wrapper) + drift_summary.md # Generated change summary with severity audit_report.md # Generated audit report scripts/ - bootstrap.sh # One-command setup - demo_drift.sh # Introduces code drift + bootstrap.sh # One-command setup (venv + dependencies) + demo_drift.sh # Introduces code drift (replaces app/main.py) demo_bad_client.sh # Simulates stale-doc client calls - demo_cleanup.sh # Runs contract tests + audit + demo_cleanup.sh # Runs contract tests + audit report pre-commit-drift-check.sh # Git pre-commit hook .github/workflows/ - drift-guard.yml # GitHub Action CI gate - .pre-commit-config.yaml # pre-commit framework config - requirements.txt - README.md + drift-guard.yml # GitHub Actions CI gate + .pre-commit-config.yaml # Ruff linting via pre-commit framework + requirements.txt # Python dependencies ``` --- ## Tech Stack -- Python 3.11+ -- FastAPI + Uvicorn -- Requests (Slack webhook) -- Rich (CLI output) -- Pytest (contract tests) -- Ruff (linting) +| Component | Version | Purpose | +|-----------|---------|---------| +| Python | 3.11+ | Runtime | +| FastAPI | >= 0.104.0 | API framework + auto-generated OpenAPI spec | +| Uvicorn | >= 0.24.0 | ASGI server | +| Requests | >= 2.31.0 | HTTP client (Slack webhooks, audit log fetching) | +| Rich | >= 13.7.0 | CLI output formatting | +| Pytest | >= 7.4.0 | Contract test suite | +| Ruff | >= 0.1.0 | Linting | + +--- + +## Wiki + +For detailed documentation on every aspect of Docs Drift Guard, see the [wiki pages](docs/wiki/Home.md) in `docs/wiki/`: + +- [Getting Started](docs/wiki/Getting-Started.md) -- Installation, setup, and first run +- [Architecture Overview](docs/wiki/Architecture-Overview.md) -- How the three layers work together +- [Drift Detection](docs/wiki/Drift-Detection.md) -- Layer 1 deep dive +- [Runtime Call Guard](docs/wiki/Runtime-Call-Guard.md) -- Layer 2 deep dive +- [Contract Tests](docs/wiki/Contract-Tests.md) -- Layer 3 deep dive +- [CLI Reference](docs/wiki/CLI-Reference.md) -- Full command reference +- [API Endpoints](docs/wiki/API-Endpoints.md) -- Complete endpoint documentation +- [Severity Classification](docs/wiki/Severity-Classification.md) -- GREEN/YELLOW/RED rules +- [Slack Notifications](docs/wiki/Slack-Notifications.md) -- Webhook setup and message format +- [CI/CD Integration](docs/wiki/CI-CD-Integration.md) -- GitHub Actions workflow +- [Pre-Commit Hooks](docs/wiki/Pre-Commit-Hooks.md) -- Local drift checking +- [Demo Walkthrough](docs/wiki/Demo-Walkthrough.md) -- Step-by-step demo guide +- [Project Structure](docs/wiki/Project-Structure.md) -- File layout and module descriptions +- [Troubleshooting](docs/wiki/Troubleshooting.md) -- Common issues and solutions --- ## License -MIT – use freely for demos, talks, and internal tooling. +MIT -- use freely for demos, talks, and internal tooling. From 90143df9e4ceaa08a311d88054f8b732a6058fd4 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 07:48:50 +0000 Subject: [PATCH 2/2] =?UTF-8?q?Fix=20test=20class=20count=20(12=E2=86=9211?= =?UTF-8?q?)=20and=20correct=20enum=20severity=20classification?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: unknown <> --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7c3d48b..5ca478c 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ python -m drift_guard.guard audit 3. Each test validates response codes, field names, and types 4. The audit log is checked to confirm the middleware caught all issues -The test suite includes 12 test classes covering: +The test suite includes 11 test classes covering: | Test Class | What It Validates | |-----------|-------------------| @@ -347,8 +347,8 @@ Drift events are classified into three severity levels that drive automation beh | Severity | What Triggers It | Exit Code | Pre-Commit Behavior | CI Behavior | |----------|-----------------|-----------|---------------------|-------------| -| **GREEN** (non-breaking) | New optional field, new endpoint, description change, enum constraint relaxed, required field becomes optional | `10` | Auto-update baseline + docs, commit proceeds | Auto-update baseline, add GitHub notice, **pass** | -| **YELLOW** (potentially breaking) | Type change, required flag toggled, enum values removed or added | `11` | Auto-update baseline + docs, commit proceeds | Add GitHub warning, **fail** -- requires PR review | +| **GREEN** (non-breaking) | New optional field, new endpoint, description change, enum constraint relaxed, enum values added (to existing enum), required field becomes optional | `10` | Auto-update baseline + docs, commit proceeds | Auto-update baseline, add GitHub notice, **pass** | +| **YELLOW** (potentially breaking) | Type change, required flag toggled, enum values removed, new enum constraint added | `11` | Auto-update baseline + docs, commit proceeds | Add GitHub warning, **fail** -- requires PR review | | **RED** (breaking) | Required field added, field removed, endpoint removed | `2` | **Block commit** -- requires human review | Add GitHub error, **fail** -- must be resolved | **Slack notifications** are only sent for YELLOW and RED severity. GREEN changes produce only local CLI output to avoid noise. @@ -490,7 +490,7 @@ DevinTestRepo/ openapi_to_md.py # OpenAPI JSON -> Markdown converter slack_notify.py # Slack Incoming Webhook integration (Block Kit format) tests/ - test_contract.py # Contract test suite (12 test classes, ~30 tests) + test_contract.py # Contract test suite (11 test classes, ~30 tests) artifacts/ openapi_baseline.json # Stored OpenAPI snapshot (with metadata wrapper) drift_summary.md # Generated change summary with severity