examples: crabbox runner for pr_diff tasks#53
Conversation
|
Quick status — this is ready for review: Live demo → https://zozo123.github.io/repo2rlenv-crabbox-demo/ (the same architecture diagram + the three verified runs from the PR description, with the captured CI gate mirrored locally (the three jobs in The 5 skipped are pre-existing (private HF e2e, hub-build smoke, ghcr live probe, …) plus the live-islo smoke I added — it requires Branch is current with Happy to address any feedback or follow up with a |
Score Repo2RLEnv pr_diff tasks on any crabbox sandbox provider via a single --provider flag — local-container (docker), islo, e2b, modal, daytona, namespace-devbox, tensorlake. Per-provider crabbox flag names aren't consistent (--islo-image, --e2b-template, --daytona-snapshot, --namespace-image, ...); a PROVIDER_CONFIG table makes the mapping explicit. Unsupported providers raise ValueError listing the supported names and noting why VM providers (aws, azure, gcp, hetzner, proxmox, ssh) need a separate adapter. Files: - examples/crabbox/runner.py — stdlib-only Python (tomllib, argparse, concurrent.futures). Single-task + parallel batch (--all -j N -> CSV) modes. Honors task.toml's reproducibility.image_ref; --allow-env for forwarding ANTHROPIC_API_KEY etc. to the verifier's LLM-judge. - examples/crabbox/crabbox.sh — 3-line shim that execs runner.py. - examples/crabbox/README.md — provider matrix, quickstart, scope. - tests/test_examples_crabbox.py — 21 unit tests parametrized over every supported provider (monkeypatched subprocess, no network or binary required); preflight error paths (missing crabbox / missing ISLO_API_KEY / missing task files); image_ref-default honored; task.repo / task.ref passed as positional bash args so a poisoned task.toml can't shell-inject. One live islo smoke gated on ISLO_API_KEY + crabbox on PATH (opt-in, skipped in CI). Reward exfil is over a sentinel-delimited stdout because islo's delegate-exec mode doesn't support crabbox --download / --capture-stdout. Verified end-to-end on a live islo.dev sandbox: oracle diff -> 1.0, empty diff -> 0.0, 3-task batch j=3 -> 1.0 each in ~57s wall. ruff check + ruff format --check clean. pytest -q: 743 passed, 5 skipped (4 pre-existing + the gated live-islo smoke).
2b05de7 to
727d33f
Compare
|
Updated the branch (force-pushed) with a self-review pass — squashed to a single commit and addressed five issues a careful reviewer would surface:
Tests: 20 unit + 1 gated live. |
|
Hey @zozo123, thank you for this, genuinely. I went through it carefully and it's excellent work: stdlib-only, zero That said, I don't think it's quite the right fit for this repo, and that's an architecture call, not a quality one. Repo2RLEnv is deliberately synthesis-only and provider-agnostic: we delegate the runtime/consumption layer to Harbor rather than own it ( The good news is you already named the right home in your "out of scope" section: a first-class Too good to bury in |
|
Thanks @adithya-s-k — that's a completely fair call, and the kind of clear architectural boundary that keeps a project healthy. "Synthesis-only, delegate the runtime layer to Harbor" is exactly the right line, and a provider-routing runner sits on the wrong side of it no matter how small the diff or how carefully it stays out of You're also right that I'd already named the proper home for this: I'll port it upstream to harbor-framework/harbor as a first-class Closing this accordingly. Thanks for the careful read and the kind words about the injection-safety and test work — genuinely appreciated 🙏 |
|
Following up on the promise above — the Harbor-side stack is up (it predates this thread, in fact):
@adithya-s-k — if you still think a crabbox backend has leverage for Harbor-format datasets, a short note to that effect on harbor#1745 would genuinely help the Harbor maintainers gauge demand. Thanks again for the redirect 🙏 |
Summary
examples/crabbox/— a small Python adapter (runner.py, stdlib only) + acrabbox.shshim — that scores Repo2RLEnvpr_difftasks on any crabbox sandbox provider via a single--providerflag.PROVIDER_CONFIGtable:local-container(docker) ·islo·e2b·modal·daytona·namespace-devbox·tensorlake. Per-provider flag names are not consistent across crabbox (--islo-image,--e2b-template,--daytona-snapshot,--local-container-image,--namespace-image, …); the table makes the mapping explicit.ValueErrorlisting the supported names and explaining why VM providers need a pre-baked image (separate, larger lift).src/. No new runtime deps. Lives entirely underexamples/+ a single test file. Diff: +863 / −0, one commit.Live demo
▶ https://zozo123.github.io/repo2rlenv-crabbox-demo/ — architecture, the runs below, the full pytest output.
Test plan
tests/test_examples_crabbox.pyparametrize over every supported provider, monkeypatchsubprocess.run, and assert the exactcrabboxargv constructed (image-flag, workdir-flag,--keep,--allow-env, no-sentinel error path, preflight rejections for missingcrabbox/ missingISLO_API_KEY/ missing task files,image_refhonored fromtask.toml, repo/ref passed as positional bash args so a poisoned task.toml cannot shell-inject). No network, nocrabboxbinary required.ISLO_API_KEY+crabboxonPATH(skipped in CI by default). Pullspallets__click-3466from the public reference dataset, scores the oracle, assertsfinal_reward == 1.0.uv run pytest -q— 743 passed, 5 skipped (4 pre-existing gated tests + the live islo one).uv run ruff check .— clean.uv run ruff format --check .— clean.uv build— sdist + wheel OK.Verified end-to-end on a live islo.dev sandbox
final_rewardpallets__click-3466)-j 3(click ×2 + chalk)Design notes
--download/--capture-stdoutaren't supported on that provider. The remote script emits a sentinel andcats/logs/verifier/reward.json; the host parses it from the subprocess pipe. Portable across every supported provider.task.repo/task.refcome from a third-party file (task.toml). They're passed as positional$1/$2arguments tobash -lc, never interpolated into the script body — a maliciousrepo = "foo; rm -rf /"cannot escape its variable expansion.image_refhonored: the wrapper defaults--imagetotask.image_ref(the value pinned by the task.toml), only falling back topython:3.12-slimif the task didn't specify one. A pr_runtime task pinning a bootstrap image is now scored on that image rather than silently downgrading.crabboxbinary, missingISLO_API_KEY(when provider=islo), and missing task files (task.toml/environment/Dockerfile/tests/test.sh/ agent patch) all fail fast with actionable messages before any sandbox is leased.[ -s agent.diff ]guards thegit applyso "agent gave up" scores its baseline instead of crashing./workspacerewrite: test.sh hardcodes/workspaceas the repo root; islo also uses/workspaceas its sync mount. The rewrite issed -E 's#(^|[^A-Za-z0-9_/])/workspace([^A-Za-z0-9_]|$)#\1/repo\2#g'so it only matches the whole-token path, not strings that merely contain/workspace.examples/, notsrc/: perCLAUDE.md("Norepo2rlenv run/ no parallel sandbox runtime — for full tasks, users runharbor run. We're synthesis-only."), this is a downstream-consumer recipe.Out of scope (happy to follow up if there's interest)
pr_runtime/commit_runtime/cve_patchesand the other sandbox pipelines — they build a per-repo Docker image duringrepo2rlenv bootstrapand need docker-in-docker (or a pre-pushed registry image).--env crabboxbackend in Harbor — that belongs upstream inharbor-framework/harbor.aws,hetzner, etc.) — currently rejected with a helpful error; supporting them would mean a separate "warmup" path that bakes Python + git into a custom AMI.