Skip to content

feat: add experimental Crabbox environment adapter#1745

Open
zozo123 wants to merge 8 commits into
harbor-framework:mainfrom
zozo123:spike/crabbox-environment
Open

feat: add experimental Crabbox environment adapter#1745
zozo123 wants to merge 8 commits into
harbor-framework:mainfrom
zozo123:spike/crabbox-environment

Conversation

@zozo123

@zozo123 zozo123 commented May 28, 2026

Copy link
Copy Markdown

Summary

  • Add an experimental CrabboxEnvironment example loaded through Harbor's environment.import_path hook.
  • Support SSH-backed Crabbox providers through crabbox inspect --json and provider-managed aliases through a constrained ssh_host_template.
  • Harden lease lifecycle, SSH command construction, subprocess cleanup, and transfer behavior.
  • Add focused unit coverage for the adapter's safety and ownership invariants.

Why this shape

Harbor keeps ownership of tasks, agents, trials, verification, and results. Crabbox keeps ownership of provider credentials, lease acquisition, lease identity, and cleanup. The adapter is the narrow bridge between Harbor's BaseEnvironment operations and an SSH-reachable Crabbox lease.

This stays behind environment.import_path; it does not add a built-in environment enum or a Crabbox dependency to Harbor core.

Hardening included

  • Parse provider-generic lease IDs from Crabbox timing JSON on stderr or the leased <id> stdout line.
  • Release a newly acquired lease when inspection, SSH setup, directory creation, or upload fails later in start().
  • Never auto-release an existing lease supplied through id; preserve state when stop fails so cleanup can be retried.
  • Pass the complete remote shell invocation to OpenSSH as one quoted argument, fixing commands containing spaces, quotes, and shell operators.
  • Honor Harbor's default-user contract and safely quote sudo -n -u execution.
  • Validate environment variable names, inspect-derived SSH fields, and template substitutions before they reach a shell or OpenSSH option parser.
  • Validate the configured Crabbox binary at instance start without rejecting valid custom paths during class-level preflight.
  • Terminate and, if needed, kill timed-out or cancelled local subprocesses.
  • Produce deterministic, non-duplicated directory tar streams and use safe local extraction.
  • Bound failure output included in exceptions.

Provider model

  • Providers exposing sshHost, sshUser, sshPort, and sshKey work directly.
  • Providers with a stable external SSH alias can use ssh_host_template; Islo remains the first documented example.
  • Delegated providers without either surface need a first-class Crabbox exec/transfer session API before they can act as Harbor environments.

Scope and non-goals

This is a Linux, host-level prototype. It does not build the task Dockerfile, reproduce Docker Compose isolation, translate Harbor resource fields, or advertise network-policy support. Those limitations are documented rather than hidden.

Dependencies

Merge or close decision

Merge this as an explicit import-path example if Harbor accepts a documented host-level environment prototype with narrow capabilities and tests.

Close it instead of expanding this PR if Harbor requires every environment example to provide Dockerfile builds, Compose parity, or built-in provider support. Those requirements call for a different CrabboxRemoteDockerEnvironment design or a first-class Crabbox exec/transfer protocol.

Test plan

  • uv run ruff format --check examples/crabbox_environment tests/unit/environments/test_crabbox_environment.py
  • uv run ruff check examples/crabbox_environment tests/unit/environments/test_crabbox_environment.py
  • uv run ty check examples/crabbox_environment/harbor_crabbox/environment.py
  • uv run pytest tests/unit/environments/test_crabbox_environment.py
  • PYTHONPATH=examples/crabbox_environment uv run python -c "from harbor_crabbox.environment import CrabboxEnvironment; print(CrabboxEnvironment.type())"

Local validation for the hardening commit: 13 tests passed, with Ruff, ty, and import validation passing.

@vercel

vercel Bot commented May 28, 2026

Copy link
Copy Markdown

@zozo123 is attempting to deploy a commit to the Harbor Framework Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

Copy link
Copy Markdown
Contributor

Enjoy a better diff viewing experience by clicking one of these URLs:

@zozo123

zozo123 commented May 28, 2026

Copy link
Copy Markdown
Author

Cross-repo stack note:

  • This PR is the provider-generic Harbor adapter foundation.
  • It is intentionally not limited to Islo: any Crabbox provider works if crabbox inspect --json exposes SSH details, and providers with external aliases can use ssh_host_template.
  • Islo is only the first delegated-provider validation example.

Related PRs:

CI note: the previous Ubuntu failure was in unrelated tests/integration/test_deterministic_openhands.py::test_openhands_traces[function_calling_enabled] with empty generated traces while lint/type-check/Windows passed. I pushed an empty chore: retrigger Crabbox adapter CI commit to rerun checks.

@zozo123

zozo123 commented May 28, 2026

Copy link
Copy Markdown
Author

Tracking issue for productionizing provider-generic Crabbox environment support: #1748

@zozo123

zozo123 commented May 28, 2026

Copy link
Copy Markdown
Author

CI rerun status: all checks are now green after the no-op retrigger commit. The earlier Ubuntu failure appears to have been transient/unrelated to this adapter change.

Copy link
Copy Markdown
Collaborator

Enjoy a better diff viewing experience by clicking one of these URLs:


Generated by Claude Code

@zozo123

zozo123 commented May 29, 2026

Copy link
Copy Markdown
Author

Status refresh after the cross-repo dependency landed:

@zozo123

zozo123 commented May 31, 2026

Copy link
Copy Markdown
Author

Status refresh: merged latest harbor-framework/harbor@main into this branch and pushed without conflicts. CI is rerunning on the updated branch.

@zozo123

zozo123 commented May 31, 2026

Copy link
Copy Markdown
Author

Latest status after merging current main: all checks are green again (Ubuntu, Windows, lint, type-check). No conflicts and no unresolved review threads. This PR is ready for Harbor maintainer review/approval.

@zozo123

zozo123 commented Jun 2, 2026

Copy link
Copy Markdown
Author

Status refresh: merged latest harbor-framework/harbor@main into this branch and pushed without conflicts. This PR remains ready for maintainer review; CI is rerunning on the new head.

@zozo123

zozo123 commented Jun 2, 2026

Copy link
Copy Markdown
Author

Latest status: updated with current main, all checks are green again (Ubuntu, Windows, lint, type-check), and there are no unresolved review threads. Ready for maintainer review/approval.

@zozo123

zozo123 commented Jun 10, 2026

Copy link
Copy Markdown
Author

New context worth surfacing, plus a direct question on direction (rather than another status refresh).

Demand signal from Hugging Face. @adithya-s-k (maintainer of huggingface/Repo2RLEnv, which emits Harbor-format tasks) reviewed a downstream crabbox runner I proposed there, declined it as out-of-scope for a synthesis-only repo, and explicitly redirected crabbox support to Harbor:

The good news is you already named the right home … a first-class --env crabbox backend upstream in harbor-framework/harbor. That's where it has real leverage, since every Harbor dataset benefits, not just ours.

Full thread: huggingface/Repo2RLEnv#53.

An honest fit re-assessment. Since this spike opened I've looked harder at Harbor's own pattern: provider environments land natively in src/harbor/environments/ (islo in #1434, TensorLake in #1237, CoreWeave in #1698), and Harbor already covers most of crabbox's container providers natively. So the differentiated value here is narrower than this PR's original framing: it's reach — providers Harbor doesn't cover (namespace-devbox, plain SSH hosts, VM providers like Hetzner/Proxmox/EC2) through one already-installed CLI — not islo, which Harbor already serves natively.

The known gap for anything beyond a spike is benchmark-grade isolation: this adapter executes on the lease host directly instead of building the task's environment/Dockerfile (tracked in #1748). A native env would want docker-on-lease (build + run the task image over the SSH transport).

The question — which direction is worth investing in?

  1. Graduate: native crabbox env in src/ with docker-on-lease isolation and tests mirroring test_islo.py. I'm happy to build this.
  2. Keep as an examples/ recipe, roughly as-is.
  3. Close, in favor of adding native per-provider envs as the need arises.

Any of those is a fine answer — I'd just rather put the work where you actually want it. cc @alexgshaw (you merged the comparable provider-env PRs).

zozo123 commented Jul 18, 2026

Copy link
Copy Markdown
Author

Pushed hardening commit 245200c93724f10c135118c6c933831719a2fcb8.

Key changes: provider-generic lease parsing (including timing JSON on stderr), startup rollback for newly acquired leases, ownership-aware/retryable stop behavior, correct one-argument SSH command quoting, Harbor default-user support, validation for env/template/SSH inputs, bounded subprocess cleanup, deterministic tar uploads, and 13 focused unit tests.

Local validation passed: Ruff format/check, ty, import smoke test, and 13 passed. GitHub Ruff and Type Check are green; the full Python matrix is currently running.

The PR description now states the decision boundary explicitly: merge this as a narrow host-level import-path example, or close it rather than silently growing it into Docker/Compose parity.

zozo123 commented Jul 18, 2026

Copy link
Copy Markdown
Author

Branch update complete:

  • Synced spike/crabbox-environment with current harbor-framework/harbor@main (678bbb6).
  • New head: 812757b (Merge current upstream/main into spike/crabbox-environment).
  • The branch is 0 commits behind main; the diff remains limited to the five intended Crabbox adapter/docs/test files.
  • There are no review submissions or unresolved review threads.
  • Fresh Ruff, type-check, and Python test runs are now executing for the updated head.

The decision boundary remains explicit: merge this as a narrow, tested import-path example, or close it rather than expanding this PR into Docker/Compose parity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants