Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Harbor Environment","local":"harbor-environment","sections":[{"title":"Quick start","local":"quick-start","sections":[],"depth":2},{"title":"Execution modes","local":"execution-modes","sections":[],"depth":2},{"title":"Task policies","local":"task-policies","sections":[],"depth":2},{"title":"The task format","local":"the-task-format","sections":[],"depth":2},{"title":"Rewards","local":"rewards","sections":[],"depth":2},{"title":"Action space","local":"action-space","sections":[],"depth":2},{"title":"Working with Repo2RLEnv","local":"working-with-repo2rlenv","sections":[],"depth":2},{"title":"Writing a task that runs in both places","local":"writing-a-task-that-runs-in-both-places","sections":[],"depth":2},{"title":"Configuration","local":"configuration","sections":[],"depth":2},{"title":"Running in Docker","local":"running-in-docker","sections":[],"depth":2},{"title":"Examples","local":"examples","sections":[],"depth":2},{"title":"Layout","local":"layout","sections":[],"depth":2},{"title":"Tests","local":"tests","sections":[],"depth":2}],"depth":1}"/> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/entry/start.B9IBUExw.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/chunks/DTQnX4l5.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/chunks/DfHjNWj2.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/entry/app.CiZ4jjXn.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/chunks/Ba1drWuH.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/chunks/K5XANBgt.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/chunks/DsnmJJEf.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/chunks/PGLvW8OU.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/nodes/0.Cl0mWmHV.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/chunks/CFswWuIO.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/nodes/3.PDbBxqNS.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/chunks/Bln0COW0.js" rel="modulepreload"> | |
| <!--gg71d6--><meta name="hf:doc:metadata" content="{"title":"Harbor Environment","local":"harbor-environment","sections":[{"title":"Quick start","local":"quick-start","sections":[],"depth":2},{"title":"Execution modes","local":"execution-modes","sections":[],"depth":2},{"title":"Task policies","local":"task-policies","sections":[],"depth":2},{"title":"The task format","local":"the-task-format","sections":[],"depth":2},{"title":"Rewards","local":"rewards","sections":[],"depth":2},{"title":"Action space","local":"action-space","sections":[],"depth":2},{"title":"Working with Repo2RLEnv","local":"working-with-repo2rlenv","sections":[],"depth":2},{"title":"Writing a task that runs in both places","local":"writing-a-task-that-runs-in-both-places","sections":[],"depth":2},{"title":"Configuration","local":"configuration","sections":[],"depth":2},{"title":"Running in Docker","local":"running-in-docker","sections":[],"depth":2},{"title":"Examples","local":"examples","sections":[],"depth":2},{"title":"Layout","local":"layout","sections":[],"depth":2},{"title":"Tests","local":"tests","sections":[],"depth":2}],"depth":1}"/><!----> | |
| <link href="/docs/openenv/pr_1018/en/_app/immutable/assets/0.tn0RQdqM.css" rel="modulepreload"> <!--[--><!--[0--><!--[--><!--[0--><!--[--><p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg><!----></button></div> <!--[-1--><!--]--></div><!----> <!--[0--><h1 class="relative group"><a id="harbor-environment" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#harbor-environment"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Harbor Environment</span></h1><!--]--><!----> <p>Runs <a href="https://www.harborframework.com/docs/tasks" rel="nofollow">Harbor</a> task directories as an | |
| OpenEnv environment.</p> <p><strong>The task directory is the interface.</strong> A directory that <code>harbor run</code> accepts is | |
| served here unchanged — no conversion, no re-authoring, no second copy of the | |
| data. That covers Terminal-Bench-lineage tasks and everything <a href="https://github.com/huggingface/Repo2RLEnv" rel="nofollow">Repo2RLEnv</a> generates from a GitHub | |
| repository, so a task set built for evaluation is also a training environment.</p> <p>The reward always comes from the task’s own verifier. This environment forwards | |
| it and never computes one of its own.</p> <!--[1--><h2 class="relative group"><a id="quick-start" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#quick-start"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Quick start</span></h2><!--]--><!----> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-bash "><!----><span class="hljs-comment"># 1. Serve the bundled example task</span> | |
| uv run --project envs/harbor_env server | |
| <span class="hljs-comment"># 2. Solve it through the client</span> | |
| PYTHONPATH=src:envs uv run python envs/harbor_env/examples/quickstart.py<!----></pre></div><!----> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-python "><!----><span class="hljs-keyword">import</span> asyncio | |
| <span class="hljs-keyword">from</span> harbor_env <span class="hljs-keyword">import</span> HarborEnv | |
| <span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">main</span>(): | |
| env = HarborEnv(base_url=<span class="hljs-string">"http://localhost:8000"</span>) | |
| start = <span class="hljs-keyword">await</span> env.reset(task_id=<span class="hljs-string">"fix-sum-bug"</span>) | |
| <span class="hljs-built_in">print</span>(start.observation.instruction) <span class="hljs-comment"># the task's instruction.md</span> | |
| <span class="hljs-keyword">await</span> env.write_file(<span class="hljs-string">"stats.py"</span>, my_fix) <span class="hljs-comment"># the agent works</span> | |
| result = <span class="hljs-keyword">await</span> env.evaluate() <span class="hljs-comment"># the task's tests/test.sh grades it</span> | |
| <span class="hljs-built_in">print</span>(result.reward) <span class="hljs-comment"># 1.0</span> | |
| <span class="hljs-built_in">print</span>(result.observation.info[<span class="hljs-string">"reward_metrics"</span>]) | |
| <span class="hljs-keyword">await</span> env.close() | |
| asyncio.run(main())<!----></pre></div><!----> <p>Point it at your own tasks with <code>HARBOR_TASKS_DIR</code>, which accepts a local | |
| directory or a Hugging Face dataset:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-bash "><!---->HARBOR_TASKS_DIR=./tasks uv run --project envs/harbor_env server | |
| HARBOR_TASKS_DIR=hf://datasets/my-org/click-tasks uv run --project envs/harbor_env server | |
| HARBOR_TASKS_DIR=./tasks HARBOR_MODE=docker uv run --project envs/harbor_env server<!----></pre></div><!----> <!--[1--><h2 class="relative group"><a id="execution-modes" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#execution-modes"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Execution modes</span></h2><!--]--><!----> <table><thead><tr><th>Mode</th><th>How it runs</th><th>Use it for</th></tr></thead><tbody><tr><td><code>docker</code> (default)</td><td>Inside the task’s own image, files streamed over the Docker API</td><td>Everything — and the only backend that can enforce a task’s network, resource and user policies</td></tr><tr><td><code>local</code></td><td>Subprocesses under a per-episode directory tree</td><td>Self-contained tasks on Docker-less hosts such as Hugging Face Spaces</td></tr></tbody></table> <blockquote><p><strong><code>local</code> mode is not a security boundary.</strong> <code>exec</code> runs shell commands as | |
| the server’s own user, so a task or a policy can read whatever that user can | |
| and can reach the network. It is opt-in for that reason.</p> <p>The server’s environment is not passed through — only <code>PATH</code>, <code>HOME</code> and a | |
| short allowlist — which keeps API keys out of the common case. Treat that as | |
| hygiene, <strong>not</strong> containment: on Linux a child process can still recover the | |
| parent’s environment through <code>/proc/<ppid>/environ</code>. If a policy you do not | |
| control can reach the socket, use <code>docker</code> mode.</p></blockquote> <p><code>local</code> mode refuses any task whose <code>task.toml</code> declares a policy it cannot | |
| enforce — <code>network_mode</code>, <code>cpus</code>/<code>memory_mb</code>, or an <code>[agent].user</code> — rather than | |
| running it unconstrained and reporting a score the task never sanctioned.</p> <p><code>docker</code> mode needs the <code>docker</code> Python package. It ships in this environment’s | |
| own dependencies, so <code>uv run --project envs/harbor_env server</code> already has it; | |
| add it explicitly when driving the environment from the repo root:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-bash "><!---->PYTHONPATH=src:envs uv run --with docker python envs/harbor_env/examples/validate_taskset.py --mode docker<!----></pre></div><!----> <p>A task is <strong>self-contained</strong> when it ships its starting files in <code>environment/</code> and declares no <code>environment/Dockerfile</code> or <code>docker-compose.yaml</code>. Those run in | |
| either mode. Anything else — including every <code>repo2rlenv</code> task with an <code>environment/Dockerfile</code> — needs <code>docker</code>, and <code>local</code> mode says so explicitly | |
| rather than grading an empty directory:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class=" "><!---->task <span class="hljs-string">'pallets__click-2951'</span> keeps its starting state <span class="hljs-keyword">in</span> <span class="hljs-keyword">a</span> container image | |
| (environment/Dockerfile), which <span class="hljs-keyword">the</span> <span class="hljs-built_in">local</span> backend cannot reproduce. | |
| Run <span class="hljs-keyword">the</span> server <span class="hljs-keyword">with</span> HARBOR_MODE=docker, <span class="hljs-keyword">or</span> use <span class="hljs-keyword">a</span> task that ships its <span class="hljs-built_in">files</span> <span class="hljs-keyword">in</span> environment/.<!----></pre></div><!----> <!--[1--><h2 class="relative group"><a id="task-policies" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#task-policies"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Task policies</span></h2><!--]--><!----> <p><code>task.toml</code> may constrain how a task runs. These are honoured in <code>docker</code> mode | |
| and cause <code>local</code> mode to refuse the task:</p> <table><thead><tr><th>Declaration</th><th>Effect</th></tr></thead><tbody><tr><td><code>[environment].network_mode = "no-network"</code></td><td>The container gets no network</td></tr><tr><td><code>[environment].cpus</code> / <code>memory_mb</code> / <code>storage_mb</code></td><td>Real container limits</td></tr><tr><td><code>[environment].workdir</code></td><td>Overrides the image’s <code>WORKDIR</code></td></tr><tr><td><code>[agent].user</code> / <code>[verifier].user</code></td><td>That phase runs as the named account</td></tr><tr><td><code>network_mode = "allowlist"</code>, <code>gpus</code></td><td><strong>Refused</strong> — needs a filtering proxy / accelerators this backend does not provide. Grade with <code>harbor run</code>.</td></tr></tbody></table> <p>A task whose phases disagree (say a <code>public</code> agent and a <code>no-network</code> verifier) | |
| gets the <strong>restrictive</strong> setting for the whole episode: a container has one | |
| network, and resolving the conflict permissively would hand a sandboxed | |
| verifier the internet.</p> <!--[1--><h2 class="relative group"><a id="the-task-format" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#the-task-format"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>The task format</span></h2><!--]--><!----> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-text "><!----><task>/ | |
| ├── task.toml # config + metadata (required) | |
| ├── instruction.md # the prompt shown to the agent | |
| ├── environment/ # Dockerfile, compose file, or seed files | |
| ├── tests/ | |
| │ └── test.sh # the verifier (required to grade) | |
| └── solution/ | |
| └── solve.sh # the reference solution (optional)<!----></pre></div><!----> <p>Both spellings of the schema field are read: Harbor writes <code>schema_version</code>, | |
| Repo2RLEnv writes <code>version</code>. Harbor’s special paths are honoured exactly:</p> <table><thead><tr><th>Path</th><th>Contents</th><th>When</th></tr></thead><tbody><tr><td>working directory</td><td>what the agent edits — the image’s <code>WORKDIR</code></td><td>for the whole episode</td></tr><tr><td><code>/tests</code></td><td>the task’s <code>tests/</code></td><td>staged just before the verifier runs</td></tr><tr><td><code>/solution</code></td><td>the task’s <code>solution/</code></td><td>staged only for <code>solve</code></td></tr><tr><td><code>/logs/verifier</code></td><td><code>reward.json</code> / <code>reward.txt</code></td><td>written by the verifier</td></tr><tr><td><code>/logs/agent</code></td><td>scratch space for agent logs</td><td>for the whole episode</td></tr></tbody></table> <!--[1--><h2 class="relative group"><a id="rewards" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#rewards"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Rewards</span></h2><!--]--><!----> <p>The verifier writes its verdict into <code>/logs/verifier</code>; <code>reward.json</code> is read | |
| first and <code>reward.txt</code> is the fallback, matching Harbor.</p> <table><thead><tr><th>Verifier wrote</th><th><code>result.reward</code></th><th><code>observation.info["reward_source"]</code></th></tr></thead><tbody><tr><td><code>reward.json</code> with a <code>reward</code> key</td><td>that value</td><td><code>reward.json</code></td></tr><tr><td><code>reward.json</code> with one metric</td><td>that value</td><td><code>reward.json</code></td></tr><tr><td><code>reward.json</code> with several metrics, no <code>reward</code> key</td><td>falls back to <code>reward.txt</code></td><td><code>reward.txt</code></td></tr><tr><td><code>reward.txt</code> only</td><td>that value</td><td><code>reward.txt</code></td></tr><tr><td>nothing</td><td><code>None</code>, <code>success=False</code></td><td><code>missing</code></td></tr></tbody></table> <p>Every numeric metric from <code>reward.json</code> is surfaced in <code>observation.info["reward_metrics"]</code>, and Repo2RLEnv’s nested <code>reward-details.json</code> sidecar (F2P/P2P counts, diff-similarity components) in <code>observation.info["reward_details"]</code>.</p> <p>A verifier that writes no reward file yields <strong>no reward at all</strong>, not a <code>0.0</code>. | |
| A fabricated zero is indistinguishable from a genuine failure and would quietly | |
| poison a training run.</p> <!--[1--><h2 class="relative group"><a id="action-space" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#action-space"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Action space</span></h2><!--]--><!----> <p><code>HarborAction.action_type</code> is one of:</p> <table><thead><tr><th>Action</th><th>Fields</th><th>Purpose</th></tr></thead><tbody><tr><td><code>exec</code></td><td><code>command</code>, <code>timeout_s</code></td><td>Run a shell command in the working directory</td></tr><tr><td><code>read</code></td><td><code>path</code></td><td>Read a file, relative to the working directory</td></tr><tr><td><code>write</code></td><td><code>path</code>, <code>content</code></td><td>Write a file, relative to the working directory</td></tr><tr><td><code>evaluate</code></td><td>—</td><td>Run <code>tests/test.sh</code> and end the episode</td></tr><tr><td><code>solve</code></td><td>—</td><td>Apply <code>solution/solve.sh</code> — Harbor’s oracle agent</td></tr></tbody></table> <p><code>exec</code>, <code>read</code> and <code>write</code> are the agent’s action space. <code>evaluate</code> and <code>solve</code> are training-orchestration controls: they decide when an episode ends and can | |
| hand over the answer, so they belong on the infrastructure side of OpenEnv’s <a href="https://github.com/huggingface/OpenEnv/blob/main/rfcs/001-architecture.md" rel="nofollow">dual API boundary</a>. | |
| Set <code>HARBOR_ALLOW_CONTROL_ACTIONS=0</code> to have the server refuse them outright, | |
| for deployments where a policy can reach the same socket.</p> <p><code>evaluate</code> ends the episode. Every later action is refused and keeps reporting <code>done=True</code> — the episode never returns to a running state without <code>reset()</code>.</p> <p><code>read</code> and <code>write</code> are confined to the working directory, so an agent cannot | |
| reach <code>/tests</code> or <code>/solution</code>. The verifier log directory is also cleared | |
| immediately before the verifier runs, so a planted reward file cannot survive | |
| into the score.</p> <!--[1--><h2 class="relative group"><a id="working-with-repo2rlenv" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#working-with-repo2rlenv"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Working with Repo2RLEnv</span></h2><!--]--><!----> <p><a href="https://github.com/huggingface/Repo2RLEnv" rel="nofollow">Repo2RLEnv</a> turns a GitHub | |
| repository into verifiable Harbor tasks. The output needs no conversion:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-bash "><!----><span class="hljs-comment"># 1. Synthesize tasks from a repository</span> | |
| repo2rlenv generate --repo pallets/click --pipeline pr_runtime \ | |
| --pipeline-opt <span class="hljs-built_in">limit</span>=10 --llm anthropic/claude-sonnet-4-6 --out ./tasks | |
| <span class="hljs-comment"># 2. Check every task is solvable by its own oracle before training on it</span> | |
| PYTHONPATH=src:envs uv run --with docker python envs/harbor_env/examples/validate_taskset.py \ | |
| --tasks ./tasks --mode docker | |
| <span class="hljs-comment"># 3. Serve them</span> | |
| HARBOR_TASKS_DIR=./tasks HARBOR_MODE=docker uv run --project envs/harbor_env server<!----></pre></div><!----> <p>Tasks published with <code>repo2rlenv push</code> live under <code>tasks/<id>/</code> in a Hugging Face | |
| dataset; that layout is discovered automatically, so <code>HARBOR_TASKS_DIR=hf://datasets/<org>/<name></code> is enough.</p> <p>Rewards line up with what the pipeline produced: <code>test_execution</code> (<code>f2p_rate × p2p_rate</code>) for the <code>_runtime</code> pipelines and <code>diff_similarity</code> for <code>pr_diff</code>, forwarded exactly as the verifier computed them.</p> <!--[1--><h2 class="relative group"><a id="writing-a-task-that-runs-in-both-places" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#writing-a-task-that-runs-in-both-places"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Writing a task that runs in both places</span></h2><!--]--><!----> <p>Harbor’s absolute paths only exist inside a container. A verifier that prefers | |
| the <code>HARBOR_*</code> variables and falls back to those paths runs unchanged under <code>harbor run</code>, under <code>docker</code> mode, and under <code>local</code> mode:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-bash "><!----><span class="hljs-meta">#!/bin/bash</span> | |
| <span class="hljs-built_in">set</span> -uo pipefail | |
| LOGS_DIR=<span class="hljs-string">"<span class="hljs-variable">${HARBOR_LOGS_DIR:-/logs/verifier}</span>"</span> | |
| TESTS_DIR=<span class="hljs-string">"<span class="hljs-variable">${HARBOR_TESTS_DIR:-/tests}</span>"</span> | |
| WORKDIR=<span class="hljs-string">"<span class="hljs-variable">${HARBOR_WORKDIR:-$(pwd)}</span>"</span> | |
| <span class="hljs-built_in">mkdir</span> -p <span class="hljs-string">"<span class="hljs-variable">$LOGS_DIR</span>"</span> | |
| <span class="hljs-built_in">cd</span> <span class="hljs-string">"<span class="hljs-variable">$WORKDIR</span>"</span> | |
| <span class="hljs-comment"># ...grade, then write the reward...</span> | |
| <span class="hljs-built_in">echo</span> <span class="hljs-string">'{"reward": 1.0}'</span> > <span class="hljs-string">"<span class="hljs-variable">$LOGS_DIR</span>/reward.json"</span> | |
| <span class="hljs-built_in">exit</span> 0 <span class="hljs-comment"># the reward file is the verdict, not the exit code</span><!----></pre></div><!----> <p>The bundled <code>examples/tasks/fix-sum-bug</code> task does exactly this, and grades | |
| identically across all three runtimes (verified against <code>harbor</code> 0.20.0):</p> <table><thead><tr><th>Runtime</th><th>Untouched task</th><th>After <code>solution/solve.sh</code></th></tr></thead><tbody><tr><td><code>harbor run -a nop</code> / <code>-a oracle</code></td><td>0.600</td><td>1.000</td></tr><tr><td><code>harbor_env</code> in <code>local</code> mode</td><td>0.600</td><td>1.000</td></tr><tr><td><code>harbor_env</code> in <code>docker</code> mode</td><td>0.600</td><td>1.000</td></tr></tbody></table> <p>Reproduce the first row with <code>harbor run -p envs/harbor_env/examples/tasks/fix-sum-bug -a nop</code> and the other two with <code>examples/validate_taskset.py</code>.</p> <p>A verifier that hardcodes <code>/logs/verifier</code> still works in <code>docker</code> mode; in <code>local</code> mode the episode reports that it could not be scored and names the fix.</p> <!--[1--><h2 class="relative group"><a id="configuration" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#configuration"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Configuration</span></h2><!--]--><!----> <table><thead><tr><th>Variable</th><th>Default</th><th>Meaning</th></tr></thead><tbody><tr><td><code>HARBOR_TASKS_DIR</code></td><td>bundled examples</td><td>Task directory, or <code>hf://datasets/<org>/<name>[@rev]</code></td></tr><tr><td><code>HARBOR_MODE</code></td><td><code>docker</code></td><td><code>docker</code> or <code>local</code></td></tr><tr><td><code>HARBOR_ALLOW_CONTROL_ACTIONS</code></td><td><code>1</code></td><td>Accept <code>evaluate</code>/<code>solve</code>; set <code>0</code> for agent-facing deployments</td></tr><tr><td><code>HARBOR_DEFAULT_TASK_ID</code></td><td>—</td><td>Task used when <code>reset()</code> names none</td></tr><tr><td><code>HARBOR_COMMAND_TIMEOUT_S</code></td><td><code>120</code></td><td>Timeout for agent <code>exec</code> actions</td></tr><tr><td><code>HARBOR_DEFAULT_IMAGE</code></td><td><code>python:3.12-slim</code></td><td>Image for self-contained tasks in <code>docker</code> mode</td></tr><tr><td><code>MAX_CONCURRENT_ENVS</code></td><td><code>8</code></td><td>Concurrent WebSocket sessions</td></tr></tbody></table> <p>Verifier and oracle timeouts come from <code>[verifier].timeout_sec</code> and <code>[agent].timeout_sec</code> in each task’s <code>task.toml</code>.</p> <!--[1--><h2 class="relative group"><a id="running-in-docker" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#running-in-docker"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Running in Docker</span></h2><!--]--><!----> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-bash "><!---->docker build -t harbor-env:latest -f envs/harbor_env/server/Dockerfile envs/harbor_env | |
| <span class="hljs-comment"># local mode, your own tasks</span> | |
| docker run --<span class="hljs-built_in">rm</span> -p 8000:8000 -v <span class="hljs-string">"<span class="hljs-variable">$PWD</span>/tasks:/tasks:ro"</span> -e HARBOR_TASKS_DIR=/tasks harbor-env:latest | |
| <span class="hljs-comment"># docker mode needs the host daemon, so tasks can start their own containers</span> | |
| docker run --<span class="hljs-built_in">rm</span> -p 8000:8000 \ | |
| -v /var/run/docker.sock:/var/run/docker.sock \ | |
| -v <span class="hljs-string">"<span class="hljs-variable">$PWD</span>/tasks:/tasks:ro"</span> \ | |
| -e HARBOR_TASKS_DIR=/tasks -e HARBOR_MODE=docker \ | |
| harbor-env:latest<!----></pre></div><!----> <p>Hugging Face Spaces cannot run Docker-in-Docker, so a Space serves <code>local</code> mode | |
| and therefore self-contained tasks that declare no restrictive policies.</p> <!--[1--><h2 class="relative group"><a id="examples" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#examples"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Examples</span></h2><!--]--><!----> <table><thead><tr><th>Script</th><th>What it shows</th></tr></thead><tbody><tr><td><a href="https://github.com/huggingface/OpenEnv/blob/main/envs/harbor_env/examples/quickstart.py" rel="nofollow"><code>examples/quickstart.py</code></a></td><td>A full episode against a running server</td></tr><tr><td><a href="https://github.com/huggingface/OpenEnv/blob/main/envs/harbor_env/examples/validate_taskset.py" rel="nofollow"><code>examples/validate_taskset.py</code></a></td><td>Oracle sweep over a task set — run this before training</td></tr><tr><td><a href="https://github.com/huggingface/OpenEnv/tree/main/envs/harbor_env/examples/tasks/fix-sum-bug" rel="nofollow"><code>examples/tasks/fix-sum-bug/</code></a></td><td>A Harbor task written to run under every runtime</td></tr></tbody></table> <!--[1--><h2 class="relative group"><a id="layout" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#layout"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Layout</span></h2><!--]--><!----> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-text "><!---->envs/harbor_env/ | |
| ├── models.py # HarborAction / HarborObservation / HarborState | |
| ├── client.py # HarborEnv | |
| ├── examples/ | |
| └── server/ | |
| ├── task.py # task.toml parsing + task discovery | |
| ├── sandbox.py # Harbor's sandbox contract; local + docker backends | |
| ├── reward.py # the reward-file contract | |
| ├── harbor_env_environment.py # Gymnasium orchestration over the three above | |
| └── app.py # FastAPI server<!----></pre></div><!----> <!--[1--><h2 class="relative group"><a id="tests" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#tests"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Tests</span></h2><!--]--><!----> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Copied</div><!----></button><!----></div> <pre class="language-bash "><!---->PYTHONPATH=src:envs uv run pytest tests/envs/test_harbor_env.py -v<!----></pre></div><!----> <p>They are hermetic — no Docker, no network — and use the bundled example task as | |
| the end-to-end fixture.</p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/openenv/blob/main/docs/source/environments/harbor.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg><!----> <span><span class="underline">Update</span> on GitHub</span></a><!----> <p></p><!--]--><!----><!--]--><!--]--><!--]--> <!--[-1--><!--]--><!--]--> | |
| <script> | |
| { | |
| __sveltekit_1ved3fe = { | |
| base: "/docs/openenv/pr_1018/en", | |
| assets: "/docs/openenv/pr_1018/en" | |
| }; | |
| const element = document.currentScript.parentElement; | |
| Promise.all([ | |
| import("/docs/openenv/pr_1018/en/_app/immutable/entry/start.B9IBUExw.js"), | |
| import("/docs/openenv/pr_1018/en/_app/immutable/entry/app.CiZ4jjXn.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 3], | |
| data: [null,null], | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 56.2 kB
- Xet hash:
- 3a3bbe13b705d3309673a8800d459d8b63f7369e593673193fc8591c935650a2
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.