Summary
Implement the bootstrap phase — the prerequisite for every sandbox-required pipeline (pr_mining, mutation, commit_mining, oss_instruct, equivalence_tests, cve_mining).
An LLM agent runs shell commands inside a long-lived Docker container, observes stdout, iterates until the repo builds and tests can run. Then we commit the container to an image, cache its digest, and reuse the image for every per-task synthesis later. Bootstrap runs once per (repo, ref).
This unlocks every full pipeline planned for v0.2+.
Design doc
See docs/BOOTSTRAP.md for the full design (2-phase architecture, cache strategy, spec changes, edge cases).
Approach
Two architectural calls:
- No external dep — RepoLaunch (Microsoft, MIT) was the obvious adoption candidate, but we wrote our own clean Apache-2.0 implementation using the same ReAct-style pattern. Acknowledgment + license posture documented in the module header.
- Two-phase architecture — Phase 1 (bootstrap, once per repo+ref, cached) → Phase 2 (per-task synthesis, reuses the cached image). Caching is content-addressed under
./envs/<owner>__<name>/<short_commit>/.
What ships in this PR
New module: src/repo2rlenv/bootstrap/
spec.py — BootstrapResult, LanguageHint enum
language.py — auto-detect Python / Node / Go / Rust / Java / C/C++ from repo files; per-language base image
docker.py — DockerSandbox long-lived container wrapper (uses docker cp not bind mount so commits capture the repo)
prompts.py — ReAct system prompt with explicit "SAVE_SETUP as soon as build + tests can RUN — test failures are fine" semantics
agent.py — ReAct loop with on_turn event callback for UI/logging consumers
cache.py — filesystem cache load/save
runner.py — ensure_bootstrap() orchestrator (resolves auth, clones, builds, commits, caches)
ui.py — Rich-based Modal-style live display (header + steps table + stats footer + outcome panel)
__init__.py — public API with explicit acknowledgment header
Spec changes
- New
BootstrapSpec Pydantic model in spec/input.py wired into GenerationInput
- Exported via
spec/__init__.py
LLM cost tracking
LLMResponse now carries cost_usd, prompt_tokens, completion_tokens
- Implementation uses
litellm.completion_cost(response) — built-in model_cost map, no extra dep
- Cost accumulates in
AgentOutcome.total_cost_estimate_usd and BootstrapResult.llm_cost_estimate_usd
CLI
- New `repo2rlenv bootstrap` subcommand with full Rich UI (auto-disabled in non-TTY / `--no-ui`)
- Flags: `--repo --ref --access --llm --max-iterations --max-seconds --cache-dir --image-registry --platform --language --force --no-ui`
Tests (4 new files, 19 new tests; 57/57 total pass)
- `test_bootstrap_spec.py` — Pydantic validation + integration into `GenerationInput`
- `test_bootstrap_language.py` — file-marker-based language detection
- `test_bootstrap_cache.py` — load/save round-trip, tolerates unknown future fields
- `test_bootstrap_agent.py` — ReAct response parser + tool dispatch
Model rename
Updated all references from `claude-sonnet-4-5` to `claude-sonnet-4-6` (14 files: docs + tests + sample configs).
Misc
- `.gitignore` — `envs/`, `envs-*/`, `.r2e_cache/` excluded
- Removed `e2b` from runtime deps (was speculative; not used)
- `rich` added as a runtime dep
Live verification
Bootstrapped `pallets/click` end-to-end on macOS + Docker Desktop:
| Metric |
Value |
| Iterations |
6 |
| Wall time |
88s |
| LLM cost |
$0.119 (claude-sonnet-4-6) |
| Image digest |
`local/r2e-bootstrap/pallets__click@sha256:...` |
| Smoke (`pytest --collect-only`) |
passes |
Then integrated with Harbor: scaffolded a Harbor task via `harbor init --task` whose `environment/Dockerfile` is `FROM` our bootstrap image, ran `harbor run --path ... -a oracle` → Mean reward: 1.000 in 9s. Confirms our bootstrap images are first-class Harbor environments with zero adapter code.
Known follow-ups (out of scope for this PR)
Acceptance
Summary
Implement the bootstrap phase — the prerequisite for every sandbox-required pipeline (
pr_mining,mutation,commit_mining,oss_instruct,equivalence_tests,cve_mining).An LLM agent runs shell commands inside a long-lived Docker container, observes stdout, iterates until the repo builds and tests can run. Then we commit the container to an image, cache its digest, and reuse the image for every per-task synthesis later. Bootstrap runs once per (repo, ref).
This unlocks every full pipeline planned for v0.2+.
Design doc
See
docs/BOOTSTRAP.mdfor the full design (2-phase architecture, cache strategy, spec changes, edge cases).Approach
Two architectural calls:
./envs/<owner>__<name>/<short_commit>/.What ships in this PR
New module:
src/repo2rlenv/bootstrap/spec.py—BootstrapResult,LanguageHintenumlanguage.py— auto-detect Python / Node / Go / Rust / Java / C/C++ from repo files; per-language base imagedocker.py—DockerSandboxlong-lived container wrapper (usesdocker cpnot bind mount so commits capture the repo)prompts.py— ReAct system prompt with explicit "SAVE_SETUP as soon as build + tests can RUN — test failures are fine" semanticsagent.py— ReAct loop withon_turnevent callback for UI/logging consumerscache.py— filesystem cache load/saverunner.py—ensure_bootstrap()orchestrator (resolves auth, clones, builds, commits, caches)ui.py— Rich-based Modal-style live display (header + steps table + stats footer + outcome panel)__init__.py— public API with explicit acknowledgment headerSpec changes
BootstrapSpecPydantic model inspec/input.pywired intoGenerationInputspec/__init__.pyLLM cost tracking
LLMResponsenow carriescost_usd,prompt_tokens,completion_tokenslitellm.completion_cost(response)— built-in model_cost map, no extra depAgentOutcome.total_cost_estimate_usdandBootstrapResult.llm_cost_estimate_usdCLI
Tests (4 new files, 19 new tests; 57/57 total pass)
Model rename
Updated all references from `claude-sonnet-4-5` to `claude-sonnet-4-6` (14 files: docs + tests + sample configs).
Misc
Live verification
Bootstrapped `pallets/click` end-to-end on macOS + Docker Desktop:
Then integrated with Harbor: scaffolded a Harbor task via `harbor init --task` whose `environment/Dockerfile` is `FROM` our bootstrap image, ran `harbor run --path ... -a oracle` → Mean reward: 1.000 in 9s. Confirms our bootstrap images are first-class Harbor environments with zero adapter code.
Known follow-ups (out of scope for this PR)
Acceptance