# Bring your policy

Your code, weights, and inference server can live in different places — pick the path that matches what you already have.

A policy is rarely one artifact. The code lives in a GitHub repo, the
trained weights on Hugging Face or in an S3 bucket, and inference might
already be a server your team operates. You don't consolidate any of
that to evaluate here — keep your training stack, your storage, your
release process. Roborama needs exactly two things: a way to run
inference, and the declared contracts — `action_space` and
`observation_contract` — that make a result attributable
([Policies](/docs/concepts/policies/)).

## Start from what you have

| What you already have | Guide |
| --- | --- |
| A model on Hugging Face | [Import a checkpoint](https://roborama.com/docs/guides/import-from-hugging-face/) — Point at a repo id and name the runtime — openpi or lerobot. *(direct integration)* |
| Code on GitHub or GitLab | [Package your policy](https://roborama.com/docs/guides/package-your-policy/) — CI builds a container; weights can live elsewhere. *(packaging workflow)* |
| Weights in S3, GCS, or Azure | [Import from private storage](https://roborama.com/docs/guides/import-from-private-storage/) — Bake weights into an image at build time — credentials never leave your CI. *(packaging workflow)* |
| A container image | [Run your container](https://roborama.com/docs/guides/run-your-container/) — Any OCI image, digest-pinned, run GPU-adjacent to the cell. *(direct integration)* |
| Checkpoint files on your computer | [Upload a checkpoint](https://roborama.com/docs/guides/upload-a-checkpoint/) — Publish to the Hub or bake into an image — two supported routes. *(packaging workflow)* |
| An inference server you already operate | [Connect your endpoint](https://roborama.com/docs/guides/connect-your-endpoint/) — Weights stay on your infrastructure; the cell streams observations. *(direct integration)* |

## Direct integrations and packaging workflows

Three of the cards are **direct integrations** — each ends in a field on
the `Policy` object itself: a checkpoint's `hf:` repo id, a container's
`image:` reference, an endpoint's `url:`. If you already have one of
those three things, you are one call away from a run.

The other three are **packaging workflows**: what you have — a repo of
code, a bucket of weights, a directory on your laptop — needs one
intermediate step, an export, a publish, or a container build, to become
one of those three fields. Each workflow guide walks that step, then
hands you to the matching direct integration.

## Importing and validating are separate steps

Getting the artifact to us and proving it can drive the pinned robot are
different jobs, and they fail at different times:

- **Import** gets the artifact into runnable form — a fetchable
  checkpoint, a pullable image, a reachable URL.
- **Admission** validates the declared `action_space` and
  `observation_contract` against the pinned robot and scene when you
  submit. A mismatch is rejected with `contract_validation_failed` —
  free, before any motor moves ([error codes](/docs/errors/)).
- **Cell startup** exercises the artifact itself: the checkpoint is
  fetched, the container started, the endpoint reached.

Before any of that, you can dry-run the whole loop at your desk: mock
mode (`ROBORAMA_MOCK=1`, or `mock=True` on the client) runs quote →
submit → result against packaged fixtures, with no API key and no
hardware involved.

*Example: dry-run the whole loop locally*

**Python**

```python
import roborama

# Mock mode: no API key, no hardware. The whole loop runs
# offline against packaged fixtures — or set ROBORAMA_MOCK=1.
client = roborama.Client(mock=True)

quote = client.quote(
    robot="aloha2-pro",
    environment="cell-a",
    episodes=300,
)
print(quote)
# {robot_hours: 10.0, env_hours: 10.0, usd: 860, queue_eta: "2h"}

run = client.run(
    robot="aloha2-pro@fw1.1",
    environment="cell-a@v1.0",
    policy=roborama.Policy.checkpoint(
        hf="acme/act-so101-pick-v2",
        runtime="lerobot",
    ),
    task="pick_place@v1",
    episodes=300,
    max_budget_usd=1000,
)
print(run.result())
# n=300  rate=0.843  ci95=(0.797, 0.881)
```

**TypeScript**

```typescript
import Roborama from "@roborama/sdk";

// Mock mode: no API key, no hardware. The whole loop runs
// offline against packaged fixtures — or set ROBORAMA_MOCK=1.
const roborama = new Roborama({ mock: true });

const quote = await roborama.quote({
  robot: "aloha2-pro",
  environment: "cell-a",
  episodes: 300,
});
console.log(quote);
// { robot_hours: 10.0, env_hours: 10.0, usd: 860, queue_eta: "2h" }

const run = await roborama.runs.create({
  robot: "aloha2-pro@fw1.1",
  environment: "cell-a@v1.0",
  policy: {
    type: "checkpoint",
    hf: "acme/act-so101-pick-v2",
    runtime: "lerobot",
  },
  task: "pick_place@v1",
  episodes: 300,
  max_budget_usd: 1000,
});
console.log(await run.result());
// n=300  rate=0.843  ci95=(0.797, 0.881)
```

**cURL**

```bash
# Mock mode is an SDK feature — curl always talks to the live
# API. ROBORAMA_MOCK=1 flips any SDK entry point to packaged
# fixtures: no API key, no hardware, no spend.
ROBORAMA_MOCK=1 python - <<'PY'
import roborama

quote = roborama.quote(
    robot="aloha2-pro", environment="cell-a", episodes=300)
print(quote)

run = roborama.run(
    robot="aloha2-pro@fw1.1",
    environment="cell-a@v1.0",
    policy=roborama.Policy.checkpoint(
        hf="acme/act-so101-pick-v2", runtime="lerobot"),
    task="pick_place@v1",
    episodes=300,
    max_budget_usd=1000,
)
print(run.result())
PY
```

**Agent (tool-use payload)**

```json
{
  "type": "tool_use",
  "name": "roborama_quote",
  "input": {
    "robot": "aloha2-pro",
    "environment": "cell-a",
    "episodes": 300
  }
}
```

> **Fixture output:** The printed quote and result above are mock-mode fixtures — the shapes
> are exact, the numbers are packaged data, and your live runs will
> differ.

## The same journey on every path

Every integration guide walks the same eight stages, in the same order:

1. **Prerequisites** — files, permissions, runtime, compatible hardware.
2. **Connect** — one complete example, from your artifact to a `Policy`.
3. **Validate** — mock dry-run, then admission, then cell startup.
4. **Quote** — both meters and the dollars, before you commit anything.
5. **Evaluate** — submit the run and follow episodes live.
6. **Inspect results** — n, rate, Wilson ci95, episodes, the report.
7. **Compare versions** — same declared test, different artifact.
8. **Troubleshoot** — the error codes that path can actually hit.

## Where next

- [Import from Hugging Face](/docs/guides/import-from-hugging-face/) — the shortest path if your model is already on the Hub.
- [Policies](/docs/concepts/policies/) — the three packagings and the declared contracts behind all of them.
- [Walkthrough: LeRobot from the Hub](/docs/guides/walkthrough-lerobot/) — the checkpoint path end to end, with real numbers.
- [Walkthrough: GitHub + S3](/docs/guides/walkthrough-github-storage/) — code in CI, weights in a bucket, one admitted policy.
