Files
Claude-Code-Game-Studios/CCGS Skill Testing Framework/skills/sprint/changelog.md
T
DonchitosandClaude Opus 5.5 b21fa0f7f2 Release 1.1.2 — the default path works end to end
Fix release for 1.1.1: the minimal path end to end, engine commands that
run on Godot, Unity and Unreal, hook warnings you can see, and verdicts
that say when they could not check. Details in CHANGELOG.md; upgrade
steps in UPGRADING.md (v1.1.1 → v1.1.2).

Fixes #67
Fixes #131

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
2026-09-29 21:32:19 +10:00

255 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Skill Test Spec: /changelog
## Skill Summary
`/changelog` is a Sonnet-tier skill that generates two changelogs — an internal
one and a player-facing one — from the git commits since the last release tag.
Before using the injected history it classifies every commit as Game or
Framework / maintenance (Unclear counts as Framework), uses only the Game
commits, and says how many of how many it used; with zero Game commits it stops.
With no history at all (not a git repository, or no commits) it skips that check
and stops at Phase 1. It reads sprint plans in `production/sprints/` and GDDs in
`design/gdd/` for context, and sorts changes into New Features, Improvements, Bug
Fixes, Balance Changes, Technical Debt / Refactoring (internal changelog only),
Known Issues and Miscellaneous. The internal changelog ends with a Metrics
section that counts commits without a task reference. With no tags it bounds the
range to `git log --oneline -n 100` rather than reading the full log. No director
gates are used. The skill asks "May I write this changelog to
`docs/CHANGELOG.md`?" with append / overwrite / decline options. Verdicts:
CHANGELOG WRITTEN after a write, COMPLETE when the user declines the write,
BLOCKED when there is no history or none of it is the game's.
---
## Static Assertions (Structural)
Checked against the SKILL.md by `/skill-test spec` — no fixture needed.
- [ ] Has required frontmatter fields: `name`, `description`, `argument-hint`, `user-invocable`, `allowed-tools`
- [ ] Has ≥2 phase headings
- [ ] Contains verdict keywords: CHANGELOG WRITTEN, COMPLETE, BLOCKED
- [ ] Contains "May I write" language (skill writes changelog)
- [ ] Has a next-step handoff (`/patch-notes` for a player-facing release, `/release-checklist`)
---
## Director Gate Checks
None. Changelog generation is a fast compilation task; no gates are invoked.
---
## Test Cases
### Case 1: Happy Path — Multiple sprints since last release tag
**Fixture:**
- Git history has a tag `v0.3.0`; it is the newest tag in the injected tag list
- Since that tag: 12 commits across sprints 006, 007, 008 — all Game commits
(mechanics, content, bug fixes) naming systems that appear in `design/`
- `production/sprints/sprint-006.md` through `sprint-008.md` exist and list the
stories whose task IDs appear in the commit messages
- `docs/CHANGELOG.md` does not yet exist
**Input:** `/changelog`
**Expected behavior:**
1. Skill classifies the injected commits as Game or Framework / maintenance and
states how many of how many it used
2. Skill reads `git log --oneline v0.3.0..HEAD`
3. Skill reads the sprint plans for sprints 006–008 in `production/sprints/`
for the context behind the changes
4. Skill categorizes changes into New Features, Improvements, Bug Fixes,
Balance Changes, Technical Debt / Refactoring, Known Issues and
Miscellaneous, with a Metrics section
5. Skill outputs both the internal and the player-facing changelog
6. Skill asks "May I write this changelog to `docs/CHANGELOG.md`?" with options
[A] append, [B] overwrite, [C] no
7. User selects [B]; the file is created; verdict CHANGELOG WRITTEN
**Assertions:**
- [ ] Changelog covers the commits in `v0.3.0..HEAD`, and the output states how many of how many injected commits it used
- [ ] Entries use the skill's section set — New Features, Improvements, Bug Fixes, Balance Changes, Technical Debt / Refactoring, Known Issues, Miscellaneous — not a generic Features/Fixes split
- [ ] Sprint plans in `production/sprints/` for the covered sprints are read for context before categorizing
- [ ] Both changelogs are presented before the "May I write" prompt, and nothing is written before approval
- [ ] Verdict is CHANGELOG WRITTEN after the write
---
### Case 2: No Git Tags Found — Bounded range used
**Fixture:**
- Git repository has 20 commits and no tags; all 20 are Game commits
- The injected tag list is empty
- `docs/CHANGELOG.md` does not exist
**Input:** `/changelog`
**Expected behavior:**
1. Skill finds no tag to anchor the range
2. Skill bounds the range with `git log --oneline -n 100` — it does not read an
unbounded full log
3. All 20 commits fall inside the 100-commit bound, so the window reaches the
start of history and the skill does not need to ask for a start ref
4. Skill states how many of the commits it used
5. Skill compiles the categorized changelog and asks "May I write" before writing
**Assertions:**
- [ ] Skill does not error when no git tags exist
- [ ] The range is read with the bounded `git log --oneline -n 100`, never an unbounded full log
- [ ] All 20 commits are covered, and the skill does not ask for a start ref (the bound reaches the first commit)
- [ ] Output states how many of the 20 commits were used
- [ ] Changelog is still organized into sections despite the missing tag
---
### Case 3: Commit Messages Without Task IDs — Categorized by content, counted in Metrics
**Fixture:**
- Git log since the last tag has 8 Game commits
- 3 commits reference task IDs (e.g. `[STORY-012]`) matching sprint stories
- 5 commits have no task ID: "tweak dash cooldown 0.8 -> 0.6",
"fix player clipping through ledge", "add footstep sounds", "level tweaks",
"combat cleanup"
**Input:** `/changelog`
**Expected behavior:**
1. Skill categorizes every commit by what it changed, whether or not it has a
task ID
2. "tweak dash cooldown 0.8 -> 0.6" goes to Balance Changes; "fix player
clipping through ledge" goes to Bug Fixes
3. "combat cleanup" says it cleans up and names no fix, feature or tuning, so it
goes to Technical Debt / Refactoring — in the internal changelog only
4. "level tweaks" is too vague to classify confidently and goes to
Miscellaneous
5. The Metrics section reports `Commits without task reference: 5`
6. Skill asks "May I write" and writes on approval
**Assertions:**
- [ ] Commits are categorized by content with or without a task ID — the untagged "tweak dash cooldown 0.8 -> 0.6" lands in Balance Changes, not in a separate no-ID group
- [ ] "combat cleanup" is listed under Technical Debt / Refactoring in the internal changelog and does not appear in the player-facing changelog
- [ ] "level tweaks", too vague to classify, is listed under Miscellaneous
- [ ] Metrics section contains `Commits without task reference: 5`
- [ ] No commits are silently dropped — all 8 appear in a section
---
### Case 4: Existing CHANGELOG.md — New entry at the top, old entries preserved
**Fixture:**
- `docs/CHANGELOG.md` already exists with sections for `v0.2.0` and `v0.3.0`
- New Game commits exist since the `v0.3.0` tag
**Input:** `/changelog`
**Expected behavior:**
1. Skill compiles new entries for the period since `v0.3.0`
2. Before asking, skill checks whether `docs/CHANGELOG.md` exists — it does, so
it recommends [A] append
3. Skill asks "May I write this changelog to `docs/CHANGELOG.md`?" with
[A] append (recommended), [B] overwrite, [C] no
4. User selects [A]; the new entry is placed at the top of the file (newest
first); the `v0.2.0` and `v0.3.0` sections are intact; verdict CHANGELOG WRITTEN
**Assertions:**
- [ ] Skill checks whether `docs/CHANGELOG.md` exists before asking, and recommends [A] append because it does
- [ ] The prompt offers append, overwrite and decline as distinct options
- [ ] On [A], the new entry is placed at the top of the file (newest first), not at the bottom and not replacing the file
- [ ] Existing `v0.2.0` and `v0.3.0` entries are preserved in the written file
---
### Case 5: Gate Compliance — No gate; declined write ends COMPLETE
**Fixture:**
- Git history has Game commits since the last tag
- `project.yaml` sets `modes.review_mode: full`
**Input:** `/changelog`
**Expected behavior:**
1. Skill compiles both changelogs; no director gate is spawned (the skill
resolves only `automation`, never `review_mode`)
2. Skill goes straight from presenting the changelogs to the write prompt
3. User selects [C] No — I'll copy it manually
4. Skill stops without writing; verdict COMPLETE
**Assertions:**
- [ ] No director gate is invoked regardless of review mode
- [ ] Output does not reference any gate result
- [ ] Skill proceeds directly from presenting the changelogs to the "May I write" prompt
- [ ] On [C], no file is written and the verdict is COMPLETE, not CHANGELOG WRITTEN
---
### Case 6: Provenance Stop — Zero Game commits
**Fixture:**
- The 30 injected commits all touch the framework or tooling — subjects such as
"fix: session-start hook timeout", "docs: skill catalog", "ci: cache the test
runner" — and none names a game system in `design/` or the code root
- `docs/CHANGELOG.md` does not exist
**Input:** `/changelog`
**Expected behavior:**
1. Skill classifies every injected commit: 0 Game, 30 Framework / maintenance
2. Skill stops with "The git history in this repo does not appear to belong to
[game] …", describing what the commits actually cover
3. No changelog is generated and nothing is written; verdict BLOCKED
**Assertions:**
- [ ] Output names the classification result — 0 of 30 commits are Game commits
- [ ] Output contains the "does not appear to belong to" stop, not a changelog built from framework commits (no "Fixed an issue where …" copy from a hook fix)
- [ ] No "May I write" prompt appears and no file is written
- [ ] Verdict is BLOCKED — not COMPLETE and not CHANGELOG WRITTEN
---
### Case 7: No History — Not a git repository
**Fixture:**
- The project directory is not a git repository, so both injected history
blocks are empty
- `docs/CHANGELOG.md` does not exist
**Input:** `/changelog`
**Expected behavior:**
1. The injected commit list is empty, so the provenance check is skipped —
there is nothing to classify
2. Phase 1's `git rev-parse --is-inside-work-tree` fails; skill outputs "No git
history found. A changelog is built from commits …"
3. Nothing is generated or written; verdict BLOCKED
**Assertions:**
- [ ] The "does not appear to belong to" provenance stop is NOT shown — an empty history is not a wrong history
- [ ] Output says no git history was found and offers committing the work or supplying the change list directly
- [ ] No changelog is generated, no "May I write" prompt appears, and no file is written
- [ ] Verdict is BLOCKED
---
## Protocol Compliance
- [ ] Classifies the injected commits as Game or Framework / maintenance and uses only Game commits
- [ ] Reads the git log and the sprint plans in `production/sprints/` before compiling
- [ ] Always asks "May I write" before writing the changelog
- [ ] No director gates are invoked
- [ ] Verdict is CHANGELOG WRITTEN after a write, COMPLETE when the write is declined, and BLOCKED when there is no history or no Game commit
- [ ] Declares `model: sonnet` — it writes player-facing copy
---
## Coverage Notes
- A git repository with no commits yet (the same Phase 1 stop as Case 7) is not
separately tested.
- More than 100 commits with no tag (the skill says so and asks for a start ref
instead of widening the range) is not tested.
- Merge commits vs. squash commits are not explicitly differentiated in
these tests; implementation detail of the git log parsing phase.
- The `/patch-notes` skill should be run after `/changelog` for player-facing
output; that handoff is verified in the patch-notes spec.