Pluggable PHP-distribution backends.
A Backend resolves a user-facing request (bougie php install 8.4)
into a [PhpRecipe] — a self-contained description of one blob to
download and how to extract it. Today there's exactly one
implementation, [bougie_index::BougieIndexBackend], which talks to
index.bougie.tools (or a configured mirror) using the signed
root → section → manifest protocol. Phase 3 of WINDOWS_PLAN.md adds
WindowsPhpNetBackend, which fetches releases.json from
windows.php.net and synthesizes a PhpRecipe for that distribution.
The trait deliberately keeps the surface narrow: resolution is
pure-ish (network I/O, no filesystem mutation). The recipe carries
everything install_php needs to drive [bougie_fetch::fetch_blob],
so the install code is identical across backends — the only
per-backend choice is which Backend impl to construct.
The trait grows symmetrically for extensions: resolve_extension
returns an [ExtRecipe] that carries everything install_extension
needs to drive the same fetch + place + conf.d dance regardless of
backend. Closure peers (bougie-index only) ride on the recipe as a
[ClosureRef] list — windows.php.net always returns an empty one,
and the install code's closure-handling step is a no-op for it.