Skip to content
Santekno.com | Level Up Your Engineering Skills
ID
📖 0%
25 Aug 2026 · 19 mnt baca ·Artikel 30 / 208
Go

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.

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

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.

text
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 consistent

Inti 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.

bash
1specify implement product-search --phase=1

Mode 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.

bash
1specify implement product-search --task=2.2

Gunakan 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.

bash
1specify implement product-search --continue

Mode 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.

bash
1specify implement product-search --all

Mode 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.

text
 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: 2

Yang 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.

sql
 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.

go
 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.

go
 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.

text
 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.

go
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.

go
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.

bash
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.

json
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.

text
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.

bash
 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.

text
 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.

bash
 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.

bash
 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.

json
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.

bash
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-20250514

Memisahkan 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.

text
1Dev A terminal:
2specify implement product-search --phase=1
3
4Dev B terminal:
5specify implement cancel-order --phase=1

Selama 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.

bash
 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.

bash
 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.md

Kuncinya 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.

bash
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.

bash
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.

bash
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.

bash
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 approvedspecify 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.

yaml
 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    fi

Dengan 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.

Artikel Terkait

💬 Komentar