Skip to content

Recipe: Fix a Bug

A bug has been reported or you’ve discovered an issue that needs investigation. You want GSD to manage the full lifecycle: create a milestone, research the codebase, plan a fix, execute it, and verify the result. This recipe walks through a real example using the full milestone flow.

Use the full lifecycle when the bug might be non-trivial — when you’re not sure of the root cause, when the fix might touch multiple files, or when you want GSD’s structured verification to confirm the fix works. For simple one-line fixes, consider the small change recipe instead.

  • GSD installed and available in your terminal
  • A project with a .gsd/ directory (run /gsd to start one if needed)
  • A bug to fix — either a report from a user or an issue you’ve noticed

The scenario: A Cookmate user reports that searching for “Pasta” returns no results, but searching for “pasta” (lowercase) works fine. The search is case-sensitive when it shouldn’t be.

Run /gsd and describe the bug when the smart entry wizard asks what you’re working on. Or, if you already have an active project and want to jump straight to milestone creation for this bug, run /gsd new-milestone:

> /gsd new-milestone
What's the vision?
> Users are reporting that search in Cookmate is case-sensitive.
> Searching for "Pasta" returns nothing, but "pasta" works.
> This should be a case-insensitive search.

GSD reflects back what it understood, scouts the codebase, then asks clarifying questions — such as whether the issue is in the API query, the database index, or the frontend — before writing a milestone context file.

2. Discussion produces context and requirements

Section titled “2. Discussion produces context and requirements”

After the conversation, GSD writes a capability contract and the milestone brief to disk:

.gsd/
├── PROJECT.md ← project description and milestone sequence (created or updated)
├── REQUIREMENTS.md ← capability contract: R001 case-insensitive search
└── milestones/
└── M003/
└── M003-CONTEXT.md ← bug scope, root cause hypothesis, fix approach

The context file captures what was discussed: the symptoms, the suspected root cause (PostgreSQL LIKE is case-sensitive by default), and the agreed approach (switch to ILIKE or add a LOWER() wrapper). The requirements file assigns stable R### IDs to each capability — doctor checks validate these throughout the milestone.

Before writing the roadmap, GSD prints it in chat and asks for approval. Only after confirmation does it write the roadmap file and tell you: “Milestone M003 ready.”

After the context file is written, auto-mode starts automatically. If it doesn’t, run:

> /gsd auto

GSD dispatches units in sequence:

  1. Milestone Research — scouts the codebase for search-related code, checks library docs for case-insensitive query options
  2. Slice Research — zooms in on the specific slice goal and integration points. For a focused single-slice bug fix, this step may be skipped if the milestone research already covered the relevant code.
  3. Plan the slice — breaks the slice into tasks (update query, add tests, verify)
.gsd/
├── REQUIREMENTS.md
└── milestones/
└── M003/
├── M003-CONTEXT.md
├── M003-RESEARCH.md ← found: searchRecipes() in lib/search.ts uses where: { title: { contains: query } }
├── M003-ROADMAP.md ← S01: Fix case-sensitive search
└── slices/
└── S01/
├── S01-RESEARCH.md
├── S01-PLAN.md
└── tasks/
├── T01-PLAN.md ← update query to use case-insensitive mode
└── T02-PLAN.md ← add test cases for mixed-case search

GSD executes each task in a fresh context window. For this bug fix:

  • T01 updates the Prisma query from contains: query to contains: query, mode: 'insensitive'
  • T02 adds test cases verifying that “Pasta”, “PASTA”, and “pasta” all return the same results

Each task calls gsd_complete_task when done, writing a summary that documents what changed and what was verified. The system reads the summary and creates a meaningful commit automatically — no manual git commands needed.

After the last task, GSD runs slice-level and milestone-level completion in sequence:

  • Writes a slice summary compressing all task work
  • Writes a UAT script with concrete test cases
  • Marks the slice done in the roadmap
  • Executes automated UAT checks against the completed slice — confirms mixed-case searches return results, writing the result to S01-ASSESSMENT.md
  • Reassesses the roadmap — confirms no further slices are needed (requires phases.reassess_after_slice preference)
  • Validates the milestone against the original success criteria
  • Seals the milestone with a completion summary
.gsd/
├── REQUIREMENTS.md
└── milestones/
└── M003/
├── M003-CONTEXT.md
├── M003-RESEARCH.md
├── M003-ROADMAP.md ← S01 ✓ checked off
├── M003-VALIDATION.md ← milestone QA check
├── M003-SUMMARY.md ← milestone completion record
└── slices/
└── S01/
├── S01-RESEARCH.md
├── S01-PLAN.md
├── S01-SUMMARY.md ← compressed slice record
├── S01-UAT.md ← test script for manual verification
├── S01-ASSESSMENT.md ← UAT execution results (+ roadmap reassessment if opt-in)
└── tasks/
├── T01-PLAN.md
├── T01-SUMMARY.md
├── T02-PLAN.md
└── T02-SUMMARY.md
FilePurpose
.gsd/PROJECT.mdProject description and milestone sequence — created or updated during the discuss phase
.gsd/REQUIREMENTS.mdCapability contract with stable R### IDs — written during the discuss phase
.gsd/DECISIONS.mdArchitectural and pattern decisions — created by gsd_decision_save during discuss; appended to during task execution
.gsd/milestones/M003/M003-CONTEXT.mdBug scope, root cause hypothesis, fix approach
.gsd/milestones/M003/M003-RESEARCH.mdCodebase findings — what code does what
.gsd/milestones/M003/M003-ROADMAP.mdSlice structure with completion checkboxes
.gsd/milestones/M003/slices/S01/S01-RESEARCH.mdSlice-level research and integration points
.gsd/milestones/M003/slices/S01/S01-PLAN.mdTask breakdown for the fix slice
.gsd/milestones/M003/slices/S01/tasks/T##-PLAN.mdIndividual task plans
.gsd/milestones/M003/slices/S01/tasks/T##-SUMMARY.mdTask completion records
.gsd/milestones/M003/slices/S01/S01-SUMMARY.mdCompressed slice record
.gsd/milestones/M003/slices/S01/S01-UAT.mdAcceptance test script
.gsd/milestones/M003/slices/S01/S01-ASSESSMENT.mdUAT execution results written by the run-uat unit; overwritten with roadmap reassessment when phases.reassess_after_slice is enabled
.gsd/milestones/M003/M003-VALIDATION.mdMilestone QA check against original success criteria
.gsd/milestones/M003/M003-SUMMARY.mdMilestone completion record
FilePurpose
.gsd/STATE.mdCurrent project state to determine next unit
.gsd/REQUIREMENTS.mdCapability contract read by research, planning, and validation phases
.gsd/KNOWLEDGE.mdAccumulated gotchas and patterns
.gsd/DECISIONS.mdArchitectural decisions that constrain the fix
FilePurpose
.gsd/STATE.mdUpdated after each unit completes
.gsd/REQUIREMENTS.mdRequirement status updated as capabilities are validated
.gsd/DECISIONS.mdAppended to when a task executor makes a notable architectural or pattern decision
.gsd/KNOWLEDGE.mdAny new patterns discovered (e.g., Prisma mode flag)
.gsd/gsd.dbSQLite database opened or auto-migrated at startup — tracks units, metrics, and routing history
.gsd/completed-units.jsonDisk-backed idempotency log — prevents double-dispatch on restart
.gsd/activity/JSONL execution logs per session
.gsd/runtime/Session metadata and lock files