A modular validation framework for validating spec outputs at each checkpoint.
The validation system has been refactored into a clean, modular structure with clear separation of concerns:
validate_spec/
├── __init__.py # Package exports
├── models.py # ValidationResult dataclass
├── schemas.py # Schema definitions and constants
├── auto_fix.py # Auto-fix utilities
├── spec_validator.py # Main orchestrator
└── validators/ # Individual checkpoint validators
├── __init__.py
├── prereqs_validator.py
├── context_validator.py
├── spec_document_validator.py
└── implementation_plan_validator.py
- ValidationResult: Data class representing validation results with errors, warnings, and suggested fixes
- IMPLEMENTATION_PLAN_SCHEMA: Schema for implementation_plan.json
- CONTEXT_SCHEMA: Schema for context.json
- PROJECT_INDEX_SCHEMA: Schema for project_index.json
- SPEC_REQUIRED_SECTIONS: Required sections in spec.md
- SPEC_RECOMMENDED_SECTIONS: Recommended sections in spec.md
Each validator is responsible for a specific checkpoint:
Validates that required prerequisites exist:
- Spec directory exists
- project_index.json exists
Validates context.json structure:
- File exists and is valid JSON
- Contains required fields (task_description)
- Warns about missing recommended fields
Validates spec.md document:
- File exists
- Contains required sections (Overview, Workflow Type, Task Scope, Success Criteria)
- Warns about missing recommended sections
- Checks minimum content length
Validates implementation_plan.json:
- File exists and is valid JSON
- Contains required top-level fields
- Valid workflow_type
- Phases have correct structure
- Subtasks have correct structure
- No circular dependencies
Automated fixes for common issues:
- Adds missing required fields to implementation_plan.json
- Fixes missing phase/subtask IDs
- Sets default status values
Orchestrates all validation checkpoints:
- Initializes individual validators
- Provides unified interface
- Runs validation for specific checkpoints or all at once
from validate_spec import SpecValidator, auto_fix_plan
from pathlib import Path
# Create validator
spec_dir = Path("auto-claude/specs/001-feature")
validator = SpecValidator(spec_dir)
# Validate specific checkpoint
result = validator.validate_context()
if not result.valid:
print(f"Errors: {result.errors}")
print(f"Suggested fixes: {result.fixes}")
# Validate all checkpoints
results = validator.validate_all()
all_valid = all(r.valid for r in results)
# Auto-fix common issues
if auto_fix_plan(spec_dir):
print("Auto-fixed implementation plan")# Validate all checkpoints
python auto-claude/validate_spec.py --spec-dir auto-claude/specs/001-feature/ --checkpoint all
# Validate specific checkpoint
python auto-claude/validate_spec.py --spec-dir auto-claude/specs/001-feature/ --checkpoint context
# Auto-fix and validate
python auto-claude/validate_spec.py --spec-dir auto-claude/specs/001-feature/ --auto-fix --checkpoint plan
# JSON output
python auto-claude/validate_spec.py --spec-dir auto-claude/specs/001-feature/ --checkpoint all --jsonOther modules should import from the package:
# Correct
from validate_spec import SpecValidator, ValidationResult, auto_fix_plan
from validate_spec.spec_validator import SpecValidator
# Avoid (internal implementation details)
from validate_spec.validators.context_validator import ContextValidator- Single 633-line file
- All logic mixed together
- Hard to maintain and extend
- Difficult to test individual components
- Main entry point: 109 lines (83% reduction)
- Clear separation of concerns
- Each validator is independent and testable
- Easy to add new validators
- Schemas centralized and reusable
- Better code organization and discoverability
Each validator can be tested independently:
from validate_spec.validators import ContextValidator
from pathlib import Path
validator = ContextValidator(Path("specs/001-feature"))
result = validator.validate()
assert result.validTo add a new checkpoint validator:
- Create a new validator in
validators/:
# validators/new_checkpoint_validator.py
from pathlib import Path
from ..models import ValidationResult
class NewCheckpointValidator:
def __init__(self, spec_dir: Path):
self.spec_dir = Path(spec_dir)
def validate(self) -> ValidationResult:
# Validation logic here
return ValidationResult(True, "new_checkpoint", [], [], [])- Add to
validators/__init__.py:
from .new_checkpoint_validator import NewCheckpointValidator
__all__ = [..., "NewCheckpointValidator"]- Add method to
SpecValidator:
def validate_new_checkpoint(self) -> ValidationResult:
validator = NewCheckpointValidator(self.spec_dir)
return validator.validate()- Update CLI in main
validate_spec.pyif needed