| name | incremental-validation |
| description | Test and validate after each component/phase instead of waiting until the end. Catches bugs early when they're cheap to fix, prevents cascade failures. Use when building complex systems with multiple components where components depend on each other. |
Incremental Validation
Test and validate after each component/phase instead of waiting until the end. Catches bugs early when they're cheap to fix, prevents cascade failures.
When to use
- Building complex systems with multiple components
- Performance-critical applications where late optimization is expensive
- Projects with >1 week duration
- When components depend on each other (Phase N uses Phase N-1)
- Collaborative projects where others build on your work
When NOT to use
- Throwaway prototypes
- Simple scripts with no dependencies
- When requirements will change drastically
- Pure research/exploration (validation would slow discovery)
Instructions
Step 1: Define Validation Levels
For each component/phase, specify what "done" means:
## Phase N: [Component Name]
### Validation Checklist:
**Correctness:**
- [ ] Unit tests pass ([X] tests)
- [ ] Edge cases covered (empty input, max size, etc.)
- [ ] Error handling verified
**Performance:**
- [ ] Latency target met: <[X] ns/μs/ms
- [ ] Throughput target met: >[Y] ops/sec
- [ ] Memory usage: <[Z] KB/MB
**Integration:**
- [ ] Integrates with Phase [N-1] output
- [ ] Provides correct input for Phase [N+1]
- [ ] No breaking API changes from plan
**Code Quality:**
- [ ] No compiler warnings
- [ ] Passes linter/formatter
- [ ] Documentation updated
Step 2: Validate Immediately After Implementation
Strict rule: Don't start Phase N+1 until Phase N validation passes.
Workflow:
vim src/module.rs
cargo test --lib module::tests
cargo bench --bench module_bench
cargo clippy
git commit -m "Phase 1: Module complete and validated"
Step 3: Create Fast Feedback Loop
Optimize for speed of validation:
Fast validation (seconds):
cargo test --lib module::tests
cargo test test_name
cargo check
Medium validation (minutes):
cargo test
cargo bench --bench module -- --quick
Slow validation (hours - run overnight/CI):
cargo test --release -- --ignored --nocapture
cargo bench
cargo test --test '*'
Step 4: Fix Issues Before Proceeding
If validation fails:
- Stop - Don't continue to next phase
- Diagnose - Understand root cause
- Fix - Correct the issue
- Re-validate - Run validation again
- Document - Note what was fixed and why
Anti-pattern:
Phase 1 fails validation → "I'll fix it later"
Phase 2 builds on broken Phase 1
Phase 3 builds on broken Phase 2
[Weeks later: Massive refactoring needed]
Correct pattern:
Phase 1 fails validation → Fix immediately
Phase 1 passes → Proceed to Phase 2
Phase 2 uses validated Phase 1
Phase 3 uses validated Phase 2
[Result: Solid foundation, no surprises]
Step 5: Document Validation Results
After each phase, record:
## Phase N Validation Results
**Tests:** ✅ 15/15 passing
**Performance:** ✅ 32ns mean (target: <50ns)
**Issues found:** 1 (Transaction size alignment)
**Issues fixed:** Array padding added, tests now pass
**Time to validate:** 5 minutes
**Time to fix issues:** 15 minutes
**Lessons learned:**
- Rust's default struct layout != expected
- Added compile-time assertion to catch early
Best Practices
✅ Do
- Test immediately - Within seconds of writing code
- Fix before proceeding - No moving on with broken code
- Automate validation - Scripts, make targets, CI
- Document issues - What broke, why, how fixed
- Celebrate green tests - Positive reinforcement
- Use watch mode -
cargo watch -x test for instant feedback
❌ Don't
- Don't defer testing - "I'll test it all at the end"
- Don't skip on time pressure - Testing saves time overall
- Don't ignore flaky tests - Fix or remove them
- Don't validate too broadly - Test specific component, not everything
- Don't over-validate - Match validation depth to component risk
Validation Strategy by Component Type
Core Data Structures
Validation:
- Size/alignment assertions (compile-time)
- Serialization round-trip
- Edge cases (empty, max size)
- Memory leaks (valgrind/asan)
Priority: HIGH (everything builds on this)
Lock-Free Algorithms
Validation:
- Unit tests (basic correctness)
- Loom tests (concurrency model checking)
- Property tests (invariants)
- Stress tests (1M+ operations)
Priority: CRITICAL (subtle bugs hard to find later)
Business Logic
Validation:
- Unit tests (all branches)
- Integration tests (with dependencies)
- Error cases
Priority: MEDIUM (bugs obvious in manual testing)
Performance-Critical Code
Validation:
- Benchmarks (P50, P99 latency)
- Profiling (flamegraph)
- Cache miss rate (perf stat)
Priority: HIGH (late optimization expensive)
Common Pitfalls
Pitfall 1: "I'll test it all at the end"
Problem:
- Build 10 components
- Test at end
- Find bug in Component 1
- All 9 other components built on broken foundation
- Result: Days/weeks of refactoring
Solution: Test Component 1 immediately, validate before building Component 2
Pitfall 2: Validation too slow
Problem:
- Full test suite takes 10 minutes
- Run after every small change
- Result: 80% of time waiting for tests
Solution:
cargo test --lib module::specific_test
cargo test --lib
cargo test
Pitfall 3: Ignoring performance until end
Problem:
- Build entire system
- Test functionality - all passes ✅
- Measure performance - 10x too slow ❌
- Result: No idea where bottleneck is, massive profiling effort
Solution: Benchmark each component as built:
Phase 2: Ring Buffer
- Target: <50ns per push/pop
- Measured: 4ns ✅
- Proceed to Phase 3
Phase 3: Order Book
- Target: <200ns per update
- Measured: 3ns ✅
- Proceed to Phase 4
Related skills
- plan-first-development - Define what to validate per phase
- parallel-subagent-orchestration - Run validations in parallel
- multi-level-testing - Different test types for validation
Skill Version: 1.0
Last Updated: 2025-01-06