---
slug: "ExpandContractMigration"
name: "ExpandContractMigration"
type: "Safety"
layer: "Infrastructure"
ref: "ExpandContractMigration#14c6"
sema_id: "sema:ExpandContractMigration#mh:SHA-256:14c61a53ba4bbc21a5a0f6b43c4510a812ce04b3ada87bf378ded624b9135e7f"
tags: ["Infrastructure","Safety"]
updated: 2026-11-11
mindscape: "bootstrap"
index_url: https://mindscape.world/scapes/bootstrap.json
url: https://mindscape.world/bootstrap/ExpandContractMigration/
related: ["CompatibilityCheck","MeaningChangeSweep","Rollout#ea8c","Deploy#bc5c","FeatureFlag#dd17","TranslationProxy#1db2"]
---

# ExpandContractMigration

Change a shared format by adding the new form beside the old, moving every consumer, then removing the old

Layer: Infrastructure · Category: Safety

## Mechanism

To change an interface, schema, storage layout or message format shared by producers and consumers that deploy independently, the change runs in three phases with a gate between each. Expand: the new form is introduced beside the old so every deployed reader and writer still works; writers may write both. Migrate: consumers move to the new form and stored data is backfilled, with [CompatibilityCheck](https://mindscape.world/scapes/bootstrap/CompatibilityCheck.md) run for every inventoried producer-consumer pair in each direction in which the pair communicates. Contract: the old form is removed only after an inventory of its remaining consumers, including old versions, caches, copies of the interface and in-flight messages, comes back empty. Each phase records the conditions under which it can be rolled back. Reusing an existing field or name with a new meaning is a contraction of the old meaning and an expansion of the new one in a single step, and its readers are found as in [MeaningChangeSweep](https://mindscape.world/scapes/bootstrap/MeaningChangeSweep.md).

## Invariants

- At every point in the transition, every inventoried producer-consumer pair can interoperate in each direction in which it communicates.
- The old form is removed only after an inventory of its remaining consumers comes back empty, with the inventory's scope recorded.
- A change of meaning under an unchanged name or position is treated as a removal plus an addition, never as compatible.

## Failure modes

- Forgotten consumer: an offline, embedded or third-party reader, such as an indexer or a hand-copied interface, still depends on the old form when it is removed.
- Dual-write divergence: the two forms drift because some writes reach only one of them.
- Single-step change: expansion and contraction ship together, so there is never a state where both forms work.
- Permanent expansion: contraction never happens and both forms are maintained indefinitely.
- Silent repurpose: a field keeps its name and type while its meaning changes, which shape-level compatibility checks cannot detect.

## Builds on

- [CompatibilityCheck](https://mindscape.world/scapes/bootstrap/CompatibilityCheck.md) (Infrastructure; References)
- [MeaningChangeSweep](https://mindscape.world/scapes/bootstrap/MeaningChangeSweep.md) (Mind; References)

## Used by

—

## Identity

- Sema ID: `sema:ExpandContractMigration#mh:SHA-256:14c61a53ba4bbc21a5a0f6b43c4510a812ce04b3ada87bf378ded624b9135e7f`
- Ref: `ExpandContractMigration#14c6`

## Links

- [Pattern page](https://mindscape.world/bootstrap/ExpandContractMigration/)
- [View in the interactive graph](https://mindscape.world/bootstrap/#ExpandContractMigration)
- [JSON](https://mindscape.world/scapes/bootstrap/ExpandContractMigration.json)
- [Index of all patterns](https://mindscape.world/scapes/bootstrap.json)
