ADR-0026: Migration of Existing Apps
Date: 2026-06-25
Context
An Almathal-built app at any point in time is fully described by its persisted Archetype Spec — “the resolved, fully-populated configuration for one specific build of an Archetype” — combined with the versions of the Adapters, Modules, and runtimes referenced in that Spec. ADR-0014 establishes that approved Specs are saved as reusable templates, so the artifact required to migrate an existing app already lives alongside it.
Adapters and Modules in the curated library evolve over time. New versions ship with security patches, language runtime updates, framework upgrades, and improvements. Customers will want to move existing apps onto newer versions — for example, an app built against Spring Boot 3.2 and Java 19 onto Spring Boot 3.5 and Java 21. Without an explicit decision on how migration is performed, the platform has no defined contract for moving an existing app forward, and no defined behavior when a new version is not backward-compatible with the previous one.
The mechanisms required to perform migration are already in place. ADR-0014 persists Specs. ADR-0010 establishes that “compatibility is a distributed matrix in each Adapter and Module Manifest.” ADR-0012 establishes Compatibility Validation as a deterministic, blocking pipeline stage. The audit trail is part of the platform’s standard build deliverables, recorded at each pipeline stage. What is missing is the explicit statement of how an existing app moves from one version-set to another.
Decision
Migration of an existing app from one version-set to another is performed by loading the app’s persisted Spec, updating its version selections to the customer’s chosen targets, and re-running the standard pipeline against the updated Spec. The migration is recorded as a new entry in the app’s audit trail. The previous Spec is retained as a recoverable artifact so the prior state is not lost.
Migration is always initiated by the customer. The platform does not push version updates to existing apps. Customers may keep an app on any version-set for as long as the underlying Adapters and Modules remain in the registry.
When a new version of an Adapter or Module is not backward-compatible with the previous version, the new version’s Manifest declares migration steps in its existing compatibility block. The Compatibility Validator applies those steps as part of the standard pipeline run, under ADR-0020’s existing rules for Manifest schema evolution. The specific mechanism by which migration steps are expressed — their schema, scope, composition across multiple versions, and behavior on failure — is addressed in ADR-0027.
Interaction with customer modifications made to previously-generated code after delivery is out of scope for this ADR and is deferred to a separate decision.
Rationale
This decision composes mechanisms that already exist rather than introducing new machinery. Specs are persisted, compatibility is declared per Manifest, the pipeline is deterministic, and audit trails are produced. Migration becomes a known sequence — update the Spec, re-run the pipeline — built entirely from primitives the platform already provides.
Customer-initiated migration is essential to the platform being a long-lived product. Customers must be able to move existing apps forward on their own schedule without engineering rework. Without this decision, every version upgrade in the curated library would push migration work to customers that the platform is designed to absorb. The no-silent-push principle is as important as the migration mechanism itself.
Retaining the previous Spec as a recoverable artifact is consistent with the reproducibility guarantee that is a stated platform differentiator. A migration that loses the prior state would undermine the audit-trail and reproducibility story.
References
- ADR-0010: Semver and Compatibility Matrix Versioning — “Compatibility is a distributed matrix. Each Adapter and Module Manifest declares its
compatibilityblock: language runtime versions, scaffolder versions, required Adapters, compatible Adapters with version ranges, incompatible Adapters, and known-good combinations.” - ADR-0012: Sanity Checks at Five Pipeline Stages — establishes Compatibility Validation as a deterministic, blocking pipeline stage.
- ADR-0014: Save Approved Specs as Reusable Templates — establishes that approved Specs are persisted alongside the app.
- ADR-0020: Manifest Schema Versioning — establishes the rules under which new fields are added to Manifest schemas.
- ADR-0027: Migration Transformation Mechanism — defines how migration steps are expressed in the Manifest compatibility block, their schema, scope, and behavior on failure.