`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
6.6 KiB
Migration Guide: v1.0 → v1.1 project.yaml
This guide covers converting an existing project's config files to
project.yaml. It is distinct from the template-diff instructions in
UPGRADING.md — that file tells you which skill and agent
files changed between releases and whether they're safe to overwrite. This
guide covers your project's own data: the values you configured in
production/stage.txt, production/review-mode.txt, and
.claude/docs/technical-preferences.md.
If you're setting up a brand-new project on v1.1, you don't need this —
/start writes project.yaml directly and none of the legacy files apply.
Do you need to migrate?
You have a v1.0 project needing migration if project.yaml does not
exist at your repo root, and at least one of these does:
production/stage.txtproduction/review-mode.txt.claude/docs/technical-preferences.mdwith real values (a copy still full of[TO BE CONFIGURED]placeholders is the untouched template default, not migratable data, and doesn't count)
Run /adopt and it will detect this automatically (Phase 2g) and walk you
through the steps below. You can also run the converter directly.
What gets preserved
| From | To (project.yaml) |
|---|---|
production/stage.txt |
project.stage |
production/review-mode.txt |
modes.review_mode |
technical-preferences.md → Engine & Language |
engine.name, engine.version, engine.language, engine.rendering, engine.physics |
technical-preferences.md → Input & Platform |
platform.targets, platform.primary_input, platform.gamepad_support, platform.touch_support |
technical-preferences.md → Naming Conventions |
naming.classes, naming.variables, naming.constants, naming.signals, naming.files, naming.scenes |
technical-preferences.md → Performance Budgets |
performance.target_framerate, performance.frame_budget_ms, performance.draw_call_limit, performance.memory_ceiling_mb |
technical-preferences.md → Testing |
testing.framework, qa.coverage_minimum |
technical-preferences.md → Engine Specialists |
specialists.code, specialists.shader, specialists.ui, specialists.additional |
Settings that don't exist in v1.0 at all (modes.rigor, qa.level,
docs.density, team.size, modes.story_granularity, and the rest of the
v1.1 modes system) get their hardcoded v1.1 defaults — there's nothing to
preserve for them.
One value was renamed: v1.0's review-mode.txt: none ("no director
reviews") becomes modes.review_mode: solo in v1.1, which is the same tier
under its new name. The converter maps it and calls it out in the migration
report's Warnings, so you'll see the rename rather than have it happen silently.
Not migrated, on purpose: technical-preferences.md's Forbidden Patterns
and Allowed Libraries sections have no project.yaml equivalent. The
converter never deletes this file for that reason — see "Finalizing," below.
Running the migration
The conversion is a tested script, not something the AI hand-edits — the
v1.1 plan rated data loss during migration as its highest-severity risk, and
prose migration can't be unit-tested the way a script can. /adopt drives
it for you, or you can run it yourself:
# 1. Preview — writes nothing, just reports what it would do
bash .claude/scripts/migrate-v1-config.sh --dry-run
# 2. Migrate — writes project.yaml + production/migration-report.md
# Every legacy file is left in place, untouched.
bash .claude/scripts/migrate-v1-config.sh
# 3. Read the report before finalizing
cat production/migration-report.md
# 4. Finalize — deletes legacy files, ONLY after re-verifying each one's
# value made it into project.yaml. Refuses (exit 4) and deletes nothing
# on any mismatch.
bash .claude/scripts/migrate-v1-config.sh --finalize
Step 4 is optional and separate on purpose. Skipping it is completely fine —
every skill and hook falls back to the legacy files for any key
project.yaml doesn't have, so the two can coexist indefinitely. Run it when
you're confident project.yaml is correct and want one config file instead
of three.
technical-preferences.md is never deleted, even with --finalize —
Forbidden Patterns and Allowed Libraries still live there and always will,
since v1.1 has no equivalent structure for them yet.
Reading production/migration-report.md
The report has five sections:
- Source files detected — which legacy files the converter found
- Values preserved — per source file, per setting, what was written to
project.yaml - Defaults applied — new v1.1 settings that had nothing to migrate from
- Warnings — anything the converter couldn't parse cleanly (see below)
- Manual review — content it found but declined to guess at (e.g. custom
sections in a forked
technical-preferences.md)
What can go wrong (and what the script does about it)
| Situation | Behavior |
|---|---|
| A legacy file is malformed / unparsable | Warns per-file, leaves it alone, continues migrating everything else it can parse. project.yaml gets the values it could read plus defaults for the rest. |
A parsed value doesn't match a v1.1 enum (e.g. a custom fork's stage: Alpha) |
Written as-is with a warning comment, flagged for manual resolution — the converter does not silently coerce or drop it. |
Both project.yaml and legacy files already exist |
Refuses to run (exit code 3). Two sources of truth with no way to know which you last edited is not something the script will guess at — resolve it yourself first (decide which is authoritative, delete or rename the other). |
Custom sections in a forked technical-preferences.md |
Logged to the migration report as "not migrated — integrate manually." Nothing is silently dropped. |
If you hit the split-brain case (both present), that usually means you
either ran /start on a project that also had old legacy files lying
around, or partially migrated by hand. Pick the one with your real values,
remove or back up the other, then re-run --dry-run.
After migrating
- Spot-check
project.yamlagainst your oldtechnical-preferences.md— engine, naming, and performance values in particular. - Run
/settingsto see the effective config the way skills will read it. - Everything else in the framework works identically whether or not you've
run
--finalize— there's no rush.
For the new settings that didn't exist in v1.0 (modes.rigor above all),
see the Configuration section of the README
and the full spec in .claude/docs/effects-map.md.