@DefinedRobo Before building anything, ask your 3PL whether their system supports substitute or alternate SKUs. Most WMS platforms do. You map SKU A with a fallback to SKU B, and the warehouse picks whichever it has.
If they support it, the whole problem leaves Shopify. One variant, one UPC, one combined inventory number, no hidden variants, no javascript, no order editing, no race condition. Its worth one email before you spend a week on the harder version.
If they cant, then on the storefront approach above, the race condition isnt actually your biggest risk. The bigger hole is that add to cart javascript only runs on your product page. Plenty of things create carts without ever loading it:
cart permalinks, the Shop app, Google and Meta product feeds, abandoned cart emails, back in stock emails, buy buttons, subscription reorders, and Shopifys agentic channel feeding ChatGPT, which is live now. Every one of those carries a variant id straight to checkout. So eventually someone buys hidden variant B while A still has stock, or hits A after its empty, and your product page logic never gets a say.
On the race condition itself, its less scary than it sounds. Shopify revalidates inventory at checkout, so two people racing for the last unit of A means the second one gets a checkout error rather than a wrong box. The thing that would actually cause a mis-ship is Continue selling when out of stock being ticked. Worth confirming thats off on both variants, since that single setting is the difference between a failed checkout and a wrong item leaving the warehouse.
One thing worth doing whichever route you take. Write the intended packaging into a line item property when the item goes into the cart. It lands on the order and the packing slip, so the warehouse has a human readable cross check that doesnt depend on any of this working.
And to close one door before someone suggests it, Cart Transform functions wont do this either. Expand is driven by metafields on the parent variant, so the components are fixed in advance and the function cant look at live stock and choose.