Documentation / Migration
Migrate context between coding agents
Bring your existing repository guidance into a new agent’s format. Keep a canonical source so the next migration can reuse the same context.
Stemma imports repository configuration into .stemma/, then compiles it for a selected destination. GitHub Copilot, Claude Code, Codex and Kiro can each be a source or a destination. The process is the same; the fidelity of individual instructions, skills and agents depends on the destination’s capabilities.
This covers repository context, not conversation history, licenses, accounts or personal settings. Review the compatibility table for supported formats and limitations. Cursor is declared but not implemented.
Migration is not a copy of the provider directory
Generated filenames and skill invocation names can change. Stemma does not automatically rewrite paths or provider names inside content, or copy the supporting files of a skill. Review names, references and resources before using the destination configuration.
Choose the migration you want to follow#
Select your current provider and the one you want to try. All command examples below update to match. You run them yourself from your repository root, in a terminal or PowerShell.
Before starting: use a working copy where you can review the diff and recover existing configuration. Run stemma version. This guide documents the v0.4.0 command interface and calls out limitations that affect the process.
Already have a canonical project?
If you already maintain .stemma/, add a destination to that project. You do not need to import again. If there is no existing provider configuration, start with the empty-project workflow.
1. Inventory the existing configuration#
stemma scanscan lists detected providers and their known configuration paths without reading file contents or writing anything. Check that the source you intend to migrate is present, and read any scan-limit warnings before assuming the inventory is complete.
If the destination already has its own configuration, review it too. Stemma does not merge two independently maintained provider setups automatically. You choose which source to import; it refuses to silently overwrite conflicting destination files.
2. Import one source into the canonical project#
stemma import --from github-copilot --targets kiro--from github-copilot selects the provider configuration to read. --targets kiro enables the destination in .stemma/project.json. It selects future output; it does not generate that output yet. Without --targets, import enables only the source provider.
Import writes the canonical Markdown, project metadata and provenance under .stemma/. Existing provider files remain in place. You do not need to run init first.
It also verifies itself. Import compiles the canonical project straight back for the source provider and compares the result with the exact bytes it read; every source reproduced byte-for-byte at the same path is recorded in the manifest as owned, in the same transaction that saves the canonical files. Nothing is written to a provider file, and no apply timestamp is recorded. This is what makes the normal order — import, edit .stemma/, plan, apply — work without a preliminary no-op apply or a blanket --adopt-untracked.
Read any STEMMA4302 before editing
A source that could not be reproduced byte-for-byte is reported at import time and left unowned; the canonical import is still saved. Overwriting that file later is a STEMMA4301 conflict, and --adopt-untracked does not lift it — that flag is for genuinely foreign files. Compare the source with the canonical content and the projection diagnostics, preserve anything missing, or generate to a separate output path so you can review without overwriting the original.
Review the import diagnostics and the Markdown it created under .stemma/context/, rules/, skills/, agents/ and procedures/, as applicable. Content that cannot be interpreted may be preserved as an opaque block; preserved input is not a guarantee that another provider can use it.
Import is a starting point, not a recurring merge
--from auto refuses to choose when several providers are detected. Choose one source explicitly. import --all is not implemented. --overwrite replaces the canonical project rather than merging another source into it, so it can replace your canonical edits. It reports the entities it removes and, with STEMMA4303, each destination and target whose ownership was revoked and not re-established by the new import.
3. Review what the destination will receive#
stemma validatestemma plan --target kiro --explainvalidate checks the canonical project. plan --explain compiles it for Kiro and shows proposed paths, file changes, entity IDs and projection explanations. Neither command writes provider files.
exact: represented faithfully according to Stemma’s compatibility model.adapted: represented through a different delivery mechanism.lossy: some information cannot be represented. Read the diagnostic and decide whether to change the source, use a target profile or accept the reviewed loss.blocked: the projection cannot proceed. Resolve the diagnostic before applying.skipped-explicitly: intentionally excluded by a configured rule or a reported optimization decision.
These outcomes describe entities. File classifications such as create, update and conflict describe the destinations on disk. Resolve file conflicts as well as blocking projection diagnostics.
stemma plan --target kiro --json The JSON plan includes proposed file contents. To investigate one mapping, copy its entity ID from the plan and replace ENTITY_ID in this command:
stemma explain ENTITY_ID --target kiroPay particular attention to scoped instructions, activation, provider extensions, tool names and model preferences. Preserving a value does not make its meaning portable. A target profile can adapt delivery for one provider without editing the canonical source.
Review before authorizing writes
apply keeps every plan diagnostic and adds its own, in human and JSON output alike — including when nothing needs writing, and including when the transaction fails. An interactive apply prints them before asking for confirmation. If the destination has a conflicting file, inspect and preserve its content before deciding how to reconcile it; --yes does not override conflicts.
Review names, references and resources#
In v0.4.0, cross-provider output can use a canonical entity ID instead of the original filename. A Copilot instruction's description can become its title and ID, producing a long context-... filename. A skill named review can be generated as skill-review. These prefixes help keep distinct entities from colliding; source filenames are not guaranteed to survive a migration. Inspect the actual paths in the plan.
For example, when migrating Copilot to Claude, a path-scoped instruction under .github/instructions/ is generated under .claude/rules/ with paths front matter. This is Claude's native scoped-instruction format, not a misplaced instructions directory. General always-on context is collected in CLAUDE.md. See Claude's rules documentation ↗.
A Copilot skill at .github/skills/review/SKILL.md can become .claude/skills/skill-review/SKILL.md. In Claude, a project skill's directory determines its invocation command, so check for /skill-review rather than assuming /review still works. See Claude's skill naming documentation ↗.
References inside the body are not automatically updated to match those generated paths. Importing SKILL.md does not copy its sibling templates, reference documents or scripts. A relative link can also stop resolving when its containing file moves. Keep any required source resources until you have reviewed and adapted the destination setup; do not globally replace .github with .claude, because paths such as .github/workflows still belong to GitHub.
For an explicit adjustment, a target profile can pin a directory or filename and replace the target's agent-facing text with contentOverride. The replacement produces STEMMA3601; it is not a path-search-and-replace feature and does not copy any referenced files. Preview with the same profile you will use to apply, and keep maintained adjustments in the canonical project or its profiles rather than editing generated files.
- Compare source and destination filenames, scopes and skill invocation names.
- Inspect links and paths in instructions, skills and agents, including relative links.
- Check that each required resource exists where the destination expects it.
- Review provider-specific wording and test a representative task with the new agent.
4. Generate, check and try the destination agent#
stemma apply --target kiro --yesstemma check --target kiroapply generates the selected provider’s files and records their hashes in the manifest. check verifies that those files match the canonical project. Review the resulting diff and try representative tasks with Kiro: a green check does not prove that referenced resources exist, that an agent loaded every instruction or that it will behave identically.
Keep the canonical project, provenance, manifest, profiles and generated files together in version control. To reverse a trial migration, restore the reviewed changes from your working copy or version control; Stemma has no migration rollback command. Its transactional rollback protects a failed write, not a later decision to switch back.
Keep both providers during a trial#
For a fresh import that needs both the current and destination agents, use this alternative to step 2. Both providers will receive output from the same canonical source:
stemma import --from github-copilot --targets github-copilot,kirostemma validatestemma plan --all --explain# Review both targets before writing.stemma apply --all --yesstemma check --all--targets saves the enabled providers in project.json. --all processes that list, not every provider Stemma supports. Each target is applied in its own transaction; a failure does not undo earlier successful targets.
Editing before the first apply is fine
Ownership of the source files is recorded at import, so you can edit .stemma/ before applying back to the source provider. A source reported as STEMMA4302 was never owned. A tracked source edited outside Stemma no longer matches its recorded hash, so an update is refused as a conflict. Before v0.4.0, import did not establish ownership, but a successful apply did: those existing records remain usable. If no record exists and the generated bytes are unchanged, a reviewed no-op apply can still establish ownership.
Ownership does not outlive the project that granted it
When import --overwrite changes the canonical project, it revokes previous target ownership before recording the newly verified sources. Import reports STEMMA4303 for each destination whose ownership was not re-established, naming its path and target and leaving its bytes untouched. If a later plan would change that now-foreign file, it reports a STEMMA4301 untracked-destination conflict and apply refuses the write. After preserving any needed content, you can authorize that replacement with --adopt-untracked; sources that failed import verification still require reconciliation. The flag adopts every foreign destination in the run — see adopting a file Stemma does not own.
If you already completed the import, keep the canonical project and add the source provider to its existing targets array instead of re-importing. Follow the multiple-agent workflow and review any ownership conflict.
5. Maintain the context and prepare the next migration#
After the initial migration, edit the Markdown under .stemma/, rather than the generated provider files. Use this loop:
stemma validatestemma plan --all --explain# Review changes and diagnostics before writing.stemma apply --all --yesstemma check --all For the next migration, add the new provider identifier to the existing targets array in .stemma/project.json, preserving its other fields. Preview with plan --target, apply the reviewed output and test that agent. The one-off --target flag does not save the provider in the project, and no new source import is needed.
If the project predates v0.4.0, expect that first plan to rename cross-provider files: generated names now carry the entity's type prefix, so testing.instructions.md becomes rule-testing.instructions.md. Stemma proposes the old paths for deletion and never executes them, so retire them yourself after reading the replacements — see provider translation.
At cutover, remove a retired provider from targets if you no longer want to maintain it. Its files remain on disk. Inspect and retire obsolete configuration yourself, including files the new agent may also discover. On versions affected by issue #5 ↗, a green check does not cover every proposed file deletion.
Continue with daily workflows, profiles and CI, or use the command reference for all flags and defaults.
Related documentation: round trips and preservation ↗.