> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tuneplane.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Job environment variables

> What the platform sets inside a training container, and which ones your code should read.

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
env | grep -E '^(TUNEPLANE_|NRL_|VOLUMES_DIR|HF_)'
```

Run that inside a job to see the whole contract. Everything below is set by the control plane;
your code reads it and never composes a platform path itself.

These are the **job-side** variables. Server settings are a different list, prefixed the same way
— see [configuration](https://docs.tuneplane.ai/en/ops/configuration.md).

## Storage

| Variable | What it is |
| - | - |
| `TUNEPLANE_OUT_DIR` | **The one directory whose contents survive the job.** Checkpoints, exports, artifacts |
| `TUNEPLANE_RUN_DIR` | This run's directory, which `out`, `work` and `logs` sit under |
| `TUNEPLANE_STORAGE_ROOT` | The deployment's single configured storage root |
| `TUNEPLANE_WORK_DIR` | Where the job package was unpacked. Exported by the capsule bootstrap rather than by the spec, because it depends on how the package was delivered |
| `TUNEPLANE_EXP_DIR` | Your experiment's directory inside the package |
| `TUNEPLANE_DATASET_OUT_DIR` | Where to write a dataset the run publishes. Set only with `--output-dataset` |
| `TUNEPLANE_DATA_CACHE` | The shared dataset cache |
| `TUNEPLANE_HUB_CACHE` | The cache for hubs with no client library |
| `HF_HOME` | The Hugging Face cache, inside the storage root |

Anything written outside `$TUNEPLANE_OUT_DIR` disappears with the scratch tree when the container
exits.

## Topology

| Variable | What it is |
| - | - |
| `TUNEPLANE_CLUSTER_NUM_NODES` | Nodes this job actually has |
| `TUNEPLANE_CLUSTER_GPUS_PER_NODE` | GPUs per node |
| `TUNEPLANE_PROFILE_OVERRIDES` | A JSON array of `key=value` entries the framework adapter appends to the training argv |
| `TUNEPLANE_POOL_TOPOLOGY` | JSON, per-pool: name, series, nodes, gpus\_per\_node, pin\_resource, roles. Absent on a single-pool job |
| `NRL_PIN_RESOURCE` | The Ray custom resource this job's series pins to |
| `CLUSTER_PROFILE` | The profile name the submission used |

Quota and the watchdog are measured against `TUNEPLANE_CLUSTER_*`. Occupying more than that gets
the job warned, and can get it stopped. Pass these numbers into `torchrun --nproc_per_node` or
`accelerate launch --num_processes`.

## Reporting

| Variable | What it is |
| - | - |
| `TUNEPLANE_JOB_ENABLED` | `1` when ingest is bound, `0` otherwise |
| `TUNEPLANE_JOB_ENDPOINT` | Where metrics, logs and samples go. Must be reachable from the GPU node |
| `TUNEPLANE_JOB_RUN_ID` | This run's id |
| `TUNEPLANE_JOB_TOKEN` | A per-run, scoped ingest token |
| `TUNEPLANE_JOB_JUDGE_ENDPOINT` | The platform judge, for a rubric reward |
| `TUNEPLANE_JOB_JUDGE_TOKEN` | Its token |
| `TUNEPLANE_JOB_MONITOR_INTERVAL` | Hardware sampling interval in seconds, default `10` |

`tuneplane.report` reads all of these. With no token it does nothing, which is what you want
outside a job. See [reporting metrics](https://docs.tuneplane.ai/en/api-reference/python-sdk.md).

## Data and material

| Variable | What it is |
| - | - |
| `VOLUMES_DIR` | The root a [Volume](https://docs.tuneplane.ai/en/guides/volumes.md) is mounted under, read-only. One variable, not one per volume: read `$VOLUMES_DIR/<name>` |
| `<NAME>_DATA_DIR` | One per referenced dataset, from its name uppercased with `-` and `.` as `_`. So `alice/gsm8k-zh@v2` becomes `GSM8K_ZH_DATA_DIR` |

## Agent environments

| Variable | Set when |
| - | - |
| `TUNEPLANE_JOB_ENVIRONMENT_DIR` | The protocol is materialised (`nemo-gym`) |
| `TUNEPLANE_JOB_ENVIRONMENT_URL` | The protocol is served (`openenv`) or remote (`openenv` (`deployment: remote`)) |
| `TUNEPLANE_JOB_ENVIRONMENT_SPLIT` | Always, for a job with an environment. `train` or `eval`, decided by the operation |

`TUNEPLANE_JOB_ENVIRONMENT_SPLIT` has no flag and no override. See
[agent environments](https://docs.tuneplane.ai/en/guides/agent-envs.md).

## Sandbox

| Variable | What it is |
| - | - |
| `TUNEPLANE_JOB_SANDBOX_ENDPOINT` | Where model-generated code runs |
| `TUNEPLANE_JOB_SANDBOX_TOKEN` | Its token |
| `TUNEPLANE_JOB_SANDBOX_FUSION_URL` | Emitted only when the bound sandbox speaks Sandbox Fusion |
| `TUNEPLANE_JOB_SANDBOX_FUSION_CONCURRENCY` | Its concurrency limit |

These are optional. Without them, an environment runs tool code in a subprocess inside the
container.

## Identity and provenance

| Variable | What it is |
| - | - |
| `TUNEPLANE_RECIPE`, `_VERSION`, `_DIGEST`, `_PLUGINS` | Which method this is, exactly |
| `TUNEPLANE_FRAMEWORK`, `_VERSION` | Which framework build |
| `TUNEPLANE_RUNTIME_ID` | Which deployment artifact runs it |
| `TUNEPLANE_CORE_VERSION` | The SDK version that built the spec |
| `NRL_RUN_ID`, `NRL_SUBMIT_USER`, `RUN_USER` | Run id and who submitted it |
| `NRL_GIT_COMMIT`, `NRL_GIT_DIRTY`, `NRL_CONFIG_SHA` | Provenance |
| `NRL_TRAIN_RUN_ID` | On a post-training step, the training run it follows |
| `NEMO_RL_DIR` | Where NeMo-RL lives in the image. Required for a `nemo-rl` job |

The `NRL_` prefix is historical and still the real name. Do not rename it in a config.

## Secrets

| Variable | What it is |
| - | - |
| `HF_TOKEN`, `HUGGING_FACE_HUB_TOKEN` | Injected when the deployment has one, or when you [linked your own account](https://docs.tuneplane.ai/en/integrations/huggingface.md) |
| `CLUSTER_SECRETS_FILE` | A path to a secrets file, for a deployment that injects by path rather than by value |

Never bake a token into an image. The platform injects these, and an empty value is dropped
rather than set to `""` so a `${VAR:-default}` in your script still falls back.

## Check it worked

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
echo "$TUNEPLANE_OUT_DIR" "$TUNEPLANE_CLUSTER_GPUS_PER_NODE"
env | grep TUNEPLANE_JOB
ls -la "$VOLUMES_DIR"
```

A variable that is empty was dropped on purpose, which is not the same as the platform failing to
set it. An unknown `TUNEPLANE_` or `NRL_` variable produces a warning from the cluster-side
self-check, because it usually means a typo in a deployment's extra environment.

## Next

[JobSpec](https://docs.tuneplane.ai/en/reference/jobspec.md) · [Custom training](https://docs.tuneplane.ai/en/guides/custom-training.md) ·
[Server configuration](https://docs.tuneplane.ai/en/ops/configuration.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.