speckit.constitution: Cara Menulis Konstitusi Project Golang yang Efektif
Panduan lengkap menulis constitution.md untuk GitHub Spec Kit di project Golang. Semua komponen wajib, contoh nyata Santekno Shop, dan teknik membuat constitution yang di-enforce AI secara konsisten.
speckit.constitution: Konstitusi Proyek yang Tidak Boleh Dilanggar
Menulis constitution untuk project Golang di GitHub Spec Kit adalah keterampilan paling berdampak dalam workflow SDD, karena constitution adalah dokumen yang paling penting di seluruh folder .specify/. Ia dibaca oleh setiap perintah Spec Kit — menjadi fondasi yang memastikan AI selalu menghasilkan kode yang konsisten dengan arsitektur dan conventions project kamu.
Analoginya: jika spec.md adalah undang-undang yang bisa berubah per-fitur, maka constitution.md adalah konstitusi — hukum dasar yang tidak boleh dilanggar oleh perintah apa pun.
05.1 Menjalankan specify constitution init
Titik awalnya adalah satu perintah sederhana yang dijalankan di root project Santekno Shop.
1# Di root project Santekno Shop
2specify constitution initSetelah dijalankan, specify CLI tidak langsung membuat file, melainkan menuntun kamu lewat serangkaian pertanyaan interaktif. Transkrip berikut memperlihatkan tujuh pertanyaan inti beserta contoh jawaban untuk project kita.
1Creating Project Constitution for Santekno Shop
2
31. What is this project?
4> B2C e-commerce platform for Indonesia
5 Sellers can list products; customers can browse, cart, and order
6
72. Primary language and version?
8> Go 1.22
9
103. Key frameworks and libraries (with versions)?
11> Echo v4, pgx/v5, go-redis/v9, confluent-kafka-go v2
12> testify/suite, gomock, github.com/google/uuid
13
144. Architecture pattern?
15> Clean Architecture
16> Layer order: handler → usecase → repository → database
17> Interfaces defined in usecase package
18
195. What MUST always happen in this codebase?
20> All errors wrapped with fmt.Errorf("func: %w", err)
21> context.Context as first parameter in service functions
22> uuid.UUID for all entity IDs (no string IDs)
23> Prices stored in cents as int64 (no float)
24> Structured logging via log/slog
25
266. What MUST NEVER happen?
27> No ORM (GORM, Ent, etc.)
28> No direct DB call from handler or usecase
29> No business logic in handler layer
30> No circular imports between layers
31
327. Testing conventions?
33> testify/suite for usecase tests
34> gomock for mocking
35> External test packages: package [name]_test
36> Naming: Test[Feature]_[Condition]_[ExpectedResult]
37> Coverage target: >= 85% for usecase layer
38
39Constitution created: .specify/constitution.mdPerhatikan bahwa jawaban yang spesifik dan berversi di setiap pertanyaan langsung menentukan kualitas constitution yang dihasilkan — jawaban malas menghasilkan aturan yang malas pula.
05.2 Anatomy Constitution.md yang Dihasilkan
Dari jawaban di atas, Spec Kit menghasilkan constitution.md yang terstruktur. Dokumen lengkap berikut menunjukkan semua bagian penting — mulai dari identitas project sampai aturan spec-first — yang menjadi kontrak permanen bagi AI.
1# Project Constitution: Santekno Shop
2# Version: 1.0
3# Created: 2025-07-01
4# Requires review before modification
5
6## 1. Project Identity
7
8**Name:** Santekno Shop
9**Type:** B2C E-commerce Platform
10**Domain:** Indonesia market, Indonesian language for user-facing features
11**Go module:** github.com/santekno/santekno-shop
12
13---
14
15## 2. Tech Stack (Canonical Versions)
16
17| Component | Package | Version |
18|-----------|---------|---------|
19| Language | Go | 1.22+ |
20| HTTP | github.com/labstack/echo/v4 | v4 |
21| Database | github.com/jackc/pgx/v5 | v5 |
22| Cache | github.com/redis/go-redis/v9 | v9 |
23| Kafka | github.com/confluentinc/confluent-kafka-go/v2 | v2 |
24| UUID | github.com/google/uuid | v1 |
25| Testing | github.com/stretchr/testify | v1.9 |
26| Mocking | go.uber.org/mock/gomock | v0.4 |
27| Logging | log/slog | stdlib |
28
29---
30
31## 3. Architecture: Clean Architecture
32
33### Dependency Direction (STRICT — NEVER VIOLATE)
34
35 delivery/http/handler
36 ↓
37 usecase/
38 ↓
39 repository/
40 ↓
41 database/cache/kafka
42
43### Rules
44- Interfaces live in usecase package — NOT in domain or repository
45- No circular imports — dependency flows one direction only
46- Handler: parse request, delegate to usecase, format response only
47- Usecase: business logic, orchestration only
48- Repository: data access only
49
50### Package Naming Convention
51
52 internal/[domain]/
53 ├── domain/ ← Entity, value objects, domain errors
54 ├── usecase/ ← Business logic + interfaces
55 ├── repository/ ← Concrete implementations (postgres, redis)
56 └── handler/ ← HTTP handlers, DTOs
57
58---
59
60## 4. Coding Rules
61
62### Must Always
63
64Error Handling — wrap with context "FunctionName: operation: %w":
65 return fmt.Errorf("CreateOrder: validateCart: %w", err)
66 var ErrOrderNotFound = errors.New("order not found")
67
68Function Signatures — context.Context ALWAYS first parameter:
69 func (uc *productUseCase) CreateProduct(ctx context.Context, input CreateProductInput) (*Product, error)
70
71IDs — ALWAYS use uuid.UUID, never string or int for entity IDs.
72Prices — ALWAYS store in smallest unit (cents) as int64, NEVER float64.
73Logging — Use log/slog with context; NEVER log.Printf or fmt.Println in production.
74
75### Must Never
76
77- Use any ORM (GORM, Ent, SQLBoiler, XORM, etc.)
78- Call database (db.Query, db.Exec) from handler or usecase directly
79- Import usecase package from repository package
80- Import delivery/handler package from any other layer
81- Use interface{} or any without explicit justification
82- Use time.Sleep without context deadline
83- Panic in business code (panics only in main.go startup)
84- Commit API keys, passwords, or secrets of any kind
85- Use global mutable state
86
87---
88
89## 5. Testing Standards
90
91- External test package: package product_test
92- Test suite dengan testify/suite
93- Test naming: Test[Feature]_[Condition]_[ExpectedResult]
94- Coverage: Usecase >= 85%, Domain 100%, Repository via integration test
95
96---
97
98## 6. Database Conventions
99
100- Table names: snake_case, plural (products, order_items)
101- Primary keys: id UUID PRIMARY KEY DEFAULT gen_random_uuid()
102- Timestamps: created_at / updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
103- Soft delete: deleted_at TIMESTAMPTZ (NULL means active)
104- ALWAYS parameterized queries: WHERE id = $1
105
106---
107
108## 7. API Response Format
109
110- Success: { "data": ... }
111- Error: { "error_code": ..., "message": ... }
112- Paginated: { "data": ..., "pagination": { page, per_page, total_items, total_pages } }
113
114---
115
116## 8. Spec-First Rule
117
118Every new feature MUST have a spec in .specify/features/[name]/spec.md
119BEFORE any implementation starts.
120
121If asked to implement without a spec:
122"This feature doesn't have a spec yet. Please run specify feature [name]
123to create one before we start implementing."Anatomy ini adalah blueprint: setiap section punya peran, dan bersama-sama mereka menutup semua celah keputusan yang biasanya diisi oleh asumsi AI.
05.3 Komponen Wajib vs Opsional
Tidak semua bagian constitution punya bobot yang sama. Sebagian mutlak harus ada, sebagian lagi bersifat pelengkap.
Wajib ada di setiap constitution:
- Project identity (nama, tipe, Go module)
- Tech stack dengan versi spesifik
- Architecture rules dengan dependency direction
- Must Always rules (minimal error handling dan context)
- Must Never rules
- Testing conventions
Opsional tapi direkomendasikan:
- Database conventions
- API response format
- Spec-first rule (sangat direkomendasikan)
- Domain glossary
- Branching strategy
Gunakan daftar wajib ini sebagai checklist minimum: constitution yang kehilangan salah satu komponen wajib hampir pasti akan menghasilkan kode yang inkonsisten di area tersebut.
05.4 Update Constitution: Kapan dan Bagaimana
Constitution bukan dokumen sekali tulis lalu dilupakan. Ia harus di-update ketika ada library baru, pattern baru yang disepakati tim, atau architectural decision baru. Perintah berikut menunjukkan dua cara meng-update-nya beserta commit yang deskriptif.
1# Update constitution interaktif
2specify constitution update
3
4# Atau edit langsung dan notify tim
5vim .specify/constitution.md
6git add .specify/constitution.md
7git commit -m "docs(constitution): add Redis caching pattern
8
9Added Redis caching conventions:
10- Cache key format: {domain}:{entity}:{id}
11- TTL default: 5 menit untuk read-heavy endpoints
12- Cache-aside pattern only (no write-through)
13
14Decision made in arch review 2025-07-15"Commit message yang menjelaskan alasan perubahan (bukan sekadar apa yang berubah) membuat constitution menjadi catatan keputusan arsitektur yang bisa ditelusuri bulanan kemudian.
05.5 Constitution Validation
Setelah menulis atau meng-update constitution, jalankan validasi untuk memastikan tidak ada aturan yang ambigu atau saling bertentangan. Output berikut memperlihatkan laporan validasi yang khas.
1specify constitution validate
2
3# Output:
4# All required sections present
5# No contradictory rules detected
6# Warning: "Must Always" section has rules without code examples
7# Consider adding examples for: logging conventions
8# Tech stack versions specified
9# Architecture dependency direction clearPerhatikan baris warning: validator tidak hanya mengecek kelengkapan, tapi juga menandai aturan yang kurang contoh — sinyal untuk memperkuat bagian yang paling rawan disalahartikan AI.
05.6 Probe Test untuk Verify Constitution
Validasi struktural saja tidak cukup; kamu perlu membuktikan constitution benar-benar mempengaruhi output AI. Probe test berikut menjalankan plan dry-run lalu memeriksa apakah plan mematuhi aturan kunci.
1specify plan test-feature --dry-run
2
3Cek apakah plan yang dihasilkan:
4- Menggunakan pgx/v5, bukan database/sql atau GORM
5- Interface didefinisikan di usecase package
6- Error wrapping menggunakan fmt.Errorf("func: %w", err)
7- IDs menggunakan uuid.UUID
8- Prices menggunakan int64 dengan suffix CentsJika kelima poin terpenuhi tanpa kamu menyebutnya di prompt, itu bukti kuat bahwa constitution “hidup” dan benar-benar memandu AI — bukan sekadar dokumen dekoratif.
05.7 Constitution untuk Tim yang Lebih Besar
Untuk tim dengan 5+ orang, constitution perlu bagian governance agar perubahannya terkendali. Section berikut menetapkan siapa yang boleh mengusulkan dan menyetujui perubahan.
1## 9. Constitution Governance
2
3### Who Can Propose Changes
4Any team member can propose changes via PR.
5
6### Who Can Approve Changes
7Tech Lead review required for all changes.
8PM review required for business rule changes.
9
10### Review Timeline
11Minimum 48-hour review window before merging.
12
13### Changelog
14| Date | Version | Changed By | Change Summary |
15|------|---------|-----------|----------------|
16| 2025-07-01 | 1.0 | @budi | Initial constitution |Governance eksplisit ini mencegah constitution berubah diam-diam oleh satu orang — perubahan aturan dasar diperlakukan seserius perubahan arsitektur.
05.8 Common Constitution Mistakes
Banyak constitution gagal bukan karena kurang panjang, tapi karena aturannya tidak actionable. Empat contoh berikut mengontraskan aturan yang buruk dengan versi yang efektif.
Kesalahan pertama adalah aturan yang terlalu generik sehingga tidak bisa di-enforce.
1# Mistake 1: Rules terlalu generik
2BURUK: "Write clean and maintainable code"
3BAIK: "Use fmt.Errorf('func: %w', err) for all error wrapping"Kesalahan kedua adalah menuliskan aturan penting tanpa contoh kode konkret.
1# Mistake 2: Tidak ada contoh kode untuk rules penting
2BURUK: "Use structured logging"
3BAIK: "Use log/slog: slog.InfoContext(ctx, 'msg', 'key', value)"Kesalahan ketiga adalah aturan yang saling bertentangan sehingga membingungkan AI.
1# Mistake 3: Contradictory rules
2BURUK: "Always use interfaces" + "Use concrete types for simplicity"
3BAIK: "Use interfaces for all external dependencies (DB, cache, kafka)"
4BAIK: "Concrete types acceptable for internal value objects"Kesalahan keempat adalah menyebut tech stack tanpa versi, yang membuka pintu bagi kode usang.
1# Mistake 4: Tech stack tanpa versi
2BURUK: "Use pgx"
3BAIK: "Use github.com/jackc/pgx/v5 (v5.x.x)"Benang merah keempat kesalahan ini sama: aturan yang baik selalu spesifik, ber-contoh, konsisten, dan berversi.
05.9 Constitution dan Context Window
Constitution yang terlalu panjang (>500 baris) menghabiskan banyak context window di setiap perintah specify. Karena itu, panjangnya perlu dijaga secara sadar dengan beberapa best practice berikut:
- Target: 150-300 baris
- Fokus pada rules yang paling sering dilanggar
- Buang rules yang redundan
- Gunakan contoh kode yang compact
Ingat, setiap token di constitution “dibayar” berulang kali di setiap perintah — jadi ringkas bukan sekadar soal keindahan, tapi soal biaya nyata.
05.10 Integrasi Constitution dengan CLAUDE.md
Constitution (untuk Spec Kit) dan CLAUDE.md (untuk Claude Code) harus konsisten agar tidak memberi AI dua sumber kebenaran yang berbeda. Perintah berikut men-sinkronkan keduanya.
1# Sync CLAUDE.md dari constitution
2specify claude-md sync
3
4# Review diff
5git diff CLAUDE.md
6
7# Jika OK, commit
8git add CLAUDE.md
9git commit -m "docs: sync CLAUDE.md from constitution v1.1"Dengan sinkronisasi ini, apa pun tool yang dipakai developer — Spec Kit atau Claude Code langsung — keduanya menegakkan aturan yang sama persis.
05.11 Shared Constitution di Monorepo
Untuk monorepo dengan banyak service, satu constitution bersama menjaga konsistensi lintas service. Struktur berikut menunjukkan bagaimana tiap service mereferensikan constitution di root.
1santekno-shop/
2├── .specify/constitution.md ← Shared constitution
3├── services/
4│ ├── order-service/
5│ │ └── specify.config.json # Reference: "constitution": "../../.specify/constitution.md"
6│ └── product-service/
7│ └── specify.config.jsonDengan satu constitution bersama, aturan error handling dan arsitektur berlaku seragam di semua service — tidak ada service yang “nakal” dengan konvensi berbeda.
05.12 Constitution Version History
Melacak riwayat perubahan constitution sama pentingnya dengan melacak perubahan kode. Changelog berikut mencatat apa yang berubah, oleh siapa, dan mengapa.
1## Changelog
2
3### v1.2 (2025-07-15) — @andi
4Added: Redis caching conventions (TTL, key format, cache-aside pattern)
5Changed: Error wrapping format clarified with more examples
6Reason: Multiple inconsistent cache implementations found during code review
7
8### v1.1 (2025-07-08) — @budi
9Added: Database conventions section (missing from initial)
10Reason: Some migration files used string concatenation for queries
11
12### v1.0 (2025-07-01) — @budi
13Initial constitution.Kolom “Reason” adalah yang paling berharga: ia menjelaskan mengapa sebuah aturan ada, sehingga tim di masa depan tidak menghapusnya tanpa sengaja.
05.13 Constitution sebagai Onboarding Document
Constitution yang baik sekaligus berfungsi sebagai dokumen onboarding yang efektif. Sesi singkat berikut menunjukkan betapa cepat developer baru bisa memahami project hanya dari satu file.
1# New developer reads in 10 minutes:
2cat .specify/constitution.md
3
4# Immediately knows:
5# - What tech stack to use and which version
6# - How to structure new packages
7# - How to handle errors
8# - How to write tests
9# - What's absolutely forbiddenKarena semua konvensi engineering terangkum di satu tempat, kamu bisa memangkas sesi knowledge transfer berjam-jam menjadi 10 menit membaca mandiri.
05.14 Automated Constitution Testing
Constitution hanya berguna jika dipatuhi, dan kepatuhan bisa diuji otomatis di CI. Skrip berikut memindai kode existing untuk mendeteksi pelanggaran aturan kunci seperti pemakaian ORM atau direct DB call dari handler.
1#!/bin/bash
2# Test bahwa kode existing comply dengan constitution
3
4# Check: tidak ada ORM
5if grep -r "gorm" internal/ --include="*.go" > /dev/null; then
6 echo "CONSTITUTION VIOLATION: ORM detected"
7 exit 1
8fi
9
10# Check: semua error pakai fmt.Errorf
11if grep -r 'return err$' internal/ --include="*.go" | grep -v "_test.go"; then
12 echo "Naked error return detected (should be wrapped)"
13fi
14
15# Check: tidak ada direct db call dari handler
16if grep -r "pgxpool\|db\.Query\|db\.Exec" internal/*/handler/ --include="*.go"; then
17 echo "CONSTITUTION VIOLATION: Direct DB call from handler"
18 exit 1
19fi
20
21echo "Constitution compliance checks passed"Skrip ini mengubah constitution dari sekadar dokumen menjadi aturan yang di-enforce mesin — pelanggaran ditangkap otomatis sebelum sampai ke review manusia.
05.15 Constitution Review Checklist
Sebelum merge constitution baru atau update, lewati checklist berikut untuk memastikan kualitasnya konsisten. Daftar ini merangkum semua kriteria yang sudah kita bahas.
1- All required sections present?
2- Tech stack has specific versions?
3- Architecture dependency direction is explicit?
4- Error handling has code example?
5- Testing conventions are specific?
6- No contradictory rules?
7- Length < 300 lines?
8- Reviewed by tech lead?
9- CLAUDE.md synced?
10- Team notified of changes?Jadikan checklist ini sebagai gerbang PR: constitution yang belum lolos semua poin sebaiknya tidak di-merge, karena celah sekecil apa pun akan diperbesar oleh AI di setiap fitur.
05.16 Constitution untuk Different Environments
Beberapa aturan hanya berlaku di environment tertentu. Section berikut memisahkan aturan development dari production agar AI tidak salah menerapkan konfigurasi.
1## Environment-Specific Rules
2
3### Development
4- Use testcontainers for integration tests
5- Log level: DEBUG acceptable
6
7### Production
8- Log level: INFO minimum (no DEBUG in prod)
9- No test data in production database
10- All secrets via environment variables
11- Enable Prometheus metrics endpointDengan memisahkan aturan per environment, kamu mencegah kesalahan berbahaya seperti log DEBUG yang bocor ke production atau data test yang masuk database asli.
05.17 Real-World Constitution: Lessons Learned
Dari pengalaman production, ada empat aturan yang paling sering menjadi sumber masalah dan karenanya butuh perhatian ekstra:
- Error wrapping format adalah aturan paling sering dilanggar — tambahkan contoh yang sangat eksplisit.
- UUID vs string ID adalah sumber bug terbanyak — nyatakan dengan sangat jelas dan tambahkan contoh WRONG vs RIGHT.
- Float untuk harga — ini menyebabkan rounding errors yang sulit di-debug; tulis aturannya dengan tegas.
- Interface placement — developer baru selalu bingung di mana harus mendefinisikan interface, jadi constitution harus sangat jelas.
Pelajaran utamanya: perkuat justru aturan yang paling sering dilanggar dengan contoh, bukan menganggapnya “sudah jelas”.
05.18 Tips & Gotchas
💡 Tip 1: Mulai dengan constitution yang minimal, expand seiring waktu — lebih baik 100 baris yang diikuti daripada 500 baris yang setengahnya di-ignore.
💡 Tip 2: Review constitution setelah setiap sprint retrospective — “ada rules yang perlu ditambah atau diubah?” adalah pertanyaan yang bagus.
💡 Tip 3: Constitution changes harus di-review seperti code changes — PR-nya sebaiknya punya approver yang sama seperti architectural changes.
💡 Tip 4: Test constitution dengan probe prompts secara berkala — setiap bulan, run beberapa probe untuk verify AI masih mengikuti constitution.
⚠️ Gotcha 1: Constitution yang outdated lebih berbahaya dari tidak ada constitution — jika ia bilang “pakai library A” padahal sudah pindah ke B, AI akan generate kode yang salah.
⚠️ Gotcha 2: Terlalu panjang = terlalu mahal — 500 token constitution dikali 100 perintah adalah 50.000 extra tokens.
⚠️ Gotcha 3: Jangan include business rules di constitution — constitution adalah tentang engineering conventions, business rules ada di spec.md.
⚠️ Gotcha 4: Constitution tidak menggantikan code review — meskipun AI mengikutinya, human review tetap diperlukan untuk architectural judgment calls.
05.19 Constitution untuk API Gateway Pattern
Jika project menggunakan API gateway, constitution perlu menetapkan aturan komunikasi antar-service. Section berikut membedakan API eksternal dari internal beserta pola autentikasinya.
1## API Gateway Conventions
2
3### Internal vs External APIs
4- External (customer-facing): via API gateway, public rate limit applied
5- Internal (service-to-service): direct calls, authenticated via mTLS + service token
6
7### Service Communication
8- Synchronous: HTTP/REST for simple request-response
9- Asynchronous: Kafka events for eventual consistency
10
11### Authentication Headers
12- External: Authorization: Bearer {jwt}
13- Internal: X-Service-Token: {service-token}
14 X-Request-ID: {uuid} (required for tracing)Aturan eksplisit soal internal vs external ini mencegah kebocoran keamanan klasik, seperti endpoint internal yang tidak sengaja terekspos dengan autentikasi customer.
05.20 Ringkasan
Constitution adalah fondasi dari semua yang dilakukan Spec Kit. Setiap perintah — dari specify plan sampai specify implement — dimulai dengan membaca constitution dan memastikan output konsisten dengan principles di dalamnya.
Komponen wajib: Project identity, tech stack dengan versi, architecture rules dengan dependency direction, must-always rules dengan contoh kode, must-never rules, testing conventions.
Update ritual: Setiap kali ada library baru, pattern baru, atau architectural decision baru, update constitution dalam PR terpisah dengan changelog yang jelas.
Length target: 150-300 baris — cukup untuk memberi guidance yang jelas, tidak terlalu panjang sampai menghabiskan context window.
Constitution vs CLAUDE.md: Constitution untuk Spec Kit (per-feature planning), CLAUDE.md untuk Claude Code (per-session context). Sinkronkan keduanya dengan specify claude-md sync.
Di artikel berikutnya, kita masuk ke perintah yang paling sering dijalankan: speckit.specify — cara menulis kebutuhan bisnis yang menjadi fondasi semua keputusan teknis, tanpa sekali pun menyebut tech stack.