Modul master Level 3 VibeKoding: Siklus Lengkap Pengembangan via GitHub Issues.Modul master Level 3 VibeKoding: Siklus Lengkap Pengembangan via GitHub Issues.
This tutorial follows one complete Spec-driven development cycle. We begin with a rough product idea, clarify it with an AI agent, turn the agreement into a written specification, publish prioritized GitHub Issues, implement them in dependency order, and review the finished software.This tutorial follows one complete Spec-driven development cycle. We begin with a rough product idea, clarify it with an AI agent, turn the agreement into a written specification, publish prioritized GitHub Issues, implement them in dependency order, and review the finished software.
[From Vibe Coding to Spec Coding](/en/stage-3/core-skills/spec-coding/) explains why specifications are becoming central to AI development. This chapter is the practical companion: a real public repository shows how a specification becomes Issues, dependencies, commits, tests, and a working product.[From Vibe Coding to Spec Coding](/en/stage-3/core-skills/spec-coding/) explains why specifications are becoming central to AI development. This chapter is the practical companion: a real public repository shows how a specification becomes Issues, dependencies, commits, tests, and a working product.
Our starting point was one sentence:Our starting point was one sentence:
> I want to build a macOS CRM that helps me manage imported contacts and understand my relationships. We can use sample data first.> I want to build a macOS CRM that helps me manage imported contacts and understand my relationships. We can use sample data first.
The result is Relationship Compass, a native macOS application that searches and filters contacts, edits relationship profiles, imports CSV files, records interactions, and calculates who needs a follow-up.The result is Relationship Compass, a native macOS application that searches and filters contacts, edits relationship profiles, imports CSV files, records interactions, and calculates who needs a follow-up.
πΌοΈ The finished Relationship Compass contact-management interfaceThe finished Relationship Compass contact-management interface
Explore the complete [public example repository](https://github.com/sanbuphy/relationship-compass-macos). It contains only sample data and preserves the specification, Issues, commit history, source code, and tests.Explore the complete [public example repository](https://github.com/sanbuphy/relationship-compass-macos). It contains only sample data and preserves the specification, Issues, commit history, source code, and tests.
A common AI coding loop looks like this:A common AI coding loop looks like this:
text Describe an idea β AI writes code β something is wrong β add another instruction β modify again
That can work for a small page. As a project grows, however, earlier requirements disappear from the conversation, large changes become hard to track, and a feature may run without actually satisfying the original request.That can work for a small page. As a project grows, however, earlier requirements disappear from the conversation, large changes become hard to track, and a feature may run without actually satisfying the original request.
Matt Pocock's Skills address this by giving the agent a repeatable workflow. A Skill tells the agent what to establish, what artifact to produce, and when to stop for confirmationβnot merely which code to write.Matt Pocock's Skills address this by giving the agent a repeatable workflow. A Skill tells the agent what to establish, what artifact to produce, and when to stop for confirmationβnot merely which code to write.
| Chat-first implementation | Spec-driven implementation |
|---|---|
| The current conversation is the main source of truth | A versioned Spec is the source of truth |
| New requirements are appended informally | Scope changes update the Spec and tasks first |
| Progress lives in agent summaries | Progress lives in Issues and commits |
| βIt runsβ is the main completion signal | Every acceptance criterion is checked |
The goal is not paperwork. It is to turn intent into a shared, durable standard that humans and agents can inspect, update, and verify.The goal is not paperwork. It is to turn intent into a shared, durable standard that humans and agents can inspect, update, and verify.
GitHub is more than code storage here. It is simultaneously:GitHub is more than code storage here. It is simultaneously:
| GitHub artifact | Plain-language meaning | Example |
|---|---|---|
| Spec | What the finished software must do | specs/relationship-compass-mvp.md |
| Issue | One independently deliverable task | #2 Browse sample Contacts |
| Dependency | Which task must finish first | #3 is blocked by #2 |
| Commit | What changed in one implementation step | feat: browse sample contacts |
| Tests | Evidence that behavior still works | swift test |
| ADR | Why an important technical choice was made | docs/adr/0002-native-swiftui-macos.md |
mermaid flowchart LR A["Agreed decisions"] --> B["Versioned Spec"] B --> C["Parent Issue #1"] C --> D["Implementation Issues #2β#6"] D --> E["Priority + dependencies"] E --> F["Commits + tests"] F --> G["Close implementation Issues"] G --> H["Final review"] H --> I["Close the parent Issue"]
GitHub therefore becomes a development workspace with memory. A new session can reconstruct the project's decisions and current frontier without replaying the entire conversation.GitHub therefore becomes a development workspace with memory. A new session can reconstruct the project's decisions and current frontier without replaying the entire conversation.
This example uses five Skills:This example uses five Skills:
grill-with-docs clarifies the product and technical boundaries;grill-with-docs clarifies the product and technical boundaries;to-spec writes the agreement as a formal specification;to-spec writes the agreement as a formal specification;to-tickets creates prioritized, dependency-aware GitHub Issues;to-tickets creates prioritized, dependency-aware GitHub Issues;implement completes the ready Issues one at a time;implement completes the ready Issues one at a time;code-review checks code health and requirement coverage.code-review checks code health and requirement coverage.text Idea β clarify β specify β create tickets β implement β review
To reproduce the example, prepare:To reproduce the example, prepare:
gh) authenticated in your terminal;GitHub CLI (gh) authenticated in your terminal;Run this inside your project directory:Run this inside your project directory:
bash npx skills@latest add mattpocock/skills
To install every Skill without selecting them individually:To install every Skill without selecting them individually:
bash npx skills@latest add mattpocock/skills -y
The practical flow is:The practical flow is:
text grill-with-docs β to-spec β to-tickets β implement β code-review
For a very large or uncertain project, wayfinder can identify the decisions that must be made before this flow begins.For a very large or uncertain project, wayfinder can identify the decisions that must be made before this flow begins.
Check GitHub authentication:Check GitHub authentication:
bash gh auth status
If necessary, sign in with gh auth login -h github.com. Then create and push the repository:If necessary, sign in with gh auth login -h github.com. Then create and push the repository:
bash gh repo create relationship-compass-macos \ --public \ --source . \ --remote origin \ --push
This tutorial uses a public repository because every record is fictional. For a personal relationship manager, use --private and check samples, logs, and Git history for names, email addresses, or private notes before pushing.This tutorial uses a public repository because every record is fictional. For a personal relationship manager, use --private and check samples, logs, and Git history for names, email addresses, or private notes before pushing.
| Label | Meaning |
|---|---|
ready-for-agent | The requirement is clear enough to implement |
priority:P0 | Foundation work that must happen first |
priority:P1 | Core work waiting on a dependency |
priority:P2 | Polish, documentation, and final verification |
completed-by-agent | Implemented and verified by the agent |
Relationship Compass is a personal relationship manager rather than a sales pipeline. The first release:Relationship Compass is a personal relationship manager rather than a sales pipeline. The first release:
It deliberately excludes cloud sync, AI relationship scoring, accounts, a backend, and macOS Contacts access. This preserves a complete but privacy-safe MVP.It deliberately excludes cloud sync, AI relationship scoring, accounts, a backend, and macOS Contacts access. This preserves a complete but privacy-safe MVP.
grill-with-docs4. Step one: clarify the request with grill-with-docsgrill-with-docs behaves like an experienced product and technical partner. It asks about decisions that materially change the implementation before any code is written.grill-with-docs behaves like an experienced product and technical partner. It asks about decisions that materially change the implementation before any code is written.
The user does not need to know SwiftUI or database design. They only need to describe the desired experience clearly.The user does not need to know SwiftUI or database design. They only need to describe the desired experience clearly.
The conversation established these durable decisions:The conversation established these durable decisions:
| Decision | Choice | Reason |
|---|---|---|
| Platform | Native SwiftUI on macOS 14+ | Native file selection, keyboard behavior, and accessibility |
| Seed data | Six deterministic samples | No sensitive data needed to evaluate the app |
| Import | UTF-8 CSV | Easy to prepare, inspect, and repair |
| Persistence | Local JSON | Transparent and backend-free |
| Strength | Close / Active / Dormant | Avoid turning relationships into sales scores |
| Privacy | No Contacts access or network | No sensitive permission in the MVP |
| Test surface | Public RelationshipStore behavior | Verify outcomes rather than implementation details |
The team records ambiguous terms in CONTEXT.md:The team records ambiguous terms in CONTEXT.md:
markdown **Interaction**: A dated note that records a meaningful exchange with a Contact. _Avoid_: Activity, event, touchpoint **Follow-up**: A suggested next connection date derived from the latest Interaction and the Relationship Profile's rhythm. _Avoid_: Task, reminder, notification
This keeps code, tests, and Issues from drifting between Contact, Lead, and Customer, or between follow-ups, reminders, and notifications.This keeps code, tests, and Issues from drifting between Contact, Lead, and Customer, or between follow-ups, reminders, and notifications.
The project contains two short ADRs:The project contains two short ADRs:
0001-local-first-private-data.md: relationship data stays local and no Contacts permission is requested;0001-local-first-private-data.md: relationship data stays local and no Contacts permission is requested;0002-native-swiftui-macos.md: the app uses SwiftUI instead of Electron or a web shell.0002-native-swiftui-macos.md: the app uses SwiftUI instead of Electron or a web shell.ADRs are valuable for decisions that are expensive to reverse and have real trade-offs. They are not needed for every small implementation choice.ADRs are valuable for decisions that are expensive to reverse and have real trade-offs. They are not needed for every small implementation choice.
The discussion happens in chat, but agreed facts are committed as CONTEXT.md and docs/adr/*. GitHub preserves the confirmed context so a later session can recover it. No implementation ticket exists yet.The discussion happens in chat, but agreed facts are committed as CONTEXT.md and docs/adr/*. GitHub preserves the confirmed context so a later session can recover it. No implementation ticket exists yet.
to-spec5. Step two: write the specification with to-spec
The resulting Spec covers the problem, proposed MVP, 24 user stories, accepted technical decisions, verification strategy, and explicit non-goals. Read it at [specs/relationship-compass-mvp.md](https://github.com/sanbuphy/relationship-compass-macos/blob/main/specs/relationship-compass-mvp.md) or [Issue #1](https://github.com/sanbuphy/relationship-compass-macos/issues/1).The resulting Spec covers the problem, proposed MVP, 24 user stories, accepted technical decisions, verification strategy, and explicit non-goals. Read it at [specs/relationship-compass-mvp.md](https://github.com/sanbuphy/relationship-compass-macos/blob/main/specs/relationship-compass-mvp.md) or [Issue #1](https://github.com/sanbuphy/relationship-compass-macos/issues/1).
A useful user story says:A useful user story says:
> As a user, I want contacts with no interaction history to appear in Follow-ups so newly imported people are not silently forgotten.> As a user, I want contacts with no interaction history to appear in Follow-ups so newly imported people are not silently forgotten.
It identifies the user, desired behavior, and value without freezing the Swift file structure. The requirement survives refactoring.It identifies the user, desired behavior, and value without freezing the Swift file structure. The requirement survives refactoring.
The Spec requires public-behavior tests for sample initialization, combined filtering, CSV validation and deduplication, JSON persistence, profile editing, interaction ordering, and follow-up calculations at a controlled date.The Spec requires public-behavior tests for sample initialization, combined filtering, CSV validation and deduplication, JSON persistence, profile editing, interaction ordering, and follow-up calculations at a controlled date.
The Markdown file supports version history and review; Issue #1 provides a visible project entry point. A later scope change must update the Spec in a commit instead of living only in a new chat.The Markdown file supports version history and review; Issue #1 provides a visible project entry point. A later scope change must update the Spec in a commit instead of living only in a new chat.
to-tickets6. Step three: turn the Spec into ordered Issues with to-tickets
Avoid horizontal tickets such as βall models,β βall stores,β βall UI,β and βtests at the end.β A vertical slice joins the minimum data, interface, and tests needed to demonstrate one user outcome.Avoid horizontal tickets such as βall models,β βall stores,β βall UI,β and βtests at the end.β A vertical slice joins the minimum data, interface, and tests needed to demonstrate one user outcome.
| Issue | Priority | Demonstrable result | Blocked by |
|---|---|---|---|
| [#2 Browse sample Contacts](https://github.com/sanbuphy/relationship-compass-macos/issues/2) | P0 | Launch, samples, search, and details | None |
| [#3 Import and persist private Contact data](https://github.com/sanbuphy/relationship-compass-macos/issues/3) | P0 | CSV deduplication and JSON persistence | #2 |
| [#4 Organize Relationship Profiles](https://github.com/sanbuphy/relationship-compass-macos/issues/4) | P1 | Profile editing, strength, circles, filters | #2 |
| [#5 Record Interactions and plan Follow-ups](https://github.com/sanbuphy/relationship-compass-macos/issues/5) | P1 | History and Follow-ups | #4 |
| [#6 Polish and verify the MVP](https://github.com/sanbuphy/relationship-compass-macos/issues/6) | P2 | Errors, docs, packaging, full verification | #3 and #5 |
mermaid flowchart LR T1["P0 Β· Browse sample Contacts"] --> T2["P0 Β· Import and persist"] T1 --> T3["P1 Β· Organize Profiles"] T3 --> T4["P1 Β· Interactions and Follow-ups"] T2 --> T5["P2 Β· Polish and verify"] T4 --> T5
Priority says how important a task is; a dependency says whether it can start now. The ready, unblocked tickets form the current task frontier.Priority says how important a task is; a dependency says whether it can start now. The ready, unblocked tickets form the current task frontier.
The Spec becomes five independently trackable Issues with priority:P0/P1/P2 and native Blocked by relationships. GitHub has now changed from an archive into the live task board.The Spec becomes five independently trackable Issues with priority:P0/P1/P2 and native Blocked by relationships. GitHub has now changed from an archive into the live task board.
| Issue | Main commit |
|---|---|
| #2 Browse samples | [9d9d7bd](https://github.com/sanbuphy/relationship-compass-macos/commit/9d9d7bd) |
| #3 Import and persist | [935750b](https://github.com/sanbuphy/relationship-compass-macos/commit/935750b) |
| #4 Organize profiles | [329bd67](https://github.com/sanbuphy/relationship-compass-macos/commit/329bd67) |
| #5 Interactions and follow-ups | [83f4af6](https://github.com/sanbuphy/relationship-compass-macos/commit/83f4af6) |
| #6 Polish and verify | [3ae0bbf](https://github.com/sanbuphy/relationship-compass-macos/commit/3ae0bbf) |
| Review fixes | [cbad102](https://github.com/sanbuphy/relationship-compass-macos/commit/cbad102), [11361ca](https://github.com/sanbuphy/relationship-compass-macos/commit/11361ca), [d1c83be](https://github.com/sanbuphy/relationship-compass-macos/commit/d1c83be) |
For the CSV ticket, the agent:For the CSV ticket, the agent:
bash swift test --filter RelationshipStoreTests swift build swift test
The final project passes all 13 public-behavior tests.The final project passes all 13 public-behavior tests.
The committed [RelationshipStore.importCSV](https://github.com/sanbuphy/relationship-compass-macos/blob/main/Sources/RelationshipCompass/RelationshipStore.swift#L69-L154) reads UTF-8, validates headers, identifies duplicates, and builds a candidate result before replacing live data. A failure therefore cannot leave a half-imported state.The committed [RelationshipStore.importCSV](https://github.com/sanbuphy/relationship-compass-macos/blob/main/Sources/RelationshipCompass/RelationshipStore.swift#L69-L154) reads UTF-8, validates headers, identifies duplicates, and builds a candidate result before replacing live data. A failure therefore cannot leave a half-imported state.
πΌοΈ CSV parsing, header validation, and safe deduplication in XcodeCSV parsing, header validation, and safe deduplication in Xcode
The matching [RelationshipStoreTests](https://github.com/sanbuphy/relationship-compass-macos/blob/main/Tests/RelationshipCompassTests/RelationshipStoreTests.swift#L29-L69) cover repeated imports, duplicate headers, malformed input, and UTF-8 BOM files.The matching [RelationshipStoreTests](https://github.com/sanbuphy/relationship-compass-macos/blob/main/Tests/RelationshipCompassTests/RelationshipStoreTests.swift#L29-L69) cover repeated imports, duplicate headers, malformed input, and UTF-8 BOM files.
πΌοΈ Public-behavior tests for repeated imports and invalid CSV headersPublic-behavior tests for repeated imports and invalid CSV headers
The agent selects work using ready-for-agent, priority, and Blocked by. On completion it posts the commit and test result, removes the ready label, adds completed-by-agent, and closes the Issue. Issue state is therefore the real project state.The agent selects work using ready-for-agent, priority, and Blocked by. On completion it posts the commit and test result, removes the ready label, adds completed-by-agent, and closes the Issue. Issue state is therefore the real project state.
Closing the implementation Issues is not enough. code-review performs two distinct passes.Closing the implementation Issues is not enough. code-review performs two distinct passes.
The first pass checks naming, duplication, oversized files, coupling, and repository conventions. It found that the main SwiftUI view carried too many responsibilities and that the follow-up interval could bypass its minimum-one-day rule. The implementation was refactored and a validated value type was introduced.The first pass checks naming, duplication, oversized files, coupling, and repository conventions. It found that the main SwiftUI view carried too many responsibilities and that the follow-up interval could bypass its minimum-one-day rule. The implementation was refactored and a validated value type was introduced.
The second pass rereads the Spec and every Issue. It found real gaps that the initial test suite missed:The second pass rereads the Spec and every Issue. It found real gaps that the initial test suite missed:
Tests were added first, the defects were fixed, and both review passes were rerun. This matters because green tests prove only the behavior those tests describe; they do not prove that every original requirement was tested.Tests were added first, the defects were fixed, and both review passes were rerun. This matters because green tests prove only the behavior those tests describe; they do not prove that every original requirement was tested.
Review fixes remain visible as separate commits. Completion comments on Issues #2β#6 link the commits and verification results; only after both reviews pass is parent Issue #1 closed.Review fixes remain visible as separate commits. Completion comments on Issues #2β#6 link the commits and verification results; only after both reviews pass is parent Issue #1 closed.
Relationship Compass is a buildable, testable, packageable native macOS applicationβnot a mockup.Relationship Compass is a buildable, testable, packageable native macOS applicationβnot a mockup.
| Deliverable | Result |
|---|---|
| GitHub planning | One parent requirement Issue and five implementation Issues, all closed |
| Implementation history | Nine focused commits completed in dependency order |
| Automated verification | 13/13 behavior tests pass and the project builds |
| Final review | Code-health and Spec-completion reviews pass |
| Runnable artifact | A script creates Relationship Compass.app |
| Privacy boundary | Local-only data, no Contacts access, no relationship upload |
Searching for Founder narrows six sample contacts to Maya Chen. Relationship strength and circle filters can be combined, and the main list and Follow-ups use the same rules.Searching for Founder narrows six sample contacts to Maya Chen. Relationship strength and circle filters can be combined, and the main list and Follow-ups use the same rules.
πΌοΈ Searching by role leaves only Maya ChenSearching by role leaves only Maya Chen
The detail view edits organization, role, email, relationship strength, circles, rhythm, and notes. Duplicate circles are normalized and the follow-up interval must be at least one day.The detail view edits organization, role, email, relationship strength, circles, rhythm, and notes. Duplicate circles are normalized and the follow-up interval must be at least one day.
πΌοΈ Editing a Relationship Compass contact profileEditing a Relationship Compass contact profile
After an interaction on August 9, 2026, a 30-day rhythm produces September 8, 2026 as the next connection date. The entry appears in Interaction History and the contact moves into Follow-ups when due.After an interaction on August 9, 2026, a 30-day rhythm produces September 8, 2026 as the next connection date. The entry appears in Interaction History and the contact moves into Follow-ups when due.
πΌοΈ The next follow-up date calculated from a new interactionThe next follow-up date calculated from a new interaction
πΌοΈ The new entry in Interaction HistoryThe new entry in Interaction History
On a Mac, run the complete project with:On a Mac, run the complete project with:
bash git clone https://github.com/sanbuphy/relationship-compass-macos.git cd relationship-compass-macos swift build swift test ./scripts/package-app.sh open "dist/Relationship Compass.app"
Cloud sync, Contacts permission, encryption, and AI analysis would require a new privacy discussion and new architecture decisions.Cloud sync, Contacts permission, encryption, and AI analysis would require a new privacy discussion and new architecture decisions.
This workflow suits scoped MVPs, sites, apps, and backends with observable behavior and reliable test or build commands. It is a poor fit when requirements change hourly, verification is impossible, or the work directly mutates production data.This workflow suits scoped MVPs, sites, apps, and backends with observable behavior and reliable test or build commands. It is a poor fit when requirements change hourly, verification is impossible, or the work directly mutates production data.
Even during continuous implementation, a person should confirm:Even during continuous implementation, a person should confirm:
Reliable autonomy does not outsource every decision. The human owns goals, boundaries, and acceptance; the agent executes the agreed work consistently.Reliable autonomy does not outsource every decision. The human owns goals, boundaries, and acceptance; the agent executes the agreed work consistently.
text Rough idea β grill-with-docs Agreed scope + vocabulary + durable technical decisions β to-spec Versioned, testable requirements β to-tickets Prioritized, dependency-aware GitHub Issues β implement One ticket, test, and commit at a time β code-review Code-health review + Spec-completion review β Buildable and verifiable software
When a chat ends, the Spec, Issues, dependency graph, commits, and test evidence remain in GitHub. The next session can resume from recorded project state instead of guessing the user's intent again.When a chat ends, the Spec, Issues, dependency graph, commits, and test evidence remain in GitHub. The next session can resume from recorded project state instead of guessing the user's intent again.