mirror of
https://github.com/Donchitos/Claude-Code-Game-Studios.git
synced 2026-10-16 10:17:06 +00:00
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
268 lines
13 KiB
Markdown
268 lines
13 KiB
Markdown
# Skill Test Spec: /hotfix
|
|
|
|
## Skill Summary
|
|
|
|
`/hotfix` runs an emergency fix outside the sprint process, with an audit trail.
|
|
It runs only when the user types it (`disable-model-invocation: true`). The flow:
|
|
|
|
1. **Assess severity** (S1 Critical / S2 High / S3 or lower, on `/bug-triage`'s scale) and confirm it with
|
|
`AskUserQuestion`; S3 or lower stops with `Verdict: **REDIRECTED**`.
|
|
2. **Hotfix record** — asks "May I write this to
|
|
`production/hotfixes/hotfix-[date]-[short-name].md`?"
|
|
3. **Branch** — checks for a git repo, then asks before running
|
|
`git checkout -b hotfix/[short-name] [base-ref]`. `[base-ref]` is the
|
|
release the bug is in: its tag on `main`, or its `release/*` branch if one
|
|
was cut to stabilise it — never the head of `main`.
|
|
4. **Investigate and propose** — root cause and minimal fix, then
|
|
"May I implement this fix?" before any code changes; implement, run targeted tests.
|
|
5. **Approvals** — `lead-programmer`, `qa-tester` and `producer` spawned in
|
|
parallel; all three must return APPROVE, and CONCERNS or REJECT blocks deployment.
|
|
6. **QA re-entry gate** — `qa-lead` picks smoke check, targeted
|
|
`/team-qa feature: [system]`, or full QA; a smoke-check FAIL sends the fix
|
|
back to Phase 4. A NOT ASSESSED result is not a pass: deploying anyway takes
|
|
an explicit producer decision, logged in the hotfix record.
|
|
7. **Deploy** — an unconditional `AskUserQuestion` before any merge, tag or deploy
|
|
(even in `autonomous` mode); merge to `main`, and to the release's
|
|
`release/*` branch only if one exists; tag the patch release and verify the
|
|
backport; ask before updating the bug file, then set it to
|
|
`Fixed — Pending Verification`; print "Hotfix Deployed" (on `[B]`,
|
|
"Hotfix Merged to main — release held", with no Tag); `[C]` stops with no
|
|
merge, tag or bug-file update; then `/bug-report verify` (a CANNOT VERIFY is
|
|
settled by playing the reproduction steps and answering its manual-play
|
|
question) and a post-incident review (recorded with the incident-response
|
|
template — `/retrospective` has no incident mode).
|
|
|
|
Targeted tests run with `commands.test` from `project.yaml`; when it is unset or
|
|
no test covers the system, the hotfix record says `Tests: NOT RUN — [reason]`.
|
|
A `/team-qa` pass that returns NOT APPROVED or BLOCKED is handled like a
|
|
smoke-check FAIL. S1 is `/bug-triage`'s definition: crash, data loss, or
|
|
complete feature failure.
|
|
|
|
---
|
|
|
|
## 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`
|
|
- [ ] Frontmatter sets `disable-model-invocation: true`
|
|
- [ ] Has ≥2 phase headings
|
|
- [ ] Contains verdict keywords: REDIRECTED, APPROVE / CONCERNS / REJECT (sign-offs), NOT ASSESSED (QA gate)
|
|
- [ ] Contains "May I write" (hotfix record), "May I implement this fix?" (code) and "May I update" (bug file) language
|
|
- [ ] Has a next-step handoff (`/bug-report verify [BUG-ID]`, a post-incident review)
|
|
|
|
---
|
|
|
|
## Director Gate Checks
|
|
|
|
No named director-gate ID (CD-*, TD-*, AD-*, PR-*) is used and the review mode
|
|
does not apply. Phase 5 spawns three **blocking sign-offs** in parallel —
|
|
`lead-programmer`, `qa-tester` and `producer` (the only director-tier agent) —
|
|
and all three must return APPROVE before deployment. Phase 5b spawns `qa-lead` to
|
|
choose the QA scope.
|
|
|
|
---
|
|
|
|
## Test Cases
|
|
|
|
### Case 1: Happy Path — S1 crash fixed with record, branch, approvals and backport
|
|
|
|
**Fixture:**
|
|
- Git repository; the live build is the release tag `v1.2.0` on `main`, and no
|
|
`release/*` branch exists (the trunk default)
|
|
- Bug in `src/gameplay/arena.gd` (crash on boss arena entry);
|
|
`production/qa/bugs/BUG-0031.md` exists with `**Status**: Open`
|
|
- All three sign-offs return APPROVE; `qa-lead` picks a smoke check, which returns PASS
|
|
|
|
**Input:** `/hotfix BUG-0031`
|
|
|
|
**Expected behavior:**
|
|
1. Assesses S1 and confirms via `AskUserQuestion`; user picks `[A] S1 (Critical)`
|
|
2. Asks "May I write this to `production/hotfixes/hotfix-[date]-boss-arena-crash.md`?" and writes it
|
|
3. Runs `git rev-parse --is-inside-work-tree`, asks "Ready to create hotfix branch
|
|
'hotfix/boss-arena-crash' from v1.2.0?", and runs
|
|
`git checkout -b hotfix/boss-arena-crash v1.2.0` only after `[A] Yes — create branch`
|
|
4. Presents root cause and minimal fix, asks "May I implement this fix?", then implements and runs targeted tests
|
|
5. Spawns `lead-programmer`, `qa-tester` and `producer` in parallel; all APPROVE
|
|
6. `qa-lead` → smoke check PASS
|
|
7. Asks "Hotfix validated and approved. Merge to `main`, tag v1.2.1 and deploy?"
|
|
(no release branch is named — none exists); user picks `[A]`
|
|
8. Merges to `main`, tags `v1.2.1` on the fixed build, and confirms the fix is on `main`
|
|
9. Asks "May I update `production/qa/bugs/BUG-0031.md` …?" before setting it to
|
|
`Fixed — Pending Verification`, then prints "Hotfix Deployed: boss-arena-crash"
|
|
with `Tag: v1.2.1` and `Next: /bug-report verify`
|
|
|
|
**Assertions:**
|
|
- [ ] The hotfix record is written before the branch is created
|
|
- [ ] The branch starts from the release tag `v1.2.0`, not from the head of `main`
|
|
- [ ] The branch is created only after the user picks `[A]`
|
|
- [ ] No code is modified before "May I implement this fix?" is approved
|
|
- [ ] The three sign-off agents are spawned as simultaneous `Agent` calls
|
|
- [ ] No merge happens before the Phase 6 deploy question is answered
|
|
- [ ] No `release/*` branch is created or merged; the patch release is tagged
|
|
- [ ] The summary's Backport line states presence on `main`
|
|
- [ ] The bug file is not edited before the user approves the "May I update" question
|
|
- [ ] `BUG-0031.md` Status becomes `Fixed — Pending Verification`
|
|
|
|
---
|
|
|
|
### Case 2: Sign-off REJECT — Deployment blocked
|
|
|
|
**Fixture:**
|
|
- Fix implemented for an S1 bug
|
|
- `qa-tester` returns REJECT: "Player health clamping regression detected";
|
|
`lead-programmer` and `producer` return APPROVE
|
|
|
|
**Input:** `/hotfix`
|
|
|
|
**Expected behavior:**
|
|
1. Phase 5 collects all three responses
|
|
2. Because one returned REJECT, the skill does not deploy: it surfaces the regression and resolves it first
|
|
3. The Phase 5b QA gate and the Phase 6 deploy question are not reached while the REJECT stands
|
|
4. No merge, tag or deploy occurs
|
|
|
|
**Assertions:**
|
|
- [ ] The qa-tester's REJECT and its regression are shown to the user
|
|
- [ ] Skill does not proceed to deployment with a REJECT outstanding
|
|
- [ ] The deploy `AskUserQuestion` is not issued while the REJECT stands
|
|
- [ ] No merge is performed
|
|
|
|
---
|
|
|
|
### Case 3: Release Branch — Deploy approval holds even in autonomous mode
|
|
|
|
**Fixture:**
|
|
- `project.yaml` sets `modes.automation: autonomous`
|
|
- The live release `v1.3.0` has a `release/1.3` branch, cut to stabilise it for
|
|
certification; the hotfix branch was started from `release/1.3`
|
|
- An S2 fix has all three APPROVE sign-offs and a smoke check PASS
|
|
|
|
**Input:** `/hotfix`
|
|
|
|
**Expected behavior:**
|
|
1. Despite `autonomous`, Phase 6 asks "Hotfix validated and approved. Merge to `main`
|
|
and `release/1.3`, tag v1.3.1 and deploy?" with `[A] Yes — merge and deploy` /
|
|
`[B] Merge to main only — hold the release` / `[C] Stop here`
|
|
2. User picks `[B]`
|
|
3. The fix is merged to `main` only; nothing is merged to `release/1.3`, tagged or deployed
|
|
4. The summary is titled "Hotfix Merged to main — release held" and has no Tag line
|
|
|
|
**Assertions:**
|
|
- [ ] The deploy question is asked even though `modes.automation` is `autonomous`
|
|
- [ ] The question names `release/1.3`, because this release has one
|
|
- [ ] All three options are offered
|
|
- [ ] With `[B]`, `release/1.3` is not merged, no tag is created and nothing is deployed
|
|
- [ ] With `[B]`, `main` receives the fix
|
|
- [ ] With `[B]`, the summary does not say "Deployed" and names no tag
|
|
|
|
---
|
|
|
|
### Case 4: Not an Emergency — a cosmetic S4 redirected before any work
|
|
|
|
**Fixture:**
|
|
- User reports a typo on the credits screen
|
|
|
|
**Input:** `/hotfix typo in the credits screen`
|
|
|
|
**Expected behavior:**
|
|
1. Phase 1 assesses S4 (Low — cosmetic) and asks the user to confirm severity
|
|
2. User picks `[C] S3 or lower — redirect to normal bug fix workflow`
|
|
3. Skill stops: Verdict REDIRECTED — use the normal bug fix workflow for S3 and below
|
|
|
|
**Assertions:**
|
|
- [ ] Severity is confirmed via `AskUserQuestion` with S1 / S2 / S3-or-lower options
|
|
- [ ] Verdict is REDIRECTED
|
|
- [ ] No hotfix record is written and no branch is created
|
|
- [ ] No code is modified and no agents are spawned
|
|
|
|
---
|
|
|
|
### Case 5: Director Gate Check — Producer sign-off, and NOT ASSESSED QA is not a pass
|
|
|
|
**Fixture:**
|
|
- `project.yaml`: `modes.rigor: standard` (so a project with no game tests gets NOT ASSESSED, not WAIVED)
|
|
- S1 fix implemented; all three sign-offs APPROVE
|
|
- `qa-lead` picks a smoke check; `/smoke-check` returns `NOT ASSESSED — no game tests found`
|
|
|
|
**Input:** `/hotfix`
|
|
|
|
**Expected behavior:**
|
|
1. `producer` is spawned as a blocking sign-off, not as a named director gate; no gate IDs appear
|
|
2. The NOT ASSESSED QA result is treated as unmet, not as a pass
|
|
3. The skill either obtains the missing result or takes the decision to the producer
|
|
explicitly as a decision to deploy an unverified hotfix. This escape hatch is
|
|
deliberate: an emergency fix may have to ship before a suite exists, but only
|
|
as a named decision, never as a gate that quietly cleared
|
|
4. If the producer decides to deploy unverified, that decision — who made it and
|
|
why — is logged in the hotfix record, and the summary's QA gate line reads
|
|
NOT ASSESSED with why and whose explicit decision it was
|
|
|
|
**Assertions:**
|
|
- [ ] No gate IDs (CD-*, TD-*, AD-*, PR-*) appear in output
|
|
- [ ] NOT ASSESSED does not advance to Phase 6 as if the QA gate passed
|
|
- [ ] Deployment goes ahead only with the three APPROVE sign-offs plus an explicit producer decision to deploy unverified
|
|
- [ ] That decision is logged in the hotfix record
|
|
- [ ] The summary records the QA gate as NOT ASSESSED with the reason and whose decision it was
|
|
|
|
---
|
|
|
|
### Case 6: Smoke Check FAIL — back to Phase 4, and a CONCERNS sign-off still blocks
|
|
|
|
**Fixture:**
|
|
- S1 fix implemented; all three sign-offs APPROVE; `qa-lead` picks a smoke check
|
|
- `/smoke-check` returns FAIL: "Player health clamping regression detected"
|
|
- On the revised fix, `lead-programmer` returns CONCERNS ("the clamp now runs on
|
|
the save path too"); `qa-tester` and `producer` return APPROVE
|
|
|
|
**Input:** `/hotfix`
|
|
|
|
**Expected behavior:**
|
|
1. The FAIL stops deployment: the skill returns to Phase 4 with the failing check,
|
|
presents a revised fix and asks "May I implement this fix?" again before
|
|
changing code
|
|
2. After implementing it (Phase 4b), it re-runs all three Phase 5 sign-offs —
|
|
qa-tester's regression run among them — and then the QA step
|
|
3. `lead-programmer`'s CONCERNS blocks exactly as a REJECT does: it is shown to the
|
|
user and resolved before the skill continues
|
|
4. The Phase 6 deploy question is asked only once all three return APPROVE and a
|
|
re-run smoke check passes
|
|
|
|
**Assertions:**
|
|
- [ ] A smoke-check FAIL never reaches the deploy question
|
|
- [ ] The revised fix gets its own "May I implement this fix?" approval
|
|
- [ ] All three sign-offs and the QA step are re-run for the revised fix
|
|
- [ ] CONCERNS from a sign-off blocks deployment until resolved; it is not treated as an approval
|
|
- [ ] No merge, tag or deploy occurs while the FAIL or the CONCERNS stands
|
|
|
|
---
|
|
|
|
## Protocol Compliance
|
|
|
|
- [ ] Confirms severity before any work; S3 or lower is REDIRECTED
|
|
- [ ] Asks "May I write" before the hotfix record
|
|
- [ ] Asks before creating the branch
|
|
- [ ] Asks "May I implement this fix?" before modifying code
|
|
- [ ] Runs targeted tests with `commands.test`, never a runner line from memory; with the key unset (or no covering test) records `Tests: NOT RUN — [reason]`
|
|
- [ ] Treats a `/team-qa` NOT APPROVED or BLOCKED like a smoke-check FAIL
|
|
- [ ] On the deploy question's `[C] Stop here`, merges, tags and updates nothing, and the record stays IN PROGRESS
|
|
- [ ] Deploys only with all three APPROVE sign-offs and a QA gate that ran — or,
|
|
when the QA gate was NOT ASSESSED, an explicit producer decision to deploy
|
|
unverified, logged in the hotfix record
|
|
- [ ] Asks before any merge, tag or deploy regardless of `modes.automation`
|
|
- [ ] Starts the hotfix branch from the release it fixes (its tag, or its `release/*` branch if one exists)
|
|
- [ ] Verifies the backport on `main`, and on the release's `release/*` branch only when one exists
|
|
- [ ] Asks "May I update" before editing the bug file
|
|
|
|
---
|
|
|
|
## Coverage Notes
|
|
|
|
- A non-git working directory ("Not a git repository — create the branch manually.")
|
|
is not separately tested.
|
|
- `qa-lead` choosing a targeted `/team-qa feature: [system]` pass (APPROVED /
|
|
APPROVED WITH CONDITIONS) or full QA is not separately tested.
|
|
- Phase 7 post-deploy verification (VERIFIED FIXED → `/bug-report close`; STILL
|
|
PRESENT → re-open and assess rollback; CANNOT VERIFY → the bug stays open until
|
|
its reproduction steps are played in the deployed build and reported through
|
|
`/bug-report verify`'s manual-play question) is not separately tested.
|