THE APP BUILT. THE DEPLOY DID NOT.
For about five minutes we thought the migration was finished.
SO THAT WAS NOT DONE
The app compiled. No obvious errors. Then Cloudflare fell over because Wrangler wanted someone to answer an interactive setup prompt. CI, quite reasonably, did not volunteer.
WHAT FIXED IT
We stopped letting the deployment infer the framework setup and committed the configuration ourselves. Next.js config, Wrangler config, OpenNext. Once those were in the repo the whole thing became a lot less mysterious.
NOTE TO SELF
If a production deploy depends on us remembering which box we ticked in a dashboard, it probably needs to be written down somewhere.