# Agent-Workflow: drift in KI-gestützter Entwicklung

Dieser Guide zeigt, wie `drift` in Workflows mit KI-Coding-Agenten wie Claude, GitHub Copilot und Cursor eingesetzt wird.
Zielgruppe sind Entwickler, die aktiv mit solchen Agenten arbeiten und sicherstellen wollen, dass generierter Code keine architektonische Erosion einführt.

---

## 1. Das Problem ohne drift

KI-Agenten schreiben Code, der lokal funktioniert und Tests besteht — aber unbewusst strukturelle Kohärenz abbaut: Pattern-Varianten proliferieren, Layer-Grenzen werden durchbrochen, Duplikate entstehen seitenweise. Da kein einzelner Commit offensichtlich falsch ist, bleibt der Schaden unsichtbar bis er akkumuliert und teuer wird. Drift macht diese Erosion sichtbar — bevor, während und nach einer Agent-Session.

---

## 2. Überblick: Die drei Workflow-Phasen

| Phase | CLI-Befehl | Zweck |
|-------|-----------|-------|
| **Vor** der Session | `drift brief --task "..."` | Scope analysieren, Guardrails für den Agent-Prompt generieren |
| **Während** der Session | `drift diff --uncommitted` | Schnelles Checkpoint-Feedback nach Änderungen (CLI) |
| **Nach** der Session | `drift check` → `drift diff` → `drift fix-plan` | Regression erkennen, Ursachen verstehen, Prioritäten setzen |

Für Clients mit MCP-Unterstützung (Claude Desktop, Cursor, VS Code Copilot) ersetzt der **MCP-Workflow** die CLI-Commands durch direkte Tool-Aufrufe. Siehe [Abschnitt 6](#6-mcp-integration).

---

## 3. Phase 1 — Vor der Agent-Session: `drift brief`

### Was `drift brief` tut

`drift brief` analysiert, welche Teile des Repositorys von einer Aufgabe betroffen sind, bewertet das strukturelle Risiko und generiert **Guardrails** — fertig formatierte Prompt-Constraints, die direkt in einen System-Prompt eingefügt werden können.

### Aufruf

`--task` ist ein **Pflichtparameter**:

```bash
# Minimalaufruf
drift brief --task "add payment integration to checkout module"

# Mit Kurzform -t und Scope-Override
drift brief -t "refactor auth service" --scope src/auth/

# Als Markdown-Datei für den System-Prompt
drift brief -t "add caching to API layer" --format markdown --output context.md

# Als JSON (agent-friendly)
drift brief -t "migrate user model to Pydantic v2" --format json
```

### Ausgabe

`drift brief` liefert vier Hauptbereiche:

| Feld | Inhalt |
|------|--------|
| `risk.level` | `LOW` / `MEDIUM` / `HIGH` / `BLOCK` |
| `risk.blocking_signals` | Signale, die Vorsicht erfordern (z. B. `AVS`, `PFS`) |
| `landscape.drift_score` | Aktueller Gesamt-Score des Repos |
| `guardrails` | Priorisierte Prompt-Constraints |

**Risk-Level-Bedeutung:**

| Level | Score-Schwelle | Bedeutung |
|-------|---------------|-----------|
| `LOW` | < 0.25 | Grünes Licht — Agent kann frei arbeiten |
| `MEDIUM` | 0.25–0.50 | Erhöhte Vorsicht; Guardrails beachten |
| `HIGH` | 0.50–0.75 | Signifikante Strukturrisiken im Scope |
| `BLOCK` | ≥ 0.75 oder CRITICAL AVS | Agent sollte ohne menschliche Freigabe nicht starten |

### Konstruiertes Beispiel-Output (Rich-Format)

```
drift brief -t "add payment integration to checkout module"

  Scope resolved: src/checkout/ (3 files, confidence: 0.82)
  Risk level:     HIGH ■■■□
  Blocking:       PFS (2), AVS (1)

  Guardrails (top 3):
  1. CONSTRAINT [PFS]: Do not introduce new payment handler variants.
     The module has 2 existing pattern fragments for PaymentProcessor.
     PREFERRED: Extend the canonical CheckoutPaymentHandler in checkout/handlers.py
  2. CONSTRAINT [AVS]: All new checkout code must stay within src/checkout/.
     Do NOT import from src/billing/ directly — use the BillingService interface.
  3. CONSTRAINT [MDS]: Avoid duplicating validation logic from checkout/validators.py.
```

### Guardrails in den System-Prompt einbauen

Mit `--format markdown --output context.md` erzeugt `drift brief` einen Block, der direkt in einen Agent-System-Prompt eingefügt werden kann:

```markdown
## Structural Constraints (generated by drift brief)

The following constraints are derived from static analysis of the target scope.
Violating these constraints will likely degrade architectural coherence.

1. CONSTRAINT [PFS]: Do not introduce new payment handler variants. Do NOT: Add a new class inheriting BasePaymentHandler without extending the existing canonical.
   PREFERRED: Extend CheckoutPaymentHandler in src/checkout/handlers.py
2. CONSTRAINT [AVS]: Stay within the checkout layer boundary. Do NOT: Import directly from src/billing/.
3. CONSTRAINT [MDS]: Do not duplicate validation logic. Do NOT: Reimplement amount_is_valid() outside of checkout/validators.py.
```

### Beispiel: Agent-Kontext-Block (CLAUDE.md / System-Prompt)

```markdown
## Pre-task drift briefing

Before you write any code for this task, the following structural constraints
apply to the checkout module (generated by `drift brief`):

<!-- paste output of: drift brief -t "add payment integration" --format markdown -->
```

Oder automatisiert:

```bash
drift brief -t "add payment integration to checkout module" \
  --format markdown \
  --output .agent-context.md

# Dann in den System-Prompt einfügen:
cat .agent-context.md
```

---

## 4. Phase 2 — Während der Session: `drift diff --uncommitted`

Während der Agent Code schreibt, kann nach jeder signifikanten Änderung ein schneller Checkpoint laufen, der zeigt, ob neue Drift-Findings entstanden sind.

### CLI-Checkpoint

```bash
# Alle nicht-committierten Änderungen gegen HEAD prüfen
drift diff --uncommitted

# Nur staged Changes prüfen
drift diff --staged-only

# Als JSON (für Script-Integration)
drift diff --uncommitted --format json
```

### Konstruiertes Beispiel-Output

```
drift diff --uncommitted

  Changed files: src/checkout/payment.py, src/checkout/handlers.py

  ✓ Drift delta: +0.012   direction: STABLE
  New findings (1):
    [MEDIUM] PFS  src/checkout/payment.py:47
      New PaymentProcessor variant detected. Existing canonical: handlers.py:CheckoutPaymentHandler
      → Consider extending the existing class instead of creating a parallel implementation.

  Resolved (0):  —
  accept_change: true   (no blocking new findings)
```

### Exit-Code-Semantik

`drift diff` verwendet die gleichen Exit-Codes wie alle drift-Befehle:

| Code | Bedeutung |
|------|-----------|
| `0` | Keine blockierenden Findings; Änderung akzeptabel |
| `1` | Neue Findings über dem Severity-Threshold |
| `2` | Konfigurationsfehler |
| `3` | Analyse-Pipeline-Fehler |
| `4` | System-Fehler (git, I/O) |

### Agent-Instruktion mit `drift diff` als Checkpoint

Beispiel für eine Agent-Instruction in `CLAUDE.md`:

```markdown
## Coding workflow

After completing each logical unit of change, run:

```bash
drift diff --uncommitted --format json
```

If `accept_change` is false or `drift_detected` is true with severity HIGH or CRITICAL,
stop and ask the user before continuing. Paste the output as context.
```

> **Hinweis:** Für noch schnelleres Intra-Session-Feedback steht das MCP-Tool `drift_nudge` zur Verfügung, das auf einem Baseline-Snapshot arbeitet und nur geänderte Dateien re-analysiert. Siehe [Abschnitt 6](#6-mcp-integration).

---

## 5. Phase 3 — Nach der Session

Nach Abschluss einer Agent-Session folgt eine dreistufige Überprüfung:

### Entscheidungslogik

```
drift check
   │
   ├─ Passed (Exit 0) ──→ fertig ✓
   │
   └─ Failed (Exit 1) ──→ drift diff
                              │
                              ├─ Neue Findings sichten
                              └─ drift fix-plan
                                     │
                                     └─ Priorisierte Reparaturaufgaben
```

### `drift check` — Score-Gate

```bash
# Mit Standard-Threshold (aus drift.yaml oder MEDIUM)
drift check

# Threshold explizit setzen
drift check --fail-on high

# Als JSON für CI-Ausgabe
drift check --format json --fail-on medium
```

**Konstruiertes Beispiel-Output:**

```
drift check

  Checking diff HEAD~1...HEAD

  Findings: 3 new   0 resolved
    [HIGH]   PFS  src/checkout/payment.py:47     — Pattern fragmentation
    [MEDIUM] MDS  src/checkout/utils.py:12       — Mutant duplicate

  ✗ Drift check failed: findings at or above 'high' severity.
  Exit code: 1
```

### `drift diff` — Was hat sich konkret verändert?

Wenn `drift check` fehlschlägt, liefert `drift diff` die detaillierte Ursachenanalyse:

```bash
# Gegen vorherigen Commit
drift diff

# Gegen main-Branch
drift diff --diff-ref main

# Gegen gespeicherte Baseline
drift diff --baseline .drift-baseline.json
```

**Konstruiertes Beispiel-Output:**

```json
{
  "drift_detected": true,
  "score_delta": 0.034,
  "direction": "degrading",
  "new_findings": [
    {
      "signal": "PFS",
      "severity": "HIGH",
      "file": "src/checkout/payment.py",
      "line": 47,
      "message": "New PaymentProcessor variant conflicts with canonical pattern in handlers.py",
      "action": "Consolidate into CheckoutPaymentHandler or extract shared base class"
    }
  ],
  "resolved_findings": [],
  "accept_change": false,
  "blocking_reasons": ["HIGH severity finding in src/checkout/payment.py"]
}
```

> **Tipp:** `drift diff`, `drift trend` und `drift timeline` sind eng verwandt. Für langfristige Trendanalyse über mehrere Sessions hinweg — siehe [health-over-time.md](health-over-time.md).

### `drift fix-plan` — Was als nächstes tun?

`drift fix-plan` priorisiert Reparaturaufgaben automatisch nach Signal-Relevanz, Automatisierbarkeit und Schweregrad:

```bash
# Top-5 Aufgaben (Standard)
drift fix-plan

# Nur für ein bestimmtes Signal
drift fix-plan --signal PFS

# Auf einen Subpath beschränken
drift fix-plan --target-path src/checkout/

# Nur gut automatisierbare Tasks
drift fix-plan --automation-fit-min high --max-tasks 3
```

**Konstruiertes Beispiel-Output:**

```json
{
  "tasks": [
    {
      "id": "pfs-a1b2c3",
      "signal": "PFS",
      "severity": "HIGH",
      "title": "Consolidate PaymentProcessor variants",
      "file": "src/checkout/payment.py",
      "action_steps": [
        "Identify canonical: handlers.py:CheckoutPaymentHandler",
        "Extend CheckoutPaymentHandler in payment.py instead of parallel class",
        "Remove duplicate __init__ validation logic"
      ],
      "do_not_over_fix": "Do not refactor the entire checkout module",
      "success_criteria": "PFS finding for payment.py resolved; no new PFS findings",
      "automation_fit": "high",
      "batch_eligible": false
    }
  ],
  "task_count": 1,
  "total_available": 3
}
```

---

## 6. MCP-Integration (Claude Desktop / Cursor / VS Code)

> ⚠️ **Experimental:** Der MCP-Server und das `drift_nudge`-Tool befinden sich im experimentellen Status. API und Verhalten können sich ändern.

### Installation

MCP-Unterstützung erfordert das optionale `mcp`-Extra:

```bash
pip install drift-analyzer[mcp]
```

Das `--list`-Flag und `--schema` funktionieren **ohne** MCP-Extra (nur `--serve` benötigt es):

```bash
# Verfügbare Tools prüfen (ohne MCP-Extra)
drift mcp --list

# Parameter-Schema als JSON ausgeben
drift mcp --schema
```

### Server starten

```bash
# Server starten (für nicht-interaktive MCP-Clients)
drift mcp --serve

# Nur für manuelle Debug-Sessions auf interaktivem TTY:
drift mcp --serve --allow-tty
```

> **Hinweis:** `--serve` blockiert auf einem interaktiven TTY und gibt einen Fehler aus. Nur für automatisierte Clients (VS Code, Claude Desktop) ohne `--allow-tty` aufrufen.

### VS Code Konfiguration

Datei `.vscode/mcp.json` im Repository-Root:

```json
{
  "servers": {
    "drift": {
      "type": "stdio",
      "command": "drift",
      "args": ["mcp", "--serve"]
    }
  }
}
```

### Claude Desktop Konfiguration

In `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "drift": {
      "command": "drift",
      "args": ["mcp", "--serve"]
    }
  }
}
```

### Exponierte MCP-Tools

| Tool | Zweck |
|------|-------|
| `drift_scan` | Vollständige Repo-Analyse, Findings nach Relevanz sortiert |
| `drift_diff` | Änderungs-basierte Drift-Erkennung (gegen Ref oder Baseline) |
| `drift_fix_plan` | Priorisierte Reparaturaufgaben mit Constraints |
| `drift_explain` | Signal, Regel oder Finding-ID erklären |
| `drift_validate` | Konfiguration und Umgebung prüfen |
| `drift_brief` | Pre-Task-Briefing mit Guardrails (Pflicht vor Code-Generierung) |
| `drift_nudge` | ⚠️ Schnelles Richtungs-Feedback nach einzelnen Dateiänderungen |
| `drift_negative_context` | Anti-Pattern-Katalog für den aktuellen Scope |
| `drift_session_start` | Stateful Session starten (mit `autopilot=true` empfohlen) |
| `drift_session_status` | Aktuellen Session-Status abfragen |
| `drift_session_update` | Session-Scope ändern, Tasks abschließen |
| `drift_session_end` | Session beenden, Zusammenfassung abrufen |

### MCP-Workflow: Empfohlene Reihenfolge

```
drift_session_start(autopilot=true)
    → session_id + kompaktes Summary (drift_score/task_count/top_signals)
      + payload_refs fuer validate/brief/scan/fix_plan
    ↓
  [Für jede Aufgabe:]
  Datei bearbeiten
    → drift_nudge(session_id=..., changed_files="src/checkout/payment.py")
    → direction: improving/stable/degrading, safe_to_commit: true/false
    ↓
  drift_fix_plan(session_id=..., max_tasks=1)  → nächste Aufgabe
    ↓
drift_diff(session_id=..., uncommitted=true)   → finale Verifikation (nur einmal!)
    ↓
drift_session_end(session_id=...)              → Zusammenfassung + Cleanup
```

Optional fuer eingebettete Vollausgabe:

```
drift_session_start(autopilot=true, autopilot_payload="full")
```

**Warum `drift_session_start(autopilot=true)`?**  
Ein einziger Aufruf ersetzt `drift_validate` + `drift_brief` + `drift_scan` + `drift_fix_plan` — spart 4 Round-Trips.

**Warum `drift_nudge` statt `drift_diff` im Loop?**  
`drift_nudge` arbeitet auf einem Baseline-Snapshot und re-analysiert nur geänderte Dateien für dateibezogene Signale (~0.2 s). `drift_diff` läuft vollständig und sollte nur einmal am Ende aufgerufen werden.

---

## 7. Fertige Vorlagen

### CLAUDE.md / AGENTS.md — drift-Commands in Agent-Instruktionen

```markdown
# Drift Integration

## Before writing code

Run drift brief to get structural constraints for the current task:

```bash
drift brief --task "<your task description here>" --format markdown
```

Paste the output as context before starting. If `risk.level` is BLOCK,
ask the user for approval before continuing.

## During development

After each logical change unit, run:

```bash
drift diff --uncommitted --format json
```

If `accept_change` is false, review the findings before continuing.
Do not commit when `drift_detected: true` with severity HIGH or CRITICAL.

## After agent session

Run the full gate:

```bash
drift check --fail-on high
```

If it fails, run `drift fix-plan --max-tasks 3` and address the top tasks.
```

### GitHub Actions — `drift check` nach Agent-Commit

```yaml
name: Drift Check

on:
  push:
    branches: [main, "feat/**"]
  pull_request:

jobs:
  drift-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2        # HEAD~1 für diff benötigt

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install drift
        run: pip install drift-analyzer

      - name: Run drift check
        run: drift check --fail-on high --format json
        # Exit 1 wenn HIGH oder CRITICAL Findings im Diff entstehen
```

Für erweiterte CI-Nutzung mit SARIF-Output und GitHub Annotations — siehe [ci-integration.md](ci-integration.md).

---

## Nächste Schritte

- **[ci-integration.md](ci-integration.md)** — drift in CI-Pipelines integrieren: SARIF-Output, GitHub Annotations, Branch-Protection
- **[health-over-time.md](health-over-time.md)** — Langzeit-Trends verfolgen mit `drift trend`, `drift timeline` und `drift diff` über mehrere Sprints
