Contributing To UniLab¶
This page summarizes the repository workflow for contributors. Contract and architecture details live in Architecture Overview.
Environment¶
Install dependencies for your platform. The setup targets also install the optional simulator extras used by the repository’s checks:
macOS (MPS, PyPI torch wheel):
make setup-motrix(ormake setup-mujoco)Linux with NVIDIA (PyTorch cu128 wheel):
make setupLinux AMD / ROCm:
make sync-rocm, then run commands withuv run .... To return to the default CUDA / macOS profile,git restore -- pyproject.toml uv.lockand re-runmake setup.Linux Intel XPU:
make sync-xpuIf you prefer direct uv commands, the full default setup is
uv sync --extra mujoco --extra motrix; use--extra mujocoor--extra motrixfor a single backend.
# Choose one core setup path:
make setup
# make setup-mujoco
# make setup-motrix
make sync-rocm
make sync-xpu
Use uv run for commands. Do not invoke python directly outside uv run.
Development Rules¶
Always use
uv run. Runmake checkbefore any code-related commit.Do not commit backup or scratch files: no
*.bak,*.tmp,*.old,*.orig, or editor backups ending in~.Do not add new owner logic to
src/unilab/utils/. The modules there are a transitional shim; lift durable logic to its owner layer orsrc/unilab/base/instead.Module naming expresses owner responsibility: use singular nouns by default, plural only when the semantics are themselves a collection contract, and a
_factorysuffix for factory modules.Code comments, public API docstrings, internal implementation notes, TODO/FIXME entries, and config comments use English by default. Chinese prose belongs in the Chinese documentation under
docs/sphinx/source/zh_CN/, not in source comments or config annotations.When a change affects a user-visible workflow, keep
README.md,CONTRIBUTING.md, and the matching pages underdocs/sphinx/source/en/anddocs/sphinx/source/zh_CN/in sync.
Common Commands¶
make format
make type
make check
make test
make test-cov
make test-slow
make test-all
For documentation changes, run these focused checks in addition to
make test-all:
uv run pytest tests/scripts/test_check_docs.py -q
cd docs/sphinx
UNILAB_DOCS_SKIP_AUTODOC=1 uv run --no-project --with-requirements requirements.txt sphinx-build -b html -n source build/html
The Docs GitHub Actions workflow runs the same prose-only build for matching
PRs whose base is main and for pushes to main. It can also be started from
the GitHub Actions web UI via workflow_dispatch. It does not install UniLab
with pip install -e ., does
not generate API reference pages, and does not publish the external docs
repository.
For a final local refresh of the full site, including API reference pages for
the UniLab-doc publication flow, use a parallel Sphinx build from a synced
developer environment:
uv sync
uv pip install -r docs/sphinx/requirements.txt
cd docs/sphinx
uv run --no-sync sphinx-build -j auto -b html -n source build/html
Collaboration¶
Use Conventional Commit titles. The canonical rules for issue scope, roadmap
branches, PR evidence, local and remote gates, ADRs, and releases are in
Collaboration Workflow. Run focused checks for the changed contract and
make test-all on the final head before creating or updating a PR.
Testing¶
Tests are grouped by owner area under tests/:
tests/
├── base/ # registry, backend selection, env contract
├── config/ # Hydra / dataclass / reward injection
├── envs/ # environment configuration and instantiation
├── dr/ # domain-randomization types and managers
├── terrains/ # terrain generators and scene materialization
├── ipc/ # shared-memory and async-runner primitives
├── scripts/ # training-script configs and entrypoint tooling
├── algos/ # runner integration, RSL-RL PPO
├── integration/ # cross-module reward / config integration
├── training/ # training-run helpers
└── utils/ # helpers and experiment tracking
Markers and skips:
Unmarked tests are fast unit / contract / env smoke tests run by
make test.@pytest.mark.slowmarks full training/script smoke runs or cumulatively expensive backend matrices. CI skips them; run them locally withmake test-slow. Theslowmarker is registered inpyproject.toml.
Notes for make test-slow:
Test-only env registration uses a subprocess hook. Off-policy / APPO runners spawn a collector subprocess via
multiprocessing.spawn, and the spawned interpreter does not executetests/conftest.py. As a result,DummyFlatTestand similar test envs cannot live inconftestalone.tests/conftest.pyaddstests._test_registryto theUNILAB_EXTRA_REGISTRY_PACKAGESenvironment variable, andunilab.base.registry.ensure_registriesre-registers those modules inside the subprocess. To add a new test env, append its module to__unilab_registry_modules__intests/_test_registry/__init__.py.Replay memory budget. Off-policy host shared memory contains only the fixed-depth ingress and scales with
num_envsand transition width, notreplay_buffer_n. The complete ring scales withreplay_buffer_non the CUDA/MPS learner device. If you see an error likeMemoryError: estimated shared-memory allocation … exceeds /dev/shm available …, the host’s shared-memory quota cannot fit the default ingress. Device-ring allocation failures report the required and available accelerator budgets separately.
Documentation Expectations¶
Commands must point to checked-in scripts, package entrypoints, Makefile targets, or config owners.
Backend and task support claims should use evidence grades such as
Registered,Configured,Tested,Benchmarked, orRecommended.Do not describe
training.sim_backend=<backend>as a standalone backend switch. Use--sim <backend>in user-facing commands and select the owner YAML path internally.Keep English pages free of manual navigation blocks.
Configuration Changes¶
Task, backend, reward, and algorithm selection belongs in Hydra owner YAMLs.
When adding or changing a runnable path, update the relevant owner config under
src/unilab/conf/ and verify script composition with tests under tests/config/ or
tests/scripts/.
See Task Owner Config Contract and Hydra Config.
Comment Language Policy¶
Public API docstrings must describe contracts, arguments, return values, and boundary conditions in English.
Inline comments should explain non-obvious intent, owner boundaries, or backend/env/config invariants in English. Delete stale comments instead of translating them mechanically.
TODO/FIXME comments must be English and should name the owner layer or dependency that can resolve the follow-up.
Hydra YAML and example config comments must be English because they are reviewed with the source contract.
Existing mixed-language comments should be migrated in small PRs. Prioritize public contracts, backend adapters, env contracts, training runners, config schema, and high-traffic tests before lower-risk examples.