## Major Integration - ✅ Integrated Requirements Engineering Agent into development workflow - ✅ Enhanced Makefile with requirements validation targets - ✅ Added pre-commit validation with mock compatibility checking - ✅ Enhanced TDD workflow to include foundation analysis ## Test Fixes - ✅ Fixed GiteaPlugin missing _add_comment_async method - ✅ Fixed LocalPlugin config.yml file not found errors in tests - ✅ Enhanced mock objects in CLI tests with proper domain model attributes - ✅ All Issue #59 tests now passing (38/38 tests pass) ## New Capabilities - `make validate-requirements` - Foundation analysis before development - `make check-interface-compatibility INTERFACE=Name` - Interface compatibility checking - `make generate-dev-checklist FEATURE='Name'` - Development checklist generation - `make validate-mocks` - Mock object compatibility validation - `make pre-commit-validate` - Complete pre-commit validation workflow ## Problem Prevention This integration prevents the exact interface compatibility issues and mock object mismatches that caused hours of debugging in Issue #59. The Requirements Engineering Agent provides proactive foundation analysis and catches problems before they occur. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
375 lines
12 KiB
Markdown
375 lines
12 KiB
Markdown
# 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. |