Stock
A bundle holds no stock of its own. Its availability is derived from what its components can supply — which is the whole difference between a bundle and a variant, and the reason a bundle can sell out without anyone editing it.
Two questions, two answers
"Can I build this box?" — exact. Given a configuration, the answer is the fewest boxes any one component can cover:
Mug: 10 in stock, 1 per box → 10 boxes
Tea: 4 in stock, 2 per box → 2 boxes
────────
2 boxes
"Is this bundle in stock at all?" — optimistic. Given no configuration, the answer is the best case across every way the box could be filled. It is an upper bound by construction, because saying "out of stock" when some box could still be built would hide a sellable product from a catalogue.
{{ craft.present.availability(bundle) }} {# optimistic #}
{{ craft.present.availability(bundle, configuration) }} {# exact #}
What counts as a limit
A component limits a bundle only if it is inventory-tracked and not allowed to be sold out of
stock. Untracked and sell-out-of-stock both mean "do not let this limit anything", and Present
reports them as null — unlimited — rather than as a stock figure of zero. Conflating the two is
how a perfectly sellable box gets marked unavailable.
One unlimited option in a slot makes the whole slot unlimited: every box could be filled from it.
The same variant in two slots
Counted once, across both. A variant offered in two slots and picked in both is two units of one thing, and anything that checks stock per slot lets twice as many through.
What Present does not reimplement
Commerce already validates stock per purchasable, summed across every line item on the order, and already commits it on order completion. Because components are real line items, all of that applies to a bundle's contents for free — including when the same variant is also in the cart on its own.
What Present adds is catching it earlier and saying something useful. A shopper adding a box with too little tea is told which shelf is empty, rather than meeting Commerce's per-item stock error on whichever component happened to fail first.
Enforcement
Enforce the stock rollup (on by default) makes a bundle unavailable when its components cannot supply a single box. Turn it off and the bundle stays purchasable; Commerce catches the shortfall at the line item instead — later, and with a worse message.
In the control panel
The bundles index has a Buildable column. The bundle edit screen shows the rollup and what is
limiting it. php craft present/bundles/check gives the same across every bundle at once — which is
the question to ask before discontinuing a variant, since a variant with no orders may still be
holding up six gift boxes.