Development
Incremental Implementation
Delivers changes incrementally. Use when implementing any feature or change that touches more than one file.
Build in thin vertical slices — implement one piece, test it, verify it, then expand.
When to Use
- Implementing any multi-file change
- Building a new feature from a task breakdown
- Refactoring existing code
- Any time you're tempted to write more than ~100 lines before testing
The Increment Cycle
┌──────────────────────────────────────┐
│ │
│ Implement ──→ Test ──→ Verify ──┐ │
│ ▲ │ │
│ └───── Commit ◄─────────────┘ │
│ │ │
│ ▼ │
│ Next slice │
│ │
└──────────────────────────────────────┘
For each slice:
- Implement the smallest complete piece of functionality
- Test — run the test suite
- Verify — confirm the slice works as expected
- Commit — save your progress with a descriptive message
- Move to the next slice
Slicing Strategies
Vertical Slices (Preferred)
Build one complete path through the stack:
Slice 1: Create a task (DB + API + basic UI)
→ Tests pass, user can create a task via the UI
Slice 2: List tasks (query + API + UI)
→ Tests pass, user can see their tasks
Slice 3: Edit a task (update + API + UI)
→ Tests pass, user can modify tasks
Slice 4: Delete a task (delete + API + UI + confirmation)
→ Tests pass, full CRUD complete
Risk-First Slicing
Tackle the riskiest piece first:
Slice 1: Prove the WebSocket connection works (highest risk)
Slice 2: Build real-time task updates on the proven connection
Slice 3: Add offline support and reconnection
Implementation Rules
Rule 0: Simplicity First
Before writing any code, ask: "What is the simplest thing that could work?"
SIMPLICITY CHECK:
✗ Generic EventBus with middleware pipeline for one notification
✓ Simple function call
✗ Abstract factory pattern for two similar components
✓ Two straightforward components with shared utilities
✗ Config-driven form builder for three forms
✓ Three form components
Rule 0.5: Scope Discipline
Touch only what the task requires. Do NOT "clean up" adjacent code.
Rule 1: One Thing at a Time
Each increment changes one logical thing. Don't mix concerns.
Rule 2: Keep It Compilable
After each increment, the project must build and existing tests must pass.
Rule 3: Feature Flags for Incomplete Features
const ENABLE_TASK_SHARING = process.env.FEATURE_TASK_SHARING === 'true';
if (ENABLE_TASK_SHARING) {
// New sharing UI
}
Rule 4: Safe Defaults
New code should default to safe, conservative behavior:
export function createTask(data: TaskInput, options?: { notify?: boolean }) {
const shouldNotify = options?.notify ?? false;
// ...
}
Rule 5: Rollback-Friendly
Each increment should be independently revertable.
Increment Checklist
After each increment:
- The change does one thing and does it completely
- All existing tests still pass (
npm test) - The build succeeds (
npm run build) - Type checking passes (
npx tsc --noEmit) - Linting passes (
npm run lint) - The new functionality works as expected
- The change is committed with a descriptive message
Verification
After completing all increments for a task:
- Each increment was individually tested and committed
- The full test suite passes
- The build is clean
- The feature works end-to-end as specified
- No uncommitted changes remain