Skip to content
Part 3: The Craft 8 min read

Lesson 09

Ship & Improve

Never Schedule a Refactoring Sprint Again

You've heard of "tech debt sprints." Two weeks where the team stops shipping features and cleans up the mess. Management hates it. Developers hate it. And the codebase is messy again within a month.

There's a better way — and it doesn't require permission from anyone.

Two phases. Every feature.

Phase 1: Make it work (2 hours)

Get the feature functional. Tests passing. Deploy it. Resist every urge to chase perfection. The goal is working software in users' hands, not a museum piece.

Phase 2: Make it right (30 minutes, next morning)

Fresh eyes. Extract the pattern you've now seen three times. Rename the confusing variable. Add the missing type. Commit, move on.

The key insight: Phase 2 happens the next morning because you have fresh eyes and you're still in context. It's not a separate task — it's the end of the current one.

The Boy Scout Rule

Leave the campground cleaner than you found it.

Every file you touch, make one small improvement. Not a rewrite. Not a refactor. One better variable name. One extracted helper. One added type annotation.

Over weeks, this compounds. What starts as scattered small improvements becomes a fundamentally cleaner codebase — without ever scheduling a "cleanup sprint."

When to improve and when to skip

The decision is simpler than you think. Ask one question: Am I already paying the context-loading cost?

SignalActionBudget
Tests pass, code is readableShip it0 min
Copied this pattern twiceExtract now (Rule of Three)30-60 min
Function is 200+ linesSplit before adding more20-40 min
Confusing variable namesRename — you have context now5-10 min
Security or data integrity riskFix before shippingWhatever it takes
Violation in a different moduleSkip, note in debt register0 min

If you're already in the file, improvement is cheap. If you'd have to context-switch to a different module, note it and move on.

The technical debt register

A simple markdown file that tracks debt worth paying down. Not a backlog that grows forever — a living document reviewed weekly.

### TD-012: Duplicate auth logic in 4 endpoints
- **Impact:** Medium
- **Trigger:** Next time we add an endpoint to this module
- **Estimate:** 1 hour
- **Status:** Open

The trigger field is key. It tells you when to pay this debt — not "someday" but "next time you're already touching this code." That's when the context cost is lowest.

Real results

MetricResult
Features shipped (6 months)40 (no feature freeze)
Time lost to refactoring45 hours (spread across 6 months)
Code duplication at month 67% (vs 18% with big-bang sprints)
Velocity trendSteady/increasing

Compare that to the big-bang approach: 2-week freeze, 40+ introduced bugs, sawtooth velocity that drops every quarter when "tech debt sprint" hits the calendar.

The Rule of Three pays off

Feature typeFirst timeFifth timeSpeedup
CRUD endpoint3 days4 hours6x
Filtered list2 days3 hours5x
Notification handler1 day45 min11x

That 30-minute extraction on the third occurrence? It's paying dividends on every feature that follows.