# Spec-Driven Development (SDD) Support

This document describes how to use the Spec-Driven Development features in abi-spec.

## Overview

The SDD module provides living spec management with drift detection between specifications and implementation code. The core principle is: **"When a bug is found, fix the spec first, then regenerate code."**

## Features

- **Spec Version Tracking**: Track specification versions with SHA-256 content hashes
- **Drift Detection**: Detect when specs and code are out of sync
- **Time-based Analysis**: Compare file modification timestamps
- **Hash-based Verification**: Compare content hashes to detect spec changes
- **Multi-file Support**: Track multiple code files or entire directories

## CLI Usage

### Track a Specification

Register a spec and link it to code files:

```bash
abi-spec drift track --spec specs/feature.md --code src/feature.py src/tests/test_feature.py
```

Or track against a directory:

```bash
abi-spec drift track --spec specs/feature.md --code src/feature/
```

Output:
```
Spec Tracked:
  Spec ID: specs/feature.md
  Version: 2026-03-05T12:34:56.789012+00:00
  Content Hash: a1b2c3d4e5f6...
  Updated At: 2026-03-05T12:34:56.789012+00:00
  Linked Code Paths: src/feature.py, src/tests/test_feature.py
```

### Check for Drift

Detect drift between a spec and its code:

```bash
abi-spec drift check --spec specs/feature.md --code src/feature/
```

#### No Drift (Exit Code 0)
```
Drift Detection Results:
  Spec: specs/feature.md
  Code: src/feature/
  Has Drift: False
  Spec Changed Since Code: False
  Code Changed Since Spec: False
  Details: Spec and code are in sync
```

#### Spec Updated (Exit Code 1)
```
Drift Detection Results:
  Spec: specs/feature.md
  Code: src/feature/
  Has Drift: True
  Spec Changed Since Code: True
  Code Changed Since Spec: False
  Details: Spec updated — code may need regeneration (spec is newer than code)
```

#### Code Updated Without Spec (Exit Code 1)
```
Drift Detection Results:
  Spec: specs/feature.md
  Code: src/feature/
  Has Drift: True
  Spec Changed Since Code: False
  Code Changed Since Spec: True
  Details: Code updated without spec update — drift detected (code is newer than spec)
```

#### Both Changed (Exit Code 1)
```
Drift Detection Results:
  Spec: specs/feature.md
  Code: src/feature/
  Has Drift: True
  Spec Changed Since Code: True
  Code Changed Since Spec: True
  Details: Both spec and code changed independently — manual reconciliation needed
```

## Programmatic Usage

### Python API

```python
from pathlib import Path
from abi_spec.sdd import SpecTracker

# Initialize tracker
tracker = SpecTracker()

# Track a spec
spec_version = tracker.track(
    spec_path="specs/feature.md",
    code_paths=["src/feature.py", "src/tests/test_feature.py"]
)

print(f"Tracked spec: {spec_version.spec_id}")
print(f"Content hash: {spec_version.content_hash}")

# Check for drift
result = tracker.detect_drift(
    spec_path="specs/feature.md",
    code_paths=["src/feature/"]
)

if result.has_drift:
    print(f"Drift detected: {result.details}")
    if result.spec_changed_since_code:
        print("Action: Regenerate code from spec")
    elif result.code_changed_since_spec:
        print("Action: Update spec to match code changes")
else:
    print("Spec and code are in sync")
```

## Drift Detection Logic

The drift detection uses both **time-based** and **hash-based** analysis:

1. **Content Hash Tracking**: SHA-256 hash of spec content is stored when tracking
2. **Modification Times**: File mtimes are compared
3. **Change Detection**:
   - Spec changed: Current hash differs from tracked hash
   - Code changed: Code mtime is newer than tracked spec timestamp
   - Both changed: Both conditions are true

## Tracking Data

Tracking data is stored in `.abi/spec_tracking.json`:

```json
{
  "specs/feature.md": {
    "spec_id": "specs/feature.md",
    "version": "2026-03-05T12:34:56.789012+00:00",
    "content_hash": "a1b2c3d4e5f6789...",
    "updated_at": "2026-03-05T12:34:56.789012+00:00",
    "linked_code_paths": [
      "src/feature.py",
      "src/tests/test_feature.py"
    ]
  }
}
```

## Workflow Example

### Spec-First Development

1. **Write the spec**:
   ```bash
   # Edit specs/auth.md
   ```

2. **Track it**:
   ```bash
   abi-spec drift track --spec specs/auth.md --code src/auth/
   ```

3. **Generate/write code**:
   ```bash
   # Implement the feature in src/auth/
   ```

4. **Check drift**:
   ```bash
   abi-spec drift check --spec specs/auth.md --code src/auth/
   # Expected: "Spec updated — code may need regeneration"
   ```

5. **Re-track after code generation**:
   ```bash
   abi-spec drift track --spec specs/auth.md --code src/auth/
   ```

### Bug Fix Workflow

1. **Bug discovered in code**

2. **Fix the spec first**:
   ```bash
   # Update specs/auth.md to reflect correct behavior
   ```

3. **Check drift**:
   ```bash
   abi-spec drift check --spec specs/auth.md --code src/auth/
   # Shows: "Spec updated — code may need regeneration"
   ```

4. **Regenerate/fix code**:
   ```bash
   # Update src/auth/ to match spec
   ```

5. **Track the fix**:
   ```bash
   abi-spec drift track --spec specs/auth.md --code src/auth/
   ```

## CI/CD Integration

### Pre-commit Hook

```bash
#!/bin/bash
# .git/hooks/pre-commit

# Check all specs for drift
for spec in specs/*.md; do
  abi-spec drift check --spec "$spec" --code src/
  if [ $? -eq 1 ]; then
    echo "Drift detected in $spec"
    echo "Fix the spec first, then regenerate code"
    exit 1
  fi
done
```

### GitHub Actions

```yaml
name: Check Spec Drift
on: [push, pull_request]

jobs:
  drift-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.11'
      - run: pip install -e .
      - run: |
          abi-spec drift check --spec specs/feature.md --code src/
```

## Best Practices

1. **Track Early**: Track specs as soon as you start implementing
2. **Check Often**: Run drift checks before commits
3. **Spec First**: Always update specs before code when fixing bugs
4. **Use Directories**: Track entire code directories for comprehensive coverage
5. **Automate**: Integrate drift checks into CI/CD pipelines
6. **Version Control**: Commit `.abi/spec_tracking.json` to track history

## Data Classes

### SpecVersion

```python
@dataclass
class SpecVersion:
    spec_id: str                    # Path to spec file
    version: str                    # ISO 8601 timestamp
    content_hash: str               # SHA-256 hex digest
    updated_at: str                 # ISO 8601 timestamp
    linked_code_paths: list[str]    # Related code paths
```

### DriftResult

```python
@dataclass
class DriftResult:
    has_drift: bool                  # True if drift detected
    spec_changed_since_code: bool    # Spec newer than code
    code_changed_since_spec: bool    # Code newer than spec
    details: str                     # Human-readable explanation
```

## Testing

The SDD module includes comprehensive tests covering:

- Spec tracking with hash computation
- Drift detection for all scenarios
- Multiple file and directory support
- Content hash verification
- Error handling for missing files

Run tests:

```bash
pytest tests/test_spec_tracker.py -v
```

All 14 spec tracker tests pass successfully.
