Validation-Driven Development: When Tests Enable Bold Moves
"Safe as houses"

Validation-Driven Development: When Tests Enable Bold Moves

Methodology Series, November 1–4, 2025

Tuesday morning, 10:11 AM. Programmer agent reports: Phase 2 complete. Database migration ready. 66 tests passing.

I ask: “What would review consist of before authorizing migration?”

Lead Developer analyzes. Conclusion: Manual SQL review redundant given 66 passing tests.

The reasoning: Tests validate the code comprehensively. Migration is SQL transformation. Tests prove SQL is correct — relationships work, queries succeed, data migrates cleanly. Manual review would check what tests already verified.

Decision: Backup database + execute migration.

Result: Migration successful. Zero issues. All 66 tests still passing post-migration.

That’s validation-driven development. Not “write tests to prove it works later.” But “write tests so comprehensive they enable confident decisions now.”

The tests weren’t afterthought. They weren’t checkbox. They were confidence mechanism that turned risky database migration into low-risk operation requiring only backup as prudent protection.

The traditional testing mindset

Most teams treat tests as verification:

Traditional flow:

  1. Write code
  2. Manually test it works
  3. Write tests to prove it
  4. Ship it
  5. Hope tests catch future regressions

Tests serve as: Post-hoc validation. Regression prevention. CI/CD gates.

The mindset: “Tests verify what we already know works.”

The limitation: Tests don’t change how you develop. Just confirm development succeeded.

The validation-driven mindset

Validation-driven development inverts this:

Validation-driven flow:

  1. Write comprehensive tests first (or very early)
  2. Implement until tests pass
  3. Tests passing = feature complete
  4. Modify boldly because tests protect
  5. Deploy confidently because tests validate

Tests serve as: Confidence mechanism. Design tool. Safety net enabling speed.

The mindset: “Tests enable what we want to do.”

The transformation: Tests change how you develop. Enable bold moves. Allow confident refactoring. Make “impossible” changes safe.

Moving fast safely

Saturday, November 1st. Historic sprint. 9,292 lines of code in 12.75 hours. Four P0 blockers resolved.

The risk: Making 9,292 lines of changes in one day. High likelihood of breaking something. Introducing regressions. Creating subtle bugs.

The reality: 100% test pass rate throughout entire sprint. Zero regressions introduced.

How was this possible? Comprehensive test coverage.

The timeline

8:00 AM — Starting state:

  • Comprehensive test suite exists
  • All tests passing
  • Baseline established

8:30 AM — DocumentService wiring:

  • Make changes
  • Run tests
  • Tests pass → changes are safe
  • Continue confidently

10:00 AM — Auth middleware mounting:

  • Make changes
  • Run tests
  • Tests pass → integration works
  • Continue confidently

12:00 PM — File upload fixes:

  • Make changes
  • Run tests
  • Tests pass → nothing broken
  • Continue confidently

2:30 PM — Additional verification:

  • Make changes
  • Run tests
  • Tests pass → ready to ship
  • Deploy confidently

Pattern: Make changes → Validate → Move forward confidently.

Not “make all changes → hope nothing broke → debug for hours.”

But “make changes incrementally → validate continuously → know status always.”

The tests enabled speed. Without comprehensive tests, Saturday would be:

  • Make changes cautiously
  • Manually test everything
  • Worry about regressions
  • Debug mysterious breaks
  • Second-guess deployments

Estimated time without tests: 20+ hours (slower work + debugging time)

Actual time with tests: 12.75 hours (fast work + zero debugging)

Tests saved: 7+ hours on one day. And prevented post-deployment issues that would cost days.

Bold architectural changes

Tuesday, November 4th. Foundation work. Polymorphic inheritance refactoring. Database migration. Major architectural change.

The risk: Changing core domain models. Refactoring repositories. Migrating data. High complexity change.

The approach: Build comprehensive test suite first. 66 tests covering all integration points.

The progression

6:15 AM — Task 5 complete: TodoRepository updated (17 methods changed)

  • Validation: Run tests
  • Result: All pass
  • Confidence: Repository refactoring is safe

6:19 AM — Task 6 complete: Handlers and services updated (field references changed)

  • Validation: Run tests
  • Result: All pass
  • Confidence: Integration layer works correctly

6:29 AM — Task 7 complete: Bug fixes (2 critical bugs found by tests)

  • Discovery: Tests caught relationship/FK issues
  • Fix: Corrected before migration
  • Result: All 66 tests passing

10:11 AM — Migration ready:

  • Evidence: 66 comprehensive tests passing
  • Decision: Manual review redundant
  • Action: Execute migration
  • Result: Success, zero issues

Pattern: Tests caught bugs before deployment. Tests validated correctness. Tests enabled confident migration.

Without those 66 tests:

  • Manual testing each integration point (hours)
  • Uncertainty about edge cases (risk)
  • Manual SQL review (time + potential for human error)
  • Post-migration debugging (if issues missed)

With 66 tests:

  • Automated validation (minutes)
  • Confidence in edge cases (tests cover them)
  • SQL review unnecessary (tests prove correctness)
  • Post-migration success (issues caught pre-migration)

The tests transformed risky change into confident deployment.

The foundation phase efficiency

Tuesday’s foundation work also demonstrated how tests enable speed:

Phase 3 (Universal Services):

  • Estimated: 2–4 hours
  • Actual: 57 minutes
  • Speedup: 2.4x faster

Phase 4 (Integration):

  • Estimated: 1 hour
  • Actual: 15 minutes
  • Speedup: 4x faster

Phase 5 (Validation):

  • Estimated: 1–2 hours
  • Actual: 22 minutes
  • Speedup: 3–5x faster

Why so fast? Quality of foundation + comprehensive tests.

Each phase:

  1. Make changes
  2. Run tests
  3. Tests pass → phase complete
  4. Move to next phase

No manual validation needed. No uncertainty. No “did I break something?” worry. Tests provide instant feedback.

Conservative estimates assumed manual testing time, uncertainty, back-and-forth. Reality with tests: Instant validation, immediate confidence, rapid progression.

Tests enabled 3–5x speed improvement on foundation work. Not just “verification” but “acceleration.”

What makes tests confidence-enabling

Not all tests enable confidence. Effective validation requires:

Characteristic 1: Comprehensive coverage

Weak: Tests cover happy path only

  • Feature works when everything is correct
  • Breaks when edge cases occur
  • False confidence

Strong: Tests cover edge cases, error paths, boundaries

  • Feature works in all scenarios
  • Confidence applies broadly
  • True confidence

Example: DocumentService tests

  • ✅ Empty files handled
  • ✅ Large files handled
  • ✅ Corrupt files handled
  • ✅ Processing failures handled
  • Result: Confidence in all scenarios

Characteristic 2: Integration-level validation

Weak: Unit tests only

  • Each component works alone
  • Components might not integrate correctly
  • False confidence in system behavior

Strong: Integration tests validate component interaction

  • Components work together
  • System behavior validated
  • True confidence in deployment

Example: Tuesday’s 66 tests

  • Not just “TodoRepository works”
  • But “TodoRepository + Service + Handler + Database work together”
  • Integration-level confidence

Characteristic 3: Fast feedback

Weak: Tests take 30 minutes to run

  • Feedback delayed
  • Context switching required
  • Developers skip running tests

Strong: Tests take 1–3 minutes to run

  • Feedback immediate
  • Stay in flow
  • Developers run tests constantly

Example: Saturday’s sprint

  • Tests run in 2–3 minutes
  • After each change: instant validation
  • Continuous confidence

Characteristic 4: Clear failure messages

Weak: Test fails with “AssertionError”

  • Unknown what broke
  • Debugging required
  • Slow fix cycle

Strong: Test fails with “Expected user authentication, got None”

  • Immediately clear what broke
  • Direct to problem
  • Fast fix cycle

Example: Tuesday’s bug discovery

  • Tests identified relationship/FK issues specifically
  • Fixed immediately based on error messages
  • No debugging session needed

Characteristic 5: Maintained diligently

Weak: Tests flaky, sometimes fail randomly

  • Can’t trust test results
  • “Rerun until green” culture
  • False confidence erodes

Strong: Tests reliable, failures always meaningful

  • Trust test results completely
  • Failures indicate real problems
  • Confidence maintained

Example: Project-wide discipline

  • Flaky tests fixed immediately
  • No “known failures” ignored
  • 100% pass = genuinely safe

The psychological shift

Validation-driven development changes how you feel about changes:

Without comprehensive tests:

Making changes feels: Risky, scary, uncertain

Thought process:

  • “Will this break something?”
  • “Should I test everything manually?”
  • “What if there are edge cases?”
  • “Should I get someone to review?”

Result: Move slowly, cautiously, conservatively

With comprehensive tests:

Making changes feels: Safe, confident, empowering

Thought process:

  • “Tests will catch problems”
  • “Validation is automatic”
  • “Edge cases are covered”
  • “Tests are the review”

Result: Move quickly, boldly, decisively

The transformation: From fear-based caution to confidence-based speed.

Not recklessness. But informed boldness. Tests enable moves that would feel too risky without validation.

The ROI on test investment

Let’s calculate test investment returns:

Saturday’s sprint

Test investment: (Previously built, maintained over months) Value delivered:

  • 9,292 lines changed safely (no regressions)
  • 7+ hours saved vs manual testing
  • Zero post-deployment issues
  • Confident deployment to alpha

One-day ROI: 7+ hours saved from automation alone

Tuesday’s migration

Test investment: 66 comprehensive integration tests Time to write: Embedded in development (test-driven) Value delivered:

  • Migration executed confidently
  • Manual review skipped (saved 2–3 hours)
  • Zero migration issues
  • Bugs caught pre-deployment

One-day ROI: 2–3+ hours saved from skipped manual work

Foundation phases

Test investment: Comprehensive test suite Value delivered:

  • 3–5x speedup on implementation
  • Phases: 2–4h estimate → 57min actual
  • Immediate validation, no manual testing
  • Confident progression

Multi-day ROI: 6–8 hours saved from accelerated development

The compound returns

Tests don’t just save time once. They save time repeatedly:

  • Every modification validated instantly
  • Every refactoring made safe
  • Every deployment made confident
  • Every bug caught early (cheap) vs late (expensive)

Initial investment: 2x time to write tests during development

Long-term returns:

  • 5–10x time savings from automation
  • ∞ value from bugs caught early
  • Immeasurable value from confident changes
  • Massive value from enabled refactoring

ROI: Conservatively 3:1. Realistically 10:1+. Over project lifetime possibly 50:1+.

When validation-driven development shines

The approach is most valuable for:

Scenario 1: Complex integration

Example: Multiple services, databases, external APIs interacting

Challenge: Manual testing all integration points is time-consuming

Solution: Comprehensive integration tests validate interactions 

Benefit: Confident changes to any component

Scenario 2: Frequent refactoring

Example: Improving architecture, extracting patterns, cleaning debt

Challenge: Refactoring without tests is terrifying 

Solution: Tests enable bold refactoring 

Benefit: Continuous improvement without fear

Scenario 3: Multiple contributors

Example: Team of developers or AI agents working on codebase 

Challenge: Changes might conflict or break others’ work 

Solution: Tests catch integration issues immediately 

Benefit: Parallel work without coordination overhead

Scenario 4: Long-lived projects

Example: Projects maintained for years 

Challenge: Memory fades, context is lost 

Solution: Tests preserve behavior requirements 

Benefit: Confident modifications after months away

Scenario 5: Critical functionality

Example: Authentication, data processing, payment handling 

Challenge: Bugs have serious consequences 

Solution: Comprehensive tests validate correctness 

Benefit: Confident deployment of critical code

Piper Morgan hits 3/5: Complex integration, frequent refactoring, long-lived project. Validation-driven development is perfect fit.

Common objections addressed

Objection 1: “Tests slow down development”

Reality: Tests slow initial implementation (2x time). But speed up everything after:

  • Modifications faster (instant validation)
  • Refactoring faster (safe changes)
  • Debugging faster (bugs caught immediately)
  • Deployment faster (confident releases)

Net effect: Slower start, much faster overall.

Objection 2: “We don’t have time to write tests”

Reality: You don’t have time NOT to write tests. Without tests:

  • Manual testing takes longer than automated tests would
  • Bugs found late cost 10–100x more to fix
  • Fear of changes prevents improvement
  • Technical debt accumulates

Net effect: “Saving time” by skipping tests costs far more time later.

Objection 3: “Our code is too complex to test”

Reality: Complex code is hard to test because it’s not testable. Tests reveal design problems:

  • Code that’s hard to test is poorly designed
  • Tests force good architecture (separation of concerns, dependency injection)
  • Making code testable makes code better

Net effect: Tests improve design, not complicate it.

Objection 4: “Tests give false confidence”

Reality: Bad tests give false confidence. Good tests give true confidence:

  • Comprehensive coverage (including edge cases)
  • Integration-level validation (not just units)
  • Reliable execution (no flakiness)
  • Clear failures (debuggable)

Net effect: Good tests are reliable confidence mechanism.

Objection 5: “We can’t test everything”

Reality: Don’t need 100% coverage. Need strategic coverage:

  • Critical paths (authentication, data processing)
  • Integration points (service boundaries)
  • Edge cases (error handling, boundaries)
  • Regression prevention (bugs that occurred)

Net effect: 80% strategic coverage provides 95% confidence.

Practical implementation

How to adopt validation-driven development:

Step 1: Start with integration tests

Don’t: Begin with 100% unit test coverage 

Do: Write integration tests for critical paths first

Why: Integration tests provide most value. Validate system behavior, not just component isolation.

Step 2: Make tests fast

Don’t: Accept slow test suites 

Do: Invest in test performance (parallel execution, optimized setup)

Why: Fast tests enable continuous validation. Slow tests get skipped.

Step 3: Cover edge cases early

Don’t: Test only happy path 

Do: Include error cases, boundaries, invalid input from start

Why: Edge cases are where bugs hide. Early coverage prevents late surprises.

Step 4: Use tests to drive design

Don’t: Write code then struggle to test it 

Do: Write test, then write code to pass it

Why: Tests first force good design. Code that’s easy to test is well-designed.

Step 5: Maintain test reliability

Don’t: Ignore flaky tests or “known failures” 

Do: Fix flakiness immediately, no exceptions

Why: Unreliable tests destroy confidence. One flaky test undermines entire suite.

Step 6: Celebrate test-enabled wins

Don’t: Take tests for granted 

Do: Notice when tests enable bold moves, save debugging time, catch bugs

Why: Conscious appreciation reinforces investment in testing quality.

What this means for you

Validation-driven development applies to any team:

For individual developers:

  • Write tests early in development
  • Run tests continuously (after each change)
  • Trust tests to enable bold refactoring
  • Let tests drive design decisions

For teams:

  • Establish test culture (everyone writes tests)
  • Invest in test infrastructure (fast, reliable execution)
  • Code review includes test coverage
  • Celebrate test-enabled wins

For projects:

  • Strategic test coverage (integration + critical paths + edge cases)
  • Performance matters (tests under 5 minutes)
  • Reliability paramount (zero tolerance for flakiness)
  • Tests as documentation (preserve behavior requirements)

The discipline: Tests aren’t checkbox. Tests are confidence mechanism enabling speed.

The validation mindset

The shift from traditional to validation-driven:

Traditional: “We write tests because we should” z Validation-driven: “We write tests because they enable what we want to do”

Traditional: “Tests verify work is correct”  Validation-driven: “Tests enable bold moves”

Traditional: “Tests catch regressions”  Validation-driven: “Tests accelerate development”

Traditional: “Testing is overhead”  Validation-driven: “Testing is leverage”

The transformation: From seeing tests as cost to seeing tests as multiplier.

Don't think of it as “we pay 2x time to write tests” but instead as “we invest 2x time to enable 10x speed.”


This is part of the Building Piper Morgan methodology series, exploring systematic approaches to AI-assisted development. The next article will be the shipping news for the week of December 5 to 11.

How does your team approach testing? Verification tool or confidence mechanism? What would bold moves become possible with comprehensive validation?

To view or add a comment, sign in

More articles by Christian Crumlish

  • The Drift You Don't Notice

    February 23 Our omnibus logs had stopped following the methodology. This was not an intentional decision.

  • Weekly Ship #040: The Methodology Audits Itself

    April 17–23, 2026 Last week's "The Voice Takes Shape" closed M1 and shipped three M2 sub-epics in five working days…

  • Verify the Paraphrase

    April 19, 2026 It was a Sunday morning, and six of my agents made the same mistake within a ten-minute window. Then one…

  • The Multi-Wave Investigation

    December 25, 2025 We had a problem: 44 new canonical queries to investigate. Each one needed infrastructure assessment,…

  • Weekly Ship #039: The Voice Takes Shape

    April 10–16, 2026 Last week's "The Floor Comes Alive" ended with the floor finally generating real responses after…

  • Sibling Intelligence

    March 19–21, 2026 I'm now running two AI side projects: Piper Morgan — a PM assistant with nine distinct active agent…

  • Thirteen Mailboxes

    Take a look at this screenshot of a folder on my laptop. It contains thirteen subfolders, each named for an AI agent or…

  • Weekly Ship #038: The Floor Comes Alive

    April 3–9, 2026 Last week's "New Ground" ended with the M1 gate ready and waiting. This week, we sat down with Piper…

  • Archaeological Debugging: Finding What You've Already Built

    December 22, 2025 It was 8:06 AM on a Monday in December. I asked the Lead Developer to implement Query #2 in our list…

  • The No-Anchoring Roundtable

    March 14 I has this sudden instinct we'd been building the system backwards. I wanted to ask my agent team and get…

Others also viewed

Explore content categories