866cdce209
Fixes #71250. `hermes update` could not repair the embedded Python runtime's vulnerable SQLite (WAL-reset bug range 3.7.0-3.51.2, except backports 3.50.7/3.44.6) on installs where `uv python install <minor>` (bare request, e.g. "3.11") resolves to an older cached/indexed patch that still links a vulnerable SQLite build, even though a newer non-vulnerable patch on the same minor line is available and known to uv. The smoke test correctly rejected the vulnerable candidate every time, but the provisioner gave up immediately after one attempt, leaving the repair permanently stuck in the same failing loop on every `hermes update` run. Implements option D from the issue (query the index, retry with an explicit newer patch), which the reporter identified as cleanest: - New `_list_available_patches()`: runs `uv python list <minor> --all-versions --only-downloads --output-format json --no-config`, filters to cpython/default-variant entries (excluding pypy/graalpy), and returns known patch versions newest-first. Fails safe (returns []) on any network/parse error. - Refactored the single install+find+probe cycle out of `_install_safe_python_generation()` into `_attempt_install_generation()`, reusable per attempt with its own generation directory (so a rejected candidate's files are fully cleaned up before the next attempt, matching the existing --reinstall semantics). - `_install_safe_python_generation()` still tries the bare minor-line request first (preserves the original comment's rationale: for a given exact patch, python-build-standalone may have no artifact with fixed SQLite at all). If that resolves vulnerable, it now queries `_list_available_patches()` and retries with explicit newer patches, newest-first, bounded to `_MAX_PATCH_RETRIES` (5) attempts -- each attempt is a real download+install+probe cycle, so the cap keeps worst-case repair time bounded. Sanity-checked `_list_available_patches()` against the real `uv` binary (0.11.7) in this environment: correctly parses live `uv python list --all-versions --output-format json 3.11` output, returns 14 patches sorted newest-first starting at 3.11.15. 9/9 new tests pass (retry succeeds with a newer patch, exhausts gracefully when every known patch is vulnerable, empty patch list degrades to None without crashing, retry count is bounded, plus direct JSON-parsing unit tests for realistic/malformed/empty uv output); 47/47 in the full tests/hermes_cli/test_managed_uv.py file (including the 3 pre-existing tests for the original bare-minor success path, confirming no regression there).