speckit.implement: Cara AI Generate Kode Golang dari Tasks Secara Berurutan
Panduan lengkap speckit.implement untuk mengeksekusi implementasi kode Golang dari task breakdown. Cara kerja phase execution, review output, dan menangani error implementasi.
speckit.implement: Eksekusi Kode dari Tasks Secara Berurutan
specify implement adalah perintah yang paling “magical” di Spec Kit sekaligus tahap paling menentukan hasil code generation Golang dari sebuah spec — tapi juga yang paling perlu dipahami secara mendalam agar tidak berubah menjadi “vibe coding yang lebih mahal”. Ini adalah tahap eksekusi di mana seluruh context yang sudah dibangun (constitution, spec, plan, tasks) digunakan oleh Claude untuk menghasilkan kode Go yang actual dan bisa dikompilasi.
Di artikel ini kita bahas cara menjalankannya dengan benar, cara mereview output, dan cara menangani ketika hasil generate tidak sesuai harapan.
10.1 Filosofi: Implement sebagai Directed Execution
specify implement bukan “AI generate seluruh kode sekaligus”. Ini adalah directed execution — AI diarahkan untuk mengerjakan satu task spesifik dari tasks.md, dengan context lengkap dari constitution, spec, plan, tasks, dan kode existing. Perbedaan ini fundamental, dan cara paling jelas melihatnya adalah membandingkan dua pendekatan secara berdampingan berikut.
1Vibe Coding:
2"Claude, build me a product search feature"
3→ AI interpret sendiri, hasil unpredictable
4
5specify implement:
6"Claude, implement Task 2.2 from product-search tasks.md"
7→ AI tahu persis: file target, interface yang harus diikuti,
8 SQL dari plan, error handling dari constitution, tests yang diperlukan
9→ Hasil predictable dan consistentInti perbedaannya bukan pada model AI-nya, melainkan pada seberapa terbatas dan terarah instruksi yang diberikan: semakin sempit scope satu task, semakin deterministik output-nya.
10.2 Menjalankan specify implement
Ada empat mode eksekusi, dan pemilihannya menentukan seberapa besar kontrol yang kamu pegang di setiap langkah. Mode pertama, per-phase, adalah yang paling direkomendasikan karena memberi checkpoint review setelah tiap task.
1specify implement product-search --phase=1Mode ini mengeksekusi semua task di Phase 1 secara berurutan dengan verification setelah setiap task — cocok sebagai default harian karena menyeimbangkan kecepatan dan kontrol.
Mode kedua, per-task, memberi kontrol maksimum dengan mengeksekusi tepat satu task saja.
1specify implement product-search --task=2.2Gunakan mode ini ketika task sebelumnya baru dimodifikasi manual, ketika satu task perlu diulang, atau saat kamu sedang men-debug satu task spesifik — di situasi itu kamu tidak ingin task lain ikut tersentuh.
Mode ketiga, continue, melanjutkan dari task terakhir yang belum selesai.
1specify implement product-search --continueMode ini menyelamatkan sesi yang terputus di tengah jalan: kamu tidak perlu mengingat sampai task mana progres terakhir, Spec Kit yang melacaknya lewat status di tasks.md.
Mode keempat, all, mengeksekusi seluruh task sekaligus dan hanya layak untuk project kecil.
1specify implement product-search --allMode ini berisiko karena tidak ada review per-phase — sekali dijalankan, semua kode ditulis tanpa titik henti untuk memeriksa arah implementasi.
10.3 Apa yang Terjadi Saat specify implement Berjalan
Agar tidak memperlakukannya sebagai kotak hitam, penting memahami langkah demi langkah yang dilakukan Spec Kit di balik layar. Log berikut memperlihatkan satu siklus penuh untuk Phase 1.
1[specify implement product-search --phase=1]
2
3Step 1: Load context
4 ✓ Loading constitution.md (1,245 chars)
5 ✓ Loading spec.md v1.3 (2,891 chars)
6 ✓ Loading clarifications.md (834 chars)
7 ✓ Loading plan.md (3,102 chars)
8 ✓ Loading tasks.md (2,456 chars)
9 ✓ Scanning existing code (internal/product/*): 8 files
10
11Step 2: Build focused prompt for Task 1.1
12 Context window: 12,528 chars
13 Model: claude-sonnet-4-20250514
14
15Step 3: Generate Task 1.1 (Create Database Migration)
16 Sending to Claude API...
17 Response received (8.3s, 512 tokens)
18 Writing: migrations/20250702001_add_search_index.sql
19
20Step 4: Run post-task verification
21 Running: go build ./...
22 Result: OK ✓
23
24Step 5: Update tasks.md
25 Task 1.1: Status changed to "done"
26
27Step 6: Commit (if auto-commit enabled)
28 git add migrations/20250702001_add_search_index.sql
29 git add .specify/features/product-search/tasks.md
30 git commit -m "feat(product-search): add FTS index migration [task 1.1]"
31
32Step 7: Generate Task 1.2 (Add Search DTOs)
33 ... (same process)
34
35Phase 1 complete!
36Summary:
37 Tasks completed: 2/2
38 Time elapsed: 3.2 minutes
39 Files created: 2
40 Auto-commits: 2Yang perlu digarisbawahi: setiap task melewati loop load context → generate → verify → update status → commit, sehingga kegagalan di satu task langsung terdeteksi sebelum task berikutnya dimulai.
10.4 Output yang Dihasilkan: Contoh Kode Actual
Teori di atas baru bermakna kalau kita lihat kode nyatanya. Task pertama menghasilkan migration database untuk full-text search — perhatikan komentar yang menautkan file ini langsung ke plan.
1-- migrations/20250702001_add_search_index.sql
2-- Task 1.1: Database migration for product full-text search
3-- Based on: product-search plan.md Phase 1
4
5CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_products_fts
6ON products
7USING gin(
8 to_tsvector('indonesian', name || ' ' || COALESCE(description, ''))
9);
10
11-- Verify after creation
12-- SELECT indexname FROM pg_indexes WHERE tablename = 'products' AND indexname = 'idx_products_fts';Index GIN di atas adalah fondasi pencarian: tanpa CONCURRENTLY, migrasi akan mengunci tabel products saat produksi, jadi detail kecil ini sudah “diwariskan” dari keputusan di plan.
Selanjutnya lapisan repository yang mengeksekusi query pencarian beserta paginasi. Kode berikut adalah hasil specify implement product-search --task=2.2.
1// internal/product/repository/postgres_repository.go (addition)
2
3// SearchProducts retrieves products matching the search query with pagination.
4// Implements: product-search spec.md v1.3 AC1-AC8
5// Note: stock=0 products included per clarification Q1 (shows is_available=false)
6func (r *postgresProductRepository) SearchProducts(
7 ctx context.Context,
8 filter usecase.SearchQuery,
9) ([]usecase.ProductSearchItem, int, error) {
10 // Count query for pagination
11 countSQL := `
12 SELECT COUNT(*)
13 FROM products p
14 WHERE p.status = 'ACTIVE'
15 AND p.deleted_at IS NULL
16 AND to_tsvector('indonesian', p.name || ' ' || COALESCE(p.description, ''))
17 @@ plainto_tsquery('indonesian', $1)
18 AND ($2::uuid IS NULL OR p.category_id = $2)
19 `
20
21 var totalItems int
22 err := r.db.QueryRow(ctx, countSQL, filter.Keyword, filter.CategoryID).Scan(&totalItems)
23 if err != nil {
24 return nil, 0, fmt.Errorf("SearchProducts: count query: %w", err)
25 }
26
27 if totalItems == 0 {
28 return []usecase.ProductSearchItem{}, 0, nil
29 }
30
31 // Sort expression based on SortBy option
32 orderBy := switch filter.SortBy {
33 case usecase.SortByNewest:
34 "p.created_at DESC"
35 case usecase.SortByPriceAsc:
36 "p.price_cents ASC"
37 case usecase.SortByPriceDesc:
38 "p.price_cents DESC"
39 default: // SortByRelevance
40 `ts_rank(to_tsvector('indonesian', p.name || ' ' || COALESCE(p.description, '')), plainto_tsquery('indonesian', $1)) DESC`
41 }
42
43 // Results query
44 resultsSQL := fmt.Sprintf(`
45 SELECT
46 p.id,
47 p.name,
48 p.price_cents,
49 p.stock,
50 p.stock > 0 AS is_available,
51 p.category_id,
52 p.thumbnail_url
53 FROM products p
54 WHERE p.status = 'ACTIVE'
55 AND p.deleted_at IS NULL
56 AND to_tsvector('indonesian', p.name || ' ' || COALESCE(p.description, ''))
57 @@ plainto_tsquery('indonesian', $1)
58 AND ($2::uuid IS NULL OR p.category_id = $2)
59 ORDER BY %s
60 LIMIT $3 OFFSET $4
61 `, orderBy)
62
63 offset := (filter.Page - 1) * filter.PerPage
64 rows, err := r.db.Query(ctx, resultsSQL, filter.Keyword, filter.CategoryID, filter.PerPage, offset)
65 if err != nil {
66 return nil, 0, fmt.Errorf("SearchProducts: results query: %w", err)
67 }
68 defer rows.Close()
69
70 var products []usecase.ProductSearchItem
71 for rows.Next() {
72 var p usecase.ProductSearchItem
73 var categoryID *uuid.UUID
74 err := rows.Scan(
75 &p.ID, &p.Name, &p.PriceCents, &p.Stock, &p.IsAvailable,
76 &categoryID, &p.ThumbnailURL,
77 )
78 if err != nil {
79 return nil, 0, fmt.Errorf("SearchProducts: scan: %w", err)
80 }
81 p.CategoryID = categoryID
82 products = append(products, p)
83 }
84
85 if rows.Err() != nil {
86 return nil, 0, fmt.Errorf("SearchProducts: rows error: %w", rows.Err())
87 }
88
89 return products, totalItems, nil
90}Perhatikan bahwa error selalu di-wrap dengan fmt.Errorf("SearchProducts: ...: %w", err) dan komentar header menautkan fungsi ke spec.md v1.3 AC1-AC8 — dua konvensi yang tidak muncul secara kebetulan, melainkan diwarisi dari constitution dan spec.
Terakhir, lapisan usecase yang membungkus validasi bisnis di atas repository. Kode berikut memperlihatkan bagaimana AC (acceptance criteria) diterjemahkan menjadi guard clause konkret.
1// internal/product/usecase/search_usecase.go
2
3package usecase
4
5import (
6 "context"
7 "fmt"
8)
9
10type searchUseCase struct {
11 repo ProductRepository
12}
13
14func NewSearchUseCase(repo ProductRepository) SearchUseCase {
15 return &searchUseCase{repo: repo}
16}
17
18// SearchProducts searches for products matching the given query.
19// Implements: product-search spec.md v1.3 AC1-AC8
20func (uc *searchUseCase) SearchProducts(
21 ctx context.Context,
22 query SearchQuery,
23) (*SearchResult, error) {
24 // Validate keyword length (AC7)
25 if len(query.Keyword) < 2 {
26 return nil, &KeywordTooShortError{
27 Given: query.Keyword,
28 Minimum: 2,
29 }
30 }
31 if len(query.Keyword) > 100 {
32 return nil, &KeywordTooLongError{
33 Given: query.Keyword,
34 Maximum: 100,
35 }
36 }
37
38 // Apply defaults (AC8)
39 if query.Page < 1 {
40 query.Page = 1
41 }
42 if query.PerPage < 1 {
43 query.PerPage = 20
44 }
45 if query.PerPage > 50 {
46 return nil, &PerPageExceedsMaxError{Given: query.PerPage, Maximum: 50}
47 }
48 if query.SortBy == "" {
49 query.SortBy = SortByRelevance
50 }
51
52 // Validate sort option
53 validSorts := map[SortOption]bool{
54 SortByRelevance: true, SortByNewest: true,
55 SortByPriceAsc: true, SortByPriceDesc: true,
56 }
57 if !validSorts[query.SortBy] {
58 return nil, &InvalidSortOptionError{Given: string(query.SortBy)}
59 }
60
61 // Execute search
62 products, totalItems, err := uc.repo.SearchProducts(ctx, query)
63 if err != nil {
64 return nil, fmt.Errorf("SearchProducts: repository: %w", err)
65 }
66
67 // Calculate pagination (AC8)
68 totalPages := totalItems / query.PerPage
69 if totalItems%query.PerPage > 0 {
70 totalPages++
71 }
72
73 return &SearchResult{
74 Products: products,
75 TotalItems: totalItems,
76 Page: query.Page,
77 PerPage: query.PerPage,
78 TotalPages: totalPages,
79 }, nil
80}Setiap komentar (AC7), (AC8) bukan sekadar dekorasi — ia membuat setiap baris validasi bisa ditelusuri balik ke acceptance criteria di spec, sehingga reviewer bisa memverifikasi kelengkapan tanpa membuka dokumen lain.
10.5 Reviewing Implementation Output
Setiap output dari specify implement harus di-review sebelum di-commit atau sebelum lanjut ke task berikutnya. Agar review konsisten dan cepat, pakai checklist per-task berikut sebagai gerbang kualitas.
1Architecture:
2✅ Kode ada di layer yang benar?
3✅ Interface digunakan (bukan concrete type)?
4✅ Tidak ada direct DB call dari usecase?
5
6Convention (Constitution):
7✅ Error wrapping: fmt.Errorf("func: %w", err)?
8✅ context.Context sebagai parameter pertama?
9✅ uuid.UUID untuk IDs?
10✅ log/slog untuk logging?
11
12Logic:
13✅ Business logic sesuai dengan spec AC?
14✅ Edge cases dari clarifications ditangani?
15✅ Error cases sesuai dengan plan error mapping?
16
17Quality:
18✅ go vet tidak ada warnings?
19✅ go build berhasil?
20✅ Test yang relevan pass?Checklist ini mengubah review dari “kelihatannya benar” menjadi verifikasi terstruktur di empat dimensi — arsitektur, konvensi, logika, dan kualitas — sehingga tidak ada aspek yang terlewat karena buru-buru.
10.6 Handling Output yang Tidak Sempurna
Tidak semua output specify implement langsung 100% benar, dan itu normal. Skenario pertama yang sering muncul adalah pola error handling yang salah — AI kadang mengembalikan error tanpa konteks.
1// AI menghasilkan (salah):
2return nil, err // naked error return
3
4// Seharusnya (sesuai constitution):
5return nil, fmt.Errorf("SearchProducts: repository: %w", err)Perbaikannya cukup edit manual lalu jalankan specify implement dengan flag --continue untuk task berikutnya — tidak perlu regenerate seluruh phase hanya karena satu baris.
Skenario kedua adalah SQL yang kurang optimal, misalnya memakai LIKE tanpa index alih-alih full-text search yang sudah dirancang di plan.
1// AI menghasilkan:
2rows, err := r.db.Query(ctx, "SELECT ... WHERE name LIKE '%' || $1 || '%'", keyword)
3// LIKE tanpa index!
4
5// Seharusnya (sesuai plan):
6rows, err := r.db.Query(ctx, "SELECT ... WHERE fts_vector @@ plainto_tsquery('indonesian', $1)", keyword)Fix-nya: edit SQL di repository file, catat penyimpangan di plan.md, lalu lanjut ke task berikutnya — dokumentasi koreksi sama pentingnya dengan koreksi itu sendiri.
Skenario ketiga adalah test case yang kurang: AI menulis test tapi tidak semua AC ter-cover. Tambahkan manual test case untuk AC yang terlewat dan beri note di tasks.md.
Skenario keempat adalah output yang sama sekali melenceng. Untuk kasus ini, regenerate task spesifik dengan instruksi tambahan yang eksplisit.
1# Regenerate task spesifik dengan instruksi tambahan
2specify implement product-search --task=2.2 \
3 --add-instruction "The SQL must use plainto_tsquery with 'indonesian' dictionary, NOT LIKE operator. See plan.md section 5."Instruksi tambahan seperti di atas menutup celah interpretasi AI dengan menunjuk langsung ke bagian plan yang relevan — jauh lebih efektif daripada menjalankan ulang perintah yang sama dan berharap hasilnya berbeda.
10.7 Auto-commit vs Manual Commit
Spec Kit mendukung dua mode commit, dan pilihannya berpengaruh besar pada kebersihan git history. Mode pertama, auto-commit, diaktifkan lewat konfigurasi berikut.
1// specify.config.json
2{
3 "implement": {
4 "auto_commit": true,
5 "commit_message_prefix": "feat",
6 "commit_after_task": true
7 }
8}Dengan konfigurasi ini setiap task yang selesai langsung di-commit otomatis, cocok saat kamu percaya penuh pada output dan ingin kecepatan maksimal.
Pesan commit yang dihasilkan mengikuti format Conventional Commits dengan nomor task, seperti contoh berikut.
1feat(product-search): implement SearchProducts repository [task 2.2]Format [task 2.2] di akhir subjek membuat setiap commit bisa ditelusuri balik ke task-nya di tasks.md — audit trail yang berjalan otomatis.
Mode kedua, manual commit, direkomendasikan untuk pemula: review dulu, baru commit dengan pesan yang lebih kaya konteks.
1# Review dulu, baru commit
2specify implement product-search --task=2.2
3
4# Review output
5cat internal/product/repository/postgres_repository.go
6
7# Jika OK:
8git add .
9git commit -m "feat(product-search): implement SearchProducts repository [task 2.2]
10
11Implements spec.md AC1-AC8 via full-text search
12Stock=0 products included per clarification Q1 (is_available=false)"Manual commit memberi kamu jeda untuk menangkap masalah sebelum masuk history — dan pesan yang mereferensikan AC serta clarification menjadikan git log sebagai dokumentasi keputusan, bukan sekadar catatan perubahan.
10.8 Post-implement Hook di Aksi
Hook go build ./... && go vet ./... yang sudah kita configure di specify.config.json berjalan otomatis setelah setiap task. Output berikut menunjukkan apa yang terjadi ketika hook menemukan build failure.
1[Task 2.2 complete]
2Running post_implement hook: go build ./... && go vet ./...
3
4go build:
5 Building github.com/santekno/santekno-shop/internal/product/repository...
6 ERROR: internal/product/repository/postgres_repository.go:187:3:
7 undefined: usecase.SortByRelevance
8
9 Spec Kit detected build failure!
10 The generated code references usecase.SortByRelevance which doesn't exist yet.
11
12 Suggestion: This error will be resolved when Task 1.2 (Add Search DTOs) is complete.
13 Task 1.2 should have been run before Task 2.2.
14
15 Action: Run 'specify implement product-search --task=1.2' first,
16 then re-run '--task=2.2'Pelajaran pentingnya: hook yang gagal adalah sinyal bahwa urutan task belum lengkap, dan Spec Kit tidak hanya melapor error tapi juga menyarankan task mana yang harus dijalankan lebih dulu — mencegah kamu terjebak menebak-nebak.
10.9 Specify implement –dry-run
Sebelum menjalankan implementasi panjang yang bisa memakan berjam-jam, gunakan --dry-run untuk melihat peta lengkap tanpa menulis satu file pun.
1specify implement product-search --all --dry-run
2
3# Output:
4# [DRY RUN] Product Search Implementation Plan
5#
6# Phase 1: Infrastructure (2 tasks)
7# Would create: migrations/20250702001_add_search_index.sql
8# Would modify: internal/product/usecase/dto.go
9#
10# Phase 2: Data Layer (4 tasks)
11# Would modify: internal/product/usecase/interface.go
12# Would modify: internal/product/repository/postgres_repository.go
13# Would create: internal/product/usecase/search_usecase.go
14#
15# Phase 3: Business Logic Tests (4 tasks)
16# Would create: internal/product/usecase/search_usecase_test.go
17#
18# Phase 4: HTTP Layer (4 tasks)
19# Would create: internal/product/handler/search_handler.go
20# Would create: internal/product/handler/search_handler_test.go
21# Would modify: internal/product/handler/router.go
22#
23# Phase 5: Integration (2 tasks)
24# Would modify: cmd/server/main.go
25#
26# Total: 16 tasks
27# Estimated time: 11.5 hours
28# Files to create: 5
29# Files to modify: 5
30#
31# Run without --dry-run to execute.Dengan dry-run kamu bisa memvalidasi cakupan perubahan, memperkirakan waktu, dan menangkap file yang seharusnya tidak tersentuh — semuanya sebelum satu baris kode ditulis.
10.10 Monitoring Progress Secara Real-time
Untuk fitur besar, kamu ingin tahu persis di task mana progres berada dan berapa biayanya. Flag --verbose menampilkan log real-time lengkap dengan timing dan token usage.
1# Jalankan implement dengan verbose logging
2specify implement product-search --phase=2 --verbose
3
4# Output real-time:
5[09:15:00] Starting Phase 2: Data Layer
6[09:15:00] Task 2.1: Add SearchUseCase Interface
7[09:15:00] Reading interface.go (current: 127 lines)
8[09:15:02] API call started (claude-sonnet-4-20250514)
9[09:15:12] API response received (10.1s, 892 tokens, $0.003)
10[09:15:12] Writing interface.go (new: 152 lines)
11[09:15:12] Running go generate ./internal/product/usecase/...
12[09:15:18] Mock regenerated: mocks/mock_product_repository.go
13[09:15:18] Running go build ./...
14[09:15:21] Build: OK ✓
15[09:15:21] Task 2.1: DONE ✓ (21 seconds)
16
17[09:15:21] Task 2.2: Implement SearchProducts Repository
18[09:15:21] Reading postgres_repository.go (current: 234 lines)
19[09:15:24] API call started...
20...Verbose logging berguna bukan hanya untuk troubleshooting, tapi juga untuk membangun intuisi biaya: melihat $0.003 per task membantu kamu memutuskan kapan cukup memakai model yang lebih murah.
10.11 Menangani Rate Limiting
Untuk fitur kompleks dengan banyak task, kamu bisa menabrak API rate limit. Konfigurasi retry berikut membuat Spec Kit menangani hal ini secara otomatis dengan exponential backoff.
1// specify.config.json
2{
3 "ai": {
4 "max_retries": 5,
5 "retry_delay_seconds": 30
6 }
7}Selain menaikkan retry, strategi hemat lain adalah memakai model yang lebih murah untuk task sederhana dan menyisakan model besar untuk logika kompleks.
1# Task sederhana (DTO, boilerplate) dengan model murah
2specify implement product-search --phase=1 --model=claude-haiku-4-5-20251001
3
4# Task kompleks (SQL, business logic) dengan model besar
5specify implement product-search --phase=2 --model=claude-sonnet-4-20250514Memisahkan model per kompleksitas task menekan biaya sekaligus mengurangi tekanan pada rate limit — task DTO tidak butuh “otak” sebesar task query full-text search.
10.12 Specify implement untuk Multiple Features Paralel
Ketika dua developer mengerjakan dua fitur berbeda, specify implement bisa berjalan paralel tanpa saling mengganggu. Ilustrasi berikut menunjukkan dua terminal berjalan bersamaan.
1Dev A terminal:
2specify implement product-search --phase=1
3
4Dev B terminal:
5specify implement cancel-order --phase=1Selama kedua fitur menyentuh file yang berbeda, tidak akan ada conflict — masalah baru muncul jika ada file shared seperti router.go, dan di titik itu koordinasi manual tetap diperlukan.
10.13 Output Quality Indicators
Setelah implement selesai, jangan hanya percaya bahwa “kode sudah jadi” — minta laporan kualitas terukur. Flag --report merangkum build, test, kepatuhan constitution, dan spec coverage dalam satu tampilan.
1# Setelah implement selesai, cek quality metrics
2specify implement product-search --report
3
4# Output:
5# Implementation Report: product-search Phase 1-4
6#
7# Code Quality:
8# - Lines of Go code generated: 487
9# - go build: PASS ✓
10# - go vet: PASS ✓
11# - go test ./...: 11/12 PASS (1 failing)
12# FAIL: TestSearchProducts_OutOfStockProduct_IsAvailableFalse
13# Expected: false, Got: true (is_available mapping issue)
14#
15# Constitution Compliance:
16# - Error wrapping: 12/12 correct ✓
17# - context.Context usage: 8/8 correct ✓
18# - uuid.UUID for IDs: 6/6 correct ✓
19# - No ORM detected ✓
20#
21# Spec Coverage:
22# - ACs covered: 8/8 ✓
23# - Error codes correct: 5/5 ✓
24# - Missing: AC2a (is_available logic needs fix)Laporan seperti ini menautkan angka ke tindakan: satu test yang fail langsung menunjuk fungsi dan AC yang bermasalah, sehingga kamu tahu persis apa yang perlu diperbaiki sebelum PR.
10.14 Iterating pada Implementasi
Ketika laporan menemukan masalah, alurnya adalah fix, test, lalu update status task. Urutan perintah berikut menutup satu siklus iterasi.
1# Fix issue yang terdeteksi oleh report
2vim internal/product/repository/postgres_repository.go
3# Fix: p.stock > 0 AS is_available sudah correct di SQL
4# Issue: scan code pakai &p.IsAvailable tapi struct-nya belum di-update
5
6# Re-run test setelah fix
7go test ./internal/product/...
8
9# Update tasks.md: task 2.2 done, note the fix
10vim .specify/features/product-search/tasks.mdKuncinya adalah selalu menutup loop di tasks.md: mencatat “task 2.2 done + note the fix” menjaga status tetap jujur, sehingga --continue di sesi berikutnya tidak mengulang task yang sudah beres.
10.15 Specify implement dengan Custom Context
Kadang ada konteks runtime yang tidak ada di file spec mana pun — misalnya keterbatasan environment database. Flag --context menyuntikkan informasi ini ke prompt tanpa mengubah spec.
1# Tambahkan context tambahan ke implement
2specify implement product-search --task=2.2 \
3 --context="Note: Our PostgreSQL instance does not have the 'indonesian'
4 dictionary installed. Use 'simple' dictionary as fallback."Context ini di-inject sebagai section “Additional Context” di prompt, berguna untuk kondisi yang sifatnya sementara atau spesifik infrastruktur dan tidak layak dipermanenkan di spec.
10.16 Commit Strategy Setelah implement
Setelah implement, kamu perlu memutuskan granularitas commit. Strategi pertama, satu commit per task, memberi jejak paling detail.
1git commit -m "feat(product-search): add search DTOs [task 1.2]"
2git commit -m "feat(product-search): add repository interface [task 2.1]"
3# ...Strategi ini memaksimalkan traceability per task, tapi bisa membuat git log panjang jika fitur punya banyak task.
Strategi kedua, satu commit per phase, menyeimbangkan detail dan keterbacaan.
1# Setelah Phase 1 selesai:
2git commit -m "feat(product-search): complete Phase 1 (infrastructure)
3
4Task 1.1: Database migration for FTS index
5Task 1.2: Search DTOs (SearchQuery, SearchResult, SortOption)"Strategi ketiga, satu commit per PR, meng-squash semuanya saat merge untuk git log yang paling bersih.
1# Squash saat merge PR
2# PR title: "feat(SHOP-123): implement product search"Rekomendasinya adalah strategi kedua (per phase): cukup granular untuk menelusuri progres tanpa membanjiri history dengan commit per task.
10.17 Specify implement vs Manual Claude Code Session
Tidak semua pekerjaan cocok untuk specify implement — sebagian lebih baik dikerjakan dalam sesi manual Claude Code. Panduannya sederhana.
Gunakan specify implement:
- Task yang well-defined di
tasks.md - Implementation yang straightforward dari plan
- Batch implementation (multiple tasks)
Gunakan manual Claude Code session:
- Task yang sangat complex dan butuh back-and-forth
- Architectural exploration yang belum ter-plan
- Debugging yang membutuhkan iterasi cepat
- Task yang tidak cocok dengan format
tasks.md
Kombinasi optimalnya: specify implement untuk sekitar 80% task yang terstruktur, dan sesi manual untuk 20% yang kompleks dan eksploratif.
10.18 Tips & Gotchas
💡 Tip 1: Selalu mulai dengan –dry-run untuk fitur besar — preview apa yang akan terjadi sebelum eksekusi yang bisa memakan 3-4 jam.
💡 Tip 2: Review setiap phase sebelum lanjut — bug yang ditemukan di Phase 1 jauh lebih murah di-fix daripada bug yang baru ketahuan di Phase 4.
💡 Tip 3: Gunakan –verbose untuk troubleshooting — verbose output menampilkan token usage, timing, dan context yang di-kirim ke AI.
💡 Tip 4: Perhatikan test yang fail, jangan skip — test yang fail setelah implement adalah indikator langsung adanya gap antara spec dan implementasi.
⚠️ Gotcha 1: specify implement mengoverwrite file tanpa konfirmasi — jika kamu edit manual lalu run implement lagi pada task yang sama, edit manual akan hilang. Gunakan flag --merge (jika tersedia) atau backup dulu.
⚠️ Gotcha 2: Context window limitation untuk codebase besar — jika internal/ sangat besar, Spec Kit mungkin tidak bisa include semua kode existing. Gunakan --scope untuk membatasi codebase yang di-scan.
⚠️ Gotcha 3: Auto-commit bisa menyebabkan commit yang terlalu granular — setiap task menghasilkan satu commit dan bisa membuat git log noise. Pertimbangkan squash sebelum merge.
⚠️ Gotcha 4: Jangan implement tanpa spec dan plan yang approved — specify implement tanpa spec dan plan sama dengan vibe coding yang lebih mahal. Seluruh value Spec Kit ada di context yang di-bawa ke implementasi.
10.19 specify implement dalam CI Pipeline
Agar konsistensi terjaga otomatis, integrasikan validasi implementasi ke CI. Job berikut menjalankan test, spec compliance check, dan gate coverage minimum.
1# Untuk validasi bahwa implementation match tasks.md
2- name: Verify Implementation Completeness
3 run: |
4 # Run semua test
5 go test ./...
6
7 # Run spec compliance check
8 specify validate --feature=product-search
9
10 # Check coverage target
11 go test -coverprofile=coverage.out ./internal/product/...
12 coverage=$(go tool cover -func coverage.out | grep total | awk '{print $3}' | tr -d '%')
13 if (( $(echo "$coverage < 85" | bc -l) )); then
14 echo "Coverage $coverage% is below target 85%"
15 exit 1
16 fiDengan gate ini, PR yang coverage-nya di bawah 85% atau melenceng dari spec akan gagal di CI — quality gate yang tidak bergantung pada disiplin manual reviewer.
10.20 Ringkasan
specify implement adalah tahap eksekusi dari siklus Spec Kit. Dengan context lengkap dari semua tahap sebelumnya, AI dapat menghasilkan kode Go yang konsisten dengan architecture, conventions, dan business logic yang sudah di-spec.
Gunakan per-phase: --phase=N adalah mode yang paling direkomendasikan — memberikan review checkpoint setelah setiap phase.
Review setiap output: Implementasi AI adalah starting point yang sangat baik, bukan final product. Constitution compliance, optimasi SQL, dan test coverage tetap perlu diverifikasi manual.
Iterasi adalah normal: Jika output tidak sempurna, fix manual dan lanjut. Jangan regenerate semua hanya karena satu bagian yang perlu diperbaiki.
Dengan menyelesaikan artikel ini, kita telah mempelajari semua enam perintah inti Spec Kit. Berikutnya kita akan melihat bagaimana semua perintah ini bekerja bersama dalam sebuah studi kasus nyata dari constitution hingga merge.