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
264 lines
12 KiB
Markdown
264 lines
12 KiB
Markdown
# Skill Test Spec: /tech-debt
|
||
|
||
## Skill Summary
|
||
|
||
`/tech-debt` tracks technical debt through four subcommands: `scan`, `add`,
|
||
`prioritize` and `report`. With no subcommand it prints usage and stops with
|
||
Verdict FAIL. `scan` searches the code root (resolved per engine: `src/`,
|
||
`Assets/` or `Source/`) for `TODO`, `FIXME`, `HACK` and `@deprecated` markers,
|
||
duplicated blocks, files over 500 lines and functions over 50 lines, sorts the
|
||
findings into six debt categories, states how many files it covered, and asks
|
||
"May I write these findings to `docs/tech-debt-register.md`?" before appending
|
||
(never overwriting) entries — updating a matching `Open` row, and proposing an
|
||
`Open` row whose pattern is gone as `Resolved [date]`. New rows follow the
|
||
skill's Debt Register Format (next `TD-NNN`, ten columns, an `Added` date). A
|
||
scan over zero source files is `NOT ASSESSED — no source files to scan`, an
|
||
unresolved code root is `NOT ASSESSED — code root unresolved`, and both write
|
||
nothing. `add` collects an
|
||
entry through prompts and three `AskUserQuestion` choices, then asks "May I append
|
||
this entry to `docs/tech-debt-register.md`?". `prioritize` scores each register
|
||
item as `impact ÷ effort` from its Impact and Effort columns, re-sorts
|
||
and asks before writing it back. `report` is read-only. No director gates are
|
||
invoked. Verdicts: COMPLETE, BLOCKED (user declined a write), FAIL (missing
|
||
subcommand), NOT ASSESSED.
|
||
|
||
---
|
||
|
||
## 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: COMPLETE, BLOCKED, FAIL, NOT ASSESSED
|
||
- [ ] Contains "May I write" language (writes `docs/tech-debt-register.md`)
|
||
- [ ] Has a next-step handoff (Phase 3: `/sprint-plan`, `/tech-debt report`)
|
||
|
||
---
|
||
|
||
## Director Gate Checks
|
||
|
||
None. Tech debt tracking is an internal codebase analysis skill; no gates are
|
||
invoked.
|
||
|
||
---
|
||
|
||
## Test Cases
|
||
|
||
### Case 1: Happy Path — Scan appends new findings to an existing register
|
||
|
||
**Fixture:**
|
||
- `project.yaml`: `engine.name: godot`; `modes.automation` unset (collaborative)
|
||
- `docs/tech-debt-register.md` is in the skill's Debt Register Format and has 2 `Open` rows:
|
||
- TD-001 — Code Quality, Files `src/core/save_system.gd`: a `# HACK` workaround for a save-path bug. That `HACK` comment is no longer in the file
|
||
- TD-002 — Code Quality, Files `src/gameplay/combat.gd`: the `# TODO` comments in that file
|
||
- `src/gameplay/combat.gd` has 2 `# TODO` comments and 1 `# FIXME` comment
|
||
- `src/ui/hud.gd` is 620 lines long; 12 source files in `src/` in total
|
||
|
||
**Input:** `/tech-debt scan`
|
||
|
||
**Expected behavior:**
|
||
1. Skill resolves the code root to `src/` and scans it for debt indicators
|
||
2. Findings include the 2 TODOs, the FIXME (treated as a bug disguised as debt) and `hud.gd` as a file over 500 lines
|
||
3. Each finding is sorted into one of the six categories (Architecture, Code Quality, Test, Documentation, Dependency, Performance)
|
||
4. The output states the denominator — 12 source files scanned
|
||
5. Matching against the register: the 2 TODOs share TD-002's file and kind, so they update TD-002; TD-001's `HACK` is gone, so TD-001 is proposed as `Resolved [date]`; the FIXME and `hud.gd` become new rows TD-003 and TD-004
|
||
6. Skill presents the findings and the TD-001 resolution, then asks "May I write these findings to `docs/tech-debt-register.md`?" — one approval covers both
|
||
7. On approval, TD-001's Status becomes `Resolved YYYY-MM-DD` and the row stays; TD-002 is updated; TD-003 and TD-004 are appended with all ten columns, Status `Open`, `Added` set to today (`YYYY-MM-DD`) and Priority `—`
|
||
8. Verdict: **COMPLETE** — scan findings written to register
|
||
|
||
**Assertions:**
|
||
- [ ] The scan covers the resolved code root `src/` for TODO, FIXME, HACK, `@deprecated`, files >500 lines and functions >50 lines
|
||
- [ ] Each finding is assigned one of the six debt categories
|
||
- [ ] The number of files scanned is stated with the findings
|
||
- [ ] "May I write" names `docs/tech-debt-register.md` and comes after the findings are shown
|
||
- [ ] The two TODO findings update TD-002 instead of adding a duplicate row
|
||
- [ ] TD-001 is proposed as `Resolved [date]` inside the same approval, and is kept in the register rather than deleted
|
||
- [ ] New rows take the next IDs (TD-003, TD-004) and carry an `Added` date; the register is updated in place, never replaced
|
||
- [ ] Verdict is COMPLETE
|
||
|
||
---
|
||
|
||
### Case 2: No Subcommand — Usage and FAIL
|
||
|
||
**Fixture:**
|
||
- `docs/tech-debt-register.md` exists
|
||
- `src/` contains source files with TODO comments
|
||
|
||
**Input:** `/tech-debt`
|
||
|
||
**Expected behavior:**
|
||
1. Phase 1 finds no subcommand
|
||
2. Skill outputs usage listing `scan`, `add`, `prioritize` and `report`
|
||
3. Skill stops — no scan runs and the register is not read or written
|
||
4. Verdict: **FAIL** — missing required subcommand
|
||
|
||
**Assertions:**
|
||
- [ ] Usage lists the four subcommands
|
||
- [ ] No scan is performed and no file is written
|
||
- [ ] Verdict is FAIL, stating the subcommand is missing
|
||
|
||
---
|
||
|
||
### Case 3: Empty Code Root — NOT ASSESSED, not a clean scan
|
||
|
||
**Fixture:**
|
||
- `project.yaml`: `engine.name: godot`
|
||
- `src/` exists but contains no source files
|
||
- `docs/tech-debt-register.md` exists with 3 entries
|
||
|
||
**Input:** `/tech-debt scan`
|
||
|
||
**Expected behavior:**
|
||
1. Skill resolves the code root to `src/` and counts the files the scan covered: zero
|
||
2. Skill reports **NOT ASSESSED — no source files to scan**, explaining that "no debt indicators found" would describe an empty search, not the codebase
|
||
3. Skill stops: no "May I write" prompt, no register write, no COMPLETE verdict
|
||
|
||
**Assertions:**
|
||
- [ ] A zero-file scan is reported as NOT ASSESSED — no source files to scan
|
||
- [ ] Output does not claim "no debt found" or a clean codebase
|
||
- [ ] The register is not written and no write is offered
|
||
- [ ] No COMPLETE verdict is emitted
|
||
|
||
---
|
||
|
||
### Case 3b: Code Root Unresolved — NOT ASSESSED, nothing scanned on a guess
|
||
|
||
**Fixture:**
|
||
- `project.yaml` has no `engine.name`; `.claude/docs/technical-preferences.md` reads `[TO BE CONFIGURED]`
|
||
- Both `src/` and `Source/` exist and hold source files, so the tree does not decide the root
|
||
- `docs/tech-debt-register.md` exists with 3 entries
|
||
|
||
**Input:** `/tech-debt scan`
|
||
|
||
**Expected behavior:**
|
||
1. The code root cannot be resolved per `.claude/docs/code-root-resolution.md`
|
||
2. Skill reports `NOT ASSESSED — code root unresolved` and stops
|
||
3. Neither directory is scanned on a guess; no "May I write" prompt, no register write, no COMPLETE verdict
|
||
|
||
**Assertions:**
|
||
- [ ] Verdict is `NOT ASSESSED — code root unresolved`
|
||
- [ ] No debt findings are reported from a guessed root
|
||
- [ ] The register is not written and no write is offered
|
||
|
||
---
|
||
|
||
### Case 4: Add Mode — User declines the write
|
||
|
||
**Fixture:**
|
||
- `docs/tech-debt-register.md` exists with 4 entries
|
||
- `modes.automation` unset (collaborative)
|
||
|
||
**Input:** `/tech-debt add`
|
||
|
||
**Expected behavior:**
|
||
1. Skill asks in plain text for the description and affected files
|
||
2. Skill uses `AskUserQuestion` for the category — six options, Architecture through Performance
|
||
3. Skill uses `AskUserQuestion` for the fix effort — S, M, L, XL
|
||
4. Skill uses `AskUserQuestion` for the impact if left unfixed — Low, Med, High, Critical
|
||
5. Skill presents the complete new entry
|
||
6. Skill asks "May I append this entry to `docs/tech-debt-register.md`?"
|
||
7. User declines — nothing is written
|
||
8. Verdict: **BLOCKED** — user declined write
|
||
|
||
**Assertions:**
|
||
- [ ] Category is collected with `AskUserQuestion` offering the six debt categories
|
||
- [ ] Effort is collected with `AskUserQuestion` offering S / M / L / XL
|
||
- [ ] Impact is collected with `AskUserQuestion` offering Low / Med / High / Critical, so `prioritize` can score the row
|
||
- [ ] The full entry is shown before the append prompt
|
||
- [ ] On decline the register is unchanged and the verdict is BLOCKED
|
||
|
||
---
|
||
|
||
### Case 4a: Add Mode — Matches an Existing Open Entry
|
||
|
||
**Fixture:**
|
||
- `docs/tech-debt-register.md` exists with an `Open` entry for the same file
|
||
and the same category as the one the user is about to add
|
||
|
||
**Input:** `/tech-debt add`
|
||
|
||
**Expected behavior:**
|
||
1. Steps 1–5 of Case 4 run as usual
|
||
2. **Match before appending:** before the append ask, the skill shows the
|
||
existing `Open` entry (same file and category) and asks whether to update
|
||
it instead of adding a duplicate
|
||
3. On "update", the matched entry is updated in place — no duplicate row is added
|
||
4. On "add anyway", a new entry is appended alongside the match
|
||
|
||
**Assertions:**
|
||
- [ ] A new entry with the same file and category as an existing `Open` entry is never appended without first showing the match and asking
|
||
- [ ] "Update" edits the matched row rather than adding a new one
|
||
|
||
---
|
||
|
||
### Case 4b: Report Mode Without a Register — NOT ASSESSED
|
||
|
||
**Fixture:**
|
||
- `docs/tech-debt-register.md` does not exist
|
||
|
||
**Input:** `/tech-debt report`
|
||
|
||
**Expected behavior:**
|
||
1. Skill looks for the register and does not find it
|
||
2. Verdict: **NOT ASSESSED** — no register to report on; run `/tech-debt scan` first
|
||
3. No trend or totals are printed and nothing is written
|
||
|
||
**Assertions:**
|
||
- [ ] Verdict is NOT ASSESSED, not a report of zero items or a "stable" trend
|
||
- [ ] The output names `/tech-debt scan` as the way to create the register
|
||
- [ ] No file is written
|
||
|
||
---
|
||
|
||
### Case 5: Prioritize in Full Review Mode — Scored, re-sorted, approved
|
||
|
||
**Fixture:**
|
||
- `project.yaml`: `modes.review_mode: full`
|
||
- `docs/tech-debt-register.md` has 4 entries: TD-001 High/S, TD-002 Low/L, TD-003
|
||
Critical/M, TD-004 Med/— (Effort not yet estimated)
|
||
|
||
**Input:** `/tech-debt prioritize`
|
||
|
||
**Expected behavior:**
|
||
1. Skill reads `docs/tech-debt-register.md`
|
||
2. Each item is scored `impact ÷ effort` (Impact Low 1 … Critical 4; Effort S 1 … XL 4): TD-001 3.0, TD-003 2.0, TD-002 0.3; TD-004 is listed after them as "not scored — Effort not judged"
|
||
3. The register is re-sorted by score and the skill recommends which items belong in the next sprint
|
||
4. No director gate is invoked regardless of review mode
|
||
5. Skill presents the re-prioritized register, then asks "May I write the re-prioritized register back to `docs/tech-debt-register.md`?"
|
||
6. On approval the file is written
|
||
7. Verdict: **COMPLETE** — register re-prioritized and saved
|
||
|
||
**Assertions:**
|
||
- [ ] Items are scored `impact ÷ effort` from their own columns and re-sorted: TD-001, TD-003, TD-002
|
||
- [ ] TD-004 gets no invented score; it is listed as not scored, naming the missing Effort
|
||
- [ ] A next-sprint recommendation is given
|
||
- [ ] No director gate is invoked in any review mode
|
||
- [ ] The write happens only after the "May I write" prompt is approved
|
||
- [ ] Verdict is COMPLETE
|
||
|
||
---
|
||
|
||
## Protocol Compliance
|
||
|
||
- [ ] Requires a subcommand; without one prints usage and stops with FAIL
|
||
- [ ] `scan` resolves the code root per engine (`src/`, `Assets/`, `Source/`) and states the number of files covered
|
||
- [ ] A zero-file or unresolved-root scan is NOT ASSESSED and writes nothing
|
||
- [ ] Every register write is preceded by a "May I write" / "May I append" prompt naming `docs/tech-debt-register.md`, after the content is shown
|
||
- [ ] `scan` appends and never overwrites existing entries; a finding matching an `Open` row updates it, and an `Open` row whose pattern is gone is proposed `Resolved [date]`, never deleted
|
||
- [ ] New rows follow the Debt Register Format: the next `TD-NNN` ID, all ten columns, an `Added` date in `YYYY-MM-DD`
|
||
- [ ] A declined write ends with BLOCKED
|
||
- [ ] No director gates are invoked
|
||
- [ ] Ends with the Phase 3 next steps (`/sprint-plan`, `/tech-debt report`)
|
||
|
||
---
|
||
|
||
## Coverage Notes
|
||
|
||
- `report` mode with a register (read-only summary by category and effort,
|
||
added and resolved counts from each row's `Added` and `Resolved` dates,
|
||
flagging items older than 3 sprints, Verdict COMPLETE — debt report generated)
|
||
is not tested here.
|
||
- Unity and Unreal scans differ only in the resolved root (`Assets/`,
|
||
`Source/`) and are not tested separately.
|