@@ -387,6 +387,56 @@ Use these quick examples to align implementation choices before opening a PR.
387387- ** Bad** : config key changes without migration notes.
388388- ** Good** : config/schema changes include defaults, compatibility impact, migration steps, and rollback guidance.
389389
390+ ## Config Schema Versioning and Migrations
391+
392+ ZeroClaw uses a forward-only schema versioning system for ` config.toml ` . This section
393+ explains when and how to create a migration.
394+
395+ ### When a migration IS needed
396+
397+ A schema version bump is required when you ** rename, move, or remove** an existing
398+ config prop. Examples:
399+
400+ - Renaming ` room_id ` to something else
401+ - Moving a prop from one section to another
402+ - Removing a deprecated prop entirely
403+
404+ ### When a migration is NOT needed
405+
406+ Adding a new config prop does ** not** require a schema version bump. Use
407+ ` #[serde(default)] ` on the new field and it will be filled with its default value
408+ when loading older config files. This is the common case.
409+
410+ ### How the migration system works
411+
412+ 1 . ` crates/zeroclaw-config/src/migration.rs ` contains ` V1Compat ` , a wrapper struct
413+ that uses ` #[serde(flatten)] ` to deserialize both old-format and current-format
414+ TOML into a single pass. Old fields live on ` V1Compat ` ; current fields land on
415+ ` Config ` .
416+ 2 . ` V1Compat::into_config() ` moves old field values into their new locations on
417+ ` Config ` using typed field access — no string-based key manipulation. All call
418+ sites use ` config.providers.* ` directly.
419+ 3 . For schema versions beyond V2, add ` fn vN_to_vM(&mut Config) ` functions that
420+ mutate the ` Config ` struct directly.
421+
422+ ### How to add a new migration step
423+
424+ 1 . Bump ` CURRENT_SCHEMA_VERSION ` in ` crates/zeroclaw-config/src/migration.rs ` .
425+ 2 . If the old field was on ` V1Compat ` , update the ` migrate_providers() ` or similar
426+ method. If the change is between V2+ layouts, add a new ` fn vN_to_vM(&mut Config) `
427+ and call it from ` into_config() ` after the schema version check.
428+ 3 . Add tests in ` tests/component/config_migration.rs ` that:
429+ - Deserialize a TOML string with the old layout
430+ - Assert the migrated ` Config ` has values in the new locations
431+ - Assert the old locations are empty/cleared
432+ 4 . Run ` cargo test --test component -- config_migration ` to verify.
433+
434+ ### ` zeroclaw config migrate `
435+
436+ Users can run ` zeroclaw config migrate ` to rewrite their on-disk ` config.toml ` to the
437+ current schema version. This command uses ` toml_edit ` to preserve comments and
438+ formatting while making structural changes.
439+
390440## How to Add a New Provider
391441
392442Create ` src/providers/your_provider.rs ` :
0 commit comments