- Make the smallest change that solves the requested problem.
- Preserve existing behavior unless the task explicitly changes it.
- Read surrounding code, callers, tests, and documentation before changing an interface.
- Do not add dependencies unless necessary. Prefer existing project dependencies and the standard library.
- Do not commit generated plans, scratch files, or agent artifacts.
- Follow a more-specific
AGENTS.mdin the directory being changed. - Use the repository's current SPDX header template for new source files; do not change existing file headers.
- Follow the existing style and abstractions in the affected package.
- Use modern Python type hints, including
X | Noneinstead ofOptional[X]. - Use
snake_casefor methods, functions, and CLI arguments. - Keep related public symbols discoverable through consistent prefixes.
- Keep joint-wrench sensor coverage separate from articulation control-joint selection. Reuse cached body bindings without changing the shared view's joint filters or creating a second view for sensing.
- For external wrenches, follow the asset API's
is_globalboolean and_b/_wbuffer naming. Keep frame conversion decisions inWrenchComposerand track pending contributions with plain booleans; do not introduce frame enums, content bitmasks, or a classification layer. - Name wrench reads
get_forces_and_torques, matching the existing add/set methods; avoid a separate "submission" API or compatibility alias for the unreleasedresolve_submissionmethod. - Use concrete types for public interfaces where practical.
- Use Google-style docstrings for public APIs.
- Document SI units for public physical quantities in docstrings using inline
[unit]notation (e.g.Particle positions [m], shape [N, 3]); use[m or rad, depending on joint type]where applicable, and skip non-physical fields (indices, counts, flags). - Keep comments brief and explain intent, constraints, or edge cases rather than restating code.
- Do not remove or rename a public API without a prior deprecation and migration path.
- Update public documentation when adding or changing public APIs.
- Verify documented technical claims against the current code and primary sources before relying on them.
- Use the uv-managed environment for routine commands.
- Use
uv run pythonfor Python scripts and tests. - Use
uv run isaaclabfor Isaac Lab CLI commands. - Use
./isaaclab.shonly for installer workflows that require it. - Do not define Warp kernels in
python -c; write a temporary Python file instead so Warp can inspect the source.
- Group imports in PEP 8 order, separated by blank lines:
__future__, standard library, third-party, Omniverse runtime packages (isaacsim,omni,pxr,carb, ...), Isaac Lab packages, then local relative imports. Ruff enforces this order throughuv run isaaclab -f; do not sort imports by hand. - Import from the same package with relative imports when the target is at most three leading dots away
(e.g.
from ...utils import math as math_utils). Use absolute imports for deeper targets and for other packages. - Keep absolute imports in modules that can run as scripts (with an
if __name__ == "__main__":block), since relative imports fail there.
- Run the narrowest relevant test first.
- Before reporting that a test cannot run because an optional dependency is missing, identify its project extra and retry with
uv run --extra <extra> .... - Do not treat an optional dependency missing from the base environment as a blocker when its project extra is available.
- Run
uv run isaaclab -fbefore committing. - For a regression test, verify that it fails without the fix and passes with it.
- Find and extend the closest existing test before creating a new test file or test case.
- Add a test only when it covers a distinct behavior, regression, boundary, or failure mode that existing tests do not cover clearly.
- Test observable behavior and public contracts, not implementation details.
- Validate joint-wrench frames with the same physical fixture and analytic load expectations across backends. Do not derive the expected wrench by repeating the production transformation on the backend's raw output.
- Use hard-coded values only when they are the intended contract or a small, independently verified example; otherwise derive the expected result from a separate, simple reference calculation.
- Keep tests focused and remove or consolidate redundant coverage instead of growing overlapping test suites.
- Do not add debug output to production Warp kernels. Use temporary standalone reproductions and remove debug output before committing.
- Do not edit
CHANGELOG.rstorconfig/extension.tomldirectly. - Add one changelog fragment for each changed source package when the change is user-visible.
- Use
.skipfragments for changes that do not require a release note. - Write changelog entries in past tense and include migration guidance for deprecated, changed, or removed behavior.
- Mark breaking changes clearly and provide migration guidance.
- Work on a feature branch; do not commit directly to
main. - Keep commits focused and atomic.
- Use an imperative, capitalized commit subject with no trailing period.
- Inspect staged changes before committing.
- Do not add AI co-author or attribution lines.
- Prefer follow-up commits over amending commits while addressing review feedback.
- Keep repository-owned skills in
skills/; do not duplicate their contents in tool-specific discovery directories. - Validate skill changes with
uv run --no-project python tools/skills/cli.py check. - Keep skills concise and point to maintained documentation and source examples.
- When migrating a spawner schema slot to fragments, migrate its readers and overrides too.
Use a bare fragment for a single instance and a list only for multiple fragments. For lists,
select the owning fragment before accessing fields or calling
replace();fix_root_linkbelongs on the spawner. - For file-spawned fixtures that must only tune existing physics bodies, use explicit fragment target mappings. A bare fragment or list may create a missing body and change the fixture's validity.