You’re right - an artifact rollback is not a rollback if the last migration already dropped something the previous code still reads.
I treat the rollback job as incomplete until it has been run against the same schema contract the old revision needs. Expand-contract is the path that makes that possible: add, dual-write, switch reads, drop only after the old path is gone.
I’ll add that as the fifth Monday check: does the last migration still let yesterday’s artifact run, or did it break the previous schema?
Thanks for writing this. It’s the failure mode I see after people already built the rollback job and assumed the image was the whole problem.
The rollback job is the one people build and then never actually test. Redeploying the previous artifact only gets you back to a working state if the database can still serve that older code, and a migration that ran with the new release is often the real blocker, not the container image. If schema changes aren't written expand-contract (add the new column, dual-write, drop the old one only after the new path is fully rolled out and stable), rolling the artifact back leaves old code pointed at a schema it doesn't understand. Worth adding a fifth question to the Monday check: does the last migration still let the previous artifact run against it, or did it drop something the old code needs?