The infrastructure move is not the hard part

AWS to Azure or GCP. VMs to Kubernetes. A monolith split into services. REST replaced by an event-driven backbone. A database engine swap. A framework major-version upgrade. These are usually described, and budgeted, as infrastructure or platform projects. The actual difficulty rarely lives in the infrastructure. It lives in what happens to the application code that has to keep running correctly while the ground underneath it changes.

Every one of these projects is, underneath the platform work, an architectural migration of exactly the kind the rest of this cluster describes: two valid patterns coexisting in one codebase for the length of the project, with agents statistically likely to reproduce the one being retired.

Why platform migrations produce more drift, not less

It is tempting to assume a platform migration is lower risk for this problem than an application-level one, because so much of the change happens in configuration and infrastructure code rather than business logic. The opposite tends to be true. Platform migrations usually touch more of the codebase, over a longer period, with less of the change concentrated in code anyone is reading line by line.

A Kubernetes migration means every service's deployment story changes, generally on a per-service schedule stretched across months. A database engine change means every query, every migration script, and often every ORM mapping is touched somewhere. An agent generating code for a not-yet-migrated service, next to a dozen already-migrated ones, faces the exact frequency problem from the pillar article: the migrated pattern is newer and rarer, the legacy pattern is older and more numerous, and nothing marks one as historical.

The pattern repeats across five common migrations

MigrationWhat agents copy by defaultWhat has to be scoped instead
AWS → Azure/GCPProvider-specific SDK calls and IAM patterns from the majority of existing servicesThe target provider's client and auth pattern, scoped to migrated services
VM → KubernetesDeployment scripts and health-check conventions built for long-lived hostsContainer-native patterns: readiness probes, externalized config, stateless assumptions
Monolith → servicesDirect in-process calls to modules that are supposed to be remote nowService-boundary contracts, scoped per extracted service as it moves
REST → event-drivenSynchronous request/response call shapes copied from the surrounding codePublish/subscribe patterns, scoped to the events already migrated
Database engine swapQuery syntax and transaction assumptions specific to the old engineTarget-engine query patterns and transaction boundaries, scoped per migrated table or service

The specific pattern being copied changes with the migration. The mechanism does not. In every row, an agent generating code near a not-yet-migrated majority reaches for what it sees, and what it sees is the platform being replaced.

Framework upgrades are the same problem in miniature

A major framework version upgrade rarely happens as one commit. It happens module by module, sometimes over quarters, with old-API and new-API usage coexisting the entire time. An agent asked to add a feature near recently-upgraded code has the same frequency problem as any other migration: the old API is usually still the majority pattern until the upgrade is nearly complete, which is exactly when the temptation to relax vigilance is highest.

This is worth naming separately from the infrastructure cases above because it is the one most likely to be treated as routine maintenance rather than a governed migration, and therefore the one most likely to have no scoped decisions at all.

What does not change: the fix is still path applicability

None of these five migrations need a different governance mechanism from the one covered throughout this cluster. Each is a legacy pattern and a target pattern occupying the same codebase, resolved by a decision scoped with include_paths for the migrated tree and exclude_paths for the legacy tree, the same shape as the persistence and adapter examples in the guardrails article.

What differs across the five is only the specific literal or pattern being scoped: a provider SDK import, a deployment manifest convention, a synchronous call shape, a query dialect, an old-version API call. The scoping mechanism, and the reason it is needed, is identical in every case.

Cross-cutting platform state needs its own decision

One thing platform migrations add that a pure application migration usually does not: cross-cutting concerns like observability, secrets, and networking often change shape at the same time as everything else, and they tend to be the parts nobody writes an ADR for because they feel like plumbing rather than architecture.

They are architecture. A service that migrates its business logic to the target platform but keeps the old logging or secrets pattern is not fully migrated, and an agent has no way to know that unless the decision covering it is recorded and scoped the same way as everything else.

Sequencing matters more here

Platform migrations frequently have hard ordering constraints that application migrations do not: a service cannot move to the new cluster until its dependencies are reachable there, a table cannot move to the new database until its consumers can read from both. As the pillar article covers, the corpus cannot express the ordering directly, but it can hold the rule that keeps a downstream tree on the legacy pattern until its dependency lands. That is worth doing because a project plan is not something an agent is checked against.

Conclusion

The infrastructure work in a cloud or platform migration gets the budget, the timeline, and the runbook. The architectural drift it creates in application code, while old and new platforms coexist, usually gets neither. The governance need is not specific to any one of these five migrations; it is the same path-scoped decision mechanism this cluster has covered throughout, applied to whichever platform boundary the project is actually crossing.

The migration demo traces the same path-scoped mechanism end to end, on the persistence boundary that recurs across all five migration types above.