Skip to main content

Command Palette

Search for a command to run...

From Sketch to Spec to Ship: Spec-Driven Development with Spec-Kit and GitHub Copilot

A practical walkthrough of Specification-Driven Development using Spec-Kit, GitHub Copilot, and a ghost that just won't stop falling

Updated
8 min read
From Sketch to Spec to Ship: Spec-Driven Development with Spec-Kit and GitHub Copilot
S

I’m Siddhesh, a Microsoft Certified Trainer, cloud architect, and AI practitioner focused on helping developers and organizations adopt AI effectively. As a Pluralsight instructor and speaker, I design and deliver hands-on AI enablement programs covering Generative AI, Agentic AI, Azure AI, and modern cloud architectures.

With a strong foundation in Microsoft .NET and Azure, my work today centers on building real-world AI solutions, agentic workflows, and developer productivity using AI-assisted tools. I share practical insights through workshops, conference talks, online courses, blogs, newsletters, and YouTube—bridging the gap between AI concepts and production-ready implementations.

I wanted to build a Flappy Ghost game — a browser-based, zero-dependency HTML5 canvas game — but instead of just vibe-coding it with an AI, I challenged myself to do it properly using Specification-Driven Development (SDD) with Spec-Kit and GitHub Copilot inside VS Code. This post walks through exactly what I did, why SDD matters, and how the whole thing came together.


The Problem with "Just Prompt It"

When most developers use AI coding assistants, the workflow looks like this:

Describe what you want → get code → tweak it → ship it

It works, kind of. But you end up with code that has no traceable spec, no acceptance criteria, and no plan. You can't answer "does this code actually match what was intended?" because there was never a written intention to begin with. That's vibe-coding — and it gets messy fast.


What Is Specification-Driven Development (SDD)?

SDD flips the order. You write the specification first, then derive the implementation from it — with AI doing the heavy lifting at every step, but always anchored to a written artifact you've reviewed and approved.

The SDD cycle looks like this:

Visual Mockup / Idea
        │
        ▼
  spec.md      ← BDD acceptance criteria (Given/When/Then)
        │
        ▼
  plan.md      ← Architecture, technical decisions, file structure
        │
        ▼
  tasks.md     ← Checkbox task list, ordered and granular
        │
        ▼
  Code         ← Generated against the tasks, traceable to spec
        │
        ▼
  Validate     ← Does the code satisfy spec.md acceptance criteria?

At each phase, a human reviews and approves the artifact before the next phase begins. Copilot doesn't proceed until you say so. This enforces spec-first discipline and gives you traceability from every line of code back to a user story.


What Is Spec-Kit?

Spec-Kit is an open-source CLI tool from GitHub that scaffolds the SDD workflow directly into your project. It installs a set of Copilot agent files (.github/agents/) that extend GitHub Copilot Chat with slash commands like /speckit.specify, /speckit.plan, /speckit.tasks, and /speckit.implement.

Once initialised, your project has a structured .specify/ folder with templates, scripts, memory (a project constitution), and integration configs. Copilot reads the agent files automatically — no extra configuration needed.


My Scenario: Flappy Ghost 👻

I had a hand-drawn mockup image of a Flappy Bird-style game with a ghost as the player. The design showed:

  • Light blue sketchy/pencil-textured background

  • Green pipes extending from top and bottom edges

  • Rounded cloud platforms as mid-field obstacles

  • A dark floor strip with a score HUD: Score: X | High: X

  • A ghost emoji (👻) as the player character

The goal: a single self-contained index.html — no frameworks, no build tools, no CDN links. Just vanilla HTML5 Canvas and JavaScript.


Step-by-Step: How I Built It

Step 1 — Install the Tooling

Spec-Kit's CLI (specify) is installed from GitHub, not PyPI. Use uv (a fast Python package manager):

# Install uv (Windows)
winget install --id=astral-sh.uv -e

# Install specify CLI (check releases for latest tag)
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@v0.11.5

# Verify
specify version

⚠️ pip install speckit installs a completely unrelated spectral analysis library. Always use the uv tool install command above.


Step 2 — Initialise the Project

mkdir flappy-ghost
cd flappy-ghost
git init
specify init flappy-ghost --integration copilot
code .

This scaffolds everything into .github/agents/, .github/prompts/, and .specify/. Open .github/agents/ — you'll see agent files like speckit.specify.agent.md, speckit.plan.agent.md, etc. These extend Copilot Chat with the /speckit.* slash commands.


Step 3 — Generate the Spec from the Mockup Image

This is where SDD gets interesting. I opened GitHub Copilot Chat in Agent mode (Ctrl+Alt+I), selected the speckit.specify agent, attached my mockup image, and described the feature:

Use the attached sketch as the visual specification for a browser-based 
HTML5 canvas game called "Flappy Ghost".

The game must match everything visible in the image:
- Hand-drawn / sketchy art style for all visuals
- Small ghost emoji as the player character
- Green pipe obstacles from top and bottom
- Rounded cloud platforms as mid-field obstacles
- Light blue pencil-stroke textured background
- Dark grey floor strip at the bottom
- Score HUD: "Score: X | High: X"
- Spacebar or click to flap; gravity pulls down
- Collision with pipes, clouds, floor, or ceiling ends the game

Copilot generated features/001-flappy-ghost-game/spec.md — a full BDD spec with user stories and acceptance scenarios. For example:

Given the game is running and the player does nothing, When each frame advances, Then the ghost's vertical velocity increases by the gravity constant until it reaches terminal velocity.

Seven user stories covered: flight loop, pipe obstacles, cloud platforms, floor/ceiling boundaries, score tracking, game over/restart, and the hand-drawn art style.

git add .
git commit -m "feat(spec): flappy-ghost-game specification"

Step 4 — Generate the Implementation Plan

Back in Copilot Chat:

/speckit.plan The game is a single self-contained index.html file.
Use vanilla HTML5 Canvas and JavaScript — no frameworks or build tools.

Copilot read spec.md and wrote plan.md covering canvas setup, the requestAnimationFrame game loop, physics model (gravity constant + flap impulse), pipe and cloud spawning, collision detection (AABB), score tracking with localStorage, and the sketchy rendering approach.

git add .
git commit -m "feat(plan): flappy-ghost-game implementation plan"

Step 5 — Break It into Tasks

/speckit.tasks

Copilot produced tasks.md — a numbered checkbox list:

  • [ ] T1: Create index.html with canvas element and score HUD

  • [ ] T2: Implement game loop with requestAnimationFrame

  • [ ] T3: Render ghost as 👻 emoji on canvas (34px, velocity-rotated)

  • [ ] T4: Implement gravity and flap physics

  • [ ] T5: Pipe spawning at random heights with fixed gap

  • [ ] T6: Cloud platform spawning (white rounded rects, mid-screen)

  • [ ] T7: Collision detection (ghost vs pipes, clouds, floor, ceiling)

  • [ ] T8: Score increment on pipe pass; high score via localStorage

  • [ ] T9: Game-over overlay with restart prompt

  • [ ] T10: Sketchy background — pencil-line pattern pre-rendered to off-screen canvas

git add .
git commit -m "feat(tasks): flappy-ghost-game task breakdown"

Step 6 — Implement

/speckit.implement

Copilot worked through tasks.md top-to-bottom and generated index.html. When the first pass looked too clean, I followed up with a targeted style prompt:

The art style must look hand-drawn:
- strokeRect with ±3px random jitter on pipes and floor
- Ghost as 👻 at 34px, rotated proportionally to vertical velocity
- Background: #a8d5e8 fill, overlaid with diagonal pencil strokes (off-screen canvas)
- Clouds: white rounded rectangles with canvas shadow blur glow
- Floor: #2d2d2d strip, 40px tall
- HUD: monospace, white, centred in the floor strip

Result: a working index.html that opens directly in the browser, no server needed.


Step 7 — Validate Against the Spec

I opened index.html in the browser and manually tested against each acceptance scenario in spec.md:

  • ✅ Press Space → ghost flaps upward, gravity pulls it back down

  • ✅ Fly into a pipe → Game Over triggers

  • ✅ Pass through a gap → score increments

  • ✅ Reload the page → high score persists via localStorage

  • ✅ Background has visible pencil-stroke texture

  • ✅ Ghost rotates with velocity direction

Every test traced back to a specific Given/When/Then in the spec.


The Key Insight: Traceability

Without SDD, you have code. With SDD, you have:

  • spec.md → what the software must do (acceptance criteria)

  • plan.md → how it will be built (architecture decisions)

  • tasks.md → what was built and in what order

  • code → the implementation, traceable to every task above

If a bug appears, you don't just fix it — you check which acceptance scenario it violates and trace it back. That's the discipline SDD enforces.


Spec-Kit Slash Commands Reference

Command Purpose
/speckit.constitution Establish project coding standards
/speckit.specify Create feature spec from description or image
/speckit.clarify Surface ambiguities before planning
/speckit.plan Generate technical implementation plan
/speckit.analyze Cross-check spec, plan, and tasks for consistency
/speckit.tasks Break plan into actionable task checklist
/speckit.implement Execute tasks and generate code
/speckit.checklist Generate quality checklist for the feature
/speckit.converge Assess codebase against spec and append remaining work

Final Thoughts

SDD with Spec-Kit didn't slow me down — it made every AI-generated output useful because it was grounded in something I had reviewed. The mockup image became a living specification. The spec became the plan. The plan became tasks. The tasks became working code.

If you're using GitHub Copilot and finding that "just prompt it" leaves you with code you can't justify, this workflow is worth trying. The spec is the contract — everything else follows from it.


Try it yourself: github.github.com/spec-kit