Skip to content

fix(bootstrap): mirror cascade + system-Python fallback for blocked networks (plan-03, closes #60) - #140

Merged
debpalash merged 2 commits into
mainfrom
004-installer-network-resilience
May 29, 2026
Merged

fix(bootstrap): mirror cascade + system-Python fallback for blocked networks (plan-03, closes #60)#140
debpalash merged 2 commits into
mainfrom
004-installer-network-resilience

Conversation

@debpalash

@debpalash debpalash commented May 29, 2026

Copy link
Copy Markdown
Owner

plan-03Closes #60. Addresses #130, #57, #127.

First-run bootstrap downloaded managed Python from GitHub with no mirror and a short retry budget — a GitHub-blocked/unresolvable network killed the install dead-on-arrival (#60: uv venv failed, DNS error).

Fix (frontend/src-tauri/src/bootstrap.rs)

  • apply_uv_http_env()UV_HTTP_TIMEOUT=120 / UV_HTTP_CONNECT_TIMEOUT=30 / UV_HTTP_RETRIES=5 on both uv venv and uv sync (step 2).
  • uv venv cascade (step 1+3): default GitHub → gh-proxy mirror (UV_PYTHON_INSTALL_MIRROR) → system Python (UV_PYTHON_PREFERENCE=only-system, only when a system Python ≥3.11 is detected). First success wins.
  • Actionable failures (step 5): "install python.org Python 3.11+ / set a mirror / Clean & Retry" instead of a raw uv exit code.
  • Frontend: a BootstrapSplash hint for the GitHub-blocked case.
  • Docs (step 4): troubleshooting.md restricted-network section — mirror env vars, China PyPI index, honest VPN note — referenced by the remediation text.

Cross-platform parity

Mirrors/fallbacks only kick in after the default path fails, so an unrestricted network is unchanged.

Tests

Rust #[cfg(test)]: parse_py_version (real + garbage), apply_uv_http_env sets the three vars — cargo test: 2 passed, crate compiles. Docs-drift validator + frontend build green.

⚠️ Verification reality — please read

This is ~90% Rust in the Tauri bootstrap. The restricted-network E2E paths (mirror install, only-system fallback) depend on real network conditions + a packaged Tauri build and cannot be reproduced in the dev/CI harnesscargo + the unit tests cover compile + the pure helpers only. Recommend a manual smoke on a GitHub-blocked network (or a VM with GitHub firewalled) before relying on it in the wild. Also note: CodeRabbit/Greptile/CodeQL give weaker coverage on Rust than on the Python PRs.

Spec/plan/tasks in specs/004-installer-network-resilience/.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • First-run setup now copes with restricted networks using mirror cascades, system-Python fallback, and extended network timeouts/retries.
  • Bug Fixes

    • Improved bootstrap failure detection and clearer, actionable remediation messages and hints for network-related issues.
  • Documentation

    • Added a troubleshooting guide and a resilience spec/plan describing installer behavior on blocked networks.
  • Tests

    • Added unit tests for version parsing and network-environment handling.

Review Change Stack

…etworks (#130)

plan-03. First-run bootstrap downloaded managed Python from GitHub with no
mirror and a short retry budget, so a GitHub-blocked/unresolvable network
killed the install dead-on-arrival (#60).

bootstrap.rs (Rust/Tauri):
- apply_uv_http_env(): UV_HTTP_TIMEOUT=120 / CONNECT_TIMEOUT=30 / RETRIES=5 on
  both `uv venv` and `uv sync`.
- `uv venv` cascade: default GitHub → gh-proxy mirror (UV_PYTHON_INSTALL_MIRROR)
  → system Python (UV_PYTHON_PREFERENCE=only-system, only if a system Python
  >=3.11 is detected). First success wins.
- Actionable failure messages (install python.org Python / set a mirror / Clean
  & Retry) instead of a raw uv exit code.

Frontend: BootstrapSplash hint for the GitHub-blocked / can't-download-Python
case. Docs: troubleshooting.md restricted-network section (mirror env vars,
China PyPI index, honest VPN note) — referenced by the remediation text.

Tests: Rust #[cfg(test)] for parse_py_version + apply_uv_http_env (cargo test:
2 passed, crate compiles); docs-drift validator + frontend build green.

NOTE: the restricted-network E2E paths (mirror install, only-system fallback)
need MANUAL verification on a real GitHub-blocked network — not reproducible in
the dev/CI harness. cargo + the unit tests cover compile + the pure helpers only.

Closes #60. Addresses #130, #57, #127.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9617b09c-ab39-4a16-a86c-8dcab959f48b

📥 Commits

Reviewing files that changed from the base of the PR and between 7378444 and e2904d9.

📒 Files selected for processing (1)
  • frontend/src-tauri/src/bootstrap.rs

📝 Walkthrough

Walkthrough

This PR implements installer bootstrap resilience for restricted networks by adding mirror-cascade strategies, HTTP timeout injection, system-Python fallback, user-facing remediation messaging, and frontend error detection integrated with updated troubleshooting documentation.

Changes

Installer Bootstrap Network Resilience

Layer / File(s) Summary
Bootstrap helper utilities and tests
frontend/src-tauri/src/bootstrap.rs
Constants for mirror and remediation messaging, plus helper functions apply_uv_http_env, parse_py_version, and system_python_ge_311; unit tests validate parsing and env injection.
venv creation with mirror cascade and fallback
frontend/src-tauri/src/bootstrap.rs
ensure_venv_ready now iterates through uv venv strategies: default, gh-proxy via UV_PYTHON_INSTALL_MIRROR, and optional system-Python-only mode when system Python ≥3.11 is available; sets a remediation message if all attempts fail.
Dependency sync with HTTP resilience
frontend/src-tauri/src/bootstrap.rs
Injects HTTP timeout/retry env for uv sync and surfaces a specific, actionable dependency-install error message on failure.
Frontend error hint detection
frontend/src/components/BootstrapSplash.jsx
detectHints() recognizes error patterns for GitHub/Python-download network blocks and returns guidance to install Python 3.11+ or configure UV_PYTHON_INSTALL_MIRROR, linking to docs.
Specification and troubleshooting documentation
docs/install/troubleshooting.md, specs/004-installer-network-resilience/spec.md, specs/004-installer-network-resilience/plan.md, specs/004-installer-network-resilience/tasks.md
New troubleshooting entry and formal spec/plan/tasks describing the mirror cascade, UV env vars, system Python fallback, and verification steps.

Sequence Diagram

sequenceDiagram
  participant Installer as Installer Bootstrap
  participant UV as uv Command
  participant DefaultHost as GitHub (default)
  participant Mirror as gh-proxy Mirror
  participant SystemPy as System Python ≥3.11
  
  rect rgba(100, 150, 200, 0.5)
  Note over Installer,SystemPy: venv Creation Cascade
  Installer->>UV: uv venv (default host)
  UV->>DefaultHost: Download python-build-standalone
  DefaultHost-->>UV: ✗ Network timeout/DNS error
  UV-->>Installer: Failure
  Installer->>UV: uv venv (gh-proxy mirror via UV_PYTHON_INSTALL_MIRROR)
  UV->>Mirror: Download python-build-standalone
  Mirror-->>UV: ✗ Mirror unreachable
  UV-->>Installer: Failure
  alt System Python ≥3.11 Available
    Installer->>UV: uv venv (UV_PYTHON_PREFERENCE=only-system)
    UV->>SystemPy: Use system Python
    SystemPy-->>UV: ✓ Success
    UV-->>Installer: venv ready
  else No System Python ≥3.11
    Installer->>Installer: Set stage=Failed with remediation message
  end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • #130: Implements the plan-03 bootstrap resilience (mirror cascade, UV_PYTHON_INSTALL_MIRROR, UV_HTTP_* timeout/retry env, and system-Python >=3.11 fallback) referenced by the issue.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding mirror cascade and system-Python fallback for bootstrap resilience on blocked networks, directly addressing issue #60.
Description check ✅ Passed The PR description comprehensively covers the fix methodology, cross-platform parity, testing approach, and verification limitations, but is missing explicit coverage of the PR type checkbox and some checklist items from the template.
Linked Issues check ✅ Passed The code changes fully implement the objectives from issue #60: multiple uv venv retry strategies (default → gh-proxy mirror → system-Python fallback), extended HTTP timeouts/retries, actionable error messaging, frontend hints, and documentation—all directly addressing the installer dead-on-arrival failure when GitHub is unreachable.
Out of Scope Changes check ✅ Passed All changes align with the stated scope: bootstrap resilience, mirror fallback, system-Python detection, failure messaging, frontend hints, and documentation. The spec/plan/tasks files provide architectural rationale and are scoped to this implementation effort.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 004-installer-network-resilience

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR addresses bootstrap failures on GitHub-blocked/restricted networks by adding a three-attempt uv venv cascade (default GitHub → gh-proxy mirror → system Python ≥3.11 with only-system), extended HTTP timeouts/retries via apply_uv_http_env, actionable failure messages, and a BootstrapSplash hint that fires on the new error text. A troubleshooting doc section is added and cross-referenced from both the Rust error strings and the hint UI.

  • Mirror cascade (bootstrap.rs): default → gh-proxy → system-Python (no --python 3.11 pin on the system attempt, correctly addressing the previously flagged 3.12/3.13 mismatch).
  • apply_uv_http_env sets UV_HTTP_TIMEOUT=120, UV_HTTP_CONNECT_TIMEOUT=30, UV_HTTP_RETRIES=5 unconditionally — the docs claim users can override these values via env vars, but cmd.env() silently replaces parent-process env, so any user-set value (e.g. UV_HTTP_TIMEOUT=300 on a very slow mirror) is ignored.
  • The "venv exists but uvicorn missing" repair path (repair_cmd, lines 399-413) still does not call apply_uv_http_env (flagged in a previous review, unaddressed here).

Confidence Score: 4/5

Safe to merge for unrestricted networks; the documented env-var override workaround won't work as described, which could leave users on very slow mirrors with no way to extend the timeout beyond the hardcoded value.

The mirror cascade and system-Python fallback logic are sound and the previously flagged 3.12/3.13 version-pin bug is correctly fixed. The one outstanding defect is that apply_uv_http_env unconditionally overwrites parent-process env vars — the troubleshooting docs explicitly promise users can raise the timeout by setting UV_HTTP_TIMEOUT in their environment, but that setting is silently discarded by cmd.env(). A user on a very slow mirror who follows the docs to set a higher timeout will still time out at 120 s with no indication why.

frontend/src-tauri/src/bootstrap.rs — the apply_uv_http_env helper and the still-missing call on the repair-sync path.

Important Files Changed

Filename Overview
frontend/src-tauri/src/bootstrap.rs Adds mirror cascade (default GitHub → gh-proxy → system Python), apply_uv_http_env for extended timeouts, and actionable error messages; apply_uv_http_env unconditionally overrides user-set env vars, contradicting the docs guidance; the repair-sync path (uvicorn-missing branch) still lacks apply_uv_http_env (previously flagged, still unresolved).
frontend/src/components/BootstrapSplash.jsx Adds a hint detection regex that correctly matches phrases from BOOTSTRAP_REMEDIATION (blocking GitHub, couldn't download Python) and triggers an actionable user hint.
docs/install/troubleshooting.md Adds a restricted-network troubleshooting section covering mirror env vars, China PyPI index, and VPN; item 4 claims users can override the bootstrap's HTTP timeouts via env vars, which is incorrect as written (the bootstrap's apply_uv_http_env overrides them unconditionally).
specs/004-installer-network-resilience/plan.md Spec/plan/tasks documents for this feature; accurately describes the verification gap (E2E restricted-network paths require manual testing).

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ensure_venv_ready] --> B{Venv exists?}
    B -- Yes, uvicorn OK --> C[Return venv_py]
    B -- Yes, uvicorn missing --> D[repair_cmd: uv sync\nNO apply_uv_http_env ⚠️]
    D --> E{repair success?}
    E -- Yes --> C
    E -- No --> F[fail: raw error]
    B -- No --> G[First-run bootstrap]
    G --> H[Attempt 1: default GitHub\napply_uv_http_env ✓]
    H --> I{success?}
    I -- Yes --> J[uv sync\napply_uv_http_env ✓]
    I -- No --> K[Attempt 2: gh-proxy mirror\napply_uv_http_env ✓]
    K --> L{success?}
    L -- Yes --> J
    L -- No --> M{system Python ≥3.11?}
    M -- Yes --> N[Attempt 3: only-system\napply_uv_http_env ✓]
    N --> O{success?}
    O -- Yes --> J
    O -- No --> P[fail: BOOTSTRAP_REMEDIATION]
    M -- No --> P
    J --> Q{sync success?}
    Q -- Yes --> C
    Q -- No --> R[fail: actionable sync message]
Loading

Fix All in Claude Code

Reviews (2): Last reviewed commit: "fix(bootstrap): drop --python 3.11 pin o..." | Re-trigger Greptile

Comment on lines +494 to +500
if system_python_ge_311() {
venv_attempts.push((
"system-python",
vec!["venv", "--python", "3.11"],
vec![("UV_PYTHON_PREFERENCE", "only-system")],
));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 System-Python fallback fails when system Python is 3.12 or 3.13

system_python_ge_311() returns true for any Python ≥ 3.11 (3.12, 3.13, …), so the system-python attempt is added to the cascade. However the args include --python 3.11, which tells uv to look for a Python interpreter matching ==3.11.* exactly. On a machine with only Python 3.12 installed, uv venv --python 3.11 UV_PYTHON_PREFERENCE=only-system will fail because there is no 3.11.x system interpreter, and the user still sees BOOTSTRAP_REMEDIATION despite having a perfectly compatible Python available. Dropping the --python 3.11 pin from the system-Python attempt lets uv resolve any >=3.11 system interpreter automatically.

Suggested change
if system_python_ge_311() {
venv_attempts.push((
"system-python",
vec!["venv", "--python", "3.11"],
vec![("UV_PYTHON_PREFERENCE", "only-system")],
));
}
if system_python_ge_311() {
venv_attempts.push((
"system-python",
vec!["venv"],
vec![("UV_PYTHON_PREFERENCE", "only-system")],
));
}

Fix in Claude Code

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in the latest commit. Dropped the --python 3.11 pin from the system-Python attempt; with only-system + the project's requires-python = ">=3.11", uv resolves any compatible system interpreter (3.12/3.13 included) instead of demanding 3.11.x exactly.

…ptile #140)

system_python_ge_311() accepts 3.12/3.13, but the fallback passed `--python
3.11`, forcing uv to find a 3.11.x interpreter exactly — so a machine with only
3.12/3.13 failed the fallback and wrongly hit the remediation. Drop the pin;
`only-system` + the project's `requires-python = ">=3.11"` lets uv resolve any
compatible system interpreter. cargo test: 2 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@debpalash
debpalash merged commit c34bc00 into main May 29, 2026
17 of 19 checks passed
@debpalash
debpalash deleted the 004-installer-network-resilience branch May 29, 2026 05:14
debpalash added a commit that referenced this pull request May 29, 2026
…gate (#142)

Verification of #140 (driving real uv) found system_python_ge_311() was
stricter than uv's own interpreter discovery: it probed only `python3`/`python`,
so on a machine where `python3` is the macOS 3.9 but a Homebrew 3.14 exists, the
gate returned false and the only-system fallback was skipped — even though
`UV_PYTHON_PREFERENCE=only-system uv venv` resolves 3.14 fine.

Fix: drop the pre-gate (and the now-unused parse_py_version/system_python_ge_311
helpers + the parse test) and always add the system-python attempt as the last
resort. uv's discovery is the authority; with `requires-python = ">=3.11"` it
resolves any compatible system interpreter or fails fast → remediation.

Verified live: `only-system uv venv` created a venv from system CPython 3.14.5
on this host (no 3.11.x present). cargo test + cargo check clean.

Refs #130.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
debpalash added a commit that referenced this pull request May 29, 2026
Bring the branch up to date with main and resolve 5 conflicts as
feature-unions so nothing shipped since #133 was opened regresses:

- useTTS.js: take main's #141 validator-safe instruct (buildDesignInstruct);
  #133 held only the stale pre-#141 dedup logic.
- dub_pipeline.py: UNION — keep #133's download-task cancel cleanup AND
  main's plan-04 logging + structured failure event (build_failure).
- dubSlice.ts / useDubWorkflow.js: UNION — keep both #133's dub
  download-progress state (setDubPrepProgress / setDubCurrentSegId) and
  main's pipeline-error-transparency state (setDubFailure).
- bootstrap.rs: take main's shipped plan-03 network-resilience cascade
  (#140/#142); #133's region-based mirror approach was the superseded
  alternative for the same concern. get_effective_region stays live
  (shared via config.rs, used by tools.rs).

Verified: frontend typecheck + build clean; 90 backend tests pass
(dub / failure / timing / onboarding / personalities), 0 failures.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] ошибка установки

1 participant