config-migrations
Migrate AICP config schema across versions — rename keys, change shapes (string → list, scalar → object), deprecate keys, add required keys with safe defaults, validate operator config files post-upgr
SKILL.md.claude/skills/config-migrations/SKILL.md
GitHubconfig-migrations
Manage AICP config SCHEMA evolution. When AICP renames a config key, changes
its shape, deprecates a feature, or requires a new key — operator config
files (config/default.yaml, config/profiles/*.yaml, ~/.aicp/config.yaml,
<project>/.aicp/config.yaml) all need migration. This skill is the
operational lifecycle for those changes.
Trigger phrases (when to load this skill)
Load when the conversation matches any of:
- Direct verb: operator says "AICP changed config shape", "migrate config X", "upgrade config to new schema", "add required key Y to all configs", "rename config key"
- Post-upgrade validation: operator upgraded AICP and wants to verify config files still parse correctly under the new schema
- Schema design: AICP team is changing config shape and needs to release notes + migration tooling
- Deprecation: a config key is being removed; need to warn operators ahead of removal
Do NOT load when:
- The concern is per-environment config values (load
config-env) - The concern is choosing which profile to deploy (load
config-deploy) - The concern is feature toggles (load
config-feature-flags) - The concern is secrets specifically (load
config-secrets)
Operations
Operation 1 — Plan a config schema change
When: AICP team wants to evolve config shape (rename / restructure / add required key).
Process:
- Identify the change category:
- Rename:
cluster.auto_route→routing.fleet_enabled - Restructure:
models: [a, b, c]→models: {gpu: [a, b], cpu: [c]} - Add required: new
version: 2key required at config root - Deprecate:
legacy_mode: trueis going away
- Rename:
- Choose the migration strategy:
- Backward-compatible: old key still read, new key takes precedence when present (preferred — rolling upgrade safe)
- One-shot: bump a
version:field; loader rejects old version with migration instructions
- Document the change in
wiki/decisions/00_inbox/<change>-config-migration.mdper Knowledge Evolution Standards - Update
aicp/config/loader.pyto emit deprecation warnings for old keys (so operators see the change before it breaks)
Quality bar: NEVER make a config schema change without an in-loader deprecation warning. Operators need a release-cycle window to migrate their YAMLs.
Operation 2 — Migrate operator config files in place
When: a schema change has shipped; operator wants to update their config files to the new shape.
Process:
- Identify which files need migration:
config/default.yaml(project-shipped — usually already updated)config/profiles/*.yaml(project-shipped — should be updated by AICP team)~/.aicp/config.yaml(operator's user-global — needs operator action)<project>/.aicp/config.yaml(operator's per-project — needs action)
- For each file with the old key:
- If backward-compatible migration: optional update, but eventually required
- If breaking migration: required update before next AICP run
- Apply the rename/restructure with
Edit(NEVER bulksed— operator files often have comments and structure that bulk edits damage) - Run
aicp --profile-cmd validateto confirm migrated files are schema-valid
Quality bar: NEVER skip the validate step after migration. Schema-valid doesn't mean semantically correct, but it's the floor.
Operation 3 — Add a version: field for one-shot migrations
When: AICP needs a hard schema break (no backward-compat possible).
Process:
- Add a
version: <N>key at the root ofconfig/default.yaml - In
aicp/config/loader.py, check the version on load:- Missing or older than expected: emit clear error with migration instructions (point to a migration script or doc)
- Matches expected: proceed normally
- Provide a migration utility (e.g.,
aicp --config-migrate <old.yaml> <new.yaml>) that operator can run to auto-upgrade their file - Document the version bump in CHANGELOG and CLAUDE.md
Quality bar: a hard schema break needs (a) clear error message naming the version mismatch, (b) the migration utility, (c) docs explaining the rationale (per Knowledge Evolution Standards — link a decision page).
Operation 4 — Deprecate a config key
When: a feature is being removed; its config key needs to go too.
Process:
- Phase 1 (current release): emit
DeprecationWarningwhen the key is read; document removal plan in CHANGELOG - Phase 2 (next release): remove the key from
config/default.yaml; loader still accepts but warns louder - Phase 3 (release after that): loader rejects the key with error
- Document each phase in
wiki/decisions/00_inbox/<key>-deprecation.mdso the timeline is operator-visible
Quality bar: NEVER skip Phase 1 (deprecation warning). Operators configure once and rarely re-read; warnings give them a chance to update ahead of the breaking removal.
Gotchas
Detection: agent renames a config key without a deprecation period. Rule: every rename gets at least one release of backward-compat with a deprecation warning. Reasoning: operator configs aren't test-covered; renames break silently if not flagged ahead of the break.
Detection: agent uses bulk
sedto migrate operator YAML files. Rule: useEditper-occurrence. YAML files contain comments and structure that bulk regex can damage. Reasoning: bulk edits often produce malformed YAML or destroy operator comments documenting why a value was set.Detection: agent migrates only
config/default.yamland forgets profile YAMLs. Rule: profile YAMLs are derived from default.yaml + overrides; schema changes propagate to BOTH. Reasoning: profiles inherit default's schema; if default changes shape, profiles' overrides may target nonexistent keys.Detection: agent skips
aicp --profile-cmd validateafter migration. Rule: every migrated file must validate before declaring done. Reasoning: schema validation is the floor — semantic correctness is harder, but at minimum the YAML must parse against the schema.Detection: agent treats deprecation as instant (skip Phase 1). Rule: deprecation is a multi-release process: warn → louder warn → remove. Reasoning: operators may not redeploy frequently; instant removal breaks production for slow-cycle teams.
Reference exemplars
aicp/config/loader.pyvalidate_config()— schema validation entry pointconfig/default.yaml— schema source of truthwiki/decisions/01_drafts/aicp-active-state-mechanism-for-hooks.md— example of a schema decision documented (state.yaml shape)- AICP changelog (if maintained) — migration history reference
Domain context
AICP's config is a 5-tier overlay
(default.yaml → profile → user → project → CLI). Schema changes need
to coordinate with this overlay — a key rename in default.yaml must
also rename in profiles, and operators with their own user/project
config files need a migration path. The cost of getting this wrong is
operator-visible: configs that worked yesterday error today.
Related skills
| Skill | When to use |
|---|---|
config-env |
When the lifecycle is env var management generally |
config-deploy |
When the concern is which profile activates per environment |
config-feature-flags |
When the concern is per-feature toggle (different from schema) |
pm-changelog |
When documenting a config migration in release notes |
evolve-migrate |
When the migration is broader (data + config + code, not just config) |