Incremental implementation

Delivers changes incrementally in thin, verifiable slices.

How to use it

Claude Code
  1. Run the line below. It pulls the whole folder into ~/.claude/skills/incremental-implementation-2.
  2. Describe your job in plain words. Claude Code follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit addyosmani/agent-skills/skills/incremental-implementation#main ~/.claude/skills/incremental-implementation-2

For one project only, change the path to .claude/skills/incremental-implementation-2.

Claude (web or desktop app)
  1. On this page open ⋯ → Download .md.
  2. Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
  3. Pick the file and Save. Claude shows the name and description and runs a security scan.
  4. Check the skill is switched on.
  5. Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
  1. ChatGPT: make a Project and paste it into Instructions.
  2. Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
  • Check which app you pasted it into — the steps above name the right one.
  • Some skills need the paid tier of Claude or ChatGPT.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Source of Incremental implementation

Show the full text250 lines
namedescription
incremental-implementationDelivers changes incrementally in thin, verifiable slices. Use when implementing any feature or change that touches more than one file, or when picking up the next task from a plan. Use when rolling a change out behind a feature flag, when you're about to write a large amount of code at once, or when a task feels too big to land in one step.

Incremental Implementation

Overview

Build in thin vertical slices — implement one piece, test it, verify it, then expand. Avoid implementing an entire feature in one pass. Each increment should leave the system in a working, testable state. This is the execution discipline that makes large features manageable.

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

When NOT to use: Single-file, single-function changes where the scope is already minimal.

The Increment Cycle

┌──────────────────────────────────────┐
│                                      │
│   Implement ──→ Test ──→ Verify ──┐  │
│       ▲                           │  │
│       └───── Commit ◄─────────────┘  │
│              │                       │
│              ▼                       │
│          Next slice                  │
│                                      │
└──────────────────────────────────────┘

For each slice:

  1. Implement the smallest complete piece of functionality
  2. Test — run the test suite (or write a test if none exists)
  3. Verify — confirm the slice works as expected (tests pass, build succeeds, manual check)
  4. Commit -- save your progress with a descriptive message (see git-workflow-and-versioning for atomic commit guidance)
  5. Move to the next slice — carry forward, don't restart

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

Each slice delivers working end-to-end functionality.

Contract-First Slicing

When backend and frontend need to develop in parallel:

Slice 0: Define the API contract (types, interfaces, OpenAPI spec)
Slice 1a: Implement backend against the contract + API tests
Slice 1b: Implement frontend against mock data matching the contract
Slice 2: Integrate and test end-to-end
Risk-First Slicing

Tackle the riskiest or most uncertain 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

If Slice 1 fails, you discover it before investing in Slices 2 and 3.

Implementation Rules

Rule 0: Simplicity First

Before writing any code, ask: "What is the simplest thing that could work?"

After writing code, review it against these checks:

  • Can this be done in fewer lines?
  • Are these abstractions earning their complexity?
  • Would a staff engineer look at this and say "why didn't you just..."?
  • Am I building for hypothetical future requirements, or the current task?
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

Three similar lines of code is better than a premature abstraction. Implement the naive, obviously-correct version first. Optimize only after correctness is proven with tests.

Rule 0.5: Scope Discipline

Touch only what the task requires.

Do NOT:

  • "Clean up" code adjacent to your change
  • Refactor imports in files you're not modifying
  • Remove comments you don't fully understand
  • Add features not in the spec because they "seem useful"
  • Modernize syntax in files you're only reading

If you notice something worth improving outside your task scope, note it — don't fix it:

NOTICED BUT NOT TOUCHING:
- src/utils/format.ts has an unused import (unrelated to this task)
- The auth middleware could use better error messages (separate task)
→ Want me to create tasks for these?
Rule 1: One Thing at a Time

Each increment changes one logical thing. Don't mix concerns:

Bad: One commit that adds a new component, refactors an existing one, and updates the build config.

Good: Three separate commits — one for each change.

Rule 2: Keep It Compilable

After each increment, the project must build and existing tests must pass. Don't leave the codebase in a broken state between slices.

Rule 3: Feature Flags for Incomplete Features

If a feature isn't ready for users but you need to merge increments:

// Feature flag for work-in-progress
const ENABLE_TASK_SHARING = process.env.FEATURE_TASK_SHARING === 'true';

if (ENABLE_TASK_SHARING) {
  // New sharing UI
}

This lets you merge small increments to the main branch without exposing incomplete work.

Rule 4: Safe Defaults

New code should default to safe, conservative behavior:

// Safe: disabled by default, opt-in
export function createTask(data: TaskInput, options?: { notify?: boolean }) {
  const shouldNotify = options?.notify ?? false;
  // ...
}
Rule 5: Rollback-Friendly

Each increment should be independently revertable:

  • Additive changes (new files, new functions) are easy to revert
  • Modifications to existing code should be minimal and focused
  • Database migrations should have corresponding rollback migrations
  • Avoid deleting something in one commit and replacing it in the same commit — separate them

Working with Agents

When directing an agent to implement incrementally:

"Let's implement Task 3 from the plan.

Start with just the database schema change and the API endpoint.
Don't touch the UI yet — we'll do that in the next increment.

After implementing, run the repository's test and build commands to
verify nothing is broken."

Be explicit about what's in scope and what's NOT in scope for each increment.

Increment Checklist

After each increment, verify with the repository's own commands (see the test-driven-development skill's Discover the Stack First section):

  • The change does one thing and does it completely
  • All existing tests still pass (the repository's test command: npm test, ./gradlew test, pytest, ...)
  • The build succeeds (the repository's build command)
  • Type checking passes, where the stack has one (npx tsc --noEmit, mypy, ...)
  • Linting passes (the repository's lint command)
  • The new functionality works as expected
  • The change is committed with a descriptive message

Note: Run each verification command after a change that could affect it. After a successful run, don't repeat the same command unless the code has changed since — re-running on unchanged code adds no information.

Common Rationalizations

Rationalization Reality
"I'll test it all at the end" Bugs compound. A bug in Slice 1 makes Slices 2-5 wrong. Test each slice.
"It's faster to do it all at once" It feels faster until something breaks and you can't find which of 500 changed lines caused it.
"These changes are too small to commit separately" Small commits are free. Large commits hide bugs and make rollbacks painful.
"I'll add the feature flag later" If the feature isn't complete, it shouldn't be user-visible. Add the flag now.
"This refactor is small enough to include" Refactors mixed with features make both harder to review and debug. Separate them.
"Let me run the build command again just to be sure" After a successful run, repeating the same command adds nothing unless the code has changed since. Run it again after subsequent edits, not as reassurance.

Red Flags

  • More than 100 lines of code written without running tests
  • Multiple unrelated changes in a single increment
  • "Let me just quickly add this too" scope expansion
  • Skipping the test/verify step to move faster
  • Build or tests broken between increments
  • Large uncommitted changes accumulating
  • Building abstractions before the third use case demands it
  • Touching files outside the task scope "while I'm here"
  • Creating new utility files for one-time operations
  • Running the same build/test command twice in a row without any intervening code change

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

See Also

Per-increment verification is the local check. Before declaring a task done, apply the project-wide Definition of Done as the final gate, the standing bar every increment clears regardless of the task. See ../../references/definition-of-done.md.

1---
2name: incremental-implementation
3description: Delivers changes incrementally in thin, verifiable slices. Use when implementing any feature or change that touches more than one file, or when picking up the next task from a plan. Use when rolling a change out behind a feature flag, when you're about to write a large amount of code at once, or when a task feels too big to land in one step.
4---
5 
6# Incremental Implementation
7 
8## Overview
9 
10Build in thin vertical slices — implement one piece, test it, verify it, then expand. Avoid implementing an entire feature in one pass. Each increment should leave the system in a working, testable state. This is the execution discipline that makes large features manageable.
11 
12## When to Use
13 
14- Implementing any multi-file change
15- Building a new feature from a task breakdown
16- Refactoring existing code
17- Any time you're tempted to write more than ~100 lines before testing
18 
19**When NOT to use:** Single-file, single-function changes where the scope is already minimal.
20 
21## The Increment Cycle
22 
23```
24┌──────────────────────────────────────┐
25│ │
26│ Implement ──→ Test ──→ Verify ──┐ │
27│ ▲ │ │
28│ └───── Commit ◄─────────────┘ │
29│ │ │
30│ ▼ │
31│ Next slice │
32│ │
33└──────────────────────────────────────┘
34```
35 
36For each slice:
37 
381. **Implement** the smallest complete piece of functionality
392. **Test** — run the test suite (or write a test if none exists)
403. **Verify** — confirm the slice works as expected (tests pass, build succeeds, manual check)
414. **Commit** -- save your progress with a descriptive message (see `git-workflow-and-versioning` for atomic commit guidance)
425. **Move to the next slice** — carry forward, don't restart
43 
44## Slicing Strategies
45 
46### Vertical Slices (Preferred)
47 
48Build one complete path through the stack:
49 
50```
51Slice 1: Create a task (DB + API + basic UI)
52 → Tests pass, user can create a task via the UI
53 
54Slice 2: List tasks (query + API + UI)
55 → Tests pass, user can see their tasks
56 
57Slice 3: Edit a task (update + API + UI)
58 → Tests pass, user can modify tasks
59 
60Slice 4: Delete a task (delete + API + UI + confirmation)
61 → Tests pass, full CRUD complete
62```
63 
64Each slice delivers working end-to-end functionality.
65 
66### Contract-First Slicing
67 
68When backend and frontend need to develop in parallel:
69 
70```
71Slice 0: Define the API contract (types, interfaces, OpenAPI spec)
72Slice 1a: Implement backend against the contract + API tests
73Slice 1b: Implement frontend against mock data matching the contract
74Slice 2: Integrate and test end-to-end
75```
76 
77### Risk-First Slicing
78 
79Tackle the riskiest or most uncertain piece first:
80 
81```
82Slice 1: Prove the WebSocket connection works (highest risk)
83Slice 2: Build real-time task updates on the proven connection
84Slice 3: Add offline support and reconnection
85```
86 
87If Slice 1 fails, you discover it before investing in Slices 2 and 3.
88 
89## Implementation Rules
90 
91### Rule 0: Simplicity First
92 
93Before writing any code, ask: "What is the simplest thing that could work?"
94 
95After writing code, review it against these checks:
96- Can this be done in fewer lines?
97- Are these abstractions earning their complexity?
98- Would a staff engineer look at this and say "why didn't you just..."?
99- Am I building for hypothetical future requirements, or the current task?
100 
101```
102SIMPLICITY CHECK:
103✗ Generic EventBus with middleware pipeline for one notification
104✓ Simple function call
105 
106✗ Abstract factory pattern for two similar components
107✓ Two straightforward components with shared utilities
108 
109✗ Config-driven form builder for three forms
110✓ Three form components
111```
112 
113Three similar lines of code is better than a premature abstraction. Implement the naive, obviously-correct version first. Optimize only after correctness is proven with tests.
114 
115### Rule 0.5: Scope Discipline
116 
117Touch only what the task requires.
118 
119Do NOT:
120- "Clean up" code adjacent to your change
121- Refactor imports in files you're not modifying
122- Remove comments you don't fully understand
123- Add features not in the spec because they "seem useful"
124- Modernize syntax in files you're only reading
125 
126If you notice something worth improving outside your task scope, note it — don't fix it:
127 
128```
129NOTICED BUT NOT TOUCHING:
130- src/utils/format.ts has an unused import (unrelated to this task)
131- The auth middleware could use better error messages (separate task)
132→ Want me to create tasks for these?
133```
134 
135### Rule 1: One Thing at a Time
136 
137Each increment changes one logical thing. Don't mix concerns:
138 
139**Bad:** One commit that adds a new component, refactors an existing one, and updates the build config.
140 
141**Good:** Three separate commits — one for each change.
142 
143### Rule 2: Keep It Compilable
144 
145After each increment, the project must build and existing tests must pass. Don't leave the codebase in a broken state between slices.
146 
147### Rule 3: Feature Flags for Incomplete Features
148 
149If a feature isn't ready for users but you need to merge increments:
150 
151```typescript
152// Feature flag for work-in-progress
153const ENABLE_TASK_SHARING = process.env.FEATURE_TASK_SHARING === 'true';
154 
155if (ENABLE_TASK_SHARING) {
156 // New sharing UI
157}
158```
159 
160This lets you merge small increments to the main branch without exposing incomplete work.
161 
162### Rule 4: Safe Defaults
163 
164New code should default to safe, conservative behavior:
165 
166```typescript
167// Safe: disabled by default, opt-in
168export function createTask(data: TaskInput, options?: { notify?: boolean }) {
169 const shouldNotify = options?.notify ?? false;
170 // ...
171}
172```
173 
174### Rule 5: Rollback-Friendly
175 
176Each increment should be independently revertable:
177 
178- Additive changes (new files, new functions) are easy to revert
179- Modifications to existing code should be minimal and focused
180- Database migrations should have corresponding rollback migrations
181- Avoid deleting something in one commit and replacing it in the same commit — separate them
182 
183## Working with Agents
184 
185When directing an agent to implement incrementally:
186 
187```
188"Let's implement Task 3 from the plan.
189 
190Start with just the database schema change and the API endpoint.
191Don't touch the UI yet — we'll do that in the next increment.
192 
193After implementing, run the repository's test and build commands to
194verify nothing is broken."
195```
196 
197Be explicit about what's in scope and what's NOT in scope for each increment.
198 
199## Increment Checklist
200 
201After each increment, verify with the repository's own commands (see the test-driven-development skill's Discover the Stack First section):
202 
203- [ ] The change does one thing and does it completely
204- [ ] All existing tests still pass (the repository's test command: `npm test`, `./gradlew test`, `pytest`, ...)
205- [ ] The build succeeds (the repository's build command)
206- [ ] Type checking passes, where the stack has one (`npx tsc --noEmit`, `mypy`, ...)
207- [ ] Linting passes (the repository's lint command)
208- [ ] The new functionality works as expected
209- [ ] The change is committed with a descriptive message
210 
211**Note:** Run each verification command after a change that could affect it. After a successful run, don't repeat the same command unless the code has changed since — re-running on unchanged code adds no information.
212 
213## Common Rationalizations
214 
215| Rationalization | Reality |
216|---|---|
217| "I'll test it all at the end" | Bugs compound. A bug in Slice 1 makes Slices 2-5 wrong. Test each slice. |
218| "It's faster to do it all at once" | It *feels* faster until something breaks and you can't find which of 500 changed lines caused it. |
219| "These changes are too small to commit separately" | Small commits are free. Large commits hide bugs and make rollbacks painful. |
220| "I'll add the feature flag later" | If the feature isn't complete, it shouldn't be user-visible. Add the flag now. |
221| "This refactor is small enough to include" | Refactors mixed with features make both harder to review and debug. Separate them. |
222| "Let me run the build command again just to be sure" | After a successful run, repeating the same command adds nothing unless the code has changed since. Run it again after subsequent edits, not as reassurance. |
223 
224## Red Flags
225 
226- More than 100 lines of code written without running tests
227- Multiple unrelated changes in a single increment
228- "Let me just quickly add this too" scope expansion
229- Skipping the test/verify step to move faster
230- Build or tests broken between increments
231- Large uncommitted changes accumulating
232- Building abstractions before the third use case demands it
233- Touching files outside the task scope "while I'm here"
234- Creating new utility files for one-time operations
235- Running the same build/test command twice in a row without any intervening code change
236 
237## Verification
238 
239After completing all increments for a task:
240 
241- [ ] Each increment was individually tested and committed
242- [ ] The full test suite passes
243- [ ] The build is clean
244- [ ] The feature works end-to-end as specified
245- [ ] No uncommitted changes remain
246 
247## See Also
248 
249Per-increment verification is the local check. Before declaring a task done, apply the project-wide Definition of Done as the final gate, the standing bar every increment clears regardless of the task. See `../../references/definition-of-done.md`.
250 

Discussion

Alternatives

Also in Specs & PRDsSee all 277 in Product →
Act as a product managerGuides the AI to act as a product manager, assisting in writing product requirement documents and addressing product-related queries.Business & ops · CC0-1.0Spec driven developmentCreates specs before coding. Use when starting a new project, feature, or significant change and no specification exists yet. Use when drafting a PRD or requirements document with objectives and scope, or when requirements are unclear, ambiguous, or only exist as a vague idea. Use when a single requirement spans several independently testable capabilities and needs decomposing into a capability map of modules before specifying.Business & ops · MITOpenapi spec generationGenerate and maintain OpenAPI 3.1 specifications from code, design-first specs, and validation patterns. Use when creating API documentation, generating SDKs, or ensuring API contract compliance.Content & docs · MITParallel feature developmentCoordinate parallel feature development with file ownership strategies, conflict avoidance rules, and integration patterns for multi-agent implementation. Use this skill when decomposing a large feature into independent work streams, when two or more agents need to implement different layers of the same system simultaneously, when establishing file ownership to prevent merge conflicts in a shared codebase, when designing interface contracts so parallel implementers can build against each other's APIs before they are ready, or when deciding whether to use vertical slices versus horizontal layers for a full-stack feature.Data & AI · MIT