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

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.

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

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.

bash
1# Di root project Santekno Shop
2specify constitution init

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

markdown
 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 endpoint

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

  1. Error wrapping format adalah aturan paling sering dilanggar — tambahkan contoh yang sangat eksplisit.
  2. UUID vs string ID adalah sumber bug terbanyak — nyatakan dengan sangat jelas dan tambahkan contoh WRONG vs RIGHT.
  3. Float untuk harga — ini menyebabkan rounding errors yang sulit di-debug; tulis aturannya dengan tegas.
  4. 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.

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

Artikel Terkait

💬 Komentar