Skip to content

Commit e124e60

Browse files
committed
docs(repo): add agent rules (AGENTS.md/CLAUDE.md), ignore local agent config
AGENTS.md holds the public repo development rules for AI coding agents (multi-repo workflow, parity discipline, style, testing, API design). CLAUDE.md is a thin shim that imports AGENTS.md via @AGENTS.md so Claude Code loads the single source of truth. .gitignore now excludes the machine-local CLAUDE.local.md and ENVIRONMENTS.local.md.
1 parent a6cacd0 commit e124e60

3 files changed

Lines changed: 183 additions & 0 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,7 @@ training_logs/
131131

132132
# local-only: report-hub publish wrappers (reports live in the external report repo)
133133
tools/publish_report*.sh
134+
135+
# local-only: personal agent rules (commit identity, push habits, private infra) and env override
136+
CLAUDE.local.md
137+
ENVIRONMENTS.local.md

AGENTS.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# AGENTS.md
2+
3+
This file defines repository-level development rules for people and AI coding agents working in
4+
the **RoboVerse** content repo (`roboverse-py`). It is read automatically by Claude Code, Codex,
5+
Cursor, and similar agents at the start of a session.
6+
7+
RoboVerse is the **downstream** half of a two-repo system:
8+
9+
- **MetaSim** (`metasim`, sibling repo) owns the core simulator abstractions, scenario config types,
10+
task registry, package discovery, and simulator backends. Its rules live in the MetaSim
11+
[`AGENTS.md`](../MetaSim/AGENTS.md) — follow that file for anything touching core, backends, or the
12+
`metasim/test` suite.
13+
- **RoboVerse** (this repo) owns tasks, robots, scenes, grounds, assets, learning code
14+
(`roboverse_learn`), examples (`get_started`), tooling, and reports. It depends on MetaSim via
15+
`metasim @ git+https://github.com/RoboVerseOrg/MetaSim.git`.
16+
17+
The goals here are:
18+
19+
- keep RoboVerse easy to extend with new tasks / robots / sims, with a low on-ramp for contributors;
20+
- protect **multi-simulator parity** — correctness across backends is load-bearing, not a nice-to-have;
21+
- keep public APIs stable so RoboVerse can become a dependable standard library;
22+
- prefer local consistency and existing infrastructure over clever new abstractions.
23+
24+
For details that this file points to:
25+
26+
- Contributor setup: [`CONTRIBUTING.md`](./CONTRIBUTING.md)
27+
- Priorities and version targets: [`ROADMAP.md`](./ROADMAP.md)
28+
- Tutorials, task migration, API: <https://roboverse.wiki/metasim/>
29+
- Simulator → environment mapping: MetaSim [`ENVIRONMENTS.md`](../MetaSim/ENVIRONMENTS.md)
30+
31+
---
32+
33+
## Multi-Repo Workflow
34+
35+
- The two repos are sibling directories. Install both editable
36+
(`python -m pip install -e ".[dev,mujoco]"` in RoboVerse), with `metasim` resolved from the local
37+
MetaSim checkout when developing cross-cutting features.
38+
- **Know which repo owns the change before editing.** A simulator-backend bug, a scenario-config
39+
type, or the task registry is a *MetaSim* change. A new task/robot/scene, a reward, a learning
40+
script, or an example is a *RoboVerse* change.
41+
- For a feature that spans both, land (or at least draft) the **MetaSim change first**, then the
42+
RoboVerse change that consumes it. Do not work around a missing core capability by duplicating it
43+
downstream.
44+
- Do not push core logic into MetaSim that is really RoboVerse content, and do not fork core types
45+
into RoboVerse. Use MetaSim's package-discovery mechanisms (`metasim.toml`, entry points,
46+
`METASIM_*_PACKAGES`) to register downstream content.
47+
48+
## General Workflow
49+
50+
- **Orient first.** When unfamiliar with an area, check the docs (<https://roboverse.wiki>,
51+
`docs/source/`), `ROADMAP.md`, and the relevant `roboverse_pack/` subtree before searching source
52+
from scratch.
53+
- **Pre-commit is the gate.** Install once with `pre-commit install`. Before opening a PR, run
54+
`pre-commit run --all-files` and resolve errors.
55+
- **Semantic commits.** Use [Conventional Commits](https://www.conventionalcommits.org/):
56+
`<type>(<scope>): <description>`, types `feat|fix|docs|style|refactor|test|chore`, scope = pack or
57+
module (e.g. `feat(tasks): add mjlab cartpole balance`, `fix(robots): correct go1 base-vel obs`).
58+
- Keep commits and pull requests focused, reviewable, and scoped to one concern.
59+
60+
## Parity Is Load-Bearing (RoboVerse-Specific)
61+
62+
RoboVerse's value is that the same task behaves consistently across MuJoCo, Newton, SAPIEN3,
63+
PyBullet, IsaacSim, etc. Treat parity as a correctness contract:
64+
65+
- **Run the task end-to-end first; chase numerical parity second.** A task that "matches" only
66+
because both sides are equally broken (e.g. both fall into the void) is not parity. See the parity
67+
harness pattern in `scripts/parity_obs_reward_cartpole.py` and `scripts/eval_*_cross_sim.py`.
68+
- When porting a reward / observation / dynamics from another framework (mjlab, ManiSkill, …), aim
69+
for **bitwise or machine-eps agreement** on obs and reward, and verify with an actual cross-sim
70+
comparison rather than asserting it.
71+
- **Closed-loop dynamics parity ≠ obs-bitwise parity.** A policy that trains on one backend may not
72+
transfer to another even when observations match; report which backend a trained demo actually
73+
ran on instead of implying transfer.
74+
- Reports must show pain points honestly. Do not present a clean number that hides a real failure.
75+
76+
## Adding Content (Tasks / Robots / Scenes)
77+
78+
- Follow the task-migration developer guide: <https://roboverse.wiki/metasim/developer_guide/new_task>.
79+
- Tasks/robots/scenes/grounds live under `roboverse_pack/`. Configs use the `@configclass` dataclass
80+
pattern from `metasim.utils`; prefer composing existing Cfg types over inventing parallel ones.
81+
- Prefer extending an existing task family over a new top-level scaffold when the new task is a
82+
variant. Keep additions additive — do not modify unrelated legacy task files to make a new one work.
83+
- Register learning entry points and example usage where the existing ones live
84+
(`roboverse_learn/{rl,il,vla}`, `get_started/`); don't scatter new top-level scripts.
85+
86+
## Design Principles
87+
88+
- Be a library, not a framework. Keep public APIs small, orthogonal, and composable.
89+
- Duplication is cheaper than the wrong abstraction. Don't add layers the code doesn't yet need.
90+
- Make it work, make it right, then make it fast — measure before optimizing.
91+
- Single source of truth: centralize shared constants, configs, and logic; don't fork them per pack.
92+
- Validate and normalize at boundaries (CLI, config, data loaders). Fail fast on invalid states with
93+
clear, actionable errors; never fail silently or turn an unsupported path into a quiet no-op.
94+
- Favor composition over inheritance. Keep side effects explicit and localized.
95+
- Optimize for readability first; future maintainers and downstream users are users too.
96+
97+
## API Design Guidelines
98+
99+
- **Prefer keyword-only arguments** over long positional lists, so the API can grow without breaking
100+
call sites: `def attention(*, query, key, value, query_mask, kv_mask): ...`. Obvious operators
101+
(`matmul(a, b)`) may stay positional.
102+
- **Return a dataclass / `@configclass`, not a dynamically-sized tuple.** New return fields should not
103+
break existing callers. A well-known operator signature (e.g. `lstm``(output, h, c)`) is the
104+
exception.
105+
- For composite configs, hold sub-module `.Config` objects rather than flattening their fields, so
106+
sub-modules can be swapped without changing the composite surface.
107+
- Keep public APIs stable. If you must break one, document a migration path.
108+
109+
## Code Style
110+
111+
RoboVerse uses **ruff** (lint + format) and **pre-commit**. The authoritative config is in
112+
`pyproject.toml` — do not invent rules that contradict it.
113+
114+
### Python
115+
116+
- **Double quotes** (ruff default — match this repo even if a sibling repo uses single quotes).
117+
- **Line length 120**; `target-version = "py38"`, so keep syntax 3.8-compatible.
118+
- **Google-style docstrings** (`pydocstyle convention = "google"`).
119+
- Use `from __future__ import annotations` (the codebase relies on string annotations and `FA`).
120+
- **Local / lazy imports are allowed here** (`E402`, `PLC0415` are intentionally ignored) because
121+
heavy optional simulator backends (isaacgym, isaacsim, newton) and the `try: import isaacgym`
122+
ordering shim must be imported lazily. Prefer top-level imports for stdlib and hard deps, but do
123+
not "fix" an existing deliberate lazy/ordered import.
124+
- Don't add global `noqa`/ignore rules to `pyproject.toml`; use per-line `# noqa: CODE` for local
125+
exceptions. The existing per-file docstring (`"D"`) ignores are tracked debt — when you add a
126+
docstring, you may remove the matching `FIXME` ignore.
127+
128+
### Commands
129+
130+
- Prefer `python -m <module>` form (e.g. `python -m pip`, `python -m pytest`, `python -m ruff`).
131+
- Prefer `git -C <dir>` over `cd <dir> && git ...` to avoid changing the working directory.
132+
133+
## Testing
134+
135+
- RoboVerse content/integration tests live in `tests/` (`test_*.py`, functions `test_*`); run with
136+
`python -m pytest tests/`. Core simulator tests live in MetaSim's `metasim/test` — run those there,
137+
following MetaSim's `AGENTS.md`.
138+
- **Be explicit about simulator scope.** Only run a simulator's tests when the change affects that
139+
simulator or shared code it uses. Read the sim→environment mapping from MetaSim
140+
[`ENVIRONMENTS.md`](../MetaSim/ENVIRONMENTS.md); if the mapping is unknown, **ask before running
141+
simulator-backed tests**.
142+
- **GPU rule.** `isaacgym`, `isaacsim`, and `newton` runs are GPU-backed. If the environment can't
143+
see a GPU, report it as an environment blocker — don't record it as a normal test result, and
144+
don't compress setup/GPU failures into "test failures".
145+
- Add a regression test for every bug fix. Do not claim "all tests pass" unless the exact requested
146+
commands ran in the correct environments.
147+
148+
## Documentation Workflow
149+
150+
For every non-trivial change (new feature, public behavior, CLI/config/data-format, module
151+
responsibility, or durable design choice), update docs together with the code:
152+
153+
- User-facing docs are Sphinx under `docs/source/` and publish to <https://roboverse.wiki>.
154+
- Ground docs in the repo: inspect code before naming paths, functions, classes, configs, or CLI
155+
flags. If something can't be verified, write `TODO: verify ...` instead of guessing.
156+
157+
## AI-Agent Rules
158+
159+
### Before changing code
160+
161+
- Read the relevant existing code paths and the existing test for the area first.
162+
- Confirm whether the change belongs in RoboVerse or MetaSim (see Multi-Repo Workflow).
163+
164+
### Before adding files
165+
166+
- Ask: can this be done by cleanly extending an existing file? If yes, do that. New files — and
167+
especially new top-level scripts or docs — are the exception, not the default.
168+
169+
### Before declaring success
170+
171+
- Say exactly what was verified and how (which command, which sim environment).
172+
- If a run was blocked by environment/GPU problems, say so and include the real blocker.
173+
- For parity claims, state the measured delta and the backend(s) actually exercised.

CLAUDE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# CLAUDE.md
2+
3+
This repo keeps a single source of truth for development rules in `AGENTS.md`.
4+
Claude Code only auto-loads `CLAUDE.md`, so this file imports it:
5+
6+
@AGENTS.md

0 commit comments

Comments
 (0)