Shattered Vales Studio Inc.

Writing Good Issues & Using Labels

Every piece of work at the studio starts as a GitHub issue: a bug, a feature, a chore. A good issue lets anyone, a teammate, a new hire, or an AI agent, understand the problem and start work without a meeting. This guide covers how to write one, how we label them, and how they connect to pull requests.

Step 1: Check Before You File

  1. Search first. The problem may already be reported. If it is, add your details as a comment rather than opening a duplicate.
  2. One problem per issue. "Save crash and also the tooltip is wrong" becomes two issues, because they'll be fixed, reviewed, and closed separately.
  3. Make sure it belongs in an issue. Questions go to the team channel; security vulnerabilities go privately to your lead, never in a public issue.
gh issue list --search "save crash" --state all

Step 2: Write Bug Reports Someone Can Reproduce

The goal of a bug report is to let someone else see the bug for themselves. A bug that can't be reproduced usually can't be fixed. Include:

## Summary
The game crashes when saving if the save folder is read-only.

## Steps to reproduce
1. Start a new game on Windows 11.
2. Make %USERPROFILE%\AppData\LocalLow\ShatteredVales\Saves read-only.
3. Press Esc > Save.

## Expected
An error message: "Couldn't save. Check folder permissions."

## Actual
The game freezes for ~2 seconds and closes. No error shown.

## Environment
Build 0.8.3 (Steam), Windows 11 23H2

## Frequency
Every time.

## Logs
UnauthorizedAccessException: Access to the path '...\slot1.sav' is denied.
  at SaveSystem.WriteSlot (System.Int32 slot) [0x0004a] in SaveSystem.cs:88

Step 3: Write Features as User Stories with Acceptance Criteria

For new features, describe the need, not just the solution. A user story says who wants something and why; acceptance criteria say exactly how everyone will know it's done. Business analysts usually own this part; developers should push back when criteria are vague.

## User story
As a tenant admin, I want to set how many days after the due date an
invoice becomes overdue, so that reminders match our payment terms.

## Acceptance criteria
- [ ] Given I am a tenant admin, when I open Billing Settings, then I can
      set "Overdue after" to a whole number of days from 0 to 90.
- [ ] Given the threshold is 15 days, when an invoice is unpaid 15 days
      after its due date, then its status shows "Overdue".
- [ ] Given I am not an admin, when I open Billing Settings, then the
      field is read-only.

## Out of scope
- Per-customer thresholds.
- Changing the reminder email wording.

## Notes
Default for existing tenants: 30 days (current behavior).

The Given / When / Then format makes every criterion testable. For issues an AI agent will work on, also see Writing Issues for Agentic AI.

Step 4: Apply the Standard Labels

Labels make issues searchable and drive the team's boards. Every issue gets one type label; leads add priority during triage.

GroupLabelsMeaning
Typebug · feature · chore · docsWhat kind of work it is. Exactly one per issue.
PriorityP0 · P1 · P2 · P3P0: drop everything (outage, data loss). P1: this sprint. P2: soon. P3: nice to have.
Statusneeds-triage · blocked · needs-infoWaiting on a lead, another task, or the reporter.
Areafor example area:billing, area:inventoryPart of the product. Defined per repository.
Workflowgood first issueSmall, well-defined, a good start for new team members.
WorkflowagenticReady for an AI agent. Applied only by maintainers.

Repository admins can create missing labels from the terminal:

gh label list
gh label create "needs-triage" --color FBCA04 --description "Waiting for a lead to review"

Step 5: Link Issues and Pull Requests

Mentioning #42 anywhere in a pull request, commit, or comment creates a link that appears on issue #42's timeline. Pull request descriptions use Resolves #42, which also shows the PR in the issue's "Development" section.

GitHub only closes issues automatically when a pull request with a closing keyword merges into the repository's default branch. Because our pull requests merge into Dev, issues stay open after merge. Close them yourself once your pull request is merged, with a comment linking it, unless your team closes them at release.

Step 6: Add Issue Templates to Each Repository

Templates in .github/ISSUE_TEMPLATE/ appear as choices when anyone clicks New issue, with the right sections and labels already filled in. Each template is a Markdown file with a short header:

---
name: Bug report
about: Something isn't working as expected
title: ""
labels: ["bug", "needs-triage"]
---

## Summary

## Steps to reproduce
1.

## Expected

## Actual

## Environment

## Frequency

## Logs / screenshots
<!-- Remove personal and customer data first. -->

Save as .github/ISSUE_TEMPLATE/bug_report.md. Add feature_request.md with the user story format from Step 3.

Step 7: Manage Issues from the Terminal

gh issue list --assignee @me                          # your open issues
gh issue list --label "good first issue"              # a place to start
gh issue view 42                                      # read an issue (add --web to open it in the browser)
gh issue create --title "..." --label bug --body-file bug.md
gh issue edit 42 --add-assignee @me                   # claim it
gh issue comment 42 --body "Reproduced on build 0.8.3."
gh issue close 42 --comment "Fixed in #57."