Skip to main content
A TunePlane lab is a normal git repository on your machine. The console never clones it. tp submit packs a subset of files, uploads that bundle, and the server injects the Job Capsule on top.

After tp init my-lab --yes

tuneplane.yaml currently needs a name whose characters match [A-Za-z0-9._-]. That name is the console project. Do not pass --project on submit.
Commands that need a project (tp new, submit, ls, validate) walk up from the current directory looking for this file. CI can set TUNEPLANE_CLIENT_REPO_ROOT instead of cd. tp login / logout / status are global and do not need it.

One experiment directory

custom/custom also gets train.sh (the only entrypoint). You can add train.py next to it. Plugins add plugins.lock.json after tp plugin install … --exp. Do not put a framework file in the experiment and expect the platform to notice. The lock file is the method.

What gets uploaded

The CLI packs the experiment, common/, and configs/. The same exclude list is shared with the server (PACKAGE_EXCLUDES in tuneplane.contract.env): The JobSpec lands in the bundle at .tuneplane/jobspec.json. That path is inside .tuneplane/, not .tuneplane/. Mixing the two directories is a real footgun: .tuneplane is excluded, so a spec written there never reaches the cluster.

What does not live in the lab

  • Cluster kubeconfig, Slurm JWT, object-storage keys
  • The Job Capsule (runner.pex). The server injects it after admit.
  • Hardware parallelism. That comes from --profile and the registry.

Git

Submit records NRL_GIT_COMMIT and NRL_GIT_DIRTY. A dirty tree is rejected unless you pass --allow-dirty. Untracked files are listed as warnings either way. Initialize git at tp init (the default) so the first commit is not an afterthought. Git is how a run becomes reproducible, not a requirement for submitting. A lab that is not a repository — tp init --no-git, a directory copied from somewhere, a machine with no git installed — submits with no commit recorded, and the console shows the run without provenance. A lab that is a repository but has no commit yet keeps its .gitignore: git still lists the files, only the commit is missing. What changes when there is no repository at all is the file list: instead of git applying .gitignore, the bundle is the same three directories walked against the platform’s built-in exclusions (outputs/, tuneplane_plugins/, __pycache__/, .venv/, the caches, and anything that looks like a key), and it is refused above 64 MB so an artifact nobody meant to ship cannot quietly become an upload. Raise that ceiling with TUNEPLANE_CLIENT_MAX_PACKAGE_MB if a lab really does carry something large.