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 (or make setup-mujoco)

  • Linux with NVIDIA (PyTorch cu128 wheel): make setup

  • Linux AMD / ROCm: make sync-rocm, then run commands with uv run .... To return to the default CUDA / macOS profile, git restore -- pyproject.toml uv.lock and re-run make setup.

  • Linux Intel XPU: make sync-xpu

  • If you prefer direct uv commands, the full default setup is uv sync --extra mujoco --extra motrix; use --extra mujoco or --extra motrix for 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. Run make check before 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 or src/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 _factory suffix 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 under docs/sphinx/source/en/ and docs/sphinx/source/zh_CN/ in sync.

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.

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.slow marks full training/script smoke runs or cumulatively expensive backend matrices. CI skips them; run them locally with make test-slow. The slow marker is registered in pyproject.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 execute tests/conftest.py. As a result, DummyFlatTest and similar test envs cannot live in conftest alone. tests/conftest.py adds tests._test_registry to the UNILAB_EXTRA_REGISTRY_PACKAGES environment variable, and unilab.base.registry.ensure_registries re-registers those modules inside the subprocess. To add a new test env, append its module to __unilab_registry_modules__ in tests/_test_registry/__init__.py.

  • Replay memory budget. Off-policy host shared memory contains only the fixed-depth ingress and scales with num_envs and transition width, not replay_buffer_n. The complete ring scales with replay_buffer_n on the CUDA/MPS learner device. If you see an error like MemoryError: 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, or Recommended.

  • 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.