Release 1.1.0 — one config file, and a process weight you choose

`project.yaml` at the repo root is now the single source of truth for a
project's configuration, replacing `production/stage.txt`,
`production/review-mode.txt` and `.claude/docs/technical-preferences.md` (all
three still read as a fallback; nothing is force-deleted).

**`modes.rigor` — one question instead of six.** `minimal`, `standard` or
`full` fronts six knobs: `modes.workflow`, `docs.density`, `qa.level`,
`modes.story_granularity`, `modes.review_mode` and `team.size`. It defaults to
`minimal`, which is a change from 1.0's behaviour: the heavier tier was
measured costing several times more to reach working code without producing a
better result, and returning nothing when a fresh developer inherited the
project. Pin `modes.rigor: standard` to keep 1.0's process level.

Also in this release:

- `/settings` to view or change any setting, and `project.local.yaml` for
  per-developer preferences that should not be committed.
- `system_overrides` to hold one system to a higher standard than the rest of
  the project, and `testing.strict` to set per test type whether missing
  evidence blocks a story or warns.
- A story that changes anything the player sees is not closed until the game
  has been launched, observed, and a screenshot retained in
  `production/qa/evidence/`. A parse check is not a run. This holds at every
  rigor level, including `minimal`, where automated tests are waived but the
  look is not.
- The code root is engine-specific and enforced as such: Godot `src/`, Unity
  `Assets/`, Unreal `Source/<Module>/`. Two of the three will not build a
  project laid out any other way.
- Migration tooling for existing projects: `.claude/scripts/migrate-v1-config.sh`
  converts a 1.0 layout, non-destructively by default, with a report to review
  before `--finalize` deletes anything.
- Ask-before-write holds regardless of personal automation settings.

Upgrading from 1.0 or earlier: see UPGRADING.md. Full list of changes:
CHANGELOG.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xvzG3i7pWQg4LjyDwWMXd
This commit is contained in:
Donchitos
2026-09-23 12:25:11 +10:00
co-authored by Claude Opus 5
parent 984023ddac
commit d05699707f
291 changed files with 24374 additions and 7740 deletions
+94 -24
View File
@@ -1,13 +1,18 @@
---
name: qa-plan
description: "Generate a QA test plan for a sprint or feature. Reads GDDs and story files, classifies stories by test type (Logic/Integration/Visual/UI), and produces a structured test plan covering automated tests required, manual test cases, smoke test scope, and playtest sign-off requirements. Run before sprint begins or when starting a major feature."
description: "QA test plan for a sprint — classifies stories by Logic/Integration/Visual/UI, covers automated tests, manual cases, smoke scope."
argument-hint: "[sprint | feature: system-name | story: path]"
user-invocable: true
allowed-tools: Read, Glob, Grep, Write, AskUserQuestion
allowed-tools: Read, Glob, Grep, Write, Edit, AskUserQuestion
model: sonnet
agent: qa-lead
---
!`source "${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/yaml-helper.sh" 2>/dev/null && resolve_config --keys automation,workflow,qa.level,system_overrides`
Resolved above — use as-is. No block → defaults in
`.claude/docs/config-resolution.md`.
# QA Plan
This skill generates a structured QA plan for a sprint, feature, or individual
@@ -24,6 +29,20 @@ plan.
---
Every `AskUserQuestion` call follows `.claude/docs/automation-modes.md`
(collaborative asks always · guided major-only · autonomous logs and proceeds;
`automation_always_ask` categories always prompt).
**Workflow tier**: resolve per the GDD's system as each is read (per
`.claude/docs/workflow-modes.md`): `workflow_overrides.system_overrides.<system>`
if the block lists one, else the project value. It sets how many GDD sections
the test plan is mined from — see Phase 2.
**`qa.level`**: at `minimal`, produce only a minimal smoke
plan — drop the automated-test-required rows and the test-file DoD; at `standard`,
a full plan per story type; at `full`, also add per-system coverage targets.
Distinct axis from `workflow` (which sets how many GDD sections are mined).
## Phase 1: Parse Scope
**Argument:** `$ARGUMENTS` (blank = ask user via AskUserQuestion)
@@ -49,32 +68,73 @@ If a story file path is referenced but the file does not exist, note it as
MISSING and continue with the remaining stories. Do not fail the entire plan
for one missing file.
> **If the resolved scope contains ZERO stories, stop — do not build a plan.**
> Report `NOT ASSESSED — no stories in scope`, naming which scope was searched
> and which path was empty, and route:
> - no file in `production/sprints/` → "No sprint plan found. Run `/sprint-plan new`."
> - a sprint plan exists but references no stories → "Sprint plan `[path]` lists no
> stories. Run `/create-stories [epic-slug]`."
> - `feature:`/`story:` scope matched nothing → name the glob that came back empty.
>
> **The N=0 guard is mandatory.** Without it an empty scope reports "Building QA
> plan for 0 stories" and continues into Phase 4, producing a plan document with
> empty tables — and **a QA plan for zero stories looks exactly like a completed
> QA plan.** This skill gates the hand-off to manual QA, so a false-clean here
> sends a build to QA on the strength of a plan that tested nothing.
>
> Note the shape, because this skill already had the harder half of the rule.
> Phase 2 states **"Never treat an absent section as an absent story"** — the
> sophisticated inner case, correctly handled. The outer boundary, no stories at
> all, had nothing. The same shape appears in `/story-readiness`, where `NOT ASSESSED`
> existed for per-story failures and the empty scope could not reach it.
>
> The rule at the top of this block still stands: one missing file among several
> is MISSING-and-continue. This is the different case where there is no *several*.
---
## Phase 2: Load Inputs
For each in-scope story file, read the full file and extract:
Establish the denominator first — glob the in-scope story files and count **N** —
then collect the fields below with **targeted section greps, not a full read of
each story**. A QA plan needs each story's type and acceptance criteria; it does
not need its implementation notes, out-of-scope boundaries or ADR rationale, and
reading N stories whole to reach two sections is where this phase's cost lives:
- **Story title** and story ID (from filename or header)
- **Story Type** field (if present in the file header — e.g., `Type: Logic`)
- **Acceptance criteria** — the complete numbered/bulleted list
- **Implementation files** — listed under "Files to Create / Modify" or similar
- **Engine notes** — any engine API warnings or version-specific notes
- **GDD reference** — the GDD path(s) cited
- **ADR reference** — the ADR(s) cited
- **Estimate** — hours or story points if present
- **Dependencies** — other stories this one depends on
```
Grep pattern="^## Acceptance Criteria" glob="production/epics/**/story-*.md" output_mode="content" -A 15
Grep pattern="^> \*\*(Type|Status|Estimate)\*\*" glob="production/epics/**/story-*.md" output_mode="content"
Grep pattern="^## (Context|Dependencies)" glob="production/epics/**/story-*.md" output_mode="content" -A 8
```
(Scope the globs to the sprint plan's story paths in `sprint` mode.) From those:
- **Story title** and story ID — from the file name and path; no read at all
- **Story Type** field — from the header grep (e.g., `Type: Logic`)
- **Acceptance criteria** — the complete numbered/bulleted list, from the first grep
- **GDD / ADR reference** and **Dependencies** — from the `## Context` grep
- **Estimate** — from the header grep if present
- **Implementation files** and **Engine notes** — only needed for stories whose
test plan actually turns on them; full-read those individual stories
**Never treat an absent section as an absent story.** If a story matched no
`## Acceptance Criteria`, full-read that one and say so — a story with no
testable criteria is a QA finding in its own right, not a story to skip.
After reading stories, load supporting context once (not per story):
- `design/gdd/systems-index.md` — to understand system priorities and which
GDDs are approved
- For each unique GDD referenced across all stories: read the
**Acceptance Criteria**, **Formulas**, and **Edge Cases** sections. Do not load
the full GDD text. These three sections contain the testable requirements, the math
to verify, and the boundary conditions that tests must cover. If an Edge Cases
section is absent from the GDD, note it per GDD: "No Edge Cases section found — edge
case coverage will be inferred from acceptance criteria only."
- For each unique GDD referenced across all stories: mine test material per that
system's workflow tier (resolved above) — at `full`, mine all 8 sections; at
`standard`, mine the test-relevant subset of the required sections
(**Acceptance Criteria** and **Edge Cases** always, plus **Formulas** for any
system that defines numeric rules); at `minimal`, **Acceptance
Criteria only**. Do not load the full GDD
text. These sections contain the testable requirements, the math to verify, and
the boundary conditions tests must cover. If an Edge Cases section is absent (or
not expected at minimal), note per GDD: "No Edge Cases section found — edge case
coverage will be inferred from acceptance criteria only."
- `docs/architecture/control-manifest.md` — scan for forbidden patterns that
automated tests should guard against (if the file exists)
@@ -118,7 +178,7 @@ Assemble the full QA plan document. Use this structure:
**Date**: [date]
**Generated by**: /qa-plan
**Scope**: [N stories across [N systems]]
**Engine**: [engine name from .claude/docs/technical-preferences.md, or "Not configured"]
**Engine**: [engine name — `engine.name` from project.yaml if present and non-empty, else the Engine field from .claude/docs/technical-preferences.md, else "Not configured"]
**Sprint File**: [path to sprint plan if applicable]
---
@@ -137,6 +197,10 @@ Assemble the full QA plan document. Use this structure:
## Automated Tests Required
*(At `qa.level: minimal`, omit this entire section and blank the Test Summary's
"Automated Test Required" column — automated tests are not required there; list
manual/smoke verification only.)*
### [Story Title] — [Type]
**Test file path**: `tests/[unit|integration]/[system]/[story-slug]_test.[ext]`
**What to test**:
@@ -210,13 +274,15 @@ this sprint.*
## Definition of Done — This Sprint
A story is DONE when ALL of the following are true:
A story is DONE when ALL of the following are true (at `qa.level: minimal`, drop
the test-file / evidence-document / smoke rows below — only acceptance-criteria
verification is required):
- [ ] All acceptance criteria verified — via automated test result OR documented
manual evidence (screenshot, video, or playtest notes with sign-off)
- [ ] Test file exists at the specified path for all Logic and Integration stories
- [ ] Manual evidence document exists for all Visual/Feel and UI stories
- [ ] Smoke check passes (run `/smoke-check sprint` before QA hand-off)
- [ ] Test file exists at the specified path for all Logic and Integration stories *(qa.level standard/full)*
- [ ] Manual evidence document exists for all Visual/Feel and UI stories *(qa.level standard/full)*
- [ ] Smoke check passes (run `/smoke-check sprint` before QA hand-off) *(qa.level standard/full)*
- [ ] No regressions introduced
- [ ] Code reviewed (via `/code-review` or documented peer review)
- [ ] Story file updated to `Status: Complete` (via `/story-done`)
@@ -265,6 +331,10 @@ Silently append to `production/session-state/active.md` (create the file if it d
## Collaborative Protocol
**Applies in `collaborative` mode (the default).** For `guided` and
`autonomous` modes, see `.claude/docs/automation-modes.md` — the rules below
describe what collaborative mode requires, not universal behavior.
- **Never write the plan without asking** — Phase 5 requires explicit approval.
- **Classify conservatively**: when a story is ambiguous between Logic and
Integration, classify it as Integration — it requires both unit and