Debugging Workflow Spec Kit: Ketika Claude Tidak Ikuti Spec
Cara mendeteksi dan memperbaiki ketika Claude Code tidak mengikuti instruksi dari spec di GitHub Spec Kit. Debugging workflow, spec audit, dan enforcement strategies untuk proyek Golang.
Debugging Workflow: Ketika Claude Melewati Instruksi Spec
Debugging workflow spec kit golang menjadi krusial karena bahkan dengan Spec Kit yang terstruktur, Claude Code kadang menghasilkan implementasi yang berbeda dari yang dispesifikasikan. Ini bukan kegagalan AI — ini adalah human oversight point yang kita butuhkan untuk menjaga kualitas. Di artikel ini kita bahas cara mendeteksi, mendebug, dan mencegah spec deviation di proyek Golang secara sistematis.
15.1 Jenis-Jenis Spec Deviation
Sebelum mendeteksi deviation, kita perlu mengenali bentuk-bentuknya lebih dulu. Daftar berikut mengategorikan lima jenis deviation yang paling sering muncul beserta contoh konkretnya.
11. Missing Implementation
2 Spec: AC13: Rating di luar 1-5 → 400 Bad Request
3 Reality: Tidak ada validasi rating di handler atau usecase
4
52. Wrong Implementation
6 Spec: AC14: Belum beli → 422 PURCHASE_REQUIRED (error code)
7 Reality: Handler return 403 dengan code "FORBIDDEN" (wrong status + wrong code)
8
93. Extra Implementation (scope creep)
10 Spec: Hanya GET, POST, DELETE untuk reviews
11 Reality: Claude juga buat PATCH endpoint yang tidak dispesifikasikan
12
134. Architecture Deviation
14 Spec (via constitution): Repository harus return domain error, bukan DB error
15 Reality: Repository langsung return pgx.ErrNoRows ke usecase
16
175. NFR Deviation
18 Spec: Response time p95 < 200ms
19 Reality: Query tidak ada index, p95 bisa 800ms di productionMengenali kategori deviation ini penting karena masing-masing butuh strategi deteksi dan perbaikan yang berbeda — missing implementation ketahuan dari audit AC, sedangkan NFR deviation baru muncul di load test.
15.2 Detect: specify audit
Alat pertama dan utama untuk mendeteksi deviation adalah specify audit. Perintah berikut memeriksa implementasi terhadap setiap AC dan EC di spec, lalu melaporkan mana yang lolos dan mana yang tidak.
1# Audit implementasi terhadap spec
2specify audit --feature product-review
3
4# Output:
5# 🔍 Auditing feature: product-review
6#
7# Checking AC compliance...
8# ✅ AC1: POST endpoint exists (/products/:id/reviews)
9# ✅ AC2: Purchase verification implemented (HasDeliveredOrder check)
10# ✅ AC3: Review stored with PUBLISHED status
11# ✅ AC4: Average rating updated in transaction
12# ✅ AC5: Response 201 with review data
13# ✅ AC6: GET endpoint with pagination
14# ✅ AC7: Response includes avg rating and count
15# ✅ AC8: DELETE requires admin role
16# ✅ AC9: Soft delete implemented
17# ✅ AC10: Rating recalculated after delete
18# ✅ AC11: Rating validation (1-5 range)
19# ❌ AC12: Content length validation — NOT FOUND
20# Expected: validation for max 1000 characters
21# Found: no content length check in handler or usecase
22# ✅ AC13: PURCHASE_REQUIRED error code verified
23# ✅ AC14: ALREADY_REVIEWED error code verified
24# ✅ AC15: 404 NOT_FOUND for missing review
25# ✅ AC16: 403 FORBIDDEN for non-admin
26#
27# Checking EC compliance...
28# ✅ EC1: UNIQUE INDEX found in migration
29# ✅ EC2: Atomic transaction in repository
30# ⚠️ EC3: Product cascade — not explicitly handled (acknowledged in plan)
31#
32# Summary:
33# ACs: 15/16 (93.8%)
34# ECs: 2/3 + 1 acknowledged (100%)
35#
36# Action required:
37# - Fix AC12: Add content length validationOutput audit ini langsung menunjuk AC12 sebagai satu-satunya yang gagal — mengubah pekerjaan “membaca ulang seluruh kode untuk cari yang salah” menjadi satu action item yang spesifik dan bisa dieksekusi.
15.3 Debugging AC12: Missing Validation
Setelah audit menemukan AC yang gagal, langkah berikutnya adalah melokalisasi masalahnya. Mode debug berikut menunjukkan persis di file dan method mana validasi seharusnya berada.
1# Debug mode: lihat di mana seharusnya validasi ini ada
2specify audit --feature product-review --debug AC12
3
4# Output:
5# Debugging AC12: Content length validation
6#
7# Spec says:
8# "Content kosong atau > 1000 karakter → 400 Bad Request"
9#
10# Plan says (plan.md):
11# Task 01: Review Domain Entity
12# - Tambah: Validation: Content max 1000 chars
13#
14# Checking implementation...
15# ❌ internal/domain/review/entity.go — validate() method:
16# Only checks: content is not empty
17# Missing: len(content) <= 1000 check
18#
19# ❌ internal/usecase/review/create_review.go — Execute():
20# No content length check before calling repository
21#
22# ❌ internal/delivery/http/handler/review_handler.go — CreateReview():
23# No content length check before calling usecase
24#
25# Recommendation:
26# Best fix location: internal/domain/review/entity.go validate() method
27# (Domain validation is the canonical place per Clean Architecture)
28#
29# Suggested code:
30# func (r *Review) validate() error {
31# if len(r.Content) == 0 {
32# return errors.New("content is required")
33# }
34# if len(r.Content) > 1000 { // ← ADD THIS
35# return ValidationError{ // ← ADD THIS
36# Field: "content",
37# Message: "content must be at most 1000 characters",
38# }
39# }
40# return nil
41# }Debug output tidak hanya bilang “AC12 hilang” tapi menunjuk tiga layer sekaligus dan merekomendasikan lokasi fix yang paling kanonik menurut Clean Architecture — menghemat waktu menebak di mana validasi seharusnya diletakkan.
15.4 Fix dan Re-audit
Dengan lokasi masalah sudah jelas, perbaikan bisa dilakukan lalu diverifikasi ulang. Perintah berikut mendelegasikan fix ke Claude Code dan menjalankan audit lagi untuk konfirmasi.
1# Fix implementasi berdasarkan suggestion
2# (bisa manual atau minta Claude Code fix-nya)
3
4claude
5
6> Fix AC12 di .specify/features/product-review/spec.md:
7 Content validation max 1000 karakter.
8
9 Lokasi yang perlu di-fix (dari specify audit debug):
10 - internal/domain/review/entity.go validate() method
11
12 Setelah fix, run:
13 go test ./internal/domain/review/... -run TestReviewValidation
14
15 Pastikan test coverage untuk content validation ada.
16
17# Setelah fix:
18specify audit --feature product-review
19
20# Expected:
21# ACs: 16/16 (100%) ✅Siklus fix-lalu-re-audit ini adalah inti debugging spec-driven: kamu tidak menganggap masalah selesai sampai audit menunjukkan 16/16, bukan sekadar karena kode “terlihat benar”.
15.5 Spec Deviation karena Context yang Kurang
Kadang deviation bukan karena AI salah, tapi karena konteks yang diberikan kurang lengkap. Skenario berikut menggambarkan kasus di mana Spec Kit tidak tahu keberadaan file konstanta error.
1Scenario: speckit.implement menghasilkan hard-coded string "PURCHASE_REQUIRED"
2tapi tim punya konstanta di internal/domain/errors/codes.go
3
4Problem: speckit.implement tidak tahu file errors/codes.go exists
5
6Fix: Tambahkan ke CLAUDE.md dan .speckit-config.yamlAkar masalahnya jelas: AI tidak bisa memakai apa yang tidak dilihatnya. Solusinya adalah memasukkan file penting ke daftar context yang selalu disertakan, seperti konfigurasi berikut.
1# .speckit-config.yaml
2context:
3 always_include:
4 - CLAUDE.md
5 - internal/domain/errors/codes.go # ← tambahkan ini
6 - internal/domain/errors/types.goSetelah context diperbaiki, task yang bermasalah bisa di-generate ulang dengan informasi yang lebih lengkap lewat perintah berikut.
1# Regenerate task yang bermasalah dengan context yang lebih lengkap
2specify implement --feature product-review \
3 --task 07 \
4 --force \ # override task yang sudah done
5 --context "internal/domain/errors/codes.go"Pelajaran dari kasus ini: sebelum menyalahkan AI, cek dulu apakah ia punya context yang cukup — sering kali fix-nya ada di always_include, bukan di kode.
15.6 Architecture Deviation: Pola yang Salah
Deviation yang lebih halus terjadi saat kode berfungsi tapi melanggar aturan arsitektur. Contoh Go berikut menunjukkan repository yang membocorkan error database ke layer domain, dibandingkan dengan versi yang benar sesuai konstitusi.
1// ❌ Generated code (architecture deviation):
2func (r *reviewRepository) GetByID(ctx context.Context, id uuid.UUID) (*domain.Review, error) {
3 var review domain.Review
4 err := r.pool.QueryRow(ctx, query, id).Scan(...)
5 if err == pgx.ErrNoRows {
6 return nil, pgx.ErrNoRows // ← WRONG: leaking DB error ke domain
7 }
8 return &review, err
9}
10
11// ✅ What spec kit should have generated (per constitution.md):
12func (r *reviewRepository) GetByID(ctx context.Context, id uuid.UUID) (*domain.Review, error) {
13 var review domain.Review
14 err := r.pool.QueryRow(ctx, query, id).Scan(...)
15 if err == pgx.ErrNoRows {
16 return nil, nil // ← CORRECT: return nil,nil untuk not-found
17 }
18 if err != nil {
19 return nil, fmt.Errorf("reviewRepository.GetByID: %w", err) // wrap error
20 }
21 return &review, nil
22}Perbedaan return nil, pgx.ErrNoRows versus return nil, nil terlihat sepele tapi berdampak besar: yang pertama membocorkan detail database ke seluruh aplikasi, melanggar batas layer Clean Architecture. Penyebabnya biasanya karena constitution.md atau CLAUDE.md tidak cukup eksplisit tentang pattern ini — dan perbaikannya adalah menuliskannya secara gamblang seperti berikut.
1## Repository Error Handling
2
3WAJIB ikuti pattern ini:
41. Not found → return (nil, nil) — BUKAN pgx.ErrNoRows
52. Database error → return (nil, fmt.Errorf("context: %w", err))
63. JANGAN return database-level errors (pgx errors) ke usecase layer
74. Usecase yang cek if repo returns nil = not found
8
9Contoh:
10✅ return nil, nil // not found
11✅ return nil, fmt.Errorf("reviewRepository.GetByID: %w", err)
12❌ return nil, pgx.ErrNoRows
13❌ return nil, err // tanpa wrapDengan menuliskan contoh BENAR dan SALAH secara eksplisit di konstitusi, kamu menutup celah interpretasi — AI tidak lagi menebak pattern error handling karena aturannya sudah hitam-putih.
15.7 Scope Creep Detection
Kebalikan dari missing implementation adalah scope creep: AI membuat lebih dari yang diminta. Perintah berikut memeriksa endpoint dan file yang tidak ada di spec.
1# Cek scope creep: endpoint yang tidak ada di spec
2specify audit --feature product-review --check-scope
3
4# Output:
5# 🔍 Scope check: product-review
6#
7# Endpoints in implementation:
8# ✅ POST /products/:id/reviews — in spec (AC1)
9# ✅ GET /products/:id/reviews — in spec (AC6)
10# ✅ DELETE /products/:id/reviews/:review_id — in spec (AC8)
11# ⚠️ PATCH /products/:id/reviews/:review_id — NOT in spec!
12#
13# Files created outside of task scope:
14# ⚠️ internal/usecase/review/update_review.go — not in tasks.md!
15#
16# Scope creep detected:
17# - PATCH endpoint implemented without AC
18# - update_review usecase created without spec
19#
20# Recommendation:
21# 1. If PATCH is needed: add AC to spec, get approval, then keep
22# 2. If PATCH is NOT needed: remove the filesScope check ini membuat kode “bonus” dari AI terlihat jelas alih-alih diam-diam masuk ke codebase. Responsnya ada dua jalur. Jika endpoint memang tidak diperlukan, hapus file-nya seperti berikut.
1rm internal/usecase/review/update_review.go
2git rm internal/usecase/review/update_review.go
3# Remove dari router jugaSebaliknya, jika fitur itu ternyata memang dibutuhkan tapi terlupa dari spec, formalkan dengan menambahkan AC baru seperti berikut.
1# Tambahkan AC ke spec
2specify update-spec --feature product-review \
3 --add-ac "AC17: PATCH /products/:id/reviews/:review_id untuk update review" \
4# Atau edit spec.md manual dan run specify audit lagi untuk verifyKunci menangani scope creep bukan langsung menghapus, tapi memutuskan: apakah kode ini seharusnya ada? Jika ya, spec-kan dulu agar tetap traceable; jika tidak, buang tanpa ragu.
15.8 DoD yang Lolos tapi Behavior Salah
Kasus paling berbahaya adalah ketika semua test hijau tapi perilaku sebenarnya salah. Skenario berikut menunjukkan bagaimana integer division lolos test karena data test kebetulan genap.
1Scenario:
2Spec: AC10 → Rating di-recalculate setelah delete
3Test: TestDeleteReview_RecalculatesRating — PASS
4
5Reality:
6Test menggunakan average = (sum / count) dengan integer division
7Hasil: (4+5)/2 = 4 (seharusnya 4.5)
8
9Test pass karena: test data punya average yang genap
10Production fail karena: real data sering tidak genapMasalahnya bukan di kode produksi saja, tapi di test yang terlalu lemah untuk menangkap bug. Perbandingan Go berikut memperlihatkan test lemah versus test kuat yang menguji nilai desimal.
1// ❌ Test yang terlalu lemah:
2func TestDeleteReview_RecalculatesRating(t *testing.T) {
3 // Setup: reviews dengan rating 4 dan 5 → avg 4.5
4 // After delete rating 4: avg should be 5.0
5 assert.Equal(t, 5.0, product.AverageRating) // OK: 5.0 genap
6}
7
8// ✅ Test yang lebih kuat:
9func TestDeleteReview_RecalculatesRating_PreservesDecimal(t *testing.T) {
10 // Setup: reviews dengan rating 4, 4, 5 → avg 4.33
11 // After delete rating 5: avg should be 4.0
12 assert.Equal(t, float64(4), product.AverageRating) // Test dengan nilai desimal
13
14 // Setup: reviews dengan rating 3, 4 → avg 3.5
15 // No delete — just verify precision
16 assert.InDelta(t, 3.5, product.AverageRating, 0.01)
17}Test kuat sengaja memilih angka yang menghasilkan pecahan (4.33, 3.5) sehingga integer division langsung ketahuan gagal — pelajaran bahwa test data harus dipilih untuk memancing bug, bukan untuk memvalidasi happy path. Untuk mencegah kasus serupa, perkuat DoD di tasks seperti berikut.
1# Tambahkan ke DoD di tasks.md untuk task rating-related:
2specify tasks --edit 10 \
3 --add-dod "- [ ] Rating calculation preserves decimal: 3.5 not 3 or 4"
4
5# Regenerate task dan re-implement
6specify implement --feature product-review --task 10 --forceMenambahkan DoD yang eksplisit soal presisi desimal memaksa implementasi berikutnya menangani kasus pecahan sejak awal — mencegah bug behavioral yang lolos dari test dangkal.
15.9 Error Code yang Tidak Match Spec
Deviation yang paling sering muncul adalah error code yang tidak persis sama dengan spec. Skenario berikut menunjukkan mismatch huruf besar-kecil yang mudah terlewat.
1Spec: AC13: "Belum beli → 422 PURCHASE_REQUIRED"
2
3Generated code:
4HTTP 422 Unprocessable Entity ✅
5JSON: {"error": "purchase_required"} ← case mismatch! Spec says "PURCHASE_REQUIRED"Status code-nya benar, tapi string error-nya beda kapitalisasi — cukup untuk membuat client yang mem-parsing error code jadi gagal. Audit bisa menangkap ini dengan pencocokan string eksak seperti berikut.
1# specify audit melakukan grep untuk exact string
2specify audit --feature product-review --ac AC13
3
4# Output:
5# Checking AC13: PURCHASE_REQUIRED error code
6# Searching for: "PURCHASE_REQUIRED" in handler and response
7#
8# Found: "purchase_required" (lowercase) in handler response
9# Expected: "PURCHASE_REQUIRED" (uppercase as per spec)
10#
11# ❌ AC13 FAIL: Error code case mismatch
12#
13# Fix: Change error code from "purchase_required" to "PURCHASE_REQUIRED"
14# Location: internal/delivery/http/handler/review_handler.go:89Cara paling ampuh mencegah mismatch semacam ini adalah menghilangkan string literal sama sekali dan memakai konstanta terpusat, seperti pola Go berikut.
1// internal/domain/errors/codes.go
2const (
3 ErrCodePurchaseRequired = "PURCHASE_REQUIRED" // exact match dengan spec
4 ErrCodeAlreadyReviewed = "ALREADY_REVIEWED"
5 ErrCodeOrderNotFound = "ORDER_NOT_FOUND"
6)
7
8// Handler selalu pakai konstanta, bukan string literal
9c.JSON(http.StatusUnprocessableEntity, map[string]string{
10 "error": domain.ErrCodePurchaseRequired, // ← tidak bisa typo
11})Dengan konstanta terpusat, typo kapitalisasi menjadi mustahil karena compiler yang menjaganya — satu perubahan struktural yang mematikan seluruh kelas deviation error code sekaligus.
15.10 Debugging speckit.implement yang Gagal di Tengah
Tidak semua kegagalan soal deviation — kadang proses implement berhenti karena error teknis. Perintah berikut menunjukkan cara resume atau restart dari task tertentu.
1# Jika speckit.implement berhenti di tengah karena error:
2specify implement --feature product-review
3
4# Output:
5# ... task 07 dimulai ...
6# ❌ FATAL: Claude API timeout after 30 seconds
7# Implementation session aborted
8
9# Recovery:
10specify implement --feature product-review --resume
11# Resume dari task yang belum selesai
12
13# Jika perlu restart dari task tertentu:
14specify implement --feature product-review --start-from 07Karena Spec Kit melacak status per task, kamu bisa melanjutkan dari titik gagal tanpa mengulang task yang sudah selesai — menghemat token dan waktu saat sesi panjang terputus di tengah jalan.
15.11 Audit dalam CI/CD
Deteksi manual saja tidak cukup untuk tim; enforcement harus otomatis. Workflow berikut menjalankan specify audit di setiap PR dan menggagalkan CI jika ada AC yang belum terimplementasi.
1# .github/workflows/spec-audit.yml
2- name: Run spec audit
3 run: |
4 # Ambil feature name dari PR
5 FEATURE=$(echo "${{ github.head_ref }}" | sed 's/feature\/[A-Z0-9-]*-//')
6
7 if [ -d ".specify/features/$FEATURE" ]; then
8 specify audit --feature $FEATURE
9
10 # Fail CI jika ada AC yang missing
11 AC_MISSING=$(specify audit --feature $FEATURE --format json | jq '.acs.missing | length')
12 if [ "$AC_MISSING" -gt "0" ]; then
13 echo "❌ $AC_MISSING ACs not implemented"
14 exit 1
15 fi
16
17 echo "✅ All ACs implemented"
18 fiDengan gate ini di CI, PR dengan AC yang belum lengkap tidak bisa di-merge — deviation tertangkap otomatis sebelum masuk main, tanpa bergantung pada reviewer yang mungkin lupa memeriksa.
15.12 Manual Debugging Checklist
Ketika audit otomatis tidak cukup menemukan masalah, pemeriksaan manual yang terstruktur diperlukan. Checklist berikut memandu penelusuran dari mapping spec-ke-kode hingga architecture check.
1## Manual Spec Debugging Checklist
2
3### Step 1: Spec vs Code Mapping
4Untuk setiap AC, cari tempat di kode yang mengimplementasikannya:
5- [ ] AC1 → handler method + route registration
6- [ ] AC2 → usecase business rule
7- [ ] AC13/AC14 → error type + response mapping
8
9### Step 2: Error Code Verification
10- [ ] Grep untuk setiap error code di spec: grep -r "PURCHASE_REQUIRED" internal/
11- [ ] Verify HTTP status code: handler return 422, bukan 400 atau 403
12- [ ] Verify response format: {"error": "PURCHASE_REQUIRED"}
13
14### Step 3: Behavioral Test
15- [ ] Integration test atau manual curl untuk setiap AC
16- [ ] Test boundary values (rating = 0, rating = 6, rating = 1, rating = 5)
17- [ ] Test edge cases (concurrent request, DB error simulation)
18
19### Step 4: Architecture Check
20- [ ] Repository tidak return DB error ke usecase
21- [ ] Usecase tidak import delivery/http package
22- [ ] Handler tidak import repository package
23- [ ] Domain tidak import external packagesChecklist berlapis ini menangkap deviation yang lolos audit otomatis — terutama architecture check dan behavioral test yang butuh penilaian manusia, bukan sekadar pattern matching.
15.13 Preventing Deviation: Upstream Fixes
Debugging bersifat reaktif; jauh lebih baik mencegah deviation sejak hulu. Perbandingan pertama menunjukkan bagaimana AC yang ambigu diperbaiki menjadi eksplisit.
1# ❌ Spec yang ambigu:
2AC12: Content yang tidak valid → return error
3
4# ✅ Spec yang eksplisit:
5AC12: Content kosong (length = 0) atau panjang > 1000 karakter
6 → HTTP 400 Bad Request
7 → JSON: {"error": "INVALID_CONTENT", "detail": "content must be 1-1000 characters"}AC yang menyebutkan angka, status code, dan format response persis meninggalkan sedikit ruang bagi AI untuk salah tafsir. Prinsip yang sama berlaku untuk DoD, seperti perbandingan berikut.
1# ❌ DoD yang lemah:
2- [ ] Content validation bekerja
3
4# ✅ DoD yang konkret:
5- [ ] curl POST review dengan content 1001 chars → 400 {"error": "INVALID_CONTENT"}
6- [ ] curl POST review dengan content kosong → 400 {"error": "INVALID_CONTENT"}
7- [ ] curl POST review dengan content 1 char → 201 (valid)
8- [ ] curl POST review dengan content 1000 chars → 201 (valid — boundary)DoD yang bisa langsung dieksekusi sebagai perintah curl mengubah “validasi bekerja” yang subjektif menjadi kriteria pass/fail yang objektif. Terakhir, konstitusi juga bisa dipertegas untuk aturan lintas fitur seperti berikut.
1# constitution.md
2## API Response Error Format
3Semua error response HARUS:
4- HTTP status: 4xx atau 5xx
5- Body: {"error": "ERROR_CODE_UPPER_SNAKE_CASE"}
6- Error code: WAJIB UPPERCASE dengan underscore (BUKAN lowercase)
7- Contoh BENAR: {"error": "PURCHASE_REQUIRED"}
8- Contoh SALAH: {"error": "purchase_required"} atau {"error": "purchaseRequired"}Ketiga upstream fix ini punya benang merah yang sama: semakin sedikit ambiguitas yang kamu tinggalkan di spec, DoD, dan konstitusi, semakin sedikit deviation yang perlu kamu debug di belakang.
15.14 Spec Audit sebagai Learning Tool
Hasil audit tidak hanya untuk memperbaiki satu fitur, tapi juga bahan belajar bagi tim. Perintah berikut menghasilkan laporan mingguan yang merangkum pola deviation paling sering.
1# Generate audit report mingguan
2specify audit --all-features --since "7 days ago" --output markdown > weekly-audit.md
3
4# Top deviation patterns minggu ini:
5# 1. Error code case mismatch (3 kali)
6# 2. Missing boundary validation (2 kali)
7# 3. Architecture deviation: DB error leak (1 kali)
8#
9# Action items:
10# → Tambahkan ke constitution.md: API error code UPPERCASE convention
11# → Tambahkan ke CLAUDE.md: boundary validation examples
12# → Tim training: clean architecture error handlingLaporan agregat ini mengubah deviation dari insiden individual menjadi sinyal sistemik — pola yang berulang tiga kali seminggu menandakan ada aturan yang perlu diperjelas di konstitusi, bukan sekadar developer yang ceroboh.
15.15 Tips & Gotchas
Sebelum masuk ke skenario recovery ekstrem, berikut sejumlah tips dan jebakan yang perlu diperhatikan saat mendebug spec deviation.
💡 Tip 1: Run specify audit sebelum raise PR — ini adalah self-check sebelum reviewer melihat kode. Tangkap deviation lebih awal.
💡 Tip 2: Include specify audit dalam PR checklist
1## PR Checklist
2- [x] specify audit --feature [name] — PASS (16/16 ACs)Mencantumkan hasil audit di PR memberi reviewer bukti objektif bahwa spec sudah dipenuhi sebelum mereka mulai membaca kode.
💡 Tip 3: Debug deviation secara sistematis — jangan langsung fix kode tanpa tahu akar masalahnya. Gunakan specify audit --debug AC{n} untuk lokalisasi masalah.
💡 Tip 4: Treat deviation sebagai signal untuk improve spec — jika deviation terjadi karena spec ambigu, perbaiki spec dulu, bukan hanya kode-nya.
⚠️ Gotcha 1: specify audit tidak sempurna — audit berbasis pattern matching dan AI analysis, tidak 100% akurat. Selalu combine dengan manual review.
⚠️ Gotcha 2: Scope creep tidak selalu salah — kadang Claude mengimplementasikan hal yang logis dan berguna yang tidak ada di spec. Evaluate sebelum delete, mungkin perlu di-spec-kan.
⚠️ Gotcha 3: DoD yang lolos bukan berarti behavior benar — test yang kuat diperlukan untuk menangkap behavioral deviation yang tidak terdeteksi oleh build dan basic test.
⚠️ Gotcha 4: Debugging dari audit output bisa misleading — jika audit salah mengidentifikasi masalah, debugging bisa ke arah yang salah. Verify secara manual sebelum melakukan perubahan besar.
Inti dari semua tips ini: perlakukan specify audit sebagai asisten yang mempercepat deteksi, bukan orakel yang selalu benar — keputusan akhir dan verifikasi tetap tanggung jawab manusia.
15.16 Recovery dari Implementasi yang Sangat Menyimpang
Untuk kasus ekstrem di mana implementasi terlalu jauh menyimpang, kadang lebih murah memulai ulang daripada menambal. Perintah berikut menunjukkan opsi reset penuh maupun reset selektif.
1# Option 1: Reset dan reimplementasi dari awal
2git checkout feature/SHOP-789-product-review
3git reset --hard {commit sebelum implement dimulai}
4
5# Perbaiki spec dan tasks, lalu reimplementasi
6specify tasks --regenerate # regenerate tasks dari plan yang sudah ada
7specify implement --feature product-review # mulai lagi
8
9# Option 2: Selective reset — hanya file yang bermasalah
10git checkout {base commit} -- internal/delivery/http/handler/review_handler.go
11# Implementasi ulang hanya file tersebut dengan context yang lebih baikKarena git history spec-driven mencatat commit “sebelum implement”, reset penuh maupun selektif menjadi aman dilakukan — kamu selalu punya titik pulih yang bersih untuk memulai ulang dengan context yang diperbaiki.
15.17 Dokumentasi Deviation yang Disengaja
Tidak semua deviation buruk — kadang ada alasan valid untuk menyimpang dari spec. Template berikut menunjukkan cara mendokumentasikan deviation yang disengaja beserta persetujuannya.
1# tasks.md — Task 04 completion note
2
3## Task 04: Repository Implementation
4**Status**: ✅ COMPLETE (dengan documented deviation)
5
6**Deviation from plan:**
7Plan mengatakan: gunakan SELECT FOR UPDATE
8Implementasi menggunakan: pgx advisory locks
9
10**Alasan:**
11Load test menunjukkan SELECT FOR UPDATE menyebabkan lock contention
12di flash sale scenarios (1000 req/detik untuk produk yang sama).
13Advisory locks lebih granular dan mencegah contention.
14
15**Spec impact:**
16EC1 (concurrent safety) masih terpenuhi — advisory locks memberikan
17mutual exclusion yang sama.
18
19**Reviewed by:** @budi (tech lead) — approved 2025-07-03Mendokumentasikan deviation lengkap dengan alasan, dampak ke spec, dan persetujuan tech lead mengubahnya dari “kode yang menyimpang misterius” menjadi keputusan sadar yang tercatat — sesuatu yang akan sangat dihargai developer berikutnya.
15.18 Iterasi: Spec → Impl → Audit → Fix → Re-audit
Seluruh proses ini pada dasarnya adalah loop iteratif. Diagram berikut merangkum siklus dari spec hingga re-audit yang lulus.
1Spec ──→ Implement ──→ Audit
2 ↑ │
3 │ ▼
4 └──── Fix spec ←─── Deviation found
5 jika perlu
6
7 atau
8
9 Fix implementation
10 └──→ Re-audit ──→ PASSDiagram ini menegaskan bahwa deviation bukan akhir, melainkan titik cabang: kamu memilih memperbaiki spec (jika ambigu) atau memperbaiki implementasi, lalu selalu kembali ke audit sampai PASS.
15.19 Spec Audit Score dan Quality Gate
Untuk enforcement yang terukur, audit bisa menghasilkan skor numerik. Perintah berikut menampilkan skor beserta rincian pengurangannya.
1# Get numerical audit score
2specify audit --feature product-review --score
3
4# Output:
5# Spec Audit Score: 97/100
6#
7# Deductions:
8# -2: EC3 tidak explicitly handled (acknowledged, tapi tidak documented di kode)
9# -1: 1 test assertion menggunakan approximation instead of exact value
10#
11# Quality gate: PASS (minimum: 90/100)Skor 97/100 dengan rincian pengurangan yang transparan memberi tim target konkret untuk diperbaiki. Skor ini kemudian bisa dijadikan gate keras di CI seperti berikut.
1- name: Spec quality gate
2 run: |
3 SCORE=$(specify audit --feature $FEATURE --score --format number)
4 if [ "$SCORE" -lt "90" ]; then
5 echo "❌ Spec audit score $SCORE < 90 (minimum)"
6 exit 1
7 fi
8 echo "✅ Spec audit score: $SCORE/100"Dengan quality gate berbasis skor, standar kualitas spec compliance menjadi angka yang tidak bisa ditawar — PR di bawah 90 otomatis ditolak, membuat “cukup baik” punya definisi yang jelas dan konsisten.
15.20 Ringkasan
Spec deviation adalah natural part of AI-assisted development — AI tidak sempurna, spec tidak selalu clear, dan kadang ada keputusan yang perlu dibuat selama implementasi. Yang penting adalah proses untuk mendeteksi dan memperbaikinya.
specify audit memberikan visibility ke mana spec tidak ter-implement dengan benar. specify audit --debug AC{n} melokalisasi masalah ke baris kode tertentu. CI integration memastikan deviation tidak bisa masuk ke main tanpa dideteksi.
Root cause dari kebanyakan deviation:
- Spec yang ambigu → fix spec sebelum implement
- Context yang kurang (CLAUDE.md tidak up-to-date) → fix CLAUDE.md
- DoD yang terlalu lemah → strengthen DoD di tasks
Di artikel berikutnya, kita masuk ke Part 4 — bagaimana Spec Kit bekerja untuk tim yang lebih besar: onboarding, shared constitution, dan kolaborasi yang terstruktur.