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

Struktur .specify Folder: Anatomy File Output GitHub Spec Kit di Golang

Pelajari anatomy semua file yang dihasilkan GitHub Spec Kit di folder .specify: constitution.md, spec.md, plan.md, tasks.md, dan history log untuk proyek Golang.

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

Struktur .specify Folder: Anatomy Output yang Dihasilkan

Memahami struktur .specify folder yang dihasilkan GitHub Spec Kit adalah fondasi sebelum kamu menjalankan perintah pertama. Kamu perlu tahu di mana file disimpan, apa isinya, dan bagaimana file-file itu saling berhubungan — karena di situlah seluruh “project memory” workflow SDD kamu tersimpan.

Di artikel ini kita bedah setiap file di dalam .specify/ folder secara detail, dari constitution.md sampai history log, sehingga kamu bisa menggunakan Spec Kit secara efektif untuk proyek Golang.


03.1 Overview Struktur Lengkap

Setelah menjalankan keenam perintah Spec Kit untuk satu fitur, kamu akan melihat struktur direktori seperti berikut. Perhatikan bagaimana setiap perintah berkontribusi pada satu file output tertentu.

text
 1santekno-shop/
 2├── .specify/
 3│   ├── constitution.md           ← Prinsip project (satu file untuk semua fitur)
 4│   ├── features/
 5│   │   ├── product-service/
 6│   │   │   ├── spec.md           ← Kebutuhan bisnis (dari specify feature)
 7│   │   │   ├── clarifications.md ← Jawaban klarifikasi (dari specify clarify)
 8│   │   │   ├── plan.md           ← Rencana teknis (dari specify plan)
 9│   │   │   └── tasks.md          ← Task breakdown (dari specify tasks)
10│   │   └── cancel-order/
11│   │       ├── spec.md
12│   │       ├── plan.md
13│   │       └── tasks.md
14│   ├── history/
15│   │   ├── 2025-07-01-product-service-specify.log
16│   │   ├── 2025-07-01-product-service-plan.log
17│   │   └── 2025-07-01-product-service-implement-phase1.log
18│   └── _templates/
19│       ├── constitution.md       ← Template default constitution
20│       └── spec.md               ← Template default spec
21└── specify.config.json           ← Konfigurasi project

Dari pohon direktori ini terlihat .specify/ memisahkan tiga hal: prinsip global (constitution.md), artefak per-fitur (features/), dan jejak audit (history/) — pemisahan yang akan kita telusuri satu per satu.


03.2 constitution.md: Prinsip yang Tidak Berubah

File paling penting di seluruh .specify/ folder. Dibaca oleh setiap perintah Spec Kit sebagai baseline context. Contoh berikut memperlihatkan isi constitution yang lengkap untuk Santekno Shop — tech stack, aturan arsitektur, hingga daftar “must always / must never”.

markdown
 1# Project Constitution: Santekno Shop
 2# Version: 1.0
 3# Last updated: 2025-07-01
 4# Updated by: @budi
 5
 6## Identity
 7This is **Santekno Shop** — a B2C e-commerce platform for Indonesia.
 8Language: Bahasa Indonesia for user-facing content, English for code.
 9
10## Tech Stack
11- Language: Go 1.22+
12- HTTP Framework: Echo v4 (labstack/echo/v4)
13- Database: PostgreSQL 15 via pgx/v5 (jackc/pgx/v5)
14- Cache: Redis 7 via go-redis/v9
15- Message Broker: Kafka via confluent-kafka-go v2
16- Testing: testify/suite v1.9 + gomock v1.6
17- UUID: github.com/google/uuid v1
18
19## Architecture: Clean Architecture
20
21### Layer Dependency (STRICT)
22```
23handler → usecase → repository → database
24```
25- Interfaces defined in usecase package (NOT domain)
26- Repository interfaces returned to usecase, not concrete types
27- No circular dependencies
28
29### Package Structure
30```
31internal/[domain]/
32├── domain/      ← Entity, errors, value objects
33├── usecase/     ← Business logic, interfaces
34├── repository/  ← Data access implementation
35└── handler/     ← HTTP handler, DTOs
36```
37
38## Must Always
39- `fmt.Errorf("function: %w", err)` for all error wrapping
40- `context.Context` as first parameter in all service/usecase/repo functions
41- `uuid.UUID` from github.com/google/uuid (NOT string IDs)
42- Store prices in **cents** as `int64` (NOT float, NOT string)
43- Structured logging via `log/slog`
44- Table-driven tests with `testify/suite`
45
46## Must Never
47- Use any ORM (GORM, Ent, SQLBoiler, etc.)
48- Call database directly from handler or usecase
49- Import usecase from repository (violates dependency direction)
50- Use `interface{}` or `any` without strong justification
51- Store secrets in code or committed config files
52- Use `time.Sleep` in production code without timeout context
53
54## Error Handling Pattern
55```go
56// Domain errors (sentinel)
57var ErrProductNotFound = errors.New("product not found")
58
59// Custom errors (when detail needed)
60type InsufficientStockError struct {
61    ProductID uuid.UUID
62    Available int
63    Requested int
64}
65
66// Wrapping pattern
67return fmt.Errorf("createOrder: validateStock: %w", err)
68```
69
70## Testing Conventions
71- Package: `package [name]_test` (external test package)
72- Naming: `Test[Feature]_[Condition]_[ExpectedResult]`
73- Mock generation: `//go:generate mockgen ...` in interface files
74- Coverage target: >= 85% for usecase layer
75
76## Database Conventions
77- Table names: snake_case plural (products, order_items)
78- Primary key: `id UUID PRIMARY KEY DEFAULT gen_random_uuid()`
79- Timestamps: `created_at TIMESTAMPTZ DEFAULT NOW()`
80- Soft delete: `deleted_at TIMESTAMPTZ` (nullable)
81- All queries: parameterized only (no string concatenation)

Karakteristik kunci dari contoh di atas: constitution tidak menyebut fitur spesifik apapun. Ini adalah prinsip universal yang berlaku untuk semua fitur, sehingga cukup ditulis sekali dan dibaca ulang di setiap perintah.


03.3 features/[name]/spec.md: Kebutuhan Bisnis

Dihasilkan oleh specify feature [name]. Sengaja ditulis tanpa menyebut tech stack — fokus pada apa yang user butuhkan, bukan bagaimana cara mengimplementasikannya. Perhatikan pada contoh berikut bahwa tidak ada satu pun baris kode Go, SQL, atau endpoint HTTP.

markdown
 1# Feature Specification: Product Catalog
 2
 3## Status: APPROVED
 4## Created: 2025-07-01
 5## Author: @andi (engineer), reviewed by @maya (PM)
 6## Spec Version: v1.2
 7
 8---
 9
10## User Story
11
12### Primary: Customer Browsing
13As a customer browsing Santekno Shop,
14I want to search and filter products by category and price range,
15so that I can find products that match my needs without scrolling through irrelevant items.
16
17### Secondary: Seller Management
18As a seller on Santekno Shop,
19I want to manage my product catalog (add, update, deactivate),
20so that customers always see accurate product information and availability.
21
22### Internal: Order Integration
23As the Order Service,
24I need to check and decrement product stock atomically,
25so that no order can be created for out-of-stock products.
26
27---
28
29## Core Capabilities
30
31### What users can do:
321. Search products by keyword (name and description)
332. Filter by category
343. Filter by price range (min and max)
354. Sort by: newest, price ascending, price descending, popularity
365. View product detail including all variants and stock status
376. See "low stock" warning when stock < 5 units
38
39### What sellers can do:
401. Create new product with: name, description, price, initial stock, category, photos
412. Update product details (price, description, photos)
423. Activate or deactivate product (deactivated products invisible to customers)
434. View their own product list with stock status
44
45### What the system automatically does:
461. Prevent stock from going negative (atomic operation)
472. Hide deactivated products from customer search
483. Show "out of stock" when stock reaches 0
49
50---
51
52## Business Rules
53
541. A product belongs to exactly one seller
552. Only the owning seller can modify a product
563. Deactivated products are NOT visible in customer search
574. Stock cannot go below 0 under any circumstance
585. Price must be positive (minimum: Rp 1)
596. Product name: 3-255 characters, required
607. Maximum 5 photos per product
618. Categories are fixed (not user-defined in this phase)
62
63---
64
65## What's Out of Scope (This Phase)
66- Product variants (size, color)  tracked as SHOP-892
67- Product reviews and ratings  tracked as SHOP-893
68- Bulk product import  tracked as SHOP-894
69- Product bundles  tracked as SHOP-895

Karakteristik kunci: tidak ada SQL, tidak ada HTTP endpoint, tidak ada kode Go di dalam spec. Semua detail teknis itu baru muncul di plan.md, sehingga spec tetap bisa dibaca oleh PM maupun stakeholder non-teknis.


03.4 features/[name]/plan.md: Rencana Teknis

Dihasilkan oleh specify plan [name]. Ini adalah dokumen teknikal yang dibuat oleh AI berdasarkan spec + constitution. Di sinilah tech stack, class diagram, schema database, dan urutan implementasi mulai muncul secara eksplisit.

markdown
  1# Technical Implementation Plan: Product Catalog
  2# Based on spec v1.2, constitution v1.0
  3# Generated: 2025-07-01
  4
  5## Architecture Overview
  6
  7```mermaid
  8classDiagram
  9    class ProductHandler {
 10        -usecase ProductUseCase
 11        +ListProducts(c echo.Context) error
 12        +GetProduct(c echo.Context) error
 13        +CreateProduct(c echo.Context) error
 14        +UpdateProduct(c echo.Context) error
 15        +DeactivateProduct(c echo.Context) error
 16    }
 17
 18    class ProductUseCase {
 19        <<interface>>
 20        +ListProducts(ctx, filter ListFilter) ([]Product, error)
 21        +GetProductByID(ctx, id uuid.UUID) (*Product, error)
 22        +CreateProduct(ctx, req CreateProductInput) (*Product, error)
 23        +UpdateProduct(ctx, id uuid.UUID, req UpdateProductInput) (*Product, error)
 24        +DeactivateProduct(ctx, id uuid.UUID, sellerID uuid.UUID) error
 25        +DeductStock(ctx, items []StockItem) error
 26    }
 27
 28    class ProductRepository {
 29        <<interface>>
 30        +FindAll(ctx, filter ListFilter) ([]Product, int, error)
 31        +FindByID(ctx, id uuid.UUID) (*Product, error)
 32        +Save(ctx, p *Product) error
 33        +Update(ctx, p *Product) error
 34        +UpdateStock(ctx, items []StockItem) error
 35    }
 36
 37    ProductHandler --> ProductUseCase
 38    ProductUseCase --> ProductRepository
 39```
 40
 41## File Structure to Create
 42
 43```
 44internal/product/
 45├── domain/
 46│   ├── entity.go           # Product struct, ProductStatus, StockItem
 47│   └── errors.go           # ErrProductNotFound, ErrInsufficientStock, etc.
 48├── usecase/
 49│   ├── interface.go        # ProductUseCase + ProductRepository interfaces
 50│   ├── dto.go              # ListFilter, CreateProductInput, UpdateProductInput
 51│   ├── product_usecase.go  # Implementation of ProductUseCase
 52│   └── product_usecase_test.go
 53├── repository/
 54│   ├── postgres_repository.go
 55│   └── postgres_repository_integration_test.go
 56└── handler/
 57    ├── http_handler.go
 58    ├── request.go          # HTTP request DTOs
 59    ├── response.go         # HTTP response DTOs
 60    └── http_handler_test.go
 61```
 62
 63## Database Schema
 64
 65```sql
 66-- Migration: 20250701001_create_products.sql
 67CREATE TABLE products (
 68    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 69    seller_id   UUID NOT NULL REFERENCES users(id),
 70    name        VARCHAR(255) NOT NULL,
 71    description TEXT,
 72    price_cents BIGINT NOT NULL CHECK (price_cents > 0),
 73    stock       INTEGER NOT NULL DEFAULT 0 CHECK (stock >= 0),
 74    status      VARCHAR(20) NOT NULL DEFAULT 'ACTIVE'
 75                    CHECK (status IN ('ACTIVE', 'INACTIVE')),
 76    category_id UUID REFERENCES categories(id),
 77    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
 78    updated_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
 79    deleted_at  TIMESTAMPTZ
 80);
 81
 82CREATE INDEX idx_products_seller    ON products(seller_id);
 83CREATE INDEX idx_products_status    ON products(status) WHERE deleted_at IS NULL;
 84CREATE INDEX idx_products_category  ON products(category_id) WHERE deleted_at IS NULL AND status = 'ACTIVE';
 85CREATE INDEX idx_products_fts       ON products
 86    USING gin(to_tsvector('indonesian', name || ' ' || COALESCE(description, '')));
 87```
 88
 89## API Endpoints
 90
 91| Method | Path | Auth | Spec Ref |
 92|--------|------|------|----------|
 93| GET | /api/v1/products | Public | Customer browsing |
 94| GET | /api/v1/products/:id | Public | Product detail |
 95| POST | /api/v1/products | Seller JWT | Create product |
 96| PATCH | /api/v1/products/:id | Seller JWT (owner) | Update product |
 97| DELETE | /api/v1/products/:id | Seller JWT (owner) | Deactivate |
 98| POST | /internal/v1/products/deduct-stock | Service token | Order integration |
 99
100## Implementation Order
101
1021. Domain types (entity.go, errors.go)
1032. UseCase interfaces + DTOs (interface.go, dto.go)
1043. PostgreSQL Repository + integration tests
1054. UseCase implementation + unit tests (with mock repo)
1065. HTTP handler + response DTOs + handler tests
1076. Route registration
1087. Wire all dependencies in main.go
1098. Manual smoke test
110
111## Risk Items
112
113- **Risk**: Full-text search in Indonesian might not work well with standard PostgreSQL configuration
114  → Mitigation: Test with real data first; fallback to ILIKE if needed
115
116- **Risk**: Stock deduction race condition with concurrent orders
117  → Mitigation: Use UPDATE with CHECK constraint (already in schema) + row-level locking

Perhatikan bahwa plan.md menerjemahkan setiap kebutuhan bisnis di spec.md menjadi keputusan teknis yang bisa langsung dieksekusi — dari nama interface hingga index PostgreSQL — tanpa mengubah maksud aslinya.


03.5 features/[name]/tasks.md: Task yang Actionable

Dihasilkan oleh specify tasks [name]. Setiap task punya estimasi waktu dan definition of done. Contoh berikut menunjukkan bagaimana satu plan dipecah menjadi fase-fase kecil yang bisa dikerjakan berurutan.

markdown
  1# Task Breakdown: Product Catalog
  2# Plan version: 2025-07-01
  3# Generated: 2025-07-01
  4
  5## Summary
  6Total estimated time: 12 hours
  7Total tasks: 18
  8
  9---
 10
 11## Phase 1: Domain Layer [~1.5 hours]
 12
 13### Task 1.1: Create Product entity [30 min]
 14**File:** `internal/product/domain/entity.go`
 15**Content:**
 16- `Product` struct dengan semua field dari schema
 17- `ProductStatus` type dengan `Active`, `Inactive` constants
 18- `StockItem` struct untuk stock deduction
 19**Done when:** `go build ./internal/product/domain/...` OK
 20
 21### Task 1.2: Create domain errors [20 min]
 22**File:** `internal/product/domain/errors.go`
 23**Content:**
 24- `ErrProductNotFound = errors.New("product not found")`
 25- `ErrProductNotOwned = errors.New("product not owned by seller")`
 26- `ErrInsufficientStock` (struct with ProductID, Available, Requested)
 27- `ErrProductInactive = errors.New("product is not active")`
 28**Done when:** All error types compile
 29
 30### Task 1.3: Create ListFilter struct [20 min]
 31**File:** `internal/product/usecase/dto.go` (partial)
 32**Content:**
 33- `ListFilter` struct: Keyword, CategoryID, MinPriceCents, MaxPriceCents, Page, PageSize, SortBy
 34- `SortBy` type with enum values
 35**Done when:** struct compiles with correct types
 36
 37---
 38
 39## Phase 2: Repository Layer [~3 hours]
 40
 41### Task 2.1: Create repository interfaces [20 min]
 42**File:** `internal/product/usecase/interface.go`
 43**Content:**
 44- `ProductRepository` interface with all methods
 45- `ProductUseCase` interface with all methods
 46**Done when:** compiles, mockgen can generate mock
 47
 48### Task 2.2: Implement FindAll with filter [60 min]
 49**File:** `internal/product/repository/postgres_repository.go`
 50**SQL:** Dynamic query with conditional clauses for keyword, category, price range
 51**Done when:** integration test `TestFindAll_WithFilters` passes
 52
 53### Task 2.3: Implement FindByID [20 min]
 54**File:** same as 2.2
 55**Done when:** `TestFindByID_ExistingProduct` passes
 56
 57### Task 2.4: Implement Save (INSERT) [20 min]
 58**File:** same as 2.2
 59**Done when:** `TestSave_NewProduct` passes
 60
 61### Task 2.5: Implement UpdateStock atomic [40 min]
 62**File:** same as 2.2
 63**SQL:** `UPDATE products SET stock = stock - $1 WHERE id = $2 AND stock - $1 >= 0`
 64**Done when:** `TestUpdateStock_Concurrent_NoNegative` passes
 65
 66---
 67
 68## Phase 3: UseCase Layer [~2.5 hours]
 69
 70### Task 3.1: Implement ListProducts [40 min]
 71**File:** `internal/product/usecase/product_usecase.go`
 72**Tests:** `TestListProducts_WithKeyword`, `TestListProducts_EmptyResult`
 73**Done when:** unit tests pass, coverage >= 85%
 74
 75### Task 3.2: Implement GetProductByID [20 min]
 76**Done when:** `TestGetProductByID_NotFound` passes
 77
 78### Task 3.3: Implement CreateProduct [40 min]
 79**Done when:** `TestCreateProduct_Success`, `TestCreateProduct_InvalidPrice` pass
 80
 81### Task 3.4: Implement DeductStock [40 min]
 82**Edge cases:** multiple items in one request, partial failure handling
 83**Done when:** `TestDeductStock_InsufficientStock` passes
 84
 85---
 86
 87## Phase 4: Handler Layer [~2.5 hours]
 88
 89### Task 4.1: Create request/response DTOs [30 min]
 90**Files:** request.go, response.go
 91**Done when:** all DTOs compile with proper json tags
 92
 93### Task 4.2: Implement ListProducts handler [30 min]
 94**Includes:** query param parsing, pagination response
 95**Done when:** `TestListProductsHandler_200` passes
 96
 97### Task 4.3: Implement CreateProduct handler [40 min]
 98**Includes:** request body parsing, multipart for photos (stub)
 99**Done when:** `TestCreateProductHandler_201` passes
100
101### Task 4.4: Implement all error mapping [30 min]
102**Done when:** all error→HTTP status mappings correct per spec
103
104---
105
106## Phase 5: Integration [~1 hour]
107
108### Task 5.1: Register routes [15 min]
109**Done when:** `go build ./...` OK, routes visible in startup log
110
111### Task 5.2: Wire dependencies in main.go [30 min]
112**Done when:** server starts without panic
113
114### Task 5.3: Smoke test [15 min]
115**Done when:** curl tests for all endpoints return expected responses

Setiap task pada breakdown di atas berdurasi di bawah 90 menit dan punya definition of done yang bisa diverifikasi — inilah yang membuat implementasi bisa dikerjakan bertahap tanpa kehilangan arah.


03.6 history/: Log Audit Trail

Setiap kali menjalankan perintah Spec Kit, interaction di-log ke history/ folder. Penamaan file di bawah ini memakai timestamp sehingga jejak setiap perintah terurut rapi.

text
1history/
2├── 2025-07-01T09:00:00-product-service-feature.log
3├── 2025-07-01T09:15:00-product-service-clarify.log
4├── 2025-07-01T09:30:00-product-service-plan.log
5├── 2025-07-01T09:32:00-product-service-tasks.log
6└── 2025-07-01T09:35:00-product-service-implement-phase1.log

Nama file saja sudah bercerita: kapan tiap tahap dijalankan dan untuk fitur apa. Untuk melihat detailnya, kita buka isi salah satu log seperti berikut.

text
 1[2025-07-01T09:30:00Z] specify plan product-service
 2[2025-07-01T09:30:00Z] Model: claude-sonnet-4-20250514
 3[2025-07-01T09:30:00Z] Constitution: .specify/constitution.md (1245 chars)
 4[2025-07-01T09:30:00Z] Spec: .specify/features/product-service/spec.md (2341 chars)
 5[2025-07-01T09:30:00Z] Sending request to Anthropic API...
 6[2025-07-01T09:30:18Z] Response received (18.3s)
 7[2025-07-01T09:30:18Z] Tokens used: 3,412 prompt + 2,891 completion = 6,303 total
 8[2025-07-01T09:30:18Z] Cost estimate: $0.019
 9[2025-07-01T09:30:18Z] Writing plan.md...
10[2025-07-01T09:30:18Z] Done. Files written: .specify/features/product-service/plan.md

Dari isi log di atas, tiga manfaat utama history langsung terlihat:

  • Audit trail: siapa request apa kapan
  • Cost tracking: berapa token yang dikonsumsi
  • Debugging: melihat apa yang dikirim ke Claude

03.7 _templates/: Customizable Templates

Spec Kit menyediakan template yang bisa dikustomisasi. Contoh berikut adalah template default spec.md yang menjadi kerangka setiap spec baru.

markdown
 1# _templates/spec.md (default)
 2
 3# Feature Specification: {FEATURE_NAME}
 4
 5## Status: DRAFT
 6## Created: {DATE}
 7## Author: {AUTHOR}
 8
 9## User Story
10
11As a [role],
12I want [action],
13so that [benefit].
14
15## Core Capabilities
16[What users can do]
17
18## Business Rules
19[Rules the system must enforce]
20
21## Out of Scope
22[What's explicitly NOT included]

Placeholder seperti {FEATURE_NAME} dan {DATE} akan otomatis terisi saat perintah dijalankan. Untuk menyesuaikan template dengan kebutuhan tim, ikuti langkah berikut.

bash
1# Copy template ke local
2cp .specify/_templates/spec.md .specify/_templates/spec-custom.md
3
4# Edit sesuai kebutuhan tim
5# Kemudian gunakan template custom
6specify feature new-feature --template=spec-custom

Dengan menaruh template custom di _templates/, seluruh tim mendapat struktur spec yang konsisten tanpa perlu menghafal format.


03.8 specify.config.json: Project Configuration

File konfigurasi di root project yang dikonsumsi oleh Spec Kit. Isinya menentukan identitas project, model AI yang dipakai per tahap, dan hook yang dijalankan otomatis.

json
 1{
 2  "version": "1",
 3  "project": {
 4    "name": "Santekno Shop",
 5    "language": "go",
 6    "architecture": "clean",
 7    "go_module": "github.com/santekno/santekno-shop"
 8  },
 9  "ai": {
10    "default_model": "claude-sonnet-4-20250514",
11    "plan_model": "claude-opus-4-6",
12    "implement_model": "claude-sonnet-4-20250514"
13  },
14  "paths": {
15    "spec_dir": ".specify",
16    "source_dir": "internal",
17    "migration_dir": "migrations"
18  },
19  "hooks": {
20    "post_implement": "go build ./... && go vet ./...",
21    "post_phase": "git add -A && git status"
22  },
23  "constitution": {
24    "auto_update": false,
25    "require_review": true
26  }
27}

Konfigurasi ini memungkinkan kamu memakai model yang lebih kuat khusus untuk tahap plan (yang butuh reasoning lebih dalam) dan menegakkan quality gate lewat hooks.post_implement.


03.9 Hubungan Antar File: Context yang Dibawa di Setiap Perintah

Ini adalah kunci pemahaman bagaimana Spec Kit bekerja. Diagram alur berikut memetakan file apa yang dibaca dan ditulis oleh masing-masing perintah.

text
 1specify feature product-service
 2└── Membaca: tidak ada (input dari user saja)
 3└── Menulis: spec.md
 4
 5specify clarify product-service
 6└── Membaca: constitution.md + spec.md
 7└── Menulis: spec.md (update) + clarifications.md
 8
 9specify plan product-service
10└── Membaca: constitution.md + spec.md + clarifications.md + kode existing
11└── Menulis: plan.md
12
13specify tasks product-service
14└── Membaca: constitution.md + spec.md + plan.md
15└── Menulis: tasks.md
16
17specify implement product-service --phase=1
18└── Membaca: constitution.md + spec.md + plan.md + tasks.md + kode existing
19└── Menulis: file kode Go sesuai tasks

Semakin ke bawah alur ini, context yang dibawa semakin lengkap. Inilah “progressive context building” yang membuat output setiap perintah semakin relevan dan konsisten dengan yang sebelumnya.


03.10 Gitignore untuk .specify/

File apa yang harus di-commit dan apa yang sebaiknya di-ignore? Contoh berikut memisahkan source of truth (yang wajib masuk git) dari file lokal yang tidak perlu.

text
 1# .gitignore
 2
 3# ✅ COMMIT: Semua file ini adalah source of truth
 4# .specify/constitution.md
 5# .specify/features/**/*.md
 6# .specify/_templates/**
 7
 8# ❌ IGNORE: History dan temporary files
 9.specify/history/
10.specify/temp/
11.specify/.cache/
12
13# ❌ IGNORE: Config dengan credentials
14specify.config.local.json  # local override dengan API key

Prinsipnya jelas: semua file Markdown adalah source of truth yang harus di-commit, sedangkan history dan config berisi credential harus di-ignore. Untuk menerapkannya cukup jalankan perintah berikut.

bash
1# Tambahkan ke .gitignore
2echo ".specify/history/" >> .gitignore
3echo ".specify/temp/" >> .gitignore
4echo ".specify/.cache/" >> .gitignore
5echo "specify.config.local.json" >> .gitignore

Setelah menjalankan empat baris di atas, folder history dan config lokal tidak akan pernah ikut ter-commit — mencegah bocornya API key ke repository.


03.11 Menginspeksi Output Spec Kit

Cara terbaik untuk memahami apa yang Spec Kit hasilkan adalah dengan menginspeksi langsung file di .specify/. Kumpulan perintah berikut membantu kamu melihat isi, menghitung token, dan mengecek biaya.

bash
 1# Lihat semua file di .specify/
 2find .specify/ -type f -name "*.md" | sort
 3
 4# Lihat isi constitution
 5cat .specify/constitution.md
 6
 7# Lihat spec fitur tertentu
 8cat .specify/features/product-service/spec.md
 9
10# Hitung total token yang dikonsumsi
11grep "Tokens used:" .specify/history/*.log | awk '{sum += $NF} END {print "Total tokens:", sum}'
12
13# Lihat cost estimate
14grep "Cost estimate:" .specify/history/*.log

Perintah find dan grep di atas mengubah folder .specify/ menjadi dashboard sederhana: kamu bisa langsung tahu apa yang dihasilkan dan berapa biayanya tanpa perlu tool tambahan.


03.12 Validasi File .specify/ yang Baik

Bagaimana tahu bahwa file-file ini sudah berkualitas baik? Berikut kriteria praktis untuk masing-masing file utama:

Constitution yang baik:

  • Tidak ada contradictory rules
  • Semua aturan actionable (bukan “write clean code”)
  • Tech stack dengan versi spesifik
  • Error handling pattern dengan contoh kode

Spec yang baik:

  • Tidak ada mention tech stack atau implementasi detail
  • User story dengan role yang spesifik
  • Business rules yang jelas dan measurable
  • Out of scope yang explicit

Plan yang baik:

  • File structure yang lengkap
  • SQL schema yang valid
  • API endpoints dengan method dan path
  • Implementation order yang masuk akal

Tasks yang baik:

  • Setiap task < 90 menit
  • Definition of done yang concrete
  • Dependency antar task yang jelas

Gunakan keempat checklist ini sebagai gate sebelum lanjut ke perintah berikutnya — file yang lolos kriteria di sini akan menghasilkan output tahap selanjutnya yang jauh lebih akurat.


03.13 Sync .specify/ dengan CLAUDE.md

Spec Kit bisa generate update untuk CLAUDE.md berdasarkan keputusan yang dibuat selama specify process. Perintah berikut menampilkan diff dulu sebelum benar-benar menerapkannya.

bash
1# Update CLAUDE.md berdasarkan constitution yang ada
2specify claude-md sync
3
4# Output: diff yang akan diterapkan ke CLAUDE.md
5# Review dulu sebelum apply
6specify claude-md sync --apply

Dengan pola review-then-apply ini, CLAUDE.md selalu selaras dengan constitution di .specify/ tanpa risiko menimpa konteks penting secara tak sengaja.


03.14 Spec Kit vs Topik #1 (Manual SDD): File Mapping

Bagi kamu yang datang dari Topik #1 (manual SDD), tabel berikut memetakan setiap file manual ke padanannya di Spec Kit sehingga transisinya terasa familier.

Manual SDD (Topik #1)GitHub Spec KitEquivalent
CLAUDE.md.specify/constitution.mdProject conventions
specs/[domain]/[feature].md.specify/features/[name]/spec.mdFeature spec
Implementation plan (ad-hoc).specify/features/[name]/plan.mdTechnical plan
Task breakdown (ad-hoc).specify/features/[name]/tasks.mdTask list
(tidak ada).specify/history/Audit trail
(tidak ada)specify.config.jsonTool config

Tabel ini menunjukkan Spec Kit bukan mengganti konsep manual SDD, melainkan menstrukturkannya — bahkan keduanya bisa co-exist karena file specs/ dan .specify/ punya fokus yang sedikit berbeda.


03.15 Troubleshooting: File yang Corrupt atau Incomplete

Terkadang file di .specify/ bisa corrupt atau incomplete, misalnya karena network error saat generate. Perintah berikut membantu memvalidasi dan me-regenerate file yang bermasalah.

bash
 1# Cek apakah spec.md valid
 2specify validate --feature=product-service
 3
 4# Output jika ada masalah:
 5# ❌ spec.md: Missing "User Story" section
 6# ❌ plan.md: Invalid YAML frontmatter
 7# ⚠️  tasks.md: Phase 3 has no tasks
 8
 9# Regenerate file yang corrupt
10specify feature product-service --regenerate  # regenerate spec.md
11specify plan product-service --regenerate     # regenerate plan.md
12specify tasks product-service --regenerate    # regenerate tasks.md

Perintah validate mendeteksi masalah sebelum kamu terlanjur lanjut ke tahap berikutnya, dan flag --regenerate memperbaikinya tanpa perlu mengetik ulang dari awal.


03.16 File Permissions dan Ownership

Di environment team dengan multiple developer, pastikan semua orang bisa membaca dan menulis folder .specify/. Perintah berikut menyetel permission dan memverifikasinya.

bash
1# Pastikan semua developer bisa read/write .specify/
2chmod -R 755 .specify/
3
4# Verify
5ls -la .specify/
6# drwxr-xr-x  constitution.md
7# drwxr-xr-x  features/

Menyeragamkan permission sejak awal mencegah error “permission denied” yang membingungkan saat anggota tim lain menjalankan perintah Spec Kit di mesin mereka.


03.17 Versioning .specify/ Files

Best practice untuk versioning spec files adalah menyematkan metadata versi di dalam setiap file. Contoh berikut menunjukkan blok metadata di spec.md.

markdown
1# Di setiap spec.md
2
3## Metadata
4- **Spec Version:** v1.2
5- **Status:** APPROVED
6- **Last Updated:** 2025-07-01 by @andi
7- **Changes from v1.1:** Added "low stock" warning rule (AC7)

Metadata versi seperti ini membuat setiap perubahan spec bisa dilacak. Pola yang sama juga diterapkan di constitution.md dalam bentuk changelog tabel berikut.

markdown
1## Changelog
2| Date | Version | Changed By | Summary |
3|------|---------|-----------|---------|
4| 2025-07-01 | 1.0 | @budi | Initial constitution |
5| 2025-07-15 | 1.1 | @andi | Add Kafka conventions |

Dengan changelog terstruktur di constitution, tim bisa langsung tahu kapan dan mengapa sebuah aturan arsitektur berubah — informasi yang sangat berharga saat menelusuri keputusan lama.


03.18 Tips & Gotchas

💡 Tip 1: Baca plan.md sebelum tasks.md

Plan.md memberikan big picture yang membantu memahami kenapa tasks.md organized seperti itu. Jangan langsung loncat ke tasks.

💡 Tip 2: History log adalah gold mine untuk debugging

Jika output tidak sesuai harapan, cek history log untuk melihat context apa yang dikirim ke Claude.

💡 Tip 3: Constitution adalah dokumen hidup

Update constitution setiap kali ada keputusan arsitektur baru. Jalankan specify claude-md sync untuk propagate ke CLAUDE.md.

💡 Tip 4: Baca clarifications.md setelah specify clarify

File ini menyimpan semua jawaban klarifikasi yang mempengaruhi spec. Berguna sebagai referensi saat ada pertanyaan “kenapa ini begini.”

⚠️ Gotcha 1: Jangan edit plan.md atau tasks.md secara manual

Jika perlu perubahan, lebih baik regenerate. Edit manual bisa menyebabkan inconsistency yang sulit di-detect.

⚠️ Gotcha 2: History folder bisa jadi besar

Setiap perintah generate satu log file. Untuk project aktif, folder history bisa mencapai ratusan file dalam sebulan. Setup rotate log atau gitignore history.

⚠️ Gotcha 3: spec.md dan plan.md harus di-sync

Jika spec berubah setelah plan dibuat, jalankan specify plan lagi untuk regenerate plan. Jangan biarkan plan outdated dari spec.

⚠️ Gotcha 4: Template override mempengaruhi semua fitur berikutnya

Jika kamu mengubah template di _templates/, perubahan ini berlaku untuk semua fitur baru. Pastikan perubahan ini sudah di-review oleh tim.


03.19 .specify/ di Monorepo

Untuk monorepo dengan multiple service, struktur .specify/ bisa dibuat berlapis. Contoh berikut menunjukkan constitution yang di-share di root dan features yang spesifik per service.

text
 1santekno-shop/              ← root monorepo
 2├── .specify/
 3│   └── constitution.md     ← SHARED constitution untuk semua service
 4├── services/
 5│   ├── order-service/
 6│   │   ├── .specify/
 7│   │   │   └── features/   ← Features specific to order service
 8│   │   └── specify.config.json
 9│   └── product-service/
10│       ├── .specify/
11│       │   └── features/   ← Features specific to product service
12│       └── specify.config.json

Pola berlapis di atas menjaga satu sumber prinsip (constitution root) untuk semua service, sementara setiap service tetap bebas mengelola fitur-fiturnya sendiri. Kita akan bahas ini lebih detail di Artikel 17.


03.20 Ringkasan

Folder .specify/ adalah “project memory” yang tersimpan dalam bentuk file Markdown yang bisa di-commit, di-review, dan di-version.

Empat file utama: constitution.md (prinsip universal), spec.md (kebutuhan bisnis), plan.md (rencana teknis), tasks.md (action items).

Progressive context building: Setiap perintah membaca semua output dari perintah sebelumnya, membuat context semakin kaya dan output semakin relevan.

Commit semua, gitignore history: Semua file Markdown harus di-commit. History log boleh di-gitignore karena hanya untuk debug lokal.

Di artikel berikutnya, kita setup integrasi penuh antara Spec Kit dan Claude Code untuk project Santekno Shop — termasuk cara kerja keduanya bersama untuk menghasilkan output yang maksimal.

Artikel Terkait

💬 Komentar