Why a new deployment always means a new URL
Apps Script ties each /exec URL to a specific deployment record, not to the project. When you click Deploy > New deployment, the editor creates a brand-new record with its own ID, and that ID is part of the URL path. The old record still exists and its URL still works, pointing at whatever version it was pinned to when you created it. Nothing migrates automatically. Anyone who bookmarked, hardcoded, or integrated the old URL is now pointing at stale code.
So the URL is not really unstable. It is stable per deployment. What changes is which deployment you are talking about, and 'New deployment' is the button that changes it.