mirror of
https://github.com/Donchitos/Claude-Code-Game-Studios.git
synced 2026-10-16 10:17:06 +00:00
`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
2422 lines
126 KiB
Markdown
2422 lines
126 KiB
Markdown
# project.yaml — Effects Map
|
||
|
||
> ## READ ONE SECTION, NEVER THIS WHOLE FILE
|
||
>
|
||
> This document is **~31,000 tokens** — roughly **four times an entire turn's
|
||
> context budget**, which sits near 8,300. It is organised as **36 sections of
|
||
> ~900 tokens each**, one per setting, headed `## <key>`.
|
||
>
|
||
> **So opening it costs 36× what you need.** To look up a setting:
|
||
>
|
||
> ```
|
||
> Grep pattern="^## modes.review_mode" path=".claude/docs/effects-map.md" -A 40
|
||
> ```
|
||
>
|
||
> Read the section for your key and stop. The same rule the skills already apply
|
||
> to their own reference files — `/gate-check` loads only the row for the target
|
||
> phase and says "never load the others" — applies here, and this is the largest
|
||
> file in the framework by a factor of seven.
|
||
>
|
||
> This banner exists because six skills cite this document and **none of them
|
||
> scoped the citation**. None instructed a full read either, so
|
||
> nothing was actually loading 31k — but "see effects-map.md for full schema" in
|
||
> front of a file this size is an invitation, and the cost of accepting it is
|
||
> silent.
|
||
|
||
This document defines what each `project.yaml` setting actually does across
|
||
every skill that reads it. It is the tracked, authoritative reference.
|
||
|
||
**Purpose:** When a skill reads a setting, this document is the authoritative
|
||
source for what each value means for that skill's behavior. Implementers update
|
||
this file when adding a new setting or changing how a skill responds to one.
|
||
|
||
**Format per setting:**
|
||
- Priority chain — which source wins when multiple are present
|
||
- Per-value intent — what the value means in plain terms
|
||
- Skill behavior table — exactly what changes per skill per value
|
||
|
||
**Coverage scope:** This document covers the skills most affected by each setting.
|
||
Skills not listed (e.g. `ux-review`, `balance-check`, `test-flakiness`, `test-helpers`,
|
||
`test-setup`, `soak-test`, `perf-profile`, `launch-checklist`, `release-checklist`,
|
||
`skill-test`, `skill-improve`, `vertical-slice`) are not meaningfully affected by
|
||
`project.yaml` settings and do not need entries here. Add a skill only when its
|
||
behavior genuinely branches on a setting value.
|
||
|
||
**Local override pattern:** `project.yaml` is committed to git as the shared team
|
||
config. Per-developer overrides live in `project.local.yaml` (gitignored). Priority
|
||
chain across all settings: `project.local.yaml` → `project.yaml` → legacy mirror →
|
||
`modes.rigor` expansion → hardcoded default. The expansion step applies only to the
|
||
six knobs `rigor` fronts (`modes.workflow`, `docs.density`, `qa.level`,
|
||
`modes.story_granularity`, `modes.review_mode`, `team.size`), which for that reason have **no** hardcoded default —
|
||
see the `modes.rigor` section.
|
||
**Secrets do NOT belong in either file — use environment variables.** See the
|
||
"Local Override Pattern" section below for full design including the whitelist of
|
||
which settings can be locally overridden.
|
||
|
||
---
|
||
|
||
## Local Override Pattern — `project.local.yaml`
|
||
|
||
The `project.local.yaml` file lets each developer override specific settings for
|
||
their own use without affecting the team. The file is gitignored and never
|
||
committed.
|
||
|
||
### How it works
|
||
|
||
Priority chain (every setting): `project.local.yaml` → `project.yaml` → hardcoded default
|
||
|
||
If a setting is present in `project.local.yaml`, that value wins. If absent, the
|
||
value from `project.yaml` is used. If absent there too, the hardcoded default
|
||
takes over.
|
||
|
||
---
|
||
|
||
### Deep merge semantics
|
||
|
||
When both files set a nested value, only the explicitly-set key is overridden.
|
||
Sibling keys in the same block are preserved.
|
||
|
||
Example:
|
||
|
||
`project.yaml`:
|
||
```yaml
|
||
testing:
|
||
strict:
|
||
logic: true
|
||
integration: true
|
||
visual: false
|
||
```
|
||
|
||
`project.local.yaml` (sparse override):
|
||
```yaml
|
||
testing:
|
||
strict:
|
||
logic: false
|
||
```
|
||
|
||
Effective config seen by skills: `logic: false, integration: true, visual: false`.
|
||
Only the explicitly-set `logic` key is overridden; sibling keys come through from
|
||
`project.yaml`.
|
||
|
||
---
|
||
|
||
### Whitelist — which settings can be locally overridden
|
||
|
||
Only personal-experience settings can be locally overridden. Project-wide facts
|
||
(engine, stage, naming conventions, what's required on disk) are locked to
|
||
`project.yaml` because divergence between developers would break team coordination.
|
||
|
||
The rule for deciding which side a setting belongs on:
|
||
|
||
> **If a setting affects what artifacts exist or what they look like on disk,
|
||
> it must be locked to `project.yaml`. If a setting only changes your personal
|
||
> experience (which agents spawn for you, whether you get prompts, your local
|
||
> CI bypass), it can be locally overridden.**
|
||
|
||
**Locally overridable** (personal experience only — no effect on artifacts on disk):
|
||
|
||
| Setting | Why local override makes sense |
|
||
|---------|-------------------------------|
|
||
| `modes.review_mode` | How much AI review you personally want |
|
||
| `modes.automation` | How often the AI prompts you |
|
||
| `modes.automation_always_ask` | Your personal safety categories |
|
||
| `team.size` | Which agents spawn for your reviews (review depth differs, artifacts don't) |
|
||
| `testing.strict.*` (each type) | Whether failures block your local work (CI still enforces project.yaml defaults) |
|
||
| `performance.enforce` | Whether budget violations block your local work (CI enforces project defaults) |
|
||
| `features.session_state` | Your session tracking preference |
|
||
| `features.token_budget_warn_at` | Your personal cost threshold |
|
||
|
||
**Locked to `project.yaml`** (project-wide — would create artifact divergence if local):
|
||
|
||
| Setting | Why it must be project-wide |
|
||
|---------|----------------------------|
|
||
| `schema_version`, `framework.*` | File metadata, not preferences — **exempt from the report below**, since a `project.local.yaml` carrying `schema_version: 1` is correct as written |
|
||
| `project.name`, `version`, `genre`, `kind`, `stage` | Project identity |
|
||
| `engine.*`, `specialists.*` | Whole team must use same engine |
|
||
| `naming.*` | Code conventions must be consistent across team |
|
||
| `platform.*` | Game facts (what platforms it ships on) |
|
||
| `performance.target_framerate`, `frame_budget_ms`, `draw_call_limit`, `memory_ceiling_mb` | Game budgets, shared targets |
|
||
| `accessibility.target` | Game commitment, project-wide |
|
||
| `cadence.*` | Sprint/milestone length affects team coordination |
|
||
| `modes.rigor` | Fronts the four below — locked for the same reason they are |
|
||
| `modes.workflow` and `workflow_overrides` | Affects which sections are required in authored docs |
|
||
| `modes.story_granularity` | Affects how big stories are in repo — team must be consistent |
|
||
| `docs.density` | Affects how deep authored docs are — team must produce consistent docs |
|
||
| `qa.level` | Affects what test evidence stories must include on disk |
|
||
| `qa.coverage_minimum` | Project quality bar |
|
||
| `strict_gate_checks` | Affects whether `project.stage` advances — a project-wide write |
|
||
| `commands.*` | Build/test commands are project facts |
|
||
| `testing.framework` | Whole project uses one framework |
|
||
|
||
> **A locked key written into `project.local.yaml` by hand is reported, not
|
||
> swallowed.** `/settings --local` refuses to write one, but the
|
||
> file is meant to be hand-edited and that path had no guard: `modes.rigor: full`
|
||
> there is a real key with a legal value, so enum validation passes it, and then
|
||
> resolution never consults the local file for that path — the setting vanishes
|
||
> and the user sees the default they were trying to override, with no error
|
||
> anywhere. Every check validated the **value**; nothing validated the
|
||
> **location**. `validate_local_scope` in `yaml-helper.sh` now names such keys on
|
||
> `resolve_config`'s `notes:` line. It **warns and never reconciles**: it does not
|
||
> edit the file, does not begin honouring the key, and does not change
|
||
> resolution — a locked setting decides which artifacts exist on disk, so
|
||
> applying one quietly would produce exactly the divergence this table prevents.
|
||
> A clean file stays silent — you are only told when a key is actually in the
|
||
> wrong place.
|
||
|
||
---
|
||
|
||
### `/settings --local` flag behavior
|
||
|
||
```
|
||
/settings workflow=minimal → writes to project.yaml (team-wide)
|
||
/settings --local automation=autonomous → writes to project.local.yaml (just you)
|
||
```
|
||
|
||
**Behavior rules:**
|
||
|
||
- Default (no flag): writes to `project.yaml`
|
||
- `--local` flag: writes to `project.local.yaml` (creates it if absent)
|
||
- `--local` on a locked setting → error:
|
||
> *"`<setting>` cannot be locally overridden — it's a project-wide setting.
|
||
> Use `/settings <setting>=<value>` (no `--local`) to change it for the whole team."*
|
||
- Writing to `project.yaml` when the same setting is currently locally overridden → warning:
|
||
> *"This setting is currently locally overridden in `project.local.yaml`.
|
||
> Writing to `project.yaml` will not affect your effective value."*
|
||
|
||
---
|
||
|
||
### Schema validation on read
|
||
|
||
When skills or hooks read either file:
|
||
|
||
| Issue | Behavior |
|
||
|-------|----------|
|
||
| Unknown key (typo or stale setting) | Session-start warning: *"`project.local.yaml` has unknown key `modes.automaton` — typo? Ignored."* Does NOT block (forwards-compat with future settings). |
|
||
| Invalid value not in enum (e.g. `automation: chaotic`) | Hard error: skill exits with explanation of valid values. |
|
||
| Type mismatch (e.g. integer field set to a string) | Hard error: skill exits with type expected. |
|
||
|
||
---
|
||
|
||
### Creation and error handling
|
||
|
||
| Scenario | Behavior |
|
||
|----------|----------|
|
||
| `/start` on fresh project | Creates `project.yaml` only. Does NOT create `project.local.yaml`. |
|
||
| `/settings --local <x>=<y>` when local.yaml doesn't exist | Creates `project.local.yaml` containing just that setting. |
|
||
| `project.local.yaml` exists but `project.yaml` doesn't | Hard error: *"`project.yaml` missing — run `/start` to create one. Local overrides require a base."* |
|
||
| Both files exist | Read `project.yaml` first, deep-merge `project.local.yaml` on top. Normal operation. |
|
||
| Both files set the same key | `project.local.yaml` wins. No prompting. |
|
||
|
||
---
|
||
|
||
### Two-developer clash scenarios — and why the whitelist prevents them
|
||
|
||
**File-level conflict (`project.yaml`):**
|
||
Standard git merge conflict. Each developer's `project.local.yaml` is gitignored
|
||
and never collides with another developer's. Normal git workflow handles team-wide
|
||
changes.
|
||
|
||
**Logical inconsistency (prevented by whitelist):**
|
||
|
||
Example of what the whitelist prevents:
|
||
|
||
> Sarah sets `modes.workflow: minimal` locally to skip GDD requirements. She
|
||
> doesn't write GDDs because her local mode doesn't require them. Mike runs
|
||
> `/gate-check` with the team default of `standard`; gate-check sees missing
|
||
> GDDs and fails.
|
||
|
||
This can't happen because `modes.workflow` is locked to `project.yaml`. Same
|
||
for `qa.level`, `docs.density`, `strict_gate_checks`, `naming.*`, and every
|
||
other setting that affects what artifacts exist on disk.
|
||
|
||
Personal experience settings (`automation`, `review_mode`, `team.size`,
|
||
`testing.strict.*`, `performance.enforce`) can diverge freely without affecting
|
||
anyone else.
|
||
|
||
---
|
||
|
||
### Stricter reviewer reviewing a looser reviewer's work
|
||
|
||
A common worry: "what if my teammate has stricter review settings than me?
|
||
Will their `/gate-check` or `/design-review` flag things in my work?"
|
||
|
||
The answer depends on which kind of difference you're talking about:
|
||
|
||
**Different review depth, same project requirements (HEALTHY):**
|
||
|
||
- Teammate A: local `review_mode: full`, `automation: collaborative`, `testing.strict.logic: true`
|
||
- Teammate B: local `review_mode: solo`, `automation: autonomous`, `testing.strict.logic: false`
|
||
- Both bound by the same project.yaml-locked settings (e.g. `workflow: standard`, `qa.level: standard`)
|
||
|
||
B writes a GDD that meets `workflow: standard` (all 5 required sections present).
|
||
B's `/design-review` runs with `review_mode: solo` — fast advisory check, no
|
||
specialists spawned. B moves on.
|
||
|
||
Later A reviews the same GDD with `review_mode: full` — spawns 5–15 specialists,
|
||
finds polish opportunities and edge cases B's lighter review missed. A files
|
||
findings as PR comments or follow-up issues. B addresses the ones that matter.
|
||
|
||
**This is normal team collaboration.** Different reviewers catching different
|
||
things is the value of having multiple reviewers. The artifacts on disk are the
|
||
same; only review depth differs. Nothing about this scenario creates project-state
|
||
divergence.
|
||
|
||
**Different requirements (PREVENTED by the whitelist):**
|
||
|
||
If `qa.level` were locally overridable:
|
||
|
||
- B sets `qa.level: minimal` locally. B's stories don't include test evidence.
|
||
- B's `/story-done` accepts the story without evidence. Story marked Complete on disk.
|
||
- A pulls. A's `qa.level: standard` requires evidence. A's `/story-done` would have rejected it.
|
||
- A's next `/gate-check` fails because evidence is missing across multiple of B's "Complete" stories.
|
||
|
||
This is the artifact divergence problem. To prevent it, `qa.level` is locked to
|
||
`project.yaml`. The team agrees together on what's required; individuals override
|
||
only their personal experience, never the team's standards.
|
||
|
||
**The pattern to remember:**
|
||
|
||
| Difference type | Outcome |
|
||
|----------------|---------|
|
||
| Different review depth (review_mode, team.size) | Stricter reviewer surfaces more findings — healthy. Artifacts unchanged. |
|
||
| Different local strictness on failures (testing.strict.*, performance.enforce) | Stricter dev's local /story-done blocks earlier — they fix it locally. CI uses project.yaml defaults so team-wide quality bar stays. |
|
||
| Different artifact requirements (workflow, qa.level, docs.density, etc.) | **Can't happen — these are locked.** Team agrees once in project.yaml. |
|
||
|
||
---
|
||
|
||
### CI behavior
|
||
|
||
CI environments have no `project.local.yaml` — the file is gitignored and never
|
||
present in a fresh clone. CI therefore always runs against `project.yaml`
|
||
defaults: strict project standards, no developer-specific overrides.
|
||
|
||
This is intentional and important:
|
||
|
||
| Setting | Local default for fast iteration | CI default (`project.yaml`) |
|
||
|---------|----------------------------------|------------------------------|
|
||
| `modes.review_mode` (locally overridable) | `solo` for one developer | `lean` (team default — phase gates always run) |
|
||
| `testing.strict.logic` (locally overridable) | `false` for fast WIP commits | `true` (failing tests block CI) |
|
||
| `modes.automation` (locally overridable) | `autonomous` for solo flow | `collaborative` (the team's collab protocol, but CI doesn't ask questions anyway — this is mostly a no-op on CI) |
|
||
|
||
A developer can iterate locally with relaxed gates, but CI catches issues using
|
||
the strict project defaults. The team's quality bar is enforced at the CI level
|
||
regardless of any individual developer's local config.
|
||
|
||
---
|
||
|
||
### Secrets — never in either file
|
||
|
||
`project.yaml` and `project.local.yaml` are for **preferences and configuration**,
|
||
never for **secrets**. API keys, tokens, and credentials belong in:
|
||
|
||
- **Environment variables** (preferred for production/CI)
|
||
- **`.env` file** (gitignored, local dev)
|
||
- **OS keychain** (when integrating with services that support it)
|
||
|
||
When a skill needs an API key (e.g. `/asset-spec` calling Midjourney), it reads
|
||
from the environment, not from `project.yaml`. `project.yaml` only stores **which**
|
||
generator is used (`art.generator: midjourney`), not the API key for it.
|
||
|
||
CI environments typically have no `project.local.yaml` (gitignored, not in the
|
||
clone) — so CI always runs against `project.yaml` defaults. This is correct
|
||
behavior: strict project defaults for CI, looser developer overrides for local work.
|
||
|
||
---
|
||
|
||
## modes.review_mode
|
||
|
||
**Controls:** How many specialist and director agents are spawned during skill execution
|
||
**Values:** `full` | `lean` | `solo`
|
||
**Default:** *none* — supplied by `modes.rigor` (`standard` yields `lean`)
|
||
**Set by:** `/start`, `/adopt`, `/settings`
|
||
**Read by:** See skill table below
|
||
|
||
**Priority chain (all skills):** inline argument flag → `modes.review_mode` in `project.yaml` → `production/review-mode.txt` (legacy fallback) → `modes.rigor` expansion (no terminal default; `minimal`→`solo`, `standard`→`lean`, `full`→`full`)
|
||
|
||
> **design-review follows the standard chain.** `modes.review_mode` controls
|
||
> design-review depth, its inline flag is `--review` for consistency with every
|
||
> other review-mode-aware skill, and the default is `lean` to match them.
|
||
|
||
> **Hotfix / day-one-patch exception:** These skills are emergency or release-critical
|
||
> pipelines. They are never gated by `review_mode` — all agents always run.
|
||
|
||
> **Known inertness — `full` and `lean` are identical in all nine `team-*`
|
||
> orchestrators.** Each of them documents a three-way split:
|
||
> `full` spawns every director and lead gate, `lean` skips director gates *unless*
|
||
> they are PHASE-GATE type, `solo` skips gate spawning entirely. But every
|
||
> `team-*` skill names exactly four gates — `CD-PHASE-GATE`, `TD-PHASE-GATE`,
|
||
> `PR-PHASE-GATE`, `AD-PHASE-GATE` — and all four are the type `lean` keeps. So
|
||
> `lean` has nothing to skip and behaves as `full`.
|
||
>
|
||
> `solo` genuinely differs, and outside the orchestrators (`/design-review`,
|
||
> `/architecture-review`) all three levels differ as documented.
|
||
>
|
||
> **This is recorded, not fixed.** Making `lean` mean something in the
|
||
> orchestrators requires deciding which non-phase-gate reviewers each of the nine
|
||
> should call at `full` — a design decision about review depth, not a wording fix,
|
||
> and one that changes how many agents a run spawns.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Intent |
|
||
|-------|--------|
|
||
| `full` | All director and specialist gates active. Best for teams, learning, or anyone who wants thorough AI feedback on every decision. |
|
||
| `lean` | Phase gates only — per-skill director sign-offs skipped. Default. Balances quality with token cost. |
|
||
| `solo` | No gates, no director spawns at all. Fastest. For confident solo iteration. |
|
||
|
||
---
|
||
|
||
### Core skills (currently review-mode aware)
|
||
|
||
| Skill | full | lean | solo |
|
||
|-------|------|------|------|
|
||
| **design-review** | 5–15 specialist agents spawned in Phase 3b | No specialist agents — single-session analysis only | Phases 1–4 only, no delegation, no next-steps prompt |
|
||
| **gate-check** | Director panel runs in parallel — **width set by `modes.workflow`**, not by this axis | Director panel runs in parallel — same width rule; phase gates always run | Artifact existence checks only, no directors spawned |
|
||
| **design-system** | All section specialists + CD-GDD-ALIGN sign-off gate | All section specialists, CD-GDD-ALIGN skipped | All section specialists, CD-GDD-ALIGN skipped |
|
||
| **art-bible** | All section specialists + AD-ART-BIBLE sign-off gate | All section specialists, AD-ART-BIBLE skipped | All section specialists, AD-ART-BIBLE skipped |
|
||
| **architecture-decision** | Engine specialist + TD-ADR gate | Both skipped | Both skipped |
|
||
| **create-architecture** | TD self-review + LP-FEASIBILITY agent | Both skipped | Both skipped |
|
||
| **brainstorm** | CD-PILLARS, AD-CONCEPT-VISUAL, TD-FEASIBILITY, PR-SCOPE | All skipped | All skipped |
|
||
| **map-systems** | TD-SYSTEM-BOUNDARY, PR-SCOPE, CD-SYSTEMS | All skipped | All skipped |
|
||
| **story-done** | QL-TEST-COVERAGE + LP-CODE-REVIEW | Both skipped | Both skipped |
|
||
| **sprint-plan** | PR-SPRINT feasibility check | Skipped | Skipped |
|
||
| **create-epics** | PR-EPIC scope check | Skipped | Skipped |
|
||
| **create-stories** | QL-STORY-READY + test case specs | Skipped | Skipped |
|
||
| **prototype** | CD-PLAYTEST director override | Skipped — prototyper verdict is final | Skipped — prototyper verdict is final |
|
||
| **milestone-review** | PR-MILESTONE feasibility check | Skipped — no producer verdict | Skipped — no producer verdict |
|
||
| **playtest-report** | CD-PLAYTEST creative assessment | Skipped | Skipped |
|
||
| **story-readiness** | QL-STORY-READY acceptance criteria check | Skipped | Skipped |
|
||
|
||
---
|
||
|
||
### Skills to be made review-mode aware (currently ignore the setting)
|
||
|
||
| Skill | full | lean | solo |
|
||
|-------|------|------|------|
|
||
| **review-all-gdds** | Phase 2 consistency pass + Phase 3 design theory pass (parallel) | Phase 2 consistency pass only, Phase 3 skipped | Phase 2 only, Phase 3 skipped |
|
||
| **architecture-review** | Engine specialist + security-engineer (if online features) | Both skipped | Both skipped |
|
||
| **dev-story** | Core programmer routing always runs + engine-specialist escalation on HIGH risk stories | Core programmer routing always runs, engine-specialist escalation skipped | Core programmer routing always runs, engine-specialist escalation skipped |
|
||
| **code-review** | Language, shader, UI specialists + qa-tester | All optional specialists skipped | All optional specialists skipped |
|
||
| **security-audit** | security-engineer spawned | Skipped | Skipped |
|
||
| **create-control-manifest** | technical-director validation step | Skipped | Skipped |
|
||
| **propagate-design-change** | technical-director validation step | Skipped | Skipped |
|
||
|
||
---
|
||
|
||
### Team orchestration skills (pipeline behavior — different relationship)
|
||
|
||
Team skills are execution pipelines, not review gates. `review_mode` controls
|
||
whether *optional* specialists within the pipeline are included — not whether
|
||
the pipeline runs.
|
||
|
||
| Skill | full | lean | solo |
|
||
|-------|------|------|------|
|
||
| **team-combat** | Full pipeline including technical-artist, sound-designer, qa-tester | Core pipeline only (game-designer, gameplay-programmer, ai-programmer) — optional specialists skipped | Core pipeline only |
|
||
| **team-ui** | Full pipeline including accessibility-specialist, art-director review pass | Core pipeline (ux-designer, ui-programmer, engine UI specialist) — optional reviewers skipped | Core pipeline only |
|
||
| **team-audio** | Full pipeline including accessibility-specialist, engine-specialist | Core pipeline (audio-director, sound-designer, technical-artist) — optional specialists skipped | Core pipeline only |
|
||
| **team-qa** | Full QA cycle including per-story qa-tester spawns + qa-lead sign-off | Core qa-lead plan only, per-story tester spawns skipped | Core qa-lead plan only |
|
||
| **team-release** | Full pipeline including security-engineer, analytics-engineer, localization-lead | Core pipeline (producer, release-manager, devops-engineer, qa-lead) — optional reviewers skipped | Core pipeline only |
|
||
| **team-narrative** | Full pipeline including world-builder, writer, localization-lead | Core pipeline (narrative-director, art-director) — optional contributors skipped | Core pipeline only |
|
||
| **team-polish** | Full pipeline including engine-programmer, sound-designer, qa-tester | Core pipeline (performance-analyst, technical-artist) — optional specialists skipped | Core pipeline only |
|
||
| **team-level** | Full pipeline including narrative-director, world-builder, accessibility-specialist, qa-tester | Core pipeline (level-designer, systems-designer, art-director) — optional reviewers skipped | Core pipeline only |
|
||
| **team-live-ops** | Full pipeline including analytics-engineer, community-manager | Core pipeline (live-ops-designer, narrative-director, economy-designer) — optional contributors skipped | Core pipeline only |
|
||
|
||
---
|
||
|
||
### Special cases and notes
|
||
|
||
- **gate-check** is the only skill where `full` and `lean` behave identically —
|
||
phase gates always run. Only `solo` skips them. This is intentional: phase
|
||
gates are the minimum quality bar, not optional extras. **How many directors
|
||
run is a separate axis** — `modes.workflow` sets panel width (`minimal` → PR
|
||
only, `standard` → TD + PR, `full` → all four), because a fixed four-director
|
||
Opus panel cost a two-system jam exactly what it cost a thirty-system
|
||
commercial project. Width never softens a verdict: the strictest verdict from
|
||
whoever ran still wins, and `/gate-check` names the perspectives it skipped.
|
||
- **design-system** and **art-bible** always spawn section specialists regardless
|
||
of mode — only the final sign-off gate is controlled by `review_mode`. Specialist
|
||
delegation is mandatory for the authoring output to be useful, and that has not
|
||
changed. What sets `art-bible`'s **spawn count** is therefore not `review_mode`
|
||
but (a) `modes.workflow`, via how many sections get authored at all — `standard`
|
||
requires sections 1–4, not all 9, and Phase 1 recommends the tier's set — and
|
||
(b) batching consecutive sections that call the *same* agent with the *same*
|
||
input into one delegation (2–4, and 5–6). Unbatched, sections 5 and 6 spawn
|
||
`art-director` twice with the identical `sections 1–4` brief. Every section is
|
||
still specialist-authored; per-section approval and write-to-file are unchanged.
|
||
- **dev-story** core programmer routing (gameplay-programmer, ui-programmer, etc.)
|
||
always runs regardless of mode — only the optional engine-specialist escalation
|
||
for HIGH risk stories is gated.
|
||
- **hotfix** and **day-one-patch** are exempt — all agents always run.
|
||
- When a gate is skipped, skills emit: `"[GATE-ID] skipped — [mode] mode."` before
|
||
proceeding. This is consistent across all skills.
|
||
|
||
---
|
||
|
||
## modes.rigor
|
||
|
||
**Controls:** How much process the project carries overall — the single question
|
||
`/start` asks that sets the six knobs below
|
||
**Values:** `minimal` | `standard` | `full`
|
||
**Default:** `minimal` — see the rationale block above `_yaml_helper_defaults`
|
||
in `.claude/hooks/yaml-helper.sh`. Short version: the heavier tier cost several
|
||
times more to reach working code without producing a better result.
|
||
**Set by:** `/start` (Phase 3d), `/settings`
|
||
**Read by:** nothing directly — it is read *through* the six knobs it supplies
|
||
|
||
**Priority chain:** `modes.rigor` in `project.yaml` → hardcoded default `minimal`
|
||
(**locked** — not overridable from `project.local.yaml`, like the four *on-disk*
|
||
knobs it fronts — `modes.workflow`, `docs.density`, `qa.level`,
|
||
`modes.story_granularity` — because those five change what artifacts exist on
|
||
disk. The two personal-experience knobs it also fronts, `modes.review_mode` and
|
||
`team.size`, stay locally overridable.)
|
||
|
||
---
|
||
|
||
### Expansion table
|
||
|
||
| `modes.rigor` | `modes.workflow` | `docs.density` | `qa.level` | `modes.story_granularity` | `modes.review_mode` | `team.size` |
|
||
|---|---|---|---|---|---|---|
|
||
| `minimal` | `minimal` | `terse` | `minimal` | `coarse` | `solo` | `individual` |
|
||
| `standard` *(default)* | `standard` | `balanced` | `standard` | `balanced` | `lean` | `individual` |
|
||
| `full` | `full` | `thorough` | `full` | `fine` | `full` | `studio` |
|
||
|
||
### It fronts, it does not replace
|
||
|
||
The expansion sits **below every explicit source and above the terminal
|
||
default**:
|
||
|
||
```
|
||
project.local.yaml → project.yaml → legacy file → rigor expansion → default
|
||
```
|
||
|
||
That ordering is the back-compat guarantee, and it is what makes the migration
|
||
free. Three consequences worth stating plainly:
|
||
|
||
- **An existing `project.yaml` behaves identically.** If it already sets
|
||
`docs.density: terse`, step 2 answers before the expansion is consulted — so
|
||
the value and its reported source (`project.yaml`) are unchanged whether or not
|
||
`rigor` is present. No migration, no `schema_version` bump.
|
||
- **Overrides go both ways.** Unlike the `workflow_overrides` **boolean flags** —
|
||
which are additive and stricter-only — an explicit knob may be *looser* than
|
||
the rigor level implies.
|
||
(`workflow_overrides.system_overrides` is also two-directional — it replaces a tier; only the flags are stricter-only.)
|
||
Inheriting the stricter-only rule would make "comprehensive but compact"
|
||
inexpressible, which is the one off-diagonal the docs have always cited.
|
||
- **`modes.workflow` keeps `workflow_overrides.system_overrides`.** Per-system
|
||
tiers still beat the rigor-derived project tier. `workflow` was fronted rather
|
||
than folded away precisely because it drives ~5 distinct behaviors and owns the
|
||
only per-system override mechanism.
|
||
|
||
The six fronted knobs therefore have **no entry in `_yaml_helper_defaults`**. A
|
||
terminal default there would answer before the expansion and make `rigor` a no-op
|
||
for anyone who had not also set the sub-knob.
|
||
|
||
### Provenance
|
||
|
||
Derived values report their source as `rigor:<level>`, so the vocabulary is
|
||
`{project.local.yaml, project.yaml, <legacy path>, rigor:<level>, default,
|
||
unset}`. `/settings` renders this as `(derived from rigor: standard)` and
|
||
force-appends the five to its view-all list — none of them is a leaf of either
|
||
YAML file, so enumerating file leaves alone would hide exactly the settings the
|
||
user just chose.
|
||
|
||
---
|
||
|
||
## modes.workflow
|
||
|
||
**Controls:** How much design documentation is required before code can begin —
|
||
the tradeoff between token/time cost of documentation and speed of reaching
|
||
working code
|
||
**Values:** `full` | `standard` | `minimal`
|
||
**Default:** *none* — supplied by `modes.rigor` (`standard` yields `standard`)
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** See skill tables below
|
||
|
||
**Priority chain:** `modes.workflow` in `project.yaml` → `modes.rigor` expansion → *(no hardcoded default)*
|
||
|
||
> **Why the middle level is `standard`, not `indie`.** A developer-type label
|
||
> would conflate "type of developer" with "level of process". `standard`
|
||
> describes the *amount of process*, not the user, and pairs cleanly with
|
||
> `minimal` and `full`.
|
||
|
||
> **Permissive, not restrictive:** `workflow` controls what is REQUIRED —
|
||
> not what is ALLOWED. Any skill can be run at any workflow level. The
|
||
> setting changes what gate-check enforces and what completeness checks
|
||
> validate, not what the user can invoke.
|
||
|
||
> **`minimal` floor:** Even in minimal mode, engine choice and a filled
|
||
> **`design/game-brief.md`** are required before code starts — the brief's
|
||
> build-order field is the plan, so there is no separate `sprint-plan` step.
|
||
> Both take minutes and prevent real problems downstream. Everything else can
|
||
> be skipped.
|
||
|
||
> **Escape hatches via `workflow_overrides`:** Users who want *almost* the
|
||
> standard set with one extra requirement (e.g. always force Edge Cases) use
|
||
> `workflow_overrides` rather than escalating to `full`. See next section.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Token/time cost | Required before code | Best for |
|
||
|-------|----------------|---------------------|----------|
|
||
| `full` | High | All 8 GDD sections per system, full architecture, all ADRs, art bible, UX specs per screen | Projects where design correctness matters more than speed — teams, commercial titles, learning the full pipeline |
|
||
| `standard` | Balanced | 5 GDD sections per system, one architecture doc, critical ADRs, game concept, systems index | Projects that have outgrown a brief — several interacting systems, or a design someone else has to implement |
|
||
| `minimal` | Low | One-page `design/game-brief.md` + engine choice (build order in the brief = the plan; no separate sprint plan) | **Default.** Get to code fast — small scope, jam projects, or the design already in your head. Raise it when the project grows |
|
||
|
||
**standard required GDD sections:** Overview, Detailed Rules, Edge Cases, Dependencies,
|
||
Acceptance Criteria.
|
||
**standard conditional:** Formulas — required when the system **defines numeric
|
||
rules**: rates, curves, thresholds, costs, damage, drop weights, or any value a
|
||
balance pass would tune. Optional only when the system defines no such value.
|
||
|
||
> **The test is what the system defines, not what it is called.** The `Category`
|
||
> column in `systems-index.md` is a *hint* — `Gameplay`, `Economy` and
|
||
> `Progression` systems almost always qualify — but it is not the test, and a
|
||
> `Core`, `UI` or `Persistence` system that defines a numeric rule qualifies too.
|
||
>
|
||
> Do not restate it as "required when system category is combat, economy,
|
||
> progression, or AI". Those four tokens are not the vocabulary `/map-systems`
|
||
> writes: `templates/systems-index.md` defines the categories as `Core ·
|
||
> Gameplay · Progression · Economy · Persistence · UI · Audio · Narrative ·
|
||
> Meta`, and lists **combat and AI as example systems under `Gameplay`**. A
|
||
> combat system categorised exactly as the template instructs therefore matched
|
||
> none of the four, and Formulas was silently dropped for the system most likely
|
||
> to need it. `coding-standards.md` and `rules/design-docs.md` already stated the
|
||
> "has math" test; the skills are reconciled to them rather than the other way
|
||
> round.
|
||
|
||
> **Edge Cases is required at `standard`.** Skipping it consistently produces
|
||
> "wait, what happens if X is null?" debt during implementation. These 5
|
||
> required sections are the minimum that produces implementable code.
|
||
|
||
> **Art bible is conditional in `standard`.** It is required only if visual
|
||
> asset stories exist in the project. Code-focused projects can skip it
|
||
> entirely at `standard` level.
|
||
|
||
---
|
||
|
||
### Authoring skills
|
||
|
||
| Skill | full | standard | minimal |
|
||
|-------|------|----------|---------|
|
||
| **design-system** | All 8 sections required | 5 required sections + conditional Formulas; Player Fantasy, Tuning Knobs skipped | Not required — game brief replaces GDDs. Can still be run voluntarily. |
|
||
| **art-bible** | All 9 sections required | Required only if visual asset stories exist; sections 1–4 minimum when required | Not required. Can still be run voluntarily. |
|
||
| **create-architecture** | Full architecture — all layers, module ownership, data flow, API boundaries, full ADR audit | Simplified — system layer map + critical ADR list only | Not required. Can still be run voluntarily. |
|
||
| **ux-design** | UX spec required per screen | Core screens only (main menu, HUD, primary game loop) | Not required. Can still be run voluntarily. |
|
||
| **map-systems** | Required before design-system | Required before design-system | Not required |
|
||
| **architecture-decision** | All ADRs on required ADR list must be completed | Critical ADRs only — Foundation layer systems | Not required |
|
||
|
||
---
|
||
|
||
### Review and validation skills
|
||
|
||
| Skill | full | standard | minimal |
|
||
|-------|------|----------|---------|
|
||
| **design-review** | All 8 sections validated — any missing section blocks approval | 5 required sections validated; missing optional sections warned but do not block | Not applicable — no GDDs to review |
|
||
| **review-all-gdds** | Validates all 8 sections across all GDDs | Validates 5 required sections across all GDDs; optional sections surfaced as advisory only | Not applicable |
|
||
| **architecture-review** | Full traceability matrix — all GDDs, all ADRs | Reduced scope — architecture doc + critical ADRs only | Not applicable |
|
||
| **consistency-check** | Full entity registry cross-check against all GDD sections | Entity registry check against required sections only | Not meaningful — no GDDs to check |
|
||
| **content-audit** | Full content count audit against all GDD specs | Limited audit — only specs in required sections counted | Cannot run — no systems index exists |
|
||
|
||
---
|
||
|
||
### Phase gate enforcement (gate-check)
|
||
|
||
`gate-check` is where workflow has the most visible impact — the artifact
|
||
checklists differ per phase per mode.
|
||
|
||
| Gate | full | standard | minimal |
|
||
|------|------|----------|---------|
|
||
| Concept → Systems Design | game-concept.md, pillars, Visual Identity Anchor | game-concept.md only | `design/game-brief.md` only (content check, not section check) |
|
||
| Systems Design → Technical Setup | systems-index, all MVP GDDs reviewed (8 sections), cross-GDD review | systems-index, 5-section GDDs reviewed, cross-GDD review optional | Not applicable — no gates between brief and code |
|
||
| Technical Setup → Pre-Production | engine, art bible sections 1–4+, 3+ ADRs, architecture, UX specs started | engine, art bible only if visual assets, critical ADRs, architecture | engine configured (required floor) |
|
||
| Pre-Production → Production | prototype, sprint plan, complete art bible, epics, 3+ playtests | prototype, sprint plan, epics, 1+ playtest | prototype (advisory); the brief's Build order is the plan — no separate sprint-plan floor |
|
||
<!-- gate-check reconciliation: the Vertical Slice / prototype keeps
|
||
its long-standing "recommended, not blocking → CONCERNS if absent; FAIL if
|
||
built-and-broken" status at ALL tiers — the tier table never upgrades it to
|
||
a hard blocker. The genuinely-required floor item at this gate is the
|
||
sprint plan at `standard`/`full`; at `minimal` (Option A) there is
|
||
no separate sprint-plan step — the brief's Build order is the plan, so the
|
||
brief existing satisfies the floor. "prototype" above means "checked,
|
||
advisory," not "blocks." -->
|
||
|
||
| Production → Polish | core mechanics, tests, smoke check, QA sign-off | core mechanics, smoke check | smoke check |
|
||
| Polish → Release | all features, content complete, QA, smoke, no critical bugs | all features, smoke, no critical bugs | smoke, no critical bugs |
|
||
|
||
**Director panel width** (`/gate-check` Section 4b) is workflow's second effect
|
||
here. Directors are Opus-tier, so a fixed four-director panel charged a
|
||
two-system jam exactly what it charged a thirty-system commercial project:
|
||
|
||
| `workflow` | Panel | Directors |
|
||
|---|---|---|
|
||
| `full` | 4 | `creative-director`, `technical-director`, `producer`, `art-director` |
|
||
| `standard` | 2 | `technical-director`, `producer` |
|
||
| `minimal` | 1 | `producer` |
|
||
|
||
`review_mode` remains the axis that decides *whether* the panel runs at all
|
||
(`solo` skips it entirely); workflow decides only how wide it is. Narrowing
|
||
never softens a verdict — the strictest verdict from whoever ran still wins, and
|
||
`/gate-check` names the perspectives that did not run.
|
||
|
||
---
|
||
|
||
### Planning and implementation skills
|
||
|
||
| Skill | full | standard | minimal |
|
||
|-------|------|----------|---------|
|
||
| **create-epics** | Requires all GDDs approved (8 sections) | Requires 5-section GDDs approved | **Skipped** (Option A) — no separate epic doc. `/create-stories` reads `design/game-brief.md` directly and synthesizes the implicit epic container itself. |
|
||
| **create-stories** | Requires all ADRs on required list present | Requires critical ADRs present | No ADR requirement |
|
||
| **dev-story** | Requires TR registry + governing ADR + control manifest — blocks without them | TR registry optional; critical ADR required where present | No TR registry, no ADR required — implements against `design/game-brief.md` |
|
||
| **story-readiness** | Full TR registry + ADR + control manifest validation | TR registry optional; critical ADR check only | Acceptance criteria check only |
|
||
| **story-done** | Full GDD traceability + ADR consistency check | 5-section GDD traceability check | Acceptance criteria check only |
|
||
| **qa-plan** | Full test plan derived from all 8 GDD sections | Test plan from 5 required sections | Test plan from acceptance criteria only |
|
||
| **regression-suite** | Critical paths mapped from all sections including Edge Cases | Critical paths from required sections (including Edge Cases) | Smoke test coverage only |
|
||
|
||
---
|
||
|
||
### Support skills
|
||
|
||
| Skill | full | standard | minimal |
|
||
|-------|------|----------|---------|
|
||
| **project-stage-detect** | Checks for all doc types; missing art bible or UX specs flagged as gaps | Adjusts expectations — art bible only flagged if visual-asset stories exist; non-core UX specs not flagged | `design/game-brief.md` + engine present = normal state; no gaps flagged for absent GDDs |
|
||
| **adopt** | Full format compliance audit across all doc types | Audit scope reduced to required docs only | `design/game-brief.md` format check only |
|
||
| **reverse-document** | Generates full 8-section GDD from code | Generates 5-section GDD from code | Generates `design/game-brief.md` from code |
|
||
| **propagate-design-change** | Full cascading impact analysis across all ADRs | Checks critical ADRs for references only | Not applicable |
|
||
| **help** | Full artifact detection — surfaces all missing docs as next steps | Adjusts "what's missing" to required docs only — optional docs not surfaced as gaps | `design/game-brief.md` + engine present = next step is code |
|
||
|
||
---
|
||
|
||
### Workflow change mid-project
|
||
|
||
When `workflow` changes via `/settings`, the skill emits an informational note:
|
||
|
||
> "Workflow changed from [old] to [new]. Run `/content-audit` to see what's now
|
||
> required or extra. No automatic migration — existing files stay in place."
|
||
|
||
No documents are auto-deleted, auto-generated, or blocked. The setting only affects
|
||
*new* enforcement going forward.
|
||
|
||
---
|
||
|
||
## workflow_overrides
|
||
|
||
**Controls:** Opt-in granular requirements that override the chosen workflow level
|
||
**Location:** **top level of `project.yaml`** — a sibling of `modes:`, *not* a child of it
|
||
**Values:** object with sub-flags (see below)
|
||
**Default:** all false / empty
|
||
**Set by:** `/settings`
|
||
**Read by:** `/design-system`, `/design-review`, `/art-bible`, `/gate-check`, `/review-all-gdds`, `/qa-plan`
|
||
|
||
> **Why the location is called out.** `resolve_config` reads
|
||
> `workflow_overrides.system_overrides.*` from the document root
|
||
> (`yaml-helper.sh`), and all 14 consuming skill files grep the same top-level
|
||
> path. Nested under `modes:` it is still valid YAML, so nothing errors — the
|
||
> setting is simply never read. If you copied a `workflow_overrides` block from
|
||
> anywhere, check its indentation: it belongs at the document root, never under
|
||
> `modes:`.
|
||
|
||
**Priority chain:** the three `workflow_overrides` **boolean flags**
|
||
(`edge_cases`, `tuning_knobs`, `art_bible_strict`) are *additive* on top of the
|
||
chosen `workflow` level — they make things stricter, never looser. None of them
|
||
has a value that opts out of a requirement the workflow level imposes.
|
||
|
||
> **`workflow_overrides.system_overrides` is not a flag and is not additive — it replaces a tier in both directions.**
|
||
> This rule does not extend to it. On a
|
||
> `full` project, `system_overrides.inventory: minimal` really does drop that
|
||
> system's required sections to zero. Intended — see
|
||
> `.claude/docs/workflow-modes.md § workflow_overrides`. Stating the additive
|
||
> rule over the whole key is wrong: the guarantee never held for
|
||
> `system_overrides`, so do not rely on it as a safety net.
|
||
|
||
---
|
||
|
||
### Fields
|
||
|
||
```yaml
|
||
workflow_overrides:
|
||
edge_cases: false # force Edge Cases section required (no-op at standard since already required; relevant at minimal)
|
||
tuning_knobs: false # force Tuning Knobs section required (relevant at standard, no-op at full)
|
||
art_bible_strict: false # force all 9 art bible sections required regardless of asset stories
|
||
system_overrides: {} # per-system tier overrides — see below
|
||
```
|
||
|
||
### Per-system overrides
|
||
|
||
```yaml
|
||
workflow_overrides:
|
||
system_overrides:
|
||
combat: full # combat-system GDD requires full (8 sections) regardless of project workflow
|
||
boss-encounters: full
|
||
inventory: minimal # inventory needs no GDD — the game brief covers it (minimal = no required sections)
|
||
```
|
||
|
||
`system_overrides` is a map of `system_name: workflow_level`. The named system uses the override; all other systems use the project-level `workflow`.
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | How workflow_overrides changes behavior |
|
||
|-------|----------------------------------------|
|
||
| **design-system** | Reads `system_overrides[system_name]` first; falls back to project `workflow`. Applies override-specific section requirements. |
|
||
| **design-review** | Same lookup — validates against the override tier, not the project default, for the named system. |
|
||
| **art-bible** | If `art_bible_strict: true`, requires all 9 sections regardless of `workflow` level. |
|
||
| **gate-check** | Considers `system_overrides` when validating that all required GDDs are complete. A system at `system_overrides.combat: full` blocks the gate until all 8 sections exist for combat. |
|
||
| **review-all-gdds** | Validates each GDD against its effective tier (project workflow + any system override). |
|
||
|
||
---
|
||
|
||
## modes.automation
|
||
|
||
**Controls:** Whether skills ask for decisions and approval before acting, or
|
||
recommend and proceed — the tradeoff between user control and speed
|
||
**Values:** `collaborative` | `guided` | `autonomous`
|
||
**Default:** `collaborative`
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** All ~40 skills that use `AskUserQuestion` or write files
|
||
|
||
**Priority chain:** `modes.automation` in `project.yaml` → hardcoded default
|
||
|
||
> **Unlike review_mode and workflow, this setting is not a per-skill table.**
|
||
> It defines universal interaction rules that apply across all skills. A
|
||
> per-skill breakdown would repeat the same answer 40 times.
|
||
|
||
> **Overrides COLLABORATIVE-DESIGN-PRINCIPLE.md:** `guided` and `autonomous`
|
||
> modes intentionally relax the Q→O→D→Draft→Approval protocol defined in that
|
||
> document. This is opt-in. `collaborative` preserves the protocol exactly.
|
||
|
||
> **Safety net — `automation_always_ask`:** Even in `autonomous` mode, certain
|
||
> categories of decision can be configured to always prompt. See next section.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Speed | Control | What changes |
|
||
|-------|-------|---------|--------------|
|
||
| `collaborative` | Slowest | Full — every decision is the user's | Current behavior. Q→O→D→Draft→Approval strictly followed. |
|
||
| `guided` | Balanced | High — major decisions are the user's, minor ones proceed automatically | AI states recommendation and proceeds for minor decisions. AskUserQuestion reserved for major/irreversible decisions. |
|
||
| `autonomous` | Fastest | Low — AI decides, logs, and proceeds | No AskUserQuestion (except categories in `automation_always_ask`). No draft review. No write approval. All decisions logged to decision log. |
|
||
|
||
---
|
||
|
||
### Universal rules per mode
|
||
|
||
#### collaborative (current behavior — no change)
|
||
|
||
- `AskUserQuestion` called for every multi-option decision
|
||
- 2–4 options presented with pros/cons for every design choice
|
||
- Full draft shown and approved before every file write
|
||
- "May I write this to [filepath]?" asked before every write
|
||
- "May I create [filepath] with skeleton?" asked before skeleton creation
|
||
- Section-by-section approval in multi-section authoring skills
|
||
- Multi-file changes require explicit approval of the full changeset
|
||
|
||
#### guided
|
||
|
||
- `AskUserQuestion` called for **major decisions only** (see classification below)
|
||
- Minor decisions: AI states recommendation inline and proceeds — e.g.
|
||
*"Going with a static utility pattern here — it fits the existing architecture.
|
||
Continuing unless you want to change direction."*
|
||
- Draft shown briefly before writing — proceeds after a short summary, does not
|
||
wait for explicit "yes"
|
||
- "May I write?" asked for **new files only** — updates to existing files proceed
|
||
directly
|
||
- Still presents options for major decisions but caps at 2 choices with a clear
|
||
recommendation
|
||
- Multi-section authoring: writes each approved section immediately, no per-section
|
||
confirmation prompt
|
||
|
||
#### autonomous
|
||
|
||
- No `AskUserQuestion` calls **except** for categories listed in `automation_always_ask`
|
||
- No draft review
|
||
- No "May I write?" prompts — writes directly
|
||
- Picks the recommended option for every decision without presenting alternatives
|
||
- All decisions logged immediately to `production/session-logs/decision-log.md`
|
||
with: timestamp, skill, decision point, option chosen, reasoning
|
||
- User reviews decision log post-session to audit choices made
|
||
|
||
---
|
||
|
||
### Major vs minor decision classification (guided mode)
|
||
|
||
**Major — always use AskUserQuestion in guided mode:**
|
||
|
||
| Decision type | Example |
|
||
|---------------|---------|
|
||
| Choosing a system name or document path | "What should we call this system?" |
|
||
| Mutually exclusive design directions | "Real-time or turn-based?" |
|
||
| Any choice that gates downstream work | Engine choice, architecture approach |
|
||
| Scope changes | "Cut this feature or slip the deadline?" |
|
||
| Any decision that can't be changed without significant rework | Core loop mechanic |
|
||
|
||
**Minor — AI recommends and proceeds in guided mode:**
|
||
|
||
| Decision type | Example |
|
||
|---------------|---------|
|
||
| Which section to work on next | "Moving to Edge Cases next" |
|
||
| Optional section inclusion | "Adding a Visual Notes section — fits the system" |
|
||
| Formatting and structure choices | Heading levels, table vs prose |
|
||
| Adding detail to an already-decided direction | Sub-options within an approved approach |
|
||
| Next-step routing after a phase completes | "Running design-review now" |
|
||
|
||
---
|
||
|
||
### Affected skills by category
|
||
|
||
**Authoring skills — highest impact.** Each pauses 10–15 times per document in
|
||
`collaborative`. Drops to 2–3 in `guided`, zero in `autonomous`.
|
||
|
||
`brainstorm`, `design-system`, `art-bible`, `create-architecture`, `ux-design`,
|
||
`map-systems`, `architecture-decision`, `create-epics`, `create-stories`,
|
||
`sprint-plan`, `prototype`
|
||
|
||
**Review skills — medium impact.** Pause after presenting findings to ask what
|
||
to do next. In `guided` routing decisions proceed automatically. In `autonomous`
|
||
the recommended path is taken and logged.
|
||
|
||
`design-review`, `architecture-review`, `gate-check`, `review-all-gdds`,
|
||
`story-readiness`, `story-done`, `milestone-review`, `playtest-report`
|
||
|
||
**Team orchestration skills — medium impact.** Pause between phases for
|
||
check-in. In `guided` the pipeline advances automatically unless BLOCKED. In
|
||
`autonomous` the full pipeline runs end to end.
|
||
|
||
`team-combat`, `team-ui`, `team-audio`, `team-qa`, `team-release`,
|
||
`team-narrative`, `team-polish`, `team-level`, `team-live-ops`
|
||
|
||
**Implementation skills — lower impact.** Pause for architectural questions
|
||
before writing code. In `guided` only genuinely ambiguous decisions stop. In
|
||
`autonomous` the conventional approach is picked and logged.
|
||
|
||
`dev-story`, `code-review`
|
||
|
||
**Setup and utility skills — lowest impact.** Pause for initial configuration
|
||
or routing questions. In `guided` defaults are applied automatically. In
|
||
`autonomous` recommended defaults are taken without prompting.
|
||
|
||
`start`, `adopt`, `setup-engine`, `retrospective`, `localize`, `propagate-design-change`,
|
||
`asset-spec`, `smoke-check`, `qa-plan`, `story-readiness`
|
||
|
||
---
|
||
|
||
### Exemptions — skills that ignore the automation setting
|
||
|
||
These skills always behave as `collaborative` regardless of the setting.
|
||
The reasons are noted.
|
||
|
||
| Skill | Why always collaborative |
|
||
|-------|--------------------------|
|
||
| **hotfix** | Emergency decisions — user must approve scope and risk before any action |
|
||
| **gate-check** | Results must be reviewed — a gate verdict without user acknowledgement defeats the purpose |
|
||
| **day-one-patch** | Release-critical — every action needs explicit sign-off |
|
||
| **setup-engine** | One-time irreversible choice that affects the entire project |
|
||
|
||
---
|
||
|
||
### Decision log format (autonomous mode)
|
||
|
||
Written to `production/session-logs/decision-log.md` — append-only.
|
||
|
||
```markdown
|
||
## [timestamp] — [skill-name]
|
||
|
||
**Decision point:** [what was being decided]
|
||
**Options considered:** [list of options that would have been presented]
|
||
**Chosen:** [what was picked]
|
||
**Reason:** [one-line rationale]
|
||
**Category:** [scope_changes | file_deletions | schema_changes | etc., or "minor"]
|
||
```
|
||
|
||
If the file does not exist, it is created. It is never truncated — each session
|
||
appends to the existing log.
|
||
|
||
---
|
||
|
||
## modes.automation_always_ask
|
||
|
||
**Controls:** Decision categories that ALWAYS trigger AskUserQuestion regardless of automation mode
|
||
**Values:** list of category names
|
||
**Default:** `[scope_changes, file_deletions, schema_changes]`
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** All skills that respect `modes.automation`
|
||
|
||
> **Makes `autonomous` safe.** Without this, `autonomous` is "AI does literally
|
||
> everything, no questions asked." With it, AI does most things but stops on
|
||
> destructive or irreversible decisions you specifically named.
|
||
|
||
---
|
||
|
||
### Recognized categories
|
||
|
||
| Category | Examples of decisions in this category |
|
||
|----------|----------------------------------------|
|
||
| `scope_changes` | Cutting a feature, slipping a deadline, splitting/merging an epic, removing acceptance criteria |
|
||
| `file_deletions` | Removing a story, deleting a GDD, removing a system, removing a test file |
|
||
| `schema_changes` | Changes to project.yaml, story template, control manifest, ADR template, GDD template |
|
||
| `architecture_decisions` | New ADR creation, ADR replacement, system boundary changes |
|
||
| `version_bumps` | Engine version change, framework version bump, dependency major version change |
|
||
| `external_calls` | Invoking external APIs (asset gen, AI services) when in autonomous mode |
|
||
|
||
The list is a YAML list of these strings. Skills check whether the current decision falls into one of the configured categories and prompt regardless of `automation` value.
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | Categories typically triggered |
|
||
|-------|--------------------------------|
|
||
| **scope-check** | `scope_changes` |
|
||
| **propagate-design-change** | `schema_changes`, `architecture_decisions` |
|
||
| **architecture-decision** | `architecture_decisions` |
|
||
| **setup-engine** | `version_bumps`, `schema_changes` |
|
||
| **story-done** | `file_deletions` (when removing/replacing test files) |
|
||
| **asset-spec** | `external_calls` (when calling external generators) |
|
||
|
||
---
|
||
|
||
## modes.story_granularity
|
||
|
||
**Controls:** How big each story is and how many stories per epic/sprint
|
||
**Values:** `coarse` | `balanced` | `fine`
|
||
**Default:** *none* — supplied by `modes.rigor` (`standard` yields `balanced`)
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** `/create-epics`, `/create-stories`, `/dev-story`, `/sprint-plan`, `/story-done`, `/sprint-status`
|
||
|
||
**Priority chain:** `modes.story_granularity` in `project.yaml` → `modes.rigor` expansion → *(no hardcoded default)*
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Story shape | Stories per sprint | Best for |
|
||
|-------|-------------|-------------------|----------|
|
||
| `coarse` | 1 story = 1 feature. 3–5 days work each. 5–10 ACs per story. | 2–4 | Solo devs, prototyping, "I know what I'm building" |
|
||
| `balanced` | 1 story = 1 task. 1–2 days work each. 2–4 ACs per story. Current default behavior. | 6–10 | Most projects |
|
||
| `fine` | 1 story = 1 AC. Hours of work each. Easy code review. Frequent /story-done. | 15–25 | Teams, learning, anything needing fine handoffs |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | coarse | balanced | fine |
|
||
|-------|--------|----------|------|
|
||
| **create-epics** | Generates 3–5 child stories per epic | Generates 5–10 child stories per epic | Generates 10–20 child stories per epic |
|
||
| **create-stories** | Each story carries 5–10 ACs covering an entire feature | Each story carries 2–4 ACs covering one task | Each story carries 1 AC; story name = AC restatement |
|
||
| **dev-story** | Routing prompt expects multi-day implementation cycle. Subagent given longer working context. | Standard 1–2 day expectation. | Each story implementable in hours; subagent given tighter context. |
|
||
| **sprint-plan** | Allocates 2–4 stories per sprint based on velocity. | Allocates 6–10 stories per sprint. | Allocates 15–25 stories per sprint. |
|
||
| **story-done** | Fires every 3–5 days on average. | Fires every 1–2 days on average. | Fires multiple times per day. |
|
||
| **sprint-status** | Burn-down reads in feature-sized chunks. | Burn-down reads in task-sized chunks. | Burn-down reads in AC-sized chunks. |
|
||
|
||
---
|
||
|
||
## docs.density
|
||
|
||
**Controls:** How deep each section in authored docs goes — independent of which sections are required
|
||
**Values:** `terse` | `balanced` | `thorough`
|
||
**Default:** *none* — supplied by `modes.rigor` (`standard` yields `balanced`)
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** `/design-system`, `/art-bible`, `/create-architecture`, `/ux-design`, `/map-systems`, `/brainstorm`
|
||
|
||
**Priority chain:** `docs.density` in `project.yaml` → `modes.rigor` expansion → *(no hardcoded default)*
|
||
|
||
> **Distinct from `workflow`, but no longer independent by default.** `workflow`
|
||
> controls which sections exist; `density` controls how deep each section goes.
|
||
> `modes.rigor` now sets both together, so the diagonal (`rigor: full` → 8
|
||
> sections *and* thorough prose) is what you get without asking. The off-diagonal
|
||
> is still reachable and is the reason `rigor` overrides both ways: `rigor: full`
|
||
> + an explicit `docs.density: terse` gives "all sections but each is compact" —
|
||
> the "comprehensive but tight" mode, which neither knob expresses alone.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Per-section output style |
|
||
|-------|--------------------------|
|
||
| `terse` | Bullet points. 2–5 lines per section. Skip rationale and narrative framing. Skip preambles like "In this game..." Just facts needed to implement. |
|
||
| `balanced` | Paragraphs with light rationale. Examples where helpful. Current default behavior. |
|
||
| `thorough` | Full prose. Rationale for every decision. Examples, alternatives considered, design history. |
|
||
|
||
---
|
||
|
||
### Combination matrix with workflow
|
||
|
||
| | docs.density: terse | balanced | thorough |
|
||
|---|---|---|---|
|
||
| **workflow: minimal** | Game brief in bullets | Game brief in prose | Game brief + rationale |
|
||
| **workflow: standard** | 5 sections, bullets | 5 sections, paragraphs *(default)* | 5 sections + examples |
|
||
| **workflow: full** | 8 sections, bullets *(comprehensive but compact)* | 8 sections, paragraphs *(current full)* | 8 sections + rationale + examples |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | terse | balanced | thorough |
|
||
|-------|-------|----------|----------|
|
||
| **design-system** | Each GDD section is 2–5 bullets. Skip Player Fantasy preambles. | Paragraphs with key decisions explained. | Full prose, decision history, alternatives considered. |
|
||
| **art-bible** | Each art bible section is a bulleted list of constraints + references. | Paragraphs explaining each visual choice. | Full prose including style explorations, references, rationale per choice. |
|
||
| **create-architecture** | Layer diagrams + decision bullets. No essays. | Diagrams + paragraph explanations of layer choices. | Full prose with rationale, trade-offs, alternatives considered per layer. |
|
||
| **ux-design** | Wireframe descriptions + interaction bullets. | Wireframes + paragraph descriptions of flows. | Full prose including user research summaries, alternative flow considerations. |
|
||
| **map-systems** | One-line system descriptions. | Brief paragraph per system + dependency notes. | Full system-by-system rationale + relationship analysis. |
|
||
| **brainstorm** | Pillar bullets + concept bullets. | Pillars + concept with brief rationale. | Pillars + concept + extensive rationale + alternatives. |
|
||
|
||
---
|
||
|
||
## testing.framework
|
||
|
||
**Controls:** Which test framework the project uses — drives test-runner commands and per-engine assumptions in CI
|
||
**Values:** engine-specific (see table)
|
||
**Default:** auto-populated by `/setup-engine` based on engine choice
|
||
**Set by:** `/setup-engine`, `/settings`
|
||
**Read by:** `/test-helpers` — the only skill that references it. `/qa-plan`, `/dev-story`, `/regression-suite`, `/test-setup` and `/smoke-check` do **not** name the key, despite being plausible readers.
|
||
*(Derived by grep. A helper-based read such as `session_state_enabled()` would not show up, so treat this list as the verified floor, not a ceiling.)*
|
||
|
||
**Priority chain:** `testing.framework` in `project.yaml` → engine default
|
||
|
||
> **Migrated from `technical-preferences.md`.**
|
||
|
||
---
|
||
|
||
### Engine defaults
|
||
|
||
| Engine | Default test framework | Alternatives |
|
||
|--------|------------------------|--------------|
|
||
| Godot | `gdunit4` | `godot-test`, `WAT` |
|
||
| Unity | `unity-test-framework` | `nunit`, custom |
|
||
| Unreal | `unreal-automation` | Google Test, custom |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | How `testing.framework` is used |
|
||
|-------|--------------------------------|
|
||
| **qa-plan** | Test plan tailored to framework's idioms (assertion style, fixture pattern, parameterized tests) |
|
||
| **dev-story** | Test framework name passed to programmer subagent in implementation brief |
|
||
| **regression-suite** | Test file naming and discovery patterns match framework conventions |
|
||
| **test-setup** | Scaffolds the right test runner config (e.g. `gdunit4_runner.gd` for Godot vs Unity Test Framework Asset) |
|
||
| **smoke-check** | Invokes framework-appropriate test runner |
|
||
|
||
---
|
||
|
||
## testing.strict
|
||
|
||
**Controls:** Whether failing or missing test evidence blocks a story from
|
||
closing, or produces a warning and lets work continue — per test type
|
||
**Values:** map of `{logic, integration, visual, ui, config}` → `true | false`
|
||
**Default:** `{logic: true, integration: true, visual: true, ui: true, config: false}`
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** `story-done`, `story-readiness`, `gate-check`, `smoke-check`, `dev-story`
|
||
|
||
> **Per-type, not a single bool.** A global `testing.strict: true|false` forces
|
||
> all-or-nothing: either all test failures block or none do. Per-type matches how
|
||
> most teams actually work — strict logic and visual gates, an advisory smoke check.
|
||
|
||
> **Composes with `qa.level`:** `qa.level` controls whether evidence is REQUIRED.
|
||
> `testing.strict` controls whether failures BLOCK when evidence exists. If
|
||
> `qa.level: minimal`, the strict map is effectively ignored (no evidence required
|
||
> means nothing to be strict about).
|
||
|
||
---
|
||
|
||
### Value intent per type
|
||
|
||
| Type | `true` | `false` |
|
||
|------|--------|---------|
|
||
| `logic` (formulas, AI, state machines) | Unit test failures BLOCK — story cannot close | Failures WARN — story can close with warning |
|
||
| `integration` (multi-system) | Integration test failures BLOCK | Failures WARN |
|
||
| `visual` (animation, VFX, feel) | Missing/failing screenshot evidence BLOCKS (default) | Advisory only — story can close |
|
||
| `ui` (menus, HUD, screens) | Missing screenshot of the screen BLOCKS (default) | Advisory only — story can close |
|
||
| `config` (balance tuning) | Failing smoke check BLOCKS | Advisory only — story can close (default) |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | strict.[type]: true | strict.[type]: false |
|
||
|-------|---------------------|----------------------|
|
||
| **story-done** | Story of that type cannot close on test/evidence failure | Story can close; warning logged in story file |
|
||
| **story-readiness** | Validates test requirements exist before implementation — blocks if absent | Validates but does not block — surfaces as warnings |
|
||
| **gate-check** | CI failures of that type block phase transition | CI failures of that type surfaced as concerns, not blockers |
|
||
| **smoke-check** | Failing smoke (config strict) blocks QA handoff | Failing smoke flagged but handoff proceeds |
|
||
| **dev-story** | References test requirements — flags story as unverifiable if absent | References test requirements — advisory only |
|
||
|
||
> **Unset-key resolution.** Each skill reads `testing.strict.<type>`; if absent
|
||
> it reads `testing.strict` as a plain boolean (legacy form); if still absent it
|
||
> falls back to a hardcoded default. For `story-done`, `story-readiness`,
|
||
> `gate-check`, and `dev-story` the hardcoded default is the per-type default map
|
||
> above (logic/integration/visual/ui strict, config advisory). **`smoke-check` is
|
||
> the exception**: it is a build-health gate, so an unset `testing.strict.config`
|
||
> defaults to *strict* (a FAIL blocks QA hand-off) — preserving its v1.0 behavior.
|
||
> Only an explicit `testing.strict.config: false` makes a failing smoke advisory.
|
||
|
||
---
|
||
|
||
## qa.level
|
||
|
||
**Controls:** What test evidence is required to mark stories Done
|
||
**Values:** `minimal` | `standard` | `full`
|
||
**Default:** *none* — supplied by `modes.rigor` (`standard` yields `standard`)
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** `/story-done`, `/story-readiness`, `/dev-story`, `/smoke-check`, `/gate-check`, `/qa-plan`, `/regression-suite`
|
||
|
||
**Priority chain:** `qa.level` in `project.yaml` → `modes.rigor` expansion → *(no hardcoded default)*
|
||
|
||
> **Different axis from `testing.strict`.** `qa.level` = what evidence is required.
|
||
> `testing.strict` = do failures block. A user wanting "minimal QA" sets
|
||
> `qa.level: minimal` and the strict map becomes effectively a no-op.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Aspect | minimal | standard | full |
|
||
|--------|---------|----------|------|
|
||
| Logic stories | No test required, no gap flagged | Unit test required (strict.logic controls block) | Unit test + coverage minimum |
|
||
| Integration stories | No test required | Integration test or playtest doc required | Same + regression coverage |
|
||
| Visual stories | No evidence required | Screenshot required (strict.visual controls block) | Screenshot + lead sign-off required |
|
||
| UI stories | No evidence required | Screenshot of each screen required (strict.ui controls block) | Screenshot + walkthrough doc + interaction test |
|
||
| Config/Data stories | No evidence required | Smoke check advisory | Smoke check required |
|
||
| /story-done test gate | Acceptance criteria only | Enforced per story type | Enforced for every story type |
|
||
| /gate-check phase enforcement | No test gates | Logic + integration must pass | Full coverage + regression suite |
|
||
| /dev-story routing prompt | No "Test required: ..." line | Per-type test requirement included | Per-type + coverage target included |
|
||
| Regression suite required by | Never | Polish stage | Production stage |
|
||
| Best for | Jam games, throwaway prototypes, fast iteration | Most projects | Commercial, console cert, learning, paranoid teams |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | minimal | standard | full |
|
||
|-------|---------|----------|------|
|
||
| **story-done** | Acceptance criteria check only — no evidence required | Per-type evidence required; strictness from `testing.strict` | All types require evidence; strictness from `testing.strict` |
|
||
| **story-readiness** | No test requirement validated | Test requirement per story type validated | Test requirement + coverage target validated |
|
||
| **dev-story** | Routing prompt has no "Test required" line | Per-type test requirement passed to programmer agent | Coverage target passed to programmer agent |
|
||
| **smoke-check** | Optional | Required before phase transition | Required before every commit |
|
||
| **gate-check** | No test enforcement at phase transitions | Logic + integration tests must pass | Full coverage check + regression suite |
|
||
| **qa-plan** | Skipped entirely or minimal smoke plan | Full plan per story type | Full plan + coverage targets per system |
|
||
| **regression-suite** | Not generated | Generated at Polish stage entry | Generated at Production stage entry |
|
||
|
||
---
|
||
|
||
## qa.coverage_minimum
|
||
|
||
**Controls:** Minimum code coverage percentage enforced at `qa.level: full`
|
||
**Values:** integer 0–100, or `null` for unset
|
||
**Default:** `null`
|
||
**Set by:** `/settings`
|
||
**Read by:** `/gate-check` only. `/story-done` does not reference the key, and no CI runner reads it.
|
||
*(Derived by grep. A helper-based read such as `session_state_enabled()` would not show up, so treat this list as the verified floor, not a ceiling.)*
|
||
|
||
**Priority chain:** `qa.coverage_minimum` in `project.yaml` → no enforcement if `null`
|
||
|
||
> **Only meaningful at `qa.level: full`.** Ignored at minimal and standard. A
|
||
> non-null value at standard or minimal level emits a warning at session-start:
|
||
> *"coverage_minimum is set but qa.level is not full — value will not be enforced."*
|
||
|
||
> **Implementation is engine-specific.** Coverage measurement is different per engine:
|
||
> - Godot: gdunit4 coverage report (markdown export)
|
||
> - Unity: Unity Test Framework coverage (xml export)
|
||
> - Unreal: gcov-style coverage from clang flags
|
||
> CCGS does not unify these — gate-check reads the engine-appropriate report.
|
||
|
||
---
|
||
|
||
## strict_gate_checks
|
||
|
||
> ### RESERVED - NOT IMPLEMENTED
|
||
>
|
||
> **No skill or hook reads this setting. Setting it has no effect.** Everything
|
||
> below describes the intended design, not current behaviour.
|
||
>
|
||
> The value is checked for valid spelling when you set it, and then ignored.
|
||
|
||
**Controls:** Whether phase gate failures block stage transition or just warn
|
||
**Values:** `true` | `false`
|
||
**Default:** `true`
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** `/gate-check`
|
||
|
||
**Priority chain:** `strict_gate_checks` in `project.yaml` → hardcoded default of `true`
|
||
|
||
> **Different from `review_mode: solo`.** `review_mode: solo` skips the gate
|
||
> *entirely* — directors don't even run. `strict_gate_checks: false` runs the
|
||
> gate normally but treats the verdict as advisory.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Behavior |
|
||
|-------|----------|
|
||
| `true` | Default. FAIL or BLOCKING-CONCERNS verdict stops the stage transition. `project.stage` is not advanced. User must address findings and re-run gate. |
|
||
| `false` | All gate verdicts are advisory. `/gate-check` still runs and reports findings. `project.stage` advances on user confirmation regardless of verdict. |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | true | false |
|
||
|-------|------|-------|
|
||
| **gate-check** | FAIL verdict stops execution before writing new stage; CONCERNS verdict prompts user but defaults to "stay at current stage." | All verdicts surfaced as informational; user is asked "advance anyway?" with default Yes. |
|
||
|
||
---
|
||
|
||
## team.size
|
||
|
||
**Controls:** Which agents are active by default — solo devs shouldn't get studio-grade gating on every change
|
||
**Values:** `individual` | `small` | `studio`
|
||
**Default:** *none* — supplied by `modes.rigor` (`minimal`/`standard` yield `individual`, `full` yields `studio`)
|
||
**Set by:** `/start` (via `modes.rigor`), `/settings`
|
||
**Read by:** All `team-*` skills, `/gate-check`, all skills that spawn agents via `Agent`
|
||
|
||
**Priority chain:** `team.size` in `project.local.yaml` → `project.yaml` → the `modes.rigor` expansion (`full` → `studio`, else `individual`) → no terminal default. Locally overridable — it is a personal-experience knob, not an on-disk artifact.
|
||
|
||
> **`individual` at `minimal`/`standard`, `studio` at `full`.** CCGS's audience is
|
||
> overwhelmingly solo indie developers, so the two lighter rigor tiers resolve
|
||
> `team.size` to `individual` — a `standard` (default) project gets one active agent
|
||
> per role, not 15 (directors and leads included). Only `rigor: full` opts into the
|
||
> full `studio` roster; a smaller team on a big project sets `team.size: small`
|
||
> explicitly, which wins over the rigor-derived value.
|
||
|
||
> **Different axis from `workflow`.** `workflow` controls *what docs are required.*
|
||
> `team.size` controls *which agents exist to make them.* A solo dev on
|
||
> `workflow: full` still doesn't need all 49 agents — they need the same coverage
|
||
> from a smaller active set.
|
||
|
||
---
|
||
|
||
### Active agent set per value
|
||
|
||
| Value | Active set | Notes |
|
||
|-------|-----------|-------|
|
||
| `individual` | Core 8: `producer`, `game-designer`, `gameplay-programmer`, engine-specialist (engine-driven), `technical-artist`, `sound-designer`, `qa-tester`, `writer`. **Default.** | Directors and lead-* run only on explicit invocation (e.g. via `/architecture-decision`). Specialists outside the core 8 routed through their nearest core agent. |
|
||
| `small` | Core 15: directors (CD, TD, PR) + leads (LP, AD, QL, ND) + game-designer + systems-designer + engine-specialist + technical-artist + sound-designer + qa-tester + ux-designer + writer | `team-*` skills run their full pipeline. Optional specialists added per `review_mode`. |
|
||
| `studio` | All 49 agents available. Engine sub-specialists (e.g. `unity-dots-specialist` separate from `unity-specialist`) routed when relevant. Adversarial review patterns active. | Commercial titles, learning the full org chart, large teams with parallel work. |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | individual | small | studio |
|
||
|-------|------|-------|--------|
|
||
| **team-combat** | Single agent (gameplay-programmer) runs the pipeline; ai-programmer escalated only if AI work flagged | Default pipeline as documented | Default + engine sub-specialists + adversarial review pass |
|
||
| **team-narrative** | writer only; narrative-director invoked only on explicit pillar conflict | narrative-director + writer + (per review_mode) localization-lead, world-builder | All narrative agents active + per-system writer reviews |
|
||
| **team-ui** | ui-programmer + ux-designer | + accessibility-specialist + art-director | + engine UI specialist + adversarial review pass |
|
||
| **team-audio** | sound-designer only | + audio-director + technical-artist | + localization-lead + per-system audio reviewers |
|
||
| **team-level** | level-designer + gameplay-programmer | + systems-designer + art-director | + narrative-director + world-builder + accessibility-specialist |
|
||
| **team-qa** | qa-tester only; qa-lead invoked at phase gates only | qa-lead + qa-tester pipeline | qa-lead + per-story qa-tester spawn + sign-off |
|
||
| **team-release** | release-manager only | + producer + devops-engineer + qa-lead | + security-engineer + analytics-engineer + localization-lead |
|
||
| **gate-check** | Panel width is `modes.workflow`'s axis, not this one (gates always run) — `team.size` affects only specialist depth within each director's review | Same as individual for directors; specialists within directors' reviews use small set | Same plus engine sub-specialists |
|
||
| **architecture-decision** | TD + lead-programmer; engine-specialist | TD + LP + engine-specialist + engine sub-specialist if applicable | All of small + adversarial review by alternate engine-specialist |
|
||
|
||
---
|
||
|
||
### Special cases
|
||
|
||
- The 3 directors (CD, TD, PR) are present in ALL team sizes — phase gates require them. The setting affects *who else* shows up.
|
||
- `individual` does not disable agents — it just changes which are active by default. Any agent can still be invoked by name.
|
||
- When `team.size: individual` and a non-core agent is needed (e.g. `network-programmer` for a multiplayer story), the skill emits an informational note and routes through the nearest active core agent.
|
||
|
||
---
|
||
|
||
## platform.multiplayer
|
||
|
||
**Controls:** Whether the project includes real-time online multiplayer — determines
|
||
which specialists are routed and which architecture sections are required
|
||
**Values:** `true` | `false`
|
||
**Default:** `false`
|
||
**Set by:** `/setup-engine`, `/settings`
|
||
**Read by:** `dev-story`, `create-architecture`, `security-audit`, `team-release`, `gate-check`
|
||
|
||
**Priority chain:** `platform.multiplayer` in `project.yaml` → hardcoded default of `false`
|
||
|
||
> **Distinct from `platform.online`.** `multiplayer` is *real-time multiplayer
|
||
> specifically* (network specialist, netcode review, replication architecture).
|
||
> `platform.online` covers everything else online (cloud saves, leaderboards,
|
||
> telemetry). See next section.
|
||
|
||
> **This is a project attribute, not a mode.** It describes what the game is,
|
||
> not how the pipeline operates. It lives in `platform` alongside `targets`,
|
||
> `primary_input`, and `gamepad_support` — not in `modes`.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Meaning |
|
||
|-------|---------|
|
||
| `true` | Game has real-time online multiplayer. Network specialist included in routing. Architecture requires networking layer. Security audit includes netcode review. |
|
||
| `false` | No real-time multiplayer. Network specialist excluded from routing. Architecture has no networking section. |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | multiplayer: true | multiplayer: false |
|
||
|-------|------------------|-------------------|
|
||
| **dev-story** | `network-programmer` included in routing table for networking stories | `network-programmer` excluded — networking stories flagged as out of scope |
|
||
| **create-architecture** | Networking layer section required in architecture doc | Networking section omitted entirely |
|
||
| **security-audit** | Includes netcode review — authentication, replication, cheat vectors | Netcode review skipped |
|
||
| **team-release** | `network-programmer` included in release sign-off pipeline | `network-programmer` excluded |
|
||
| **gate-check** | Technical Setup gate checks for network architecture ADR | No network architecture requirement |
|
||
|
||
---
|
||
|
||
## platform.online
|
||
|
||
**Controls:** Whether the project has any online features (leaderboards, cloud saves, telemetry, IAP)
|
||
**Values:** `true` | `false`
|
||
**Default:** `false`
|
||
**Set by:** `/setup-engine`, `/settings`
|
||
**Read by:** `dev-story`, `create-architecture`, `security-audit`, `team-live-ops`, `gate-check`
|
||
|
||
**Priority chain:** `platform.online` in `project.yaml` → hardcoded default of `false`
|
||
|
||
> **Independent of `platform.multiplayer`.** A single-player game with Steam
|
||
> Cloud and leaderboards is `online: true, multiplayer: false`. The two settings
|
||
> have different specialist routing implications.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Meaning |
|
||
|-------|---------|
|
||
| `true` | Project includes online services (cloud saves, leaderboards, achievements, telemetry, IAP, anything calling external APIs at runtime). Analytics-engineer included; live-ops considerations active; security-audit includes data-transit review. |
|
||
| `false` | Project is fully offline. No analytics-engineer routing, no live-ops scope, security audit is local-only. |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | online: true | online: false |
|
||
|-------|--------------|---------------|
|
||
| **create-architecture** | Data layer must include online service integration (cloud save sync, leaderboard auth, telemetry buffering) | Data layer is local storage only |
|
||
| **security-audit** | Includes data-transit review — TLS, save data integrity, leaderboard tampering | Local-only review (save file tampering, save data privacy) |
|
||
| **dev-story** | `analytics-engineer` routed for telemetry stories | analytics-engineer not routed |
|
||
| **team-live-ops** | Skill is available (live-ops-designer routes meaningfully) | Skill emits "no online features — live ops scope is empty" |
|
||
| **gate-check** | Technical Setup gate checks for online architecture decisions in critical ADRs | No online ADR requirement |
|
||
|
||
---
|
||
|
||
## platform.cert_tier
|
||
|
||
> ### WIRED — this setting is live
|
||
>
|
||
> `/launch-checklist` and `/release-checklist` both resolve it and emit
|
||
> console/mobile certification items only for the platforms it names, asking
|
||
> which are in scope when it is unset.
|
||
|
||
**Controls:** Certification target — scopes what `/launch-checklist` asks for
|
||
**Values:** `none` | `itch` | `steam` | `console`
|
||
**Default:** `none`
|
||
**Set by:** `/setup-engine`, `/settings`
|
||
**Read by:** `/launch-checklist`, `/release-checklist`
|
||
|
||
**Priority chain:** `platform.cert_tier` in `project.yaml` → hardcoded default of `none`
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Required compliance | Best for |
|
||
|-------|---------------------|----------|
|
||
| `none` | No certification — internal release, alpha, jam game | Default |
|
||
| `itch` | itch.io upload requirements (build size, page setup, age tags) | Indie web/desktop releases |
|
||
| `steam` | Steamworks integration, store page, achievements, depot build, system requirements, common content rules | Commercial PC releases |
|
||
| `console` | Platform certification (PlayStation/Xbox/Switch) — heavy compliance: TRC/XR/Lotcheck, save data rules, controller mapping rules, age rating boards | Console releases |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | none | itch | steam | console |
|
||
|-------|------|------|-------|---------|
|
||
| **launch-checklist** | Internal launch only — no external requirements | + itch.io page setup, butler upload, build size | + Steamworks integration, store page, achievements depot, common content checks | + Platform-specific TRC, certification submission, console save format compliance |
|
||
| **release-checklist** | Smoke pass + version bump only | + itch.io page live, build uploaded to butler | + Steam store page live, depot pushed, achievements live | + Platform submission accepted, age rating boards cleared |
|
||
| **/pre-cert** (future) | Not applicable | Lightweight readiness check | Steam common content audit | Full TRC compliance audit |
|
||
|
||
---
|
||
|
||
## accessibility.target
|
||
|
||
> ### RESERVED - NOT IMPLEMENTED
|
||
>
|
||
> **No skill or hook reads this setting. Setting it has no effect.** Everything
|
||
> below describes the intended design, not current behaviour.
|
||
>
|
||
> The value is checked for valid spelling when you set it, and then ignored.
|
||
> The accessibility-specialist routing and the Polish-stage audit described
|
||
> below **do not happen at any level** — `/team-ui`, `/team-level`,
|
||
> `/team-polish` and `/gate-check` do not read this setting, and `/start`
|
||
> does not ask for it.
|
||
|
||
**Controls:** Accessibility commitment level — routes accessibility specialist and gates audit requirements
|
||
**Values:** `none` | `standard` | `aaa`
|
||
**Default:** `none`
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** `/team-ui`, `/team-level`, `/team-polish`, `/gate-check`
|
||
|
||
**Priority chain:** `accessibility.target` in `project.yaml` → hardcoded default of `none`
|
||
|
||
> **Default is `none`, not `standard`.** Most CCGS users are solo devs and jam-game
|
||
> makers — defaulting to `standard` would auto-spawn the accessibility specialist
|
||
> for projects where it's overhead. `/start` asks the question explicitly so users
|
||
> who care can opt into `standard` or `aaa` consciously.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Required features | Specialist routing |
|
||
|-------|-------------------|--------------------|
|
||
| `none` | None enforced | `accessibility-specialist` not spawned |
|
||
| `standard` | Colorblind-safe palette, subtitles for any voice content, key remapping | `accessibility-specialist` runs in team-ui, team-level |
|
||
| `aaa` | Full Game Accessibility Guidelines: motor, vision, hearing, cognitive categories | `accessibility-specialist` runs in all team-* skills; mandatory audit at Polish stage |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | none | standard | aaa |
|
||
|-------|------|----------|-----|
|
||
| **team-ui** | accessibility-specialist not spawned | accessibility-specialist included for HUD/menu reviews | accessibility-specialist included for every screen + accessibility audit pass |
|
||
| **team-level** | accessibility-specialist not spawned | accessibility-specialist reviews level for colorblind safety and signposting | accessibility-specialist reviews for full mobility/audio/cognitive considerations |
|
||
| **team-polish** | No accessibility pass | Final accessibility pass added | Full accessibility audit required before completion |
|
||
| **gate-check** | No accessibility check at any stage | Polish gate checks for the standard required features | Polish gate requires full Game Accessibility Guidelines compliance audit |
|
||
|
||
---
|
||
|
||
## cadence.sprint_length and cadence.milestone_length
|
||
|
||
> ### RESERVED - NOT IMPLEMENTED
|
||
>
|
||
> **No skill or hook reads this setting. Setting it has no effect.** Everything
|
||
> below describes the intended design, not current behaviour.
|
||
>
|
||
> No reference anywhere outside this file.
|
||
|
||
**Controls:** Default sprint and milestone durations for planning
|
||
**Values:**
|
||
- `sprint_length`: `1w` | `2w` | `3w` | `4w` | `none`
|
||
- `milestone_length`: `4w` | `6w` | `8w` | `12w`
|
||
**Defaults:** `sprint_length: 2w`, `milestone_length: 8w`
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** `/sprint-plan`, `/milestone-review`, `/sprint-status`, future velocity tracking
|
||
|
||
**Priority chain:** `cadence.*` in `project.yaml` → hardcoded defaults
|
||
|
||
> **`none` for `sprint_length`** means continuous-flow / kanban-style — no sprint boundaries.
|
||
> `/sprint-plan` becomes `/work-plan` and is invoked manually as needed. Velocity tracking
|
||
> is per-week rather than per-sprint.
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | What changes |
|
||
|-------|--------------|
|
||
| **sprint-plan** | Capacity calculated as `sprint_length × team.size velocity baseline`. `none` makes the skill emit a continuous-flow plan instead. |
|
||
| **milestone-review** | Milestone window for retrospective scope = `milestone_length`. |
|
||
| **sprint-status** | Burn-down chart x-axis spans `sprint_length`. |
|
||
| **retrospective** | Sprint retro fires at `sprint_length` cadence (or weekly when sprint_length is `none`). |
|
||
|
||
---
|
||
|
||
## performance.target_framerate and performance.frame_budget_ms
|
||
|
||
**Controls:** The frame-rate target and its per-frame millisecond budget
|
||
**Values:** integers (e.g. `60`, `16.67`)
|
||
**Default:** none — unset means no budget was ever committed to
|
||
**Set by:** the user, by hand or via `/settings`
|
||
**Read by:** `/perf-profile`, `/gate-check`
|
||
|
||
## performance.draw_call_limit and performance.memory_ceiling_mb
|
||
|
||
**Controls:** Per-frame draw-call ceiling and total memory ceiling
|
||
**Values:** integers
|
||
**Default:** none — unset means no budget was ever committed to
|
||
**Set by:** the user, by hand or via `/settings`
|
||
**Read by:** `/perf-profile`, `/gate-check`
|
||
|
||
> **Every setting needs its own `## ` heading in this file, not just a table
|
||
> row.** The dead-settings audit derives what it checks from those headings, so
|
||
> a setting mentioned only inside a table is invisible to it — it can neither be
|
||
> reported DEAD if it loses its reader, nor caught if it gains one. A setting
|
||
> outside the audit's field of view is exactly how a documented-but-dead entry,
|
||
> or a working-but-listed-as-dead one, survives unnoticed.
|
||
>
|
||
> **Unset is not zero and not a default.** A budget nobody set is not a budget
|
||
> that was met — `/perf-profile` must report `NOT ASSESSED` for a metric with no
|
||
> committed target rather than measuring against a placeholder. That exact
|
||
> failure (">99% headroom against a 16.67ms budget", from zero profiler data)
|
||
> is one of the two instances that motivated `.claude/rules/skill-authoring.md`.
|
||
|
||
## performance.enforce
|
||
|
||
**Controls:** Whether performance budget violations warn or block
|
||
**Values:** `warn` | `block` | `off`
|
||
**Default:** `warn`
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** `/perf-profile`, `/gate-check`, CI runner
|
||
|
||
**Priority chain:** `performance.enforce` in `project.local.yaml` → `project.yaml` → hardcoded default of `warn`, resolved by `resolve_config --keys performance.enforce`
|
||
|
||
> **Read it from the resolved block, never from `project.yaml` directly.** The key is on the `/settings --local` whitelist. `/perf-profile` Phase 0 and `/gate-check` Section 3 are the two readers the table above promises — a key that is enum-validated, accepted and displayed while nothing reads it is exactly the failure this warning guards against.
|
||
|
||
> **Mirrors the `testing.strict` pattern.** Defines what happens when a budget
|
||
> defined in `performance.target_framerate`, `frame_budget_ms`, `draw_call_limit`,
|
||
> or `memory_ceiling_mb` is exceeded.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Behavior |
|
||
|-------|----------|
|
||
| `warn` | Default. Profile runs flag violations as findings. CI logs them but doesn't fail. `/gate-check` surfaces them as concerns, not blockers. |
|
||
| `block` | Profile failures block CI. `/gate-check` treats violations as FAIL verdict (Polish stage onward). |
|
||
| `off` | Performance budgets are informational only — no profile runs gated, no findings surfaced. |
|
||
|
||
---
|
||
|
||
## project.stage
|
||
|
||
**Controls:** The current development phase — determines which gate-check
|
||
validates and what artifacts are expected to exist
|
||
**Values:** `Concept` | `Systems Design` | `Technical Setup` | `Pre-Production` | `Production` | `Polish` | `Release`
|
||
**Default:** `Concept`
|
||
**Set by:** `/gate-check` on PASS verdict only — never set manually
|
||
**Read by:** `gate-check`, `project-stage-detect`, `help`, `sprint-status`, `day-one-patch`
|
||
|
||
> **Stage count:** This document uses the
|
||
> 7-stage reality implemented by gate-check:
|
||
> `Concept | Systems Design | Technical Setup | Pre-Production | Production | Polish | Release`
|
||
|
||
> **This is a project attribute, not a mode.** It records where the project is
|
||
> in its lifecycle. Only `/gate-check` writes it — and only on a PASS verdict
|
||
> with user confirmation. Never write it manually mid-session except to correct
|
||
> an incorrect auto-detect.
|
||
|
||
> **Legacy fallback + dual-write.** Stage is read from `project.stage` in
|
||
> `project.yaml` first, then legacy `production/stage.txt`, then artifact
|
||
> auto-detection. When `/gate-check` advances the stage it dual-writes BOTH
|
||
> `project.yaml` and `production/stage.txt`, so hooks that have not migrated
|
||
> still resolve correctly. `/start` also dual-writes the initial stage. The
|
||
> legacy `.txt` file is retired at `.claude/scripts/migrate-v1-config.sh --finalize`.
|
||
|
||
---
|
||
|
||
### Stage progression and gate requirements
|
||
|
||
Each row is the gate that must be passed to advance FROM that stage.
|
||
|
||
| From stage | Key artifacts required to pass | gate-check writes |
|
||
|------------|-------------------------------|-------------------|
|
||
| **Concept** | `game-concept.md`, design pillars, Visual Identity Anchor | `Systems Design` |
|
||
| **Systems Design** | `systems-index.md`, all MVP GDDs reviewed, cross-GDD consistency check | `Technical Setup` |
|
||
| **Technical Setup** | Engine configured, art bible sections 1–4 (if visual stories exist), 3+ ADRs, architecture doc, control manifest, test framework | `Pre-Production` |
|
||
| **Pre-Production** | Prototype, 3+ playtests, UX specs, epics defined, first sprint plan | `Production` |
|
||
| **Production** | Core mechanics implemented, main path playable, smoke check passes, QA sign-off | `Polish` |
|
||
| **Polish** | All features complete, content complete, localization, no critical bugs | `Release` |
|
||
|
||
Gates adjust per `modes.workflow` — see `modes.workflow` section for what is
|
||
required at `standard` and `minimal` levels.
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | How it uses stage |
|
||
|-------|------------------|
|
||
| **gate-check** | Reads current stage to determine which gate to validate. Writes next stage on PASS. |
|
||
| **project-stage-detect** | Reads `project.stage` first — if set, uses it as authoritative. Falls back to heuristic detection only if absent. |
|
||
| **help** | Uses stage to determine "where are you in the pipeline" and surfaces the correct next steps. |
|
||
| **sprint-status** | Displays current stage in status summary. |
|
||
| **day-one-patch** | Validates that stage is `Release` before proceeding — refuses to run if project is not at release stage. |
|
||
|
||
---
|
||
|
||
## project.kind
|
||
|
||
> ### RESERVED - NOT IMPLEMENTED
|
||
>
|
||
> **No skill or hook reads this setting. Setting it has no effect.** Everything
|
||
> below describes the intended design, not current behaviour.
|
||
>
|
||
> No reference anywhere outside this file.
|
||
|
||
**Controls:** What type of project this is — routes skill subsets
|
||
**Values:** `game` | `tool` | `engine` | `mod` | `library`
|
||
**Default:** `game`
|
||
**Set by:** `/start`, `/setup-engine`
|
||
**Read by:** Many skills (advisory routing — see below)
|
||
|
||
**Priority chain:** `project.kind` in `project.yaml` → hardcoded default of `game`
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Meaning | What's deactivated |
|
||
|-------|---------|-------------------|
|
||
| `game` | Default. Full CCGS framework applies. | Nothing |
|
||
| `tool` | Developer tool, not a game | Skip art bible, narrative, level design, playtesting |
|
||
| `engine` | Custom engine or library underneath games | Skip game-specific concerns entirely (narrative, art, playtest) |
|
||
| `mod` | Mod for an existing game | Skip engine setup; assume parent engine; reduce architecture scope |
|
||
| `library` | Reusable library | Emphasize tests + API design; design docs lighter; no asset pipeline |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | game | tool | engine | mod | library |
|
||
|-------|------|------|--------|-----|---------|
|
||
| **brainstorm** | Full game-concept output | Tool concept output (user, problem, solution) | Engine concept (target use cases, scope) | Mod concept (what changes) | Library concept (API surface, target consumers) |
|
||
| **art-bible** | Required at appropriate workflow level | Skipped | Skipped | Optional (depends on visual scope) | Skipped |
|
||
| **map-systems** | Full game systems decomposition | Tool subsystems | Engine subsystems | Modified-system map | Library module map |
|
||
| **playtest-report** | Required at appropriate stages | Skipped or replaced with user testing | Skipped | Required (compatibility testing) | Skipped or replaced with API usage testing |
|
||
| **setup-engine** | Game engine setup | Skipped or replaced with build tool setup | Self-referential — engine IS the project | Parent engine assumed | Skipped or replaced with library scaffolding |
|
||
|
||
---
|
||
|
||
## engine.name and specialists
|
||
|
||
**Controls:** Which engine-specific specialist agents are routed to for code
|
||
implementation, review, and architecture validation
|
||
**Values:** `Godot` | `Unity` | `Unreal`
|
||
**Default:** `[UNSET]` — must be configured via `/setup-engine`
|
||
**Set by:** `/setup-engine`
|
||
**Read by:** `dev-story`, `code-review`, `architecture-decision`, `create-architecture`, all `team-*` skills
|
||
|
||
> **Currently stored in `technical-preferences.md`**, not `project.yaml`. After
|
||
> YAML expansion, `engine.name` and the specialist routing table move to
|
||
> `project.yaml specialists` block. Skill behavior is unchanged — only the
|
||
> source file changes.
|
||
|
||
> **This is a project attribute, not a mode.** Engine choice drives specialist
|
||
> routing the same way `platform.multiplayer` drives network routing — skills
|
||
> respond to a fact about the project, not a process preference.
|
||
|
||
---
|
||
|
||
### Specialist routing by engine
|
||
|
||
| Engine | Language/code specialist | Shader specialist | UI specialist | Additional specialists |
|
||
|--------|--------------------------|-------------------|---------------|----------------------|
|
||
| **Godot** | `godot-gdscript-specialist` (GDScript) or `godot-csharp-specialist` (C#) — driven by `engine.language` | `godot-shader-specialist` | `godot-specialist` | `godot-gdextension-specialist` |
|
||
| **Unity** | `unity-specialist` | `unity-shader-specialist` | `unity-ui-specialist` | `unity-addressables-specialist`, `unity-dots-specialist` |
|
||
| **Unreal** | `unreal-specialist` | `unreal-specialist` | `ue-umg-specialist` | `ue-gas-specialist`, `ue-blueprint-specialist`, `ue-replication-specialist` |
|
||
| **[UNSET]** | No specialist spawned — warning emitted | No specialist spawned | No specialist spawned | None |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | How engine.name is used |
|
||
|-------|------------------------|
|
||
| **dev-story** | Routes code stories to language specialist. Spawns engine specialist alongside for HIGH engine-risk stories or engine-specific API usage. |
|
||
| **code-review** | Routes review to language, shader, or UI specialist based on file type being reviewed. |
|
||
| **architecture-decision** | Loads `docs/engine-reference/[engine]/VERSION.md` before authoring. Spawns engine specialist to validate ADR for API correctness and post-cutoff compatibility. |
|
||
| **create-architecture** | Includes engine-specific constraints and patterns in architecture doc based on engine choice. |
|
||
| **team-combat / team-ui / team-audio / team-level / team-polish** | All team skills spawn the appropriate engine specialist for implementation phases. |
|
||
|
||
---
|
||
|
||
## commands
|
||
|
||
> **Live since the run-and-observe step.** This block was RESERVED — written by
|
||
> `/setup-engine`, read by nothing — through most of v1.1. `test`, `smoke` and
|
||
> `build` gained readers as the parse-check and smoke gates landed; `run` gained
|
||
> its reader last, when `/dev-story` Phase 6 step 4 started launching the game to
|
||
> look at it. The per-skill table at the bottom is now current behaviour, not
|
||
> intent. `validate-push.sh` was once named as a reader and never was.
|
||
|
||
**Controls:** Explicit shell commands to build, test, run, and smoke-test the project
|
||
**Values:** strings — shell-executable commands
|
||
**Default:** `[UNSET]` — populated by `/setup-engine` with engine-typical defaults
|
||
**Set by:** `/setup-engine`, `/settings`
|
||
**Written by:** `/setup-engine`, `/settings`. **Read by:** `test` — `/dev-story` (Phase 6 parse check), `/smoke-check`, `project-coherence.sh`; `smoke` — `/dev-story`; `build` — `/smoke-check`, `project-coherence.sh`; `run` — `/dev-story` (Phase 6 step 4, the run-and-observe step). `/launch-checklist` and `/regression-suite` name these commands but cannot execute them — their `allowed-tools` has no `Bash`.
|
||
*(Derived by grep. A helper-based read would not show up, so treat this list as the verified floor, not a ceiling.)*
|
||
|
||
**Priority chain:** `commands.*` in `project.yaml` → engine-typical default → no command available
|
||
|
||
> **Why explicit:** Without this block, CCGS has to guess engine-typical conventions
|
||
> for invoking the project. Better to be explicit per-project — covers cases where
|
||
> projects customize their build (e.g., a Godot project using gdunit4 for tests but
|
||
> a custom export script for builds).
|
||
|
||
---
|
||
|
||
### Fields
|
||
|
||
Each command can be a simple string (used on all OSes) or an OS-aware map:
|
||
|
||
**Simple form** (one command, used on every OS):
|
||
```yaml
|
||
commands:
|
||
build: "godot --headless --export-debug '<PRESET>'" # ask; see the note below
|
||
test: "godot --headless --script tests/gdunit4_runner.gd"
|
||
run: "godot --path . --windowed --resolution 1280x720"
|
||
smoke: "godot --headless --quit-after 5"
|
||
```
|
||
|
||
Note that `build` is the one row the simple form suits least: an export preset
|
||
names a *platform*, so a single build string is portable only for a project that
|
||
builds one platform. The other three rows are genuinely OS-independent.
|
||
|
||
**OS-aware form** (different commands per OS):
|
||
```yaml
|
||
commands:
|
||
build:
|
||
default: "godot --headless --export-debug 'Linux/X11'"
|
||
windows: "godot.exe --headless --export-debug 'Windows Desktop'"
|
||
macos: "godot --headless --export-debug 'macOS'"
|
||
test:
|
||
default: "godot --headless --script tests/gdunit4_runner.gd"
|
||
run:
|
||
default: "godot --path . --windowed --resolution 1280x720"
|
||
smoke:
|
||
default: "godot --headless --quit-after 5"
|
||
```
|
||
|
||
**Resolution rule:** if the value is a string, use it as-is on any OS. If the
|
||
value is a map, skills/hooks read the current OS and pick the matching key
|
||
(`linux`, `windows`, `macos`). Fall back to `default` if no OS-specific key
|
||
matches.
|
||
|
||
This solves the Windows/Linux/macOS path-and-binary-name differences without
|
||
breaking the whitelist (commands stays locked to project.yaml — the OS-specific
|
||
keys are inside the locked file, not a local override).
|
||
|
||
| Field | Purpose |
|
||
|-------|---------|
|
||
| `build` | Full project build for CI or release. Used by `/launch-checklist`, CI hooks. |
|
||
| `test` | Run the full test suite. Used by `/smoke-check`, `/regression-suite`, CI hooks. |
|
||
| `run` | Launch the **game** windowed at a fixed resolution — not the editor. Used by `/dev-story` Phase 6 step 4 to observe the feature and retain a screenshot; see `.claude/docs/run-and-observe.md` for the per-engine capture flags that are appended to it. |
|
||
| `smoke` | Minimal "does it boot?" check. Named by `/smoke-check` in its prose. Should complete in < 5 seconds. |
|
||
|
||
---
|
||
|
||
### Engine defaults
|
||
|
||
When `/setup-engine` runs, it populates `commands` based on engine choice — except
|
||
the **build** row, which it must **ask** for. The build artifact is named by a
|
||
project-defined string (a Godot export preset, a Unity build target), and no
|
||
engine reference in this repo can source it. See `/setup-engine` §"The Godot
|
||
`build` row must not hardcode `'Linux/X11'`".
|
||
|
||
| Engine | build | test | run | smoke |
|
||
|--------|-------|------|-----|-------|
|
||
| Godot | `godot --headless --export-debug '<PRESET>'` | `godot --headless --script tests/gdunit4_runner.gd` | `godot --path . --windowed --resolution 1280x720` | `godot --headless --quit-after 5` |
|
||
| Unity | `Unity -batchmode -quit -projectPath . -buildTarget <TARGET>` | `Unity -runTests -projectPath . -testPlatform PlayMode` | `Builds/<Target>/<Game>.exe -screen-width 1280 -screen-height 720 -screen-fullscreen 0` | `Unity -batchmode -quit -projectPath . -executeMethod SmokeCheck.Run` |
|
||
| Unreal | engine-specific (varies by version) | engine-specific | engine-specific | engine-specific |
|
||
|
||
> **`<PRESET>` and `<TARGET>` are placeholders, not values to copy.** A Godot
|
||
> export preset is whatever string the operator typed into `export_presets.cfg`;
|
||
> the shipped defaults are per-platform (`Windows Desktop`, `macOS`, `Web`,
|
||
> `Linux/X11`). Copying a preset name you do not have gives you a build command
|
||
> that fails with `Unknown export preset`; copying one you *do* have, but did not
|
||
> mean, gives you a command that succeeds and builds the wrong platform. The
|
||
> second is the dangerous one. If no presets exist yet — common, since
|
||
> `/setup-engine` usually runs before the project has any — write
|
||
> `[TO BE CONFIGURED]` rather than guessing a name.
|
||
|
||
Users override per-project as needed via `/settings commands.<field>=<value>` or by editing `project.yaml` directly.
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | How `commands` is used |
|
||
|-------|------------------------|
|
||
| **smoke-check** | Invokes `commands.smoke` (or `commands.test` for full pass). Critical path for QA hand-off. |
|
||
| **launch-checklist** | Emits a checklist **item** asking whether the build produces a valid artifact. It does **not** run `commands.build` — its `allowed-tools` has no `Bash`. The verification is a human step. |
|
||
| **validate-push.sh** | Does **not** read `commands.*`. It warns on pushes to protected branches (`develop`/`main`/`master`) and runs no build or smoke command — the block path in it is commented out, so it never fails a push. |
|
||
| **dev-story** | Phase 6 step 2 runs `commands.test` or `commands.smoke` as the parse check. Phase 6 step 4 runs `commands.run` — the windowed game launch — to observe the feature and retain a screenshot (`.claude/docs/run-and-observe.md`). |
|
||
| **regression-suite** | Maps coverage by **globbing test filenames**. It does **not** invoke `commands.test` — its `allowed-tools` has no `Bash`, so coverage here means "a test file exists", never "a test passed". |
|
||
|
||
---
|
||
|
||
## naming
|
||
|
||
**Controls:** Code naming conventions for the project
|
||
**Values:** see field list below
|
||
**Default:** engine-specific (auto-populated by `/setup-engine`)
|
||
**Set by:** `/setup-engine`, `/settings`
|
||
**Read by:** `/adopt`, `/architecture-review`, `/asset-spec`,
|
||
`/create-architecture`, `/create-control-manifest`, `/dev-story`,
|
||
`/vertical-slice` — each reads `naming.*` from `project.yaml` and feeds the
|
||
conventions into a brief, manifest or spec. **NOT by `/code-review` and NOT by
|
||
`validate-commit.sh`**.
|
||
*(Reader list derived by grep, so treat it as the verified floor rather than
|
||
a ceiling — a skill reading the value through a helper would not show up.)*
|
||
|
||
> **These conventions are guidance, not a gate.** They reach your project by
|
||
> being passed into briefs, manifests and specs for whoever writes the code.
|
||
> Nothing checks the result: `/code-review` does not validate files against them
|
||
> and `validate-commit.sh` does not warn on violations — neither contains any
|
||
> naming logic. If you need enforcement, it has to be added.
|
||
>
|
||
> **Known rough edge — asset filenames.** `validate-assets.sh` warns unless files
|
||
> under `assets/` are lowercase-with-underscores, and it takes no config input,
|
||
> while `/asset-spec` specifies asset names from `naming.*`. On Unity, Unreal and
|
||
> Godot-C#, where `/setup-engine` sets `naming.files: PascalCase`, that hook will
|
||
> warn on assets named exactly as `/asset-spec` specified them. The two are
|
||
> measuring different things — `naming.files` describes **source** files by its
|
||
> own examples (`PlayerController.cs`), and no key currently governs asset
|
||
> filenames — so treat the hook's naming warning as advisory on those engines.
|
||
|
||
> **Moved from `technical-preferences.md`**, which is being deleted. Naming
|
||
> conventions are project-level facts shared by everyone on the project, so they
|
||
> belong in `project.yaml` alongside the rest of your structured config.
|
||
|
||
---
|
||
|
||
### Fields
|
||
|
||
| Field | Values | Godot default | Unity default | Unreal default |
|
||
|-------|--------|---------------|---------------|----------------|
|
||
| `classes` | `PascalCase` \| `snake_case` \| `camelCase` | PascalCase | PascalCase | PascalCase |
|
||
| `variables` | `snake_case` \| `camelCase` | snake_case | camelCase | camelCase |
|
||
| `constants` | `SCREAMING_SNAKE` \| `PascalCase` | SCREAMING_SNAKE | SCREAMING_SNAKE | SCREAMING_SNAKE |
|
||
| `signals` (Godot) / `events` (Unity, Unreal) | `past_tense` \| `on_event_name` | past_tense | on_event_name | OnEventName |
|
||
| `files` | `snake_case` \| `PascalCase` \| `kebab-case` | snake_case | PascalCase | PascalCase |
|
||
| `scenes` / `prefabs` | `snake_case` \| `PascalCase` | snake_case | PascalCase | PascalCase |
|
||
|
||
> **`signals` vs `events`:** Godot uses signals natively; Unity uses C# events
|
||
> or UnityEvents; Unreal uses delegates and dynamic multicast. The field stays
|
||
> named `signals` in project.yaml for consistency across engines — interpret as
|
||
> "event-like callbacks" regardless of engine.
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | How naming is used |
|
||
|-------|--------------------|
|
||
| **dev-story** | Passes the naming conventions to the programmer subagent as part of the implementation context |
|
||
| **create-control-manifest** | Emits the conventions as manifest rows (classes, variables, signals/events, files, constants) |
|
||
| **asset-spec** | Specifies asset naming per the configured convention |
|
||
| **create-architecture** / **architecture-review** | Read as project config alongside `performance.*` |
|
||
| **vertical-slice** / **adopt** | Read as project config; `/adopt` audits conformance at MEDIUM severity |
|
||
|
||
No skill or hook validates code *against* these conventions — see the note above.
|
||
|
||
---
|
||
|
||
## features.session_state
|
||
|
||
> ⚠️ **`active.yaml` does not exist and nothing writes it — anywhere in this
|
||
> document.** It is deferred design. What ships is
|
||
> `production/session-state/**active.md**`, whose `<!-- CHECKPOINT -->` region
|
||
> `session-start.sh` and `pre-compact.sh` both read, and whose
|
||
> `<!-- STATUS -->` block `statusline.sh` parses. **Read every `active.yaml` and
|
||
> `status:` mention in this file — above and below — as the deferred design, and
|
||
> substitute `active.md` (and its STATUS block).** This scope note is
|
||
> document-wide on purpose: the equivalent warning under *Status line behavior*
|
||
> scoped itself to mentions "below", which left this section's own Controls line
|
||
> and Hook behavior table describing a file that does not exist.
|
||
|
||
**Controls:** Whether the harness runs a full session tracking pipeline (hooks,
|
||
log files, `active.yaml` checkpoint — see the scope note above) or relies on
|
||
skeleton-first output files for recovery
|
||
**Values:** `off` | `on`
|
||
**Default:** `on`
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** All 7 session-lifecycle hooks; `statusline.sh`; any skill that writes
|
||
to `production/session-state/`
|
||
|
||
> **This is the recommended setting for most users.** The session state pipeline
|
||
> was built to solve mid-task context loss during long conversations, but the
|
||
> problem is better solved by long-form skills writing self-describing skeleton
|
||
> files upfront. `session_state: on` is an opt-in for teams or power users who
|
||
> want explicit tracking across many files over many days.
|
||
|
||
> **Priority chain:** `features.session_state` in `project.local.yaml` →
|
||
> `project.yaml` → hardcoded default of **`on`**. Hooks read it via
|
||
> `session_state_enabled()` in `yaml-helper.sh` and exit early when `off`.
|
||
> Skills check it before writing to `production/session-state/`.
|
||
|
||
> **The default is `on`, deliberately.** `.claude/docs/context-management.md`
|
||
> tells you to rely on `production/session-state/active.md` as your
|
||
> crash-recovery checkpoint, so defaulting this off would quietly take away
|
||
> recovery, the session archive and the subagent tally. The ~2–5k tokens per
|
||
> session are an explicit opt-out (`/settings features.session_state=off`),
|
||
> never a silent default.
|
||
|
||
> **`session-start.sh` is gated per-block, not at the top.** Its sprint,
|
||
> milestone and git context is not part of the session-state pipeline; only the
|
||
> `active.md` recovery preview is gated. Its check also fails OPEN — that hook
|
||
> sources `yaml-helper.sh` conditionally, and an undefined function is falsey,
|
||
> which would suppress the recovery checkpoint invisibly.
|
||
|
||
---
|
||
|
||
### Value intent
|
||
|
||
| Value | Intent |
|
||
|-------|--------|
|
||
| `off` | Recovery via skeleton-first output files. Long-form skills write a complete skeleton (all section headers, empty bodies) before starting. If context clears or compacts, the agent reads the skeleton + relevant docs and resumes. No hooks, no logs, no separate state file. ~2,000–5,000 tokens saved per session. |
|
||
| `on` | Full session tracking. `active.yaml` checkpoint, session-stop archival, compaction log, agent audit log, and STATUS breadcrumb all active. Adds ~2,000–5,000 tokens per session-start and ~1,000–6,000 per compaction event. |
|
||
|
||
---
|
||
|
||
### Hook behavior
|
||
|
||
> **Implementation note:** The feature flag check lives inside each hook script,
|
||
> not at the harness level. Every session-state-aware hook reads
|
||
> `features.session_state` from `project.yaml` at its top (via Python fallback
|
||
> chain) and exits silently with no output if the value is `off`. This ensures
|
||
> the harness always fires the hook — the hook decides whether to act.
|
||
|
||
| Hook | session_state: off | session_state: on |
|
||
|------|--------------------|-------------------|
|
||
| **session-start.sh** | Runs normally (git/sprint context) — skips active.yaml preview block | Runs fully including active.yaml preview |
|
||
| **detect-gaps.sh** | Runs unchanged — gap detection is independent of session state | Runs unchanged |
|
||
| **pre-compact.sh** | Emits: "Read skeleton files and relevant docs to resume" — no active.yaml dump, no WIP scan, no compaction-log append | Full dump: active.yaml content + git diff + WIP scan + compaction-log append |
|
||
| **post-compact.sh** | No-op — exits silently | Runs: reminds agent to re-read active.yaml |
|
||
| **session-stop.sh** | No-op — exits silently | Archives active.yaml to session-log, appends commits and diffs |
|
||
| **log-agent.sh** | No-op — exits silently | Appends to agent-audit.log |
|
||
| **log-agent-stop.sh** | No-op — exits silently | Appends to agent-audit.log |
|
||
|
||
---
|
||
|
||
### File existence by mode
|
||
|
||
| File | session_state: off | session_state: on |
|
||
|------|--------------------|-------------------|
|
||
| `production/session-state/active.yaml` | Not created | Written by skills, read by hooks and status line |
|
||
| `production/session-logs/session-log.md` | Not written | Append-only archive of each session's active.yaml |
|
||
| `production/session-logs/compaction-log.txt` | Not written | Append-only timestamp log of compaction events |
|
||
| `production/session-logs/agent-audit.log` | Not written | Append-only log of agent spawn/complete events |
|
||
|
||
---
|
||
|
||
### Skeleton-first pattern (session_state: off recovery mechanism)
|
||
|
||
Long-form skills must write a skeleton file as their first action — before any
|
||
section discussion begins. The skeleton contains all section headers with empty
|
||
bodies and a `<!-- STATUS: incomplete -->` marker per section.
|
||
|
||
```markdown
|
||
# Combat System — GDD
|
||
|
||
## Overview
|
||
<!-- STATUS: incomplete -->
|
||
|
||
## Player Fantasy
|
||
<!-- STATUS: incomplete -->
|
||
|
||
## Detailed Rules
|
||
<!-- STATUS: incomplete -->
|
||
...
|
||
```
|
||
|
||
As each section is approved and written, the marker changes to `<!-- STATUS: done -->`.
|
||
On recovery (after /clear or compaction), the agent reads the skeleton, identifies
|
||
which sections are `done` vs `incomplete`, reads relevant ADRs and the systems index,
|
||
and resumes at the first `incomplete` section. No active.yaml needed.
|
||
|
||
**Skills required to implement skeleton-first:**
|
||
|
||
| Skill | Output file | Skeleton written when |
|
||
|-------|-------------|----------------------|
|
||
| **design-system** | `design/gdd/[system].md` | Before Phase 1 (section discussion) |
|
||
| **art-bible** | `design/art/art-bible.md` | Before section 1 discussion |
|
||
| **create-architecture** | `docs/architecture/architecture.md` | Before layer discussion |
|
||
| **ux-design** | `design/ux/[screen].md` | Before screen discussion |
|
||
| **create-stories** | `production/epics/[epic-slug]/story-NNN-[slug].md` | Before story authoring loop |
|
||
| **create-epics** | `production/epics/[epic-slug]/EPIC.md` | Before epic authoring loop |
|
||
| **map-systems** | `design/gdd/systems-index.md` | Before system enumeration |
|
||
| **brainstorm** | `design/gdd/game-concept.md` (`standard`/`full`) · `design/game-brief.md` (`minimal`) | Before concept discussion |
|
||
|
||
> **Note on agents:** `world-builder` and `narrative-director` are agents, not
|
||
> invocable skills — they do not have SKILL.md files. Long-form output from these
|
||
> agents is produced via the skills above (design-system, art-bible, etc.) which
|
||
> are responsible for skeleton-first enforcement.
|
||
|
||
---
|
||
|
||
### Status line behavior
|
||
|
||
> ⚠️ **The table below describes POST-YAML-EXPANSION behavior, which is NOT
|
||
> IMPLEMENTED.** `active.yaml` does not exist and nothing writes it. What ships
|
||
> today: `statusline.sh` parses the `<!-- STATUS --> ... <!-- /STATUS -->`
|
||
> markdown comment block inside `production/session-state/active.md`. Substitute
|
||
> "the STATUS block in `active.md`" for every `active.yaml` / `status:` mention
|
||
> here. **The same substitution applies document-wide, not just below this
|
||
> point** — see the scope note under `## features.session_state`.
|
||
|
||
> **Stage detection is always independent of session state.** `statusline.sh`
|
||
> auto-detects stage from `project.yaml` `project.stage` or artifact heuristics regardless
|
||
> of `session_state` value — only the breadcrumb is gated.
|
||
|
||
| Feature | session_state: off | session_state: on |
|
||
|---------|--------------------|-------------------|
|
||
| Context % display | Always shown | Always shown |
|
||
| Model display | Always shown | Always shown |
|
||
| Stage display | Always shown (from project.yaml or heuristics) | Always shown (same) |
|
||
| Epic/Feature/Task breadcrumb | Not shown — no active.yaml parsed | Parsed from `status:` block in `active.yaml` |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
Skills interact with session state in two ways: **inference** (reading active.yaml
|
||
to resolve a missing argument) and **extraction** (appending a SESSION EXTRACT
|
||
block after completing work). Both behaviors are gated by `session_state`.
|
||
|
||
#### Inference — skills that read active.yaml to fill in missing arguments
|
||
|
||
When `session_state: off`, these skills cannot infer from active.yaml and must
|
||
receive the argument explicitly. If called without an argument, they should prompt
|
||
the user rather than fail silently.
|
||
|
||
| Skill | What it infers from active.yaml | Fallback when `off` |
|
||
|-------|----------------------------------|---------------------|
|
||
| **dev-story** | Active story path (when no arg given) | Prompt user for story path |
|
||
| **story-done** | In-progress story path (when no arg given) | Prompt user for story path |
|
||
| **team-release** | Target version (when no arg given) | Prompt user for version |
|
||
| **team-qa** | Active sprint (when no arg given) | Prompt user for sprint file |
|
||
| **help** | Current task and STATUS block for context-aware suggestions | Responds without session context — surfaces next steps from sprint/epics only |
|
||
|
||
#### Extraction — skills that append SESSION EXTRACT to active.yaml
|
||
|
||
These skills append a structured block after completing work when `session_state: on`.
|
||
When `off`, they skip this write entirely.
|
||
|
||
| Skill | What it writes to active.yaml |
|
||
|-------|-------------------------------|
|
||
| **dev-story** | Story path, files changed, test written, blockers, next steps |
|
||
| **story-done** | Verdict, story path, tech debt count, next recommended story |
|
||
| **architecture-review** | Verdict, TR coverage counts, new TR-IDs, GDD flags, ADR gaps, report path |
|
||
| **prototype** | Prototype scope, current phase, key decisions |
|
||
| **vertical-slice** | Slice concept, current phase, blocked items |
|
||
| **team-qa** | QA phase comment, blocking issues |
|
||
| **map-systems** | Task record: systems enumerated, current phase |
|
||
|
||
---
|
||
|
||
### Token cost summary
|
||
|
||
| Scenario | session_state: off | session_state: on |
|
||
|----------|--------------------|-------------------|
|
||
| Per session start | ~500 tokens (git/sprint context only) | ~2,000–5,000 tokens (+ active.yaml preview) |
|
||
| Per compaction event | ~200 tokens (reminder only) | ~1,000–6,000 tokens (active.yaml + git diff + WIP scan) |
|
||
| Per session end | 0 | File I/O only (no conversation tokens) |
|
||
| Recovery after /clear | Read skeleton + 2–3 docs (~1,000–3,000 tokens) | Read active.yaml (~200–500 tokens) |
|
||
| Net for 50 sessions, 2 compactions/session | ~60,000 tokens | ~250,000–550,000 tokens |
|
||
|
||
> **Note:** The `off` recovery cost (reading skeleton + docs) is paid only when
|
||
> recovery is actually needed. The `on` session-start cost is paid every session
|
||
> whether recovery is needed or not.
|
||
|
||
---
|
||
|
||
## features.token_budget_warn_at
|
||
|
||
> ### RESERVED - NOT IMPLEMENTED
|
||
>
|
||
> **No skill or hook reads this setting. Setting it has no effect.** Everything
|
||
> below describes the intended design, not current behaviour.
|
||
>
|
||
> The value is checked for valid spelling when you set it, and then ignored.
|
||
> Nothing warns at any threshold.
|
||
|
||
**Controls:** Context usage threshold at which session warnings fire
|
||
**Values:** float between 0.0 and 1.0
|
||
**Default:** `0.7` (warn at 70%)
|
||
**Set by:** `/start`, `/settings`
|
||
**Read by:** `pre-compact.sh`, `session-start.sh`, `statusline.sh`
|
||
|
||
**Priority chain:** `features.token_budget_warn_at` in `project.yaml` → hardcoded default of `0.7`
|
||
|
||
> Surfaces a warning when session context usage exceeds the threshold. Helps
|
||
> cost-conscious users hit `/clear` before runaway sessions. Set to `1.0` to
|
||
> disable.
|
||
|
||
---
|
||
|
||
### Behavior
|
||
|
||
| Threshold | What fires |
|
||
|-----------|-----------|
|
||
| Below `warn_at` | No warning |
|
||
| At or above `warn_at` | `statusline.sh` shows context usage in yellow; next session-start hook emits a one-line note: *"Last session reached [X]% context — consider /clear if continuing work."* |
|
||
| At 90%+ | Yellow becomes red regardless of `warn_at` value |
|
||
|
||
---
|
||
|
||
## schema_version
|
||
|
||
**Controls:** Which version of the project.yaml schema this file conforms to
|
||
**Values:** integer
|
||
**Default:** `1` (for v1.1 of CCGS)
|
||
**Set by:** `/start`, `/adopt`
|
||
**Read by:** All skills and hooks that parse project.yaml (for migration safety)
|
||
|
||
> Lets future CCGS versions detect and migrate old project.yaml files. The
|
||
> migration logic compares `schema_version` in the file against the current
|
||
> CCGS's expected version. If newer, warn. If older, run migrations.
|
||
|
||
---
|
||
|
||
### Migration behavior
|
||
|
||
| project.yaml schema_version | Current CCGS expects | Behavior |
|
||
|----------------------------|---------------------|----------|
|
||
| Matches expected | — | Normal operation |
|
||
| Lower than expected | — | `/adopt` warns and offers migration; skills run with deprecation warnings |
|
||
| Higher than expected | — | All skills warn: "This project.yaml was created by a newer CCGS version. Some settings may be ignored." |
|
||
| Missing | — | Treated as legacy (pre-v1.1); migration prompted on next `/start` or `/adopt` |
|
||
|
||
---
|
||
|
||
## framework
|
||
|
||
**Controls:** Tracks which CCGS version created or last touched this project
|
||
**Values:** `framework.version` (semver string) + `framework.last_upgraded` (ISO date)
|
||
**Default:** auto-populated by `/start` and `/adopt`
|
||
**Set by:** `/start`, `/adopt`
|
||
**Read by:** no skill branches on it — it is file metadata, not a behavioural setting. It appears in `/start`, `/gate-check`, `/brainstorm`, `/settings` and `/setup-engine` as part of the `project.yaml` block they **write or display**, and in `yaml-helper.sh`.
|
||
*(The five skills above were verified to name it; whether each reads it or merely emits it was NOT separated, so this says 'appears in', not 'read by'.)*
|
||
|
||
---
|
||
|
||
### Fields
|
||
|
||
```yaml
|
||
framework:
|
||
version: "1.1.0"
|
||
last_upgraded: "2026-05-14"
|
||
```
|
||
|
||
| Field | Purpose |
|
||
|-------|---------|
|
||
| `version` | The CCGS version that created the project (or last ran `/upgrade`). Used to determine which migrations apply when CCGS itself is updated. |
|
||
| `last_upgraded` | ISO date of most recent `/adopt` or `/upgrade` run. Helps detect long-stale projects. |
|
||
|
||
---
|
||
|
||
### Affected skills
|
||
|
||
| Skill | How it uses framework |
|
||
|-------|----------------------|
|
||
| **adopt** | Reads `framework.version` to determine which migration steps apply. Updates both fields after running. |
|
||
| **session-start hook** | Warns if `last_upgraded` is more than 90 days stale: "Project was last upgraded over 3 months ago — consider running /adopt." |
|
||
|
||
---
|
||
|
||
## Migration from v1.0 → v1.1
|
||
|
||
When a v1.0 CCGS project upgrades to v1.1, migration tooling (run via `/adopt`)
|
||
converts legacy files to `project.yaml`. This section specifies the intended
|
||
behavior.
|
||
|
||
### Detection
|
||
|
||
A project is detected as needing migration when:
|
||
- `project.yaml` does **NOT** exist at the repo root, AND
|
||
- One or more legacy files exists:
|
||
- `production/stage.txt`
|
||
- `production/review-mode.txt`
|
||
- `.claude/docs/technical-preferences.md`
|
||
|
||
### Preservation
|
||
|
||
| Legacy source | Migrates to |
|
||
|---------------|-------------|
|
||
| `production/stage.txt` (single line) | `project.stage` |
|
||
| `production/review-mode.txt` (single line) | `modes.review_mode` |
|
||
| `.claude/docs/technical-preferences.md` → "Engine & Language" section | `engine.name`, `engine.version`, `engine.language`, `engine.rendering`, `engine.physics` |
|
||
| `technical-preferences.md` → "Input & Platform" section | `platform.targets`, `platform.primary_input`, `platform.gamepad_support`, `platform.touch_support` |
|
||
| `technical-preferences.md` → "Naming Conventions" section | `naming.classes`, `naming.variables`, `naming.constants`, `naming.signals`, `naming.files`, `naming.scenes` |
|
||
| `technical-preferences.md` → "Performance Budgets" section | `performance.target_framerate`, `performance.frame_budget_ms`, `performance.draw_call_limit`, `performance.memory_ceiling_mb` |
|
||
| `technical-preferences.md` → "Testing" section | `testing.framework`, `qa.coverage_minimum` (bare number only — prose is reported for manual entry) |
|
||
| `technical-preferences.md` → "Engine Specialists" section | `specialists.code`, `specialists.shader`, `specialists.ui`, `specialists.additional` |
|
||
|
||
**Value rename — `review_mode: none` → `solo`.** v1.0 used `none` for the "no
|
||
director reviews" tier; v1.1 renamed that tier to `solo` (the enum is
|
||
`full | lean | solo`). Migration **coerces** a legacy `none` to `solo` and reports
|
||
the rename in the migration report's Warnings. This is the one documented value
|
||
rename, so it is mapped-and-flagged rather than preserved raw: writing `none`
|
||
verbatim would produce an enum-invalid `project.yaml` that `resolve_config` rejects
|
||
and falls back to `lean` (reviews *on*) — inverting the user's intent. The
|
||
`--finalize` preservation check applies the same mapping so it does not falsely
|
||
refuse. Every *other* non-v1.1 stage/review value is a fork, not a rename:
|
||
preserved raw and flagged for manual resolution, never coerced (test II.21-23; the
|
||
rename is II.25-27).
|
||
|
||
Settings absent from the legacy files (new v1.1 settings like `qa.level`,
|
||
`docs.density`, `team.size`, etc.) get hardcoded defaults from the v1.1 schema.
|
||
|
||
### Cleanup (deferred, non-destructive)
|
||
|
||
Migration is **non-destructive in v1.1**: legacy files are NOT auto-deleted.
|
||
Migration produces `project.yaml` and leaves the legacy files in place. Hooks
|
||
and skills read `project.yaml` first; they fall back to the legacy file if a
|
||
specific key is missing.
|
||
|
||
Legacy files are deleted only when the user runs
|
||
`.claude/scripts/migrate-v1-config.sh --finalize` (driven by `/adopt`, which
|
||
detects a v1.0 project automatically at Phase 2g). The cleanup step verifies
|
||
that every legacy file's content has been preserved in `project.yaml` before
|
||
deleting.
|
||
|
||
### Failure modes
|
||
|
||
| Problem | Behavior |
|
||
|---------|----------|
|
||
| Legacy file is malformed (can't parse) | Migration emits warning per file, leaves it untouched, continues with the others. `project.yaml` gets the parseable values + defaults for the rest. |
|
||
| Parsed value doesn't match v1.1 enum (e.g. `stage: Alpha` from a fork) | Migration writes the raw value with a `_migration_warning` comment in `project.yaml`. User resolves manually. |
|
||
| Both `project.yaml` AND a legacy file exist (split-brain) | Migration tooling refuses to run. Error: "Both project.yaml and legacy files exist — resolve which is authoritative before migrating." |
|
||
| Custom sections in forked `technical-preferences.md` | Custom content logged to `production/migration-report.md` as "not migrated — please integrate manually." |
|
||
|
||
### Migration report
|
||
|
||
Every migration run writes `production/migration-report.md`:
|
||
|
||
- Source files detected
|
||
- Values preserved (per file → per setting)
|
||
- Defaults applied (for v1.1-new settings)
|
||
- Warnings encountered (malformed, mismatched enums, etc.)
|
||
- Manual review items
|
||
|
||
User reads the report before running `--finalize`.
|
||
|
||
---
|
||
|
||
## Complete example `project.yaml`
|
||
|
||
A full project.yaml with every setting, showing sensible defaults for a solo
|
||
Godot project. Use this as the reference shape when authoring or migrating.
|
||
|
||
```yaml
|
||
schema_version: 1
|
||
|
||
framework:
|
||
version: "1.1.0"
|
||
last_upgraded: "2026-05-15"
|
||
|
||
project:
|
||
name: "Forge Knights"
|
||
genre: "ARPG"
|
||
version: "0.1.0"
|
||
stage: Concept # Concept | Systems Design | Technical Setup | Pre-Production | Production | Polish | Release
|
||
kind: game # game | tool | engine | mod | library
|
||
|
||
modes:
|
||
review_mode: lean # full | lean | solo
|
||
workflow: standard # minimal | standard | full
|
||
automation: collaborative # collaborative | guided | autonomous
|
||
automation_always_ask: # decision categories that always prompt regardless of mode
|
||
- scope_changes
|
||
- file_deletions
|
||
- schema_changes
|
||
story_granularity: balanced # coarse | balanced | fine
|
||
|
||
# TOP-LEVEL, not nested under `modes:` — resolve_config reads
|
||
# `workflow_overrides.system_overrides.*` from the document root
|
||
# (yaml-helper.sh), and every skill greps the same top-level path.
|
||
# Nesting it under `modes:` parses as valid YAML and is silently never read.
|
||
workflow_overrides:
|
||
edge_cases: false # force GDD Edge Cases section required
|
||
tuning_knobs: false # force GDD Tuning Knobs section required
|
||
art_bible_strict: false # force all 9 art bible sections regardless of asset stories
|
||
system_overrides: {} # { combat: full, inventory: minimal }
|
||
|
||
docs:
|
||
density: balanced # terse | balanced | thorough
|
||
|
||
testing:
|
||
framework: gdunit4 # engine-specific — auto-populated by /setup-engine
|
||
strict:
|
||
logic: true # unit test failures BLOCK story closure
|
||
integration: true # integration test failures BLOCK
|
||
visual: true # missing screenshot BLOCKS
|
||
ui: true # missing screenshot BLOCKS
|
||
config: false # advisory only
|
||
|
||
qa:
|
||
level: standard # minimal | standard | full
|
||
coverage_minimum: null # integer 0-100; only enforced at level: full
|
||
|
||
strict_gate_checks: true # phase gate failures block stage transition
|
||
|
||
team:
|
||
size: individual # individual | small | studio
|
||
|
||
platform:
|
||
multiplayer: false # real-time multiplayer
|
||
online: false # any online features (leaderboards, cloud, telemetry)
|
||
targets: [PC] # [PC, Mobile, Web, Console]
|
||
primary_input: "Keyboard/Mouse"
|
||
gamepad_support: "Full" # Full | Partial | None
|
||
touch_support: "None" # Full | Partial | None
|
||
cert_tier: none # none | itch | steam | console
|
||
|
||
engine:
|
||
name: "Godot" # Godot | Unity | Unreal — set by /setup-engine
|
||
version: "4.6"
|
||
language: "GDScript" # GDScript | C# | C++ | Blueprint
|
||
rendering: "Forward+"
|
||
physics: "Jolt"
|
||
|
||
specialists: # auto-populated by /setup-engine
|
||
code: "godot-gdscript-specialist"
|
||
shader: "godot-shader-specialist"
|
||
ui: "godot-specialist"
|
||
additional: ["godot-gdextension-specialist"]
|
||
|
||
naming:
|
||
classes: PascalCase # PascalCase | snake_case | camelCase
|
||
variables: snake_case
|
||
constants: SCREAMING_SNAKE
|
||
signals: past_tense # past_tense | on_event_name (engine-interpreted)
|
||
files: snake_case
|
||
scenes: snake_case
|
||
|
||
accessibility:
|
||
target: none # none | standard | aaa
|
||
|
||
cadence:
|
||
sprint_length: "2w" # 1w | 2w | 3w | 4w | none
|
||
milestone_length: "8w" # 4w | 6w | 8w | 12w
|
||
|
||
performance:
|
||
target_framerate: 60
|
||
frame_budget_ms: 16.67
|
||
draw_call_limit: null
|
||
memory_ceiling_mb: null
|
||
enforce: warn # warn | block | off
|
||
|
||
commands: # simple string OR OS-aware map per command
|
||
build: "godot --headless --export-debug '<PRESET>'" # your export_presets.cfg name
|
||
test: "godot --headless --script tests/gdunit4_runner.gd"
|
||
run: "godot --editor"
|
||
smoke: "godot --headless --quit-after 5"
|
||
|
||
features:
|
||
session_state: on # off | on
|
||
token_budget_warn_at: 0.7 # 0.0-1.0; warn at this context % usage
|
||
```
|
||
|
||
And a minimal sparse `project.local.yaml` example — a single developer who wants autonomous mode locally:
|
||
|
||
```yaml
|
||
modes:
|
||
automation: autonomous
|
||
features:
|
||
session_state: on
|
||
```
|
||
|
||
Only the overridden keys are present; everything else cascades from `project.yaml`.
|
||
See "Local Override Pattern" section for full whitelist of what can/cannot be overridden locally.
|