Skip to content
Santekno.com | Level Up Your Engineering Skills
EN
📖 0%
29 Jul 2026 · 16 min read ·Article 11 / 208
Go

Task Breakdown: Splitting a Golang Spec into Executable Work Units

A task breakdown technique for Specification-Driven Development: split a Golang spec into small work units you can execute incrementally with Claude Code.

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

Task Breakdown: Splitting a Spec into Golang Work Units

Task breakdown for Golang in SDD is the discipline that turns an approved plan into work you can actually ship. An implementation plan from Plan Mode is still too abstract to execute directly — “Implement CancelWithStockRestore in the repository” is a plan item, not a task you can assign to a developer and track to completion.

Task Breakdown is the process of splitting an implementation plan into work units that are completable in one to four hours, have a clear definition of done, can be committed independently, and can be tested in isolation. This article covers the technique end to end for a Golang SDD workflow.


11.1 Why Task Breakdown Matters

There’s a very common failure pattern: a developer has a good spec and a good plan, but execution is chaotic because there’s no clear breakdown. To see the difference, compare two versions of the same day of work — the first without a breakdown, the second with one.

Here’s what execution without a breakdown typically looks like:

text
1Day 1 morning:   Start implementation (open every file at once)
2Day 1 afternoon: Half-done, many uncommitted changes
3Day 1 evening:   "Stuck" on one complex part
4Day 2:           Still "in progress," unclear what percentage is done
5Day 3:           Finally done, but hard to review as one massive PR

And here’s the same feature with a breakdown:

text
1Task 1 (30 min): Add StatusCancelled to entity.go        -> commit
2Task 2 (45 min): Add interface methods to repository.go  -> commit
3Task 3 (60 min): Implement SQL in order_repository.go    -> commit
4Task 4 (90 min): Implement CancelOrderUseCase            -> commit + test
5Task 5 (60 min): Implement HTTP handler                  -> commit
6Task 6 (30 min): Integration and smoke test             -> commit
7Total: ~6 hours, 6 commits, measurable progress

The takeaway: the total effort is roughly the same, but the second version is observable and reviewable at every step. Measurable progress is not a nice-to-have — it’s what lets you catch a problem on hour two instead of day three.


11.2 Principles of Effective Task Breakdown

Good breakdowns aren’t arbitrary; they follow a handful of principles. The first is single responsibility — each task should have exactly one clear goal. The contrast below shows a well-scoped task next to one that’s too large to reason about.

text
1Good task:
2"Add GetByIDAndUserID to the OrderRepository interface
3and implement it in the PostgreSQL repository."
4
5Too large:
6"Implement all repository methods for cancel order."

The second principle is a verifiable definition of done — each task must have completion criteria you can actually check, not a feeling. The block below shows what that looks like for a usecase.

text
1Task: Implement CancelOrderUseCase
2Done when:
3- cancel_order.go exists with the correct struct and method
4- go build ./... succeeds without error
5- The happy-path unit test passes
6- Unit tests for AC7-AC10 (all error cases) pass
7- go test -race ./internal/usecase/order/... passes

The remaining two principles are shorter: independent commit (each task commits without breaking the build — use stubs if needed) and 30-90 minutes per task (under 30 minutes is too granular, over two hours needs splitting).

The takeaway: single responsibility keeps reviews small, a verifiable done removes ambiguity, independent commits keep the build green, and the time box keeps momentum. Together they make execution predictable.


11.3 A Complete Task Breakdown for Cancel Order

Turning the earlier plan into a full breakdown produces a document you can hand to a developer or feed to Claude Code task by task. The markdown below is the complete breakdown for the cancel-order feature, with file, changes, time box, and done criteria for each unit.

markdown
 1## TASK 1: Domain Entity Update [30 min]
 2File: internal/domain/order/entity.go
 3- Add StatusCancelled to the Status enum
 4- Add CanBeCancelled() bool (checks PENDING + 15-min window)
 5Done when: go test ./internal/domain/... passes
 6
 7## TASK 2: Repository Interface [30 min]
 8File: internal/domain/order/repository.go
 9- Add GetByIDAndUserID to the interface
10- Add CancelWithStockRestore to the interface
11- Regenerate the mock
12Done when: go build ./... passes, mock updated
13
14## TASK 3: Database Migration [20 min]
15File: migrations/20250701_cancel_order_index.sql
16Content: CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_orders_user_id_status...
17Done when: Migration tested on the local dev DB
18
19## TASK 4: Repository Implementation [90 min]
20File: internal/repository/postgres/order_repository.go
21- GetByIDAndUserID implementation
22- CancelWithStockRestore with transaction + SELECT FOR UPDATE
23Done when: Integration tests with the test DB pass
24
25## TASK 5: UseCase Implementation [90 min]
26File: internal/usecase/order/cancel_order.go
27Done when: go build passes
28
29## TASK 6: UseCase Tests [60 min]
30File: internal/usecase/order/cancel_order_test.go
31Coverage: TestSuccess, TestNotFound, TestNotCancellable x2, TestConcurrent, TestKafkaFails
32Done when: go test -race -cover ./... coverage > 85%
33
34## TASK 7: HTTP Handler [60 min]
35File: internal/delivery/http/handler/order_handler.go
36Done when: Handler tests pass for all scenarios
37
38## TASK 8: Route Registration [15 min]
39File: internal/delivery/http/router/router.go
40Done when: go build passes, route test passes
41
42## TASK 9: E2E Smoke Test [30 min]
43Manual curl tests for the happy path and all error cases
44Done when: All manual test scenarios match expected behavior

The takeaway: notice how the ordering respects dependencies — entity before interface, interface before implementation, implementation before handler. Following the list top-to-bottom keeps every intermediate commit buildable.


11.4 Using Claude Code to Generate the Breakdown

You don’t have to write the breakdown by hand. Once the plan is approved, Claude Code can decompose it for you — as long as you specify the shape you want. The prompt below asks for exactly the five fields each task needs.

text
 1Based on the implementation plan we created for cancel order,
 2create a more granular task breakdown.
 3
 4Requirements for each task:
 51. Time estimate (in minutes)
 62. Files to be changed
 73. Specific changes to make
 84. Definition of Done (how to know the task is complete?)
 95. Dependencies on other tasks
10
11Format: a Markdown list ready to copy into a project management tool.
12Target: each task 30-90 minutes. Nothing longer than 2 hours.

The takeaway: the “nothing longer than 2 hours” constraint is doing real work here — it forces Claude to split the large repository and usecase items instead of returning three giant tasks.


11.5 Executing Tasks Incrementally

With the breakdown in hand, you drive Claude Code one task at a time rather than dumping the whole feature. The prompt below starts Task 1 and, crucially, asks for verification before moving on.

text
1Task 1 — Start:
2"Implement Task 1: add StatusCancelled to entity.go
3and the CanBeCancelled() method.
4
5Spec: cancel is only possible within 15 minutes (AC4) and only if the
6order is PENDING (AC3).
7
8After completing, show the changes and confirm
9go test ./internal/domain/... passes."

After Task 1 is done and committed, the next prompt makes the incremental hand-off explicit so context carries forward cleanly:

text
1Task 2 — Continue:
2"Task 1 is done and committed.
3Now implement Task 2: add two methods to the OrderRepository interface
4and regenerate the mock with mockgen.
5
6Needed method signatures: [from the plan]
7
8After completing, run go build ./... to verify there are no compile errors."

The takeaway: verifying after each task (go test, go build) is what makes the whole approach safe — every step is confirmed green before the next begins, so a failure is always isolated to the task you just did.


11.6 Task Breakdown and Git Workflow

Each task should ideally produce one meaningful commit, so git log becomes a readable history of the implementation. The commands below show two task commits that each carry a spec reference in the message.

bash
 1# Task 1 commit
 2git commit -m "feat(order): add StatusCancelled and CanBeCancelled method
 3
 4- Add StatusCancelled to the order Status enum
 5- Add CanBeCancelled() bool checking PENDING status and the 15-min window
 6
 7Implements: specs/order/cancel-order.md AC3, AC4"
 8
 9# Task 2 commit
10git commit -m "feat(order): add cancel order repository interface methods
11
12- Add GetByIDAndUserID to the OrderRepository interface
13- Add CancelWithStockRestore to the OrderRepository interface
14- Regenerate mock with gomock"

The takeaway: putting the spec’s AC/EC identifiers in the commit body ties every commit back to the requirement it satisfies — invaluable when you later need to prove a rule was implemented or debug why it changed.


11.7 Handling Blocked Tasks

Some tasks get blocked by factors outside your control. Tracking them explicitly — rather than silently stalling — lets you keep moving on unblocked work. The block below shows how to record a blocked task with its workaround and unblock target.

markdown
1## Blocked Tasks
2
3Task 3 (Database Migration):
4-> BLOCKED: needs DBA approval for the CONCURRENTLY index
5-> Workaround: run without CONCURRENTLY in development
6-> Unblock target: Tuesday (DBA meeting)
7-> Not blocking other tasks (app runs without the index, just slower)

The takeaway: an explicit “not blocking other tasks” note is the key detail — it tells the team the feature can proceed, and it surfaces the dependency early instead of as an end-of-sprint surprise.


11.8 Realistic Task Estimation

AI time estimates are almost always optimistic. From experience, it helps to multiply Claude’s estimate by a factor that reflects the real risk of the work. The reference below lists the multipliers worth applying.

text
 1Task involving new SQL:
 2x1.5 for straightforward queries
 3x2.0 for transaction/locking
 4x2.5 for complex subqueries or CTEs
 5
 6Task involving tests:
 7x1.5 for happy path only
 8x2.0 for all AC + EC tests
 9x2.5 for concurrent scenario tests
10
11Task involving interface changes:
12x2.0 (always unexpected cascade effects)
13
14Familiar task:                          x1.0-1.3
15Unfamiliar task (new library/pattern):  x2.0-3.0

The takeaway: interface changes and concurrency tests are the two categories that consistently blow estimates, so pad them the most — the factors are a starting calibration, not a law, and you should tune them to your team’s history.


11.9 Task Breakdown for Multi-Service Features

When a feature spans more than one service, the breakdown has to respect service boundaries and the dependencies between them. The block below shows cancel order split across an Order Service and a Notification Service, with the integration dependency called out.

markdown
 1## Cancel Order (Multi-Service)
 2
 3### Order Service (Team A)
 4- Task 1-4: Core cancel implementation
 5- Task 5: ORDER_CANCELLED event schema definition
 6
 7### Notification Service (Team B, after Task 5)
 8- Task 6: Consumer for the ORDER_CANCELLED event
 9- Task 7: Email template for cancellation
10
11### Integration Dependency
12Task 5 (event schema) must complete before Task 6 (consumer).
13Team B can start Task 6 while Team A is still on Task 3-4.

The takeaway: the event schema (Task 5) is the contract that unblocks the other team — defining it early lets Team B start in parallel instead of waiting for Team A to finish the whole service.


11.10 Task Breakdown in Sprint Planning

An existing breakdown plugs straight into sprint planning because the estimates are already there. The scenario below shows how per-task minutes roll up into a capacity decision.

text
1Sprint Planning Scenario:
2The team breaks down the cancel order feature before the sprint.
3
4Task 1-6: 360 min -> fits in Sprint N
5Task 7-9: 105 min -> Sprint N or N+1 depending on capacity
6
7With existing estimates, velocity planning becomes more accurate.

The takeaway: because the breakdown already carries time estimates, sprint commitment turns into arithmetic rather than negotiation — you can see exactly which tasks fit the remaining capacity.


11.11 Progress Tracking

A structured breakdown makes progress tracking almost free. Dropping the tasks into a status table gives everyone a live view of where the feature stands. The table below is that view mid-implementation.

TaskEstimateStatusCommitNotes
1. Entity30 minDONEabc123
2. Interface30 minDONEdef456Mock regenerated
3. Migration20 minIN PROGRESS-Waiting on DBA
4. Repository90 minPENDING-
5. UseCase90 minPENDING-Blocked by Task 4

The takeaway: the “Notes” column carries the real signal — it’s where blockers and dependencies live, turning a static list into an early-warning system for the sprint.


11.12 Task Templates for Common Tasks

Some tasks recur across features, so it pays to keep reusable templates. The two below cover the most common Go work units — a new usecase and a new repository method — with their standard done criteria and estimates.

markdown
 1## Template: New UseCase Task
 2
 3File: internal/usecase/[domain]/[feature].go
 4Content: Input struct, UseCase struct, Execute method, error types
 5Done when: go build passes, all AC + EC unit tests pass
 6Estimate: 90 minutes
 7
 8## Template: New Repository Method Task
 9
10File: internal/repository/postgres/[domain]_repository.go
11SQL Query: [SQL to implement]
12Done when: method implemented, integration tests with the test DB pass
13Estimate: 45-90 minutes

The takeaway: templates keep your breakdowns consistent across features and remove the effort of re-deriving the done criteria every time — fill in the blanks and the task is ready.


11.13 Task Breakdown Under Deadline

When time is short, a breakdown becomes a prioritization tool: you can consciously choose which tasks are essential and which debt you’re deferring. The block below shows a deadline strategy that ships core functionality and documents the deferred work.

text
 1Deadline: tomorrow afternoon. Cancel order must be live.
 2Tasks: 9, total estimate 6-8 hours.
 3Available time: 5 hours.
 4
 5Strategy (essential tasks only):
 61. Task 1-4: core functionality — 3 hours
 72. Task 5: basic UseCase without all error cases — 1 hour
 83. Task 7: minimal handler — 1 hour
 94. Task 9: quick smoke test — 30 minutes
10
11Acknowledged debt (documented in the PR):
12- Task 6 (full tests) -> carry to next sprint [JIRA-456]
13- Task 3 (migration index) -> next maintenance window [JIRA-457]
14- EC1 (concurrent test) -> monitor in production [JIRA-458]

The takeaway: the “acknowledged debt” list is what makes deadline-driven work responsible — deferring tests is fine when it’s a tracked, visible decision rather than a silent gap someone discovers later.


11.14 Anti-Patterns to Avoid

A few breakdown mistakes show up again and again, and each has a clear fix.

  • Anti-pattern 1 — tasks based on “feeling”: no objective definition of done. Fix: every task gets a checkable done criterion.
  • Anti-pattern 2 — all tasks in one huge PR: hard to review, impossible to roll back. Fix: one PR per two or three related tasks.
  • Anti-pattern 3 — tasks that can’t build independently: always maintain buildability with stubs.
  • Anti-pattern 4 — skipping breakdown for “small” tasks: “small” tasks have a habit of expanding into days.

The takeaway: three of these four collapse into the same rule — keep tasks small, verifiable, and independently buildable — and the fourth is a warning never to trust an un-estimated “quick” task.


11.15 Validating the Breakdown

Before you start executing, it’s worth asking Claude to sanity-check the breakdown against the spec. The prompt below has it hunt for missing dependencies, oversized tasks, and uncovered acceptance criteria.

text
 1Here is the task breakdown for cancel order:
 2[paste task list]
 3
 4Please validate:
 51. Are there missing dependencies between tasks?
 62. Are there tasks too large (> 90 min) that need splitting?
 73. Are all ACs and ECs from the spec covered?
 84. Are there potential issues not captured in the breakdown?
 9
10Spec being implemented: specs/order/cancel-order.md v1.3

The takeaway: question 3 — “are all ACs and ECs covered?” — is the one that catches silent gaps, because it forces a cross-check between the breakdown and the spec’s full requirement set.


11.16 Pair Programming with AI Using the Breakdown

A breakdown also structures how you pair with the AI itself. There are two workable rhythms — one task per session, or a full list in one session — and the block below contrasts them.

text
 1Approach 1: One task per session
 2-> Each Claude Code session focuses on one task
 3-> Complete the task, commit, start a new session for the next task
 4-> CLAUDE.md keeps context consistent between sessions
 5
 6Approach 2: Full task list in one session
 7-> Open one Claude Code session
 8-> "Implement all tasks from this breakdown one by one"
 9-> Review after each task completes
10-> One session can handle 3-5 tasks for a medium feature

The takeaway: use one-task-per-session for high-risk work where a fresh context prevents drift, and the full-list approach for medium features where momentum matters more than isolation.


11.17 Keeping the Breakdown Updated

A breakdown is a living document, not a one-time artifact. When implementation surfaces something unexpected, update the breakdown rather than working around it silently. Concretely, that means:

  • Update the breakdown document itself
  • Document why the change was made
  • Note any new tasks added or tasks that were split
  • Keep the definition of done current if the scope changed

The takeaway: an updated-but-imperfect breakdown beats an accurate-at-creation-but-stale one every time — the document is only useful if it reflects what’s actually being built.


11.18 Tips & Gotchas

A handful of practical habits separate a breakdown that helps from one that just adds ceremony.

  • Tip 1: Task 0 is “read and understand the spec” — 15-20 minutes that’s often skipped but very valuable.
  • Tip 2: Test tasks should accompany implementation tasks — don’t separate “implement” and “write tests” by many tasks.
  • Tip 3: Save the breakdown in the PR description — it gives reviewers context on your implementation strategy.
  • Tip 4: Update the breakdown when new discoveries arise during implementation.
  • Gotcha 1: A perfect breakdown takes longer than the tasks themselves — find the sweet spot.
  • Gotcha 2: AI time estimates need calibration against your team’s codebase familiarity.
  • Gotcha 3: Don’t be too rigid about task order — if there’s a technical reason to reorder, do it and document why.
  • Gotcha 4: The breakdown doesn’t replace the spec — the spec remains the source of truth for expected behavior.

The takeaway: the breakdown is about how you’ll work, never what you’re building — keep it lightweight, keep it current, and always defer to the spec on behavior.


11.19 The Complete Planning Cycle

With task breakdown in place, the full SDD planning cycle is now complete. The flow below shows how each layer adds specificity, from the feature spec down to incremental execution.

text
 11. Feature Spec (specs/*.md)
 2   | "What to build + business rules"
 32. OpenAPI Spec (api/openapi.yaml)
 4   | "HTTP contract"
 53. Plan Mode (Claude Code)
 6   | "Files, SQL, risks, questions"
 74. Task Breakdown (this article)
 8   | "Executable 30-90 min units"
 95. Incremental Execution (next article)
10   | "One task at a time, commit after each"

The takeaway: each layer narrows ambiguity and adds verifiability, so by the time you execute there are no surprises — the breakdown is the last translation step from intent to code.


11.20 Summary

Task Breakdown is the bridge between an abstract implementation plan and concrete code. With a good breakdown, implementation becomes a series of small, measurable, verifiable, trackable steps instead of one opaque push.

The core principles are consistent: single responsibility per task, a verifiable definition of done, independent commits, and 30-90 minutes per task. The recommended workflow follows naturally — Plan Mode, then Task Breakdown, then execute one task at a time, commit after each, and track progress. On a team, the same breakdown doubles as sprint assignment planning, since each task can go to a different developer with clear context. Avoid the familiar anti-patterns: tasks that are too large, missing definitions of done, everything crammed into one giant PR, and estimates made without real context.

In the next article we get into the core practice: generating Go code from the spec, using a tight iterative feedback loop with Claude Code.

Related Articles

💬 Comments