Most schema migrations fail at the decision point, not the plumbing. Teams deploy the new version, watch dashboards for a few days, feel nervous, and either cut over too early or leave both versions running forever. The fix is to treat retirement as a measurement problem with a pre-agreed answer key.
Shadow testing gives you that measurement. The established pattern is to run a candidate version in parallel with production, send it a copy of real traffic, and capture its output without ever returning it to the user, which is how Microsoft's engineering playbook describes shadow testing. That page notes the technique is also called traffic mirroring or dark launching, and that the point is to compare the candidate against the current system before you replace it.
For tool schemas the mechanics differ from a whole-service swap. A tool call is not a stateless HTTP request you can fork at the gateway. It is a function invocation that may write a row, send a message or charge a card. So the mirror has to sit inside the tool execution layer, where you control which schema the real call uses and which schema the replay uses.
The retirement rule you write down first looks like this:
| Decision | What you fix before burn-in | Why it matters |
|---|---|---|
| Which tools retire | A named list of tool IDs and schema versions | Prevents scope creep mid-migration |
| Disagreement rate ceiling | A per-tool percentage, for example 1 percent of mirrored calls | Turns "looks fine" into a number |
| Severity classes that always block | Type change, enum value removed, required field changed | Some disagreements are never acceptable |
| Burn-in length | A fixed number of days plus a minimum call count | Stops endless shadowing |
| Rollback path | One-step flip back to the old schema | Makes cutover reversible |
| Evidence retention | Shadow logs kept past cutover | Incident response and audits need them |
Write those six down in the migration ticket. Every later argument about readiness resolves against them.



