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
13 KiB
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:
- Assess severity (S1 Critical / S2 High / S3 or lower, on
/bug-triage's scale) and confirm it withAskUserQuestion; S3 or lower stops withVerdict: **REDIRECTED**. - Hotfix record — asks "May I write this to
production/hotfixes/hotfix-[date]-[short-name].md?" - 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 onmain, or itsrelease/*branch if one was cut to stabilise it — never the head ofmain. - Investigate and propose — root cause and minimal fix, then "May I implement this fix?" before any code changes; implement, run targeted tests.
- Approvals —
lead-programmer,qa-testerandproducerspawned in parallel; all three must return APPROVE, and CONCERNS or REJECT blocks deployment. - QA re-entry gate —
qa-leadpicks 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. - Deploy — an unconditional
AskUserQuestionbefore any merge, tag or deploy (even inautonomousmode); merge tomain, and to the release'srelease/*branch only if one exists; tag the patch release and verify the backport; ask before updating the bug file, then set it toFixed — 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 —/retrospectivehas 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.0onmain, and norelease/*branch exists (the trunk default) - Bug in
src/gameplay/arena.gd(crash on boss arena entry);production/qa/bugs/BUG-0031.mdexists with**Status**: Open - All three sign-offs return APPROVE;
qa-leadpicks a smoke check, which returns PASS
Input: /hotfix BUG-0031
Expected behavior:
- Assesses S1 and confirms via
AskUserQuestion; user picks[A] S1 (Critical) - Asks "May I write this to
production/hotfixes/hotfix-[date]-boss-arena-crash.md?" and writes it - Runs
git rev-parse --is-inside-work-tree, asks "Ready to create hotfix branch 'hotfix/boss-arena-crash' from v1.2.0?", and runsgit checkout -b hotfix/boss-arena-crash v1.2.0only after[A] Yes — create branch - Presents root cause and minimal fix, asks "May I implement this fix?", then implements and runs targeted tests
- Spawns
lead-programmer,qa-testerandproducerin parallel; all APPROVE qa-lead→ smoke check PASS- Asks "Hotfix validated and approved. Merge to
main, tag v1.2.1 and deploy?" (no release branch is named — none exists); user picks[A] - Merges to
main, tagsv1.2.1on the fixed build, and confirms the fix is onmain - Asks "May I update
production/qa/bugs/BUG-0031.md…?" before setting it toFixed — Pending Verification, then prints "Hotfix Deployed: boss-arena-crash" withTag: v1.2.1andNext: /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 ofmain - 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
Agentcalls - 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.mdStatus becomesFixed — Pending Verification
Case 2: Sign-off REJECT — Deployment blocked
Fixture:
- Fix implemented for an S1 bug
qa-testerreturns REJECT: "Player health clamping regression detected";lead-programmerandproducerreturn APPROVE
Input: /hotfix
Expected behavior:
- Phase 5 collects all three responses
- Because one returned REJECT, the skill does not deploy: it surfaces the regression and resolves it first
- The Phase 5b QA gate and the Phase 6 deploy question are not reached while the REJECT stands
- 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
AskUserQuestionis not issued while the REJECT stands - No merge is performed
Case 3: Release Branch — Deploy approval holds even in autonomous mode
Fixture:
project.yamlsetsmodes.automation: autonomous- The live release
v1.3.0has arelease/1.3branch, cut to stabilise it for certification; the hotfix branch was started fromrelease/1.3 - An S2 fix has all three APPROVE sign-offs and a smoke check PASS
Input: /hotfix
Expected behavior:
- Despite
autonomous, Phase 6 asks "Hotfix validated and approved. Merge tomainandrelease/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 - User picks
[B] - The fix is merged to
mainonly; nothing is merged torelease/1.3, tagged or deployed - The summary is titled "Hotfix Merged to main — release held" and has no Tag line
Assertions:
- The deploy question is asked even though
modes.automationisautonomous - The question names
release/1.3, because this release has one - All three options are offered
- With
[B],release/1.3is not merged, no tag is created and nothing is deployed - With
[B],mainreceives 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:
- Phase 1 assesses S4 (Low — cosmetic) and asks the user to confirm severity
- User picks
[C] S3 or lower — redirect to normal bug fix workflow - Skill stops: Verdict REDIRECTED — use the normal bug fix workflow for S3 and below
Assertions:
- Severity is confirmed via
AskUserQuestionwith 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-leadpicks a smoke check;/smoke-checkreturnsNOT ASSESSED — no game tests found
Input: /hotfix
Expected behavior:
produceris spawned as a blocking sign-off, not as a named director gate; no gate IDs appear- The NOT ASSESSED QA result is treated as unmet, not as a pass
- 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
- 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-leadpicks a smoke check /smoke-checkreturns FAIL: "Player health clamping regression detected"- On the revised fix,
lead-programmerreturns CONCERNS ("the clamp now runs on the save path too");qa-testerandproducerreturn APPROVE
Input: /hotfix
Expected behavior:
- 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
- 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
lead-programmer's CONCERNS blocks exactly as a REJECT does: it is shown to the user and resolved before the skill continues- 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) recordsTests: NOT RUN — [reason] - Treats a
/team-qaNOT 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'srelease/*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-leadchoosing 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.