# Requirements Engineering Agent Integration Guide

## Quick Start

Add these commands to your development workflow to prevent interface compatibility issues and mock object mismatches:

```bash
# Before starting any new feature
make validate-requirements

# When planning interface changes
python tools/requirements_engineering_toolkit.py plan-interface --interface YourInterface

# Before writing tests
python tools/requirements_engineering_toolkit.py checklist --feature "Your Feature"

# When creating mocks
python examples/issue_59_prevention_demo.py  # See correct patterns
```

## Integration with Existing Workflow

### 1. Enhanced Makefile Targets

Add these targets to your `Makefile`:

```makefile
# Requirements Engineering Integration
validate-requirements:
	@echo "🔍 Validating project requirements and foundations..."
	python tools/requirements_engineering_toolkit.py analyze

check-interface-compatibility:
	@echo "🔌 Checking interface compatibility..."
	python tools/requirements_engineering_toolkit.py plan-interface --interface $(INTERFACE)

generate-dev-checklist:
	@echo "📋 Generating development checklist..."
	python tools/requirements_engineering_toolkit.py checklist --feature "$(FEATURE)"

# Enhanced TDD workflow
tdd-start: validate-requirements
	@echo "🚀 Starting TDD workflow with requirements validation..."
	python tddai_cli.py tdd-start $(NUM)

# Pre-commit validation
pre-commit-validate:
	make validate-requirements
	python -m pytest tests/test_mock_compatibility.py -xvs
```

### 2. Enhanced TDD8 Workflow

The TDD8 workflow is enhanced with requirements engineering checkpoints:

```
1. ANALYZE     - Analyze existing domain models and interfaces
2. ISSUE       - Understand requirements in architectural context
3. TEST        - Write tests that match actual interfaces
4. RED         - Verify tests fail for the right reasons
5. GREEN       - Implement with interface compatibility
6. REFACTOR    - Maintain interface contracts
7. DOCUMENT    - Update interface documentation
8. PUBLISH     - Commit with interface change documentation
```

### 3. TodoWrite Integration

Enhanced TodoWrite with validation checkpoints:

```python
# Example enhanced todo list
todos = [
    {
        "content": "Analyze existing domain models",
        "status": "pending",
        "activeForm": "Analyzing existing domain models",
        "checkpoint": "foundation_analysis"
    },
    {
        "content": "Define interface contracts",
        "status": "pending",
        "activeForm": "Defining interface contracts",
        "checkpoint": "interface_definition"
    },
    {
        "content": "Create spec-compliant mocks",
        "status": "pending",
        "activeForm": "Creating spec-compliant mocks",
        "checkpoint": "mock_validation"
    }
]
```

## Pre-Development Checklist

Before starting any new feature development:

### Foundation Analysis
- [ ] Run `make validate-requirements`
- [ ] Review existing domain models in target area
- [ ] Map current interface contracts
- [ ] Understand dependency relationships

### Interface Planning
- [ ] Define new interface contracts
- [ ] Check compatibility with existing interfaces
- [ ] Plan evolution strategy for existing interfaces
- [ ] Document interface specifications

### Test Strategy
- [ ] Plan test architecture that matches application architecture
- [ ] Identify domain models that will need mocking
- [ ] Plan integration test points
- [ ] Define validation checkpoints

## Mock Object Guidelines

### ✅ Correct Mock Patterns

```python
from unittest.mock import Mock
from domain.issues.models import Issue, IssueState, Label
from datetime import datetime, timezone

# CORRECT: Use spec= parameter
mock_issue = Mock(spec=Issue)
mock_issue.number = 59
mock_issue.title = "Test Issue"
mock_issue.state = IssueState.OPEN  # Use actual enum
mock_issue.labels = []
mock_issue.created_at = datetime.now(timezone.utc)
mock_issue.updated_at = datetime.now(timezone.utc)
```

### ❌ Incorrect Mock Patterns

```python
# WRONG: No spec parameter
mock_issue = Mock()
mock_issue.number = 59
mock_issue.state = "open"  # String instead of enum!
# Missing required attributes

# WRONG: Assumption-based attributes
mock_issue.some_attribute_that_doesnt_exist = "value"
```

### Mock Validation Script

Create `tests/test_mock_compatibility.py`:

```python
import pytest
from unittest.mock import Mock
from domain.issues.models import Issue, IssueState
from datetime import datetime, timezone


class TestMockCompatibility:
    """Validate that test mocks match actual domain models."""

    def test_issue_mock_has_all_required_attributes(self):
        """Test that Issue mocks include all required attributes."""
        # Create a real Issue to get expected attributes
        real_issue = Issue(
            number=1,
            title="Real Issue",
            state=IssueState.OPEN,
            labels=[],
            created_at=datetime.now(timezone.utc),
            updated_at=datetime.now(timezone.utc)
        )

        # Create mock with spec
        mock_issue = Mock(spec=Issue)
        mock_issue.number = 1
        mock_issue.title = "Mock Issue"
        mock_issue.state = IssueState.OPEN
        mock_issue.labels = []
        mock_issue.created_at = datetime.now(timezone.utc)
        mock_issue.updated_at = datetime.now(timezone.utc)

        # Verify critical attributes match
        real_attrs = {attr for attr in dir(real_issue) if not attr.startswith('_')}
        mock_attrs = {attr for attr in dir(mock_issue) if not attr.startswith('_')}

        missing_attrs = real_attrs - mock_attrs
        critical_missing = [attr for attr in missing_attrs
                          if not callable(getattr(real_issue, attr))]

        assert not critical_missing, f"Mock missing critical attributes: {critical_missing}"

    def test_issue_mock_uses_correct_types(self):
        """Test that Issue mocks use correct types."""
        mock_issue = Mock(spec=Issue)
        mock_issue.state = IssueState.OPEN  # Should be enum, not string

        assert isinstance(mock_issue.state, IssueState), "State should be IssueState enum"
```

## Interface Evolution Guidelines

### Planning Interface Changes

1. **Analyze Current Usage**:
   ```bash
   # Find all usages of the interface
   grep -r "YourInterface" . --include="*.py"
   ```

2. **Plan Backward Compatibility**:
   ```python
   # Example: Adding new method while maintaining compatibility
   class YourInterface(ABC):
       # Existing methods (don't change signatures)
       @abstractmethod
       def existing_method(self, param: str) -> str:
           pass

       # New methods (with default implementations if possible)
       def new_method(self, param: str) -> Optional[str]:
           """New method with default implementation for compatibility."""
           return None  # Safe default
   ```

3. **Create Migration Plan**:
   - Phase 1: Add new interface methods with defaults
   - Phase 2: Update implementations incrementally
   - Phase 3: Add deprecation warnings to old methods
   - Phase 4: Remove deprecated methods after transition period

### Interface Compatibility Checking

```bash
# Check if new interface is compatible with existing implementations
python tools/requirements_engineering_toolkit.py plan-interface \
    --interface NewInterface \
    --existing-implementations ExistingRepo,AnotherRepo
```

## Common Patterns and Solutions

### Pattern 1: Plugin Interface Design

```python
# Base interface that matches existing repository patterns
class IssueBackend(ABC):
    def __init__(self, config: Dict[str, Any]):
        self.config = config

    @abstractmethod
    def list_issues(self, state: Optional[str] = None) -> List[Issue]:
        pass

    @abstractmethod
    def get_issue(self, issue_id: str) -> Issue:
        pass

# Implementation that adapts async repository
class GiteaPlugin(IssueBackend):
    def __init__(self, config: Dict[str, Any]):
        super().__init__(config)
        self.repository = GiteaIssueRepository(self._create_connection_manager())

    def list_issues(self, state: Optional[str] = None) -> List[Issue]:
        # Adapter pattern: async -> sync
        return asyncio.run(self.repository.get_issues(state=state))
```

### Pattern 2: Domain Model Extension

```python
# Extending domain model while maintaining compatibility
@dataclass
class Issue:
    # Existing attributes (don't change order or remove)
    number: int
    title: str
    state: IssueState
    labels: List[Label]
    created_at: datetime
    updated_at: datetime

    # New attributes with defaults for backward compatibility
    body: str = ""
    assignees: List[str] = field(default_factory=list)
    html_url: str = ""
```

### Pattern 3: Test Architecture Alignment

```python
# Test structure that matches application architecture
class TestIssuePluginManager:
    def setup_method(self):
        # Use real domain models for mocks
        self.mock_issue = Mock(spec=Issue)
        self.mock_backend = Mock(spec=IssueBackend)

        # Configure mocks with realistic data
        self._configure_realistic_mocks()

    def _configure_realistic_mocks(self):
        """Configure mocks to match real object behavior."""
        self.mock_issue.number = 59
        self.mock_issue.state = IssueState.OPEN
        self.mock_issue.created_at = datetime.now(timezone.utc)
        # ... all required attributes
```

## Error Prevention Checklist

### Before Writing Tests
- [ ] Analyze target domain models with `python tools/requirements_engineering_toolkit.py analyze`
- [ ] Understand existing interface contracts
- [ ] Plan mock strategy using `Mock(spec=ActualClass)`
- [ ] Verify enum usage instead of strings

### Before Implementation
- [ ] Check interface compatibility
- [ ] Plan async/sync adapter layers if needed
- [ ] Verify backward compatibility strategy
- [ ] Document interface contracts

### Before Committing
- [ ] Run mock compatibility tests: `pytest tests/test_mock_compatibility.py`
- [ ] Validate interface evolution plan
- [ ] Check that no existing tests are broken
- [ ] Update documentation for interface changes

## Troubleshooting Common Issues

### Issue: Mock doesn't match domain model
**Solution**: Use `Mock(spec=ActualClass)` and include all required attributes

### Issue: Enum vs string mismatch
**Solution**: Import and use actual enums: `from domain.issues.models import IssueState`

### Issue: Async/sync interface mismatch
**Solution**: Add adapter layer to convert between async and sync interfaces

### Issue: Missing attributes in mock
**Solution**: Run domain analysis to see all required attributes, ensure mock includes them

### Issue: Interface breaking changes
**Solution**: Use evolution plan with backward compatibility and deprecation period

## Integration with Existing Tools

### CLI Commands
```bash
# Add to existing CLI
markitect validate-requirements    # Run foundation analysis
markitect check-interfaces        # Verify interface compatibility
markitect plan-migration          # Plan interface evolution
markitect validate-mocks          # Check mock compatibility
```

### IDE Integration
- Add pre-commit hooks for requirements validation
- Configure IDE to run mock compatibility tests
- Set up interface change detection

### CI/CD Integration
```yaml
# Add to GitHub Actions / CI pipeline
- name: Validate Requirements
  run: make validate-requirements

- name: Check Mock Compatibility
  run: python -m pytest tests/test_mock_compatibility.py
```

This integration ensures that the Requirements Engineering Agent becomes a natural part of the development workflow, preventing the interface compatibility issues encountered in Issue #59 and improving overall code quality and development efficiency.