feat: Integrate Requirements Engineering Agent and fix Issue #59 test failures
## 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>
This commit is contained in:
375
docs/integration/requirements_engineering_integration.md
Normal file
375
docs/integration/requirements_engineering_integration.md
Normal file
@@ -0,0 +1,375 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user