diff --git a/.agents/AGENTS.md b/.agents/AGENTS.md new file mode 100644 index 000000000..7073c9b93 --- /dev/null +++ b/.agents/AGENTS.md @@ -0,0 +1,82 @@ +# RocketPy Workspace Instructions + +## Code Style +- Use snake_case for variables, functions, methods, and modules. Use descriptive names. +- Use PascalCase for classes and UPPER_SNAKE_CASE for constants. +- Keep lines at 88 characters and follow PEP 8 unless existing code in the target file differs. +- Run Ruff as the source of truth for formatting/import organization: + - `make format` + - `make lint` +- Use NumPy-style docstrings for public classes, methods, and functions, including units. +- In case of tooling drift between docs and config, prefer current repository tooling in `Makefile` + and `pyproject.toml`. + +## Architecture +- RocketPy is a modular Python library; keep feature logic in the correct package boundary: + - `rocketpy/simulation`: flight simulation and Monte Carlo orchestration. + - `rocketpy/rocket`, `rocketpy/motors`, `rocketpy/environment`: domain models. + - `rocketpy/mathutils`: numerical primitives and interpolation utilities. + - `rocketpy/plots`, `rocketpy/prints`: output and visualization layers. +- Prefer extending existing classes/patterns over introducing new top-level abstractions. +- Preserve public API stability in `rocketpy/__init__.py` exports. + +## Build and Test +- Use Makefile targets for OS-agnostic workflows: + - `make install` + - `make pytest` + - `make pytest-slow` + - `make coverage` + - `make coverage-report` + - `make build-docs` +- Before finishing code changes, run focused tests first, then broader relevant suites. +- When running Python directly in this workspace, prefer the project virtual + environment interpreter: `.venv/bin/python` on Unix/macOS or + `.venv/Scripts/python.exe` on Windows. +- Slow tests are explicitly marked with `@pytest.mark.slow` and are run with `make pytest-slow`. +- For docs changes, check `make build-docs` output and resolve warnings/errors when practical. + +## Development Workflow +- Target pull requests to `develop` by default; `master` is the stable branch. +- Use branch names in `type/description` format, such as: + - `bug/` + - `doc/` + - `enh/` + - `mnt/` + - `tst/` +- Prefer rebasing feature branches on top of `develop` to keep history linear. +- Keep commit and PR titles explicit and prefixed with project acronyms when possible: + - `BUG`, `DOC`, `ENH`, `MNT`, `TST`, `BLD`, `REL`, `REV`, `STY`, `DEV`. + +## Conventions +- SI units are the default. Document units and coordinate-system references explicitly. +- Position/reference-frame arguments are critical in this codebase. Be explicit about orientation + (for example, `tail_to_nose`, `nozzle_to_combustion_chamber`). +- Include unit tests for new behavior. Follow AAA structure and clear test names. +- Use fixtures from `tests/fixtures`; if adding a new fixture module, update `tests/conftest.py`. +- Use `pytest.approx` for floating-point checks where appropriate. +- Use `@cached_property` for expensive computations when helpful, and be careful with stale-cache + behavior when underlying mutable state changes. +- Keep behavior backward compatible across the public API exported via `rocketpy/__init__.py`. +- Prefer extending existing module patterns over creating new top-level package structure. + +## Testing Taxonomy +- Unit tests are mandatory for new behavior. +- Unit tests in RocketPy can be sociable (real collaborators allowed) but should still be fast and + method-focused. +- Treat tests as integration tests when they are strongly I/O-oriented or broad across many methods, + including `all_info()` convention cases. +- Acceptance tests represent realistic user/flight scenarios and may compare simulation thresholds to + known flight data. + +## Documentation Links +- Contributor workflow and setup: `docs/development/setting_up.rst` +- Style and naming details: `docs/development/style_guide.rst` +- Testing philosophy and structure: `docs/development/testing.rst` +- API reference conventions: `docs/reference/index.rst` +- Domain/physics background: `docs/technical/index.rst` + +## Scoped Customizations +- Simulation-specific rules: `.agents/skills/simulation-safety/SKILL.md` +- Test-authoring rules: `.agents/skills/tests-python/SKILL.md` +- RST/Sphinx documentation rules: `.agents/skills/sphinx-docs/SKILL.md` +- Specialized review persona: `.agents/skills/rocketpy-reviewer/SKILL.md` diff --git a/.agents/skills/rocketpy-reviewer/SKILL.md b/.agents/skills/rocketpy-reviewer/SKILL.md new file mode 100644 index 000000000..30d3f7598 --- /dev/null +++ b/.agents/skills/rocketpy-reviewer/SKILL.md @@ -0,0 +1,62 @@ +--- +description: "Physics-safe RocketPy code review agent. Use for pull request review, unit consistency checks, coordinate-frame validation, cached-property risk detection, and regression-focused test-gap analysis." +name: "RocketPy Reviewer" +tools: [read, search] +argument-hint: "Review these changes for physics correctness and regression risk: " +user-invocable: true +--- +You are a RocketPy-focused reviewer for physics safety and regression risk. + +## Goals + +- Detect behavioral regressions and numerical/physics risks before merge. +- Validate unit consistency and coordinate/reference-frame correctness. +- Identify stale-cache risks when `@cached_property` interacts with mutable state. +- Check test coverage quality for changed behavior. +- Verify alignment with RocketPy workflow and contributor conventions. + +## Review Priorities + +1. Correctness and safety issues (highest severity). +2. Behavioral regressions and API compatibility. +3. Numerical stability and tolerance correctness. +4. Missing tests or weak assertions. +5. Documentation mismatches affecting users. +6. Workflow violations (test placement, branch/PR conventions, or missing validation evidence). + +## RocketPy-Specific Checks + +- SI units are explicit and consistent. +- Orientation conventions are unambiguous (`tail_to_nose`, `nozzle_to_combustion_chamber`, etc.). +- New/changed simulation logic does not silently invalidate cached values. +- Floating-point assertions use `pytest.approx` where needed. +- New fixtures are wired through `tests/conftest.py` when applicable. +- Test type is appropriate for scope (`unit`, `integration`, `acceptance`) and `all_info()`-style tests + are not misclassified. +- New behavior includes at least one regression-oriented test and relevant edge-case checks. +- For docs-affecting changes, references and paths remain valid and build warnings are addressed. +- Tooling recommendations match current repository setup (prefer Makefile plus `pyproject.toml` + settings when docs are outdated). + +## Validation Expectations + +- Prefer focused test runs first, then broader relevant suites. +- Recommend `make format` and `make lint` when style/lint risks are present. +- Recommend `make build-docs` when `.rst` files or API docs are changed. + +## Output Format + +Provide findings first, ordered by severity. +For each finding include: +- Severity: Critical, High, Medium, or Low +- Location: file path and line +- Why it matters: behavioral or physics risk +- Suggested fix: concrete, minimal change + +After findings, include: +- Open questions or assumptions +- Residual risks or testing gaps +- Brief change summary +- Suggested validation commands (only when useful) + +If no findings are identified, state that explicitly and still report residual risks/testing gaps. diff --git a/.agents/skills/simulation-safety/SKILL.md b/.agents/skills/simulation-safety/SKILL.md new file mode 100644 index 000000000..cc2af5d27 --- /dev/null +++ b/.agents/skills/simulation-safety/SKILL.md @@ -0,0 +1,41 @@ +--- +description: "Use when editing rocketpy/simulation code, including Flight state updates, Monte Carlo orchestration, post-processing, or cached computations. Covers simulation state safety, unit/reference-frame clarity, and regression checks." +name: "Simulation Safety" +applyTo: "rocketpy/simulation/**/*.py" +--- +# Simulation Safety Guidelines + +- Keep simulation logic inside `rocketpy/simulation` and avoid leaking domain behavior that belongs in + `rocketpy/rocket`, `rocketpy/motors`, or `rocketpy/environment`. +- Preserve public API behavior and exported names used by `rocketpy/__init__.py`. +- Prefer extending existing simulation components before creating new abstractions: + - `flight.py`: simulation state, integration flow, and post-processing. + - `monte_carlo.py`: orchestration and statistical execution workflows. + - `flight_data_exporter.py` and `flight_data_importer.py`: persistence and interchange. + - `flight_comparator.py`: comparative analysis outputs. +- Be explicit with physical units and reference frames in new parameters, attributes, and docstrings. +- For position/orientation-sensitive behavior, use explicit conventions (for example + `tail_to_nose`, `nozzle_to_combustion_chamber`) and avoid implicit assumptions. +- Treat state mutation carefully when cached values exist. +- If changes can invalidate `@cached_property` values, either avoid post-computation mutation or + explicitly invalidate affected caches in a controlled, documented way. +- Keep numerical behavior deterministic unless stochastic behavior is intentional and documented. +- For Monte Carlo and stochastic code paths, make randomness controllable and reproducible when tests + rely on it. +- Prefer vectorized NumPy operations for hot paths and avoid introducing Python loops in + performance-critical sections without justification. +- Guard against numerical edge cases (zero/near-zero denominators, interpolation limits, and boundary + conditions). +- Do not change default numerical tolerances or integration behavior without documenting motivation and + validating regression impact. +- Add focused regression tests for changed behavior, including edge cases and orientation-dependent + behavior. +- For floating-point expectations, use `pytest.approx` with meaningful tolerances. +- Run focused tests first, then broader relevant tests (`make pytest` and `make pytest-slow` when + applicable). + +See: +- `docs/development/testing.rst` +- `docs/development/style_guide.rst` +- `docs/development/setting_up.rst` +- `docs/technical/index.rst` diff --git a/.agents/skills/sphinx-docs/SKILL.md b/.agents/skills/sphinx-docs/SKILL.md new file mode 100644 index 000000000..8c24cac53 --- /dev/null +++ b/.agents/skills/sphinx-docs/SKILL.md @@ -0,0 +1,32 @@ +--- +description: "Use when writing or editing docs/**/*.rst. Covers Sphinx/reStructuredText conventions, cross-references, toctree hygiene, and RocketPy unit/reference-frame documentation requirements." +name: "Sphinx RST Conventions" +applyTo: "docs/**/*.rst" +--- +# Sphinx and RST Guidelines + +- Follow existing heading hierarchy and style in the target document. +- Prefer linking to existing documentation pages instead of duplicating content. +- Use Sphinx cross-references where appropriate (`:class:`, `:func:`, `:mod:`, `:doc:`, `:ref:`). +- Keep API names and module paths consistent with current code exports. +- Document physical units and coordinate/reference-frame conventions explicitly. +- Include concise, practical examples when introducing new user-facing behavior. +- Keep prose clear and technical; avoid marketing language in development/reference docs. +- When adding a new page, update the relevant `toctree` so it appears in navigation. +- Use RocketPy docs build workflow: + - `make build-docs` from repository root for normal validation. + - If stale artifacts appear, clean docs build outputs via `cd docs && make clean`, then rebuild. +- Treat new Sphinx warnings/errors as issues to fix or explicitly call out in review notes. +- Keep `docs/index.rst` section structure coherent with user, development, reference, technical, and + examples navigation. +- Do not edit Sphinx-generated scaffolding files unless explicitly requested: + - `docs/Makefile` + - `docs/make.bat` +- For API docs, ensure references remain aligned with exported/public objects and current module paths. + +See: +- `docs/index.rst` +- `docs/development/build_docs.rst` +- `docs/development/style_guide.rst` +- `docs/reference/index.rst` +- `docs/technical/index.rst` diff --git a/.agents/skills/tests-python/SKILL.md b/.agents/skills/tests-python/SKILL.md new file mode 100644 index 000000000..1e9626142 --- /dev/null +++ b/.agents/skills/tests-python/SKILL.md @@ -0,0 +1,36 @@ +--- +description: "Use when creating or editing pytest files in tests/. Enforces AAA structure, naming conventions, fixture usage, parameterization, slow-test marking, and numerical assertion practices for RocketPy." +name: "RocketPy Pytest Standards" +applyTo: "tests/**/*.py" +--- +# RocketPy Test Authoring Guidelines + +- Unit tests are mandatory for new behavior. +- Follow AAA structure in each test: Arrange, Act, Assert. +- Use descriptive test names matching project convention: + - `test_methodname` + - `test_methodname_stateundertest` + - `test_methodname_expectedbehaviour` +- Include docstrings that clearly state expected behavior and context. +- Prefer parameterization for scenario matrices instead of duplicated tests. +- Classify tests correctly: + - `tests/unit`: fast, method-focused tests (sociable unit tests are acceptable in RocketPy). + - `tests/integration`: broad multi-method/component interactions and strongly I/O-oriented cases. + - `tests/acceptance`: realistic end-user/flight scenarios with threshold-based expectations. +- By RocketPy convention, tests centered on `all_info()` behavior are integration tests. +- Reuse fixtures from `tests/fixtures` whenever possible. +- Keep fixture organization aligned with existing categories under `tests/fixtures` + (environment, flight, motor, rockets, surfaces, units, etc.). +- If you add a new fixture module, update `tests/conftest.py` so fixtures are discoverable. +- Keep tests deterministic: set seeds when randomness is involved and avoid unstable external + dependencies unless integration behavior explicitly requires them. +- Use `pytest.approx` for floating-point comparisons with realistic tolerances. +- Mark expensive tests with `@pytest.mark.slow` and ensure they can run under the project slow-test + workflow. +- Include at least one negative or edge-case assertion for new behaviors. +- When adding a bug fix, include a regression test that fails before the fix and passes after it. + +See: +- `docs/development/testing.rst` +- `docs/development/style_guide.rst` +- `docs/development/setting_up.rst` diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..049a10eb5 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,20 @@ +{ + "permissions": { + "allow": [ + "Bash(git fetch *)", + "Bash(git merge *)", + "Bash(git checkout *)", + "Bash(python -m ruff --version)", + "Bash(python -m pylint --version)", + "Bash(python -m ruff check rocketpy/plots/flight_plots.py tests/unit/test_plots.py)", + "Bash(python -m ruff format --check rocketpy/plots/flight_plots.py tests/unit/test_plots.py)", + "Bash(python -m ruff check .)", + "Bash(python -m ruff format --check .)", + "Bash(python -m pylint rocketpy/plots/flight_plots.py tests/unit/test_plots.py)", + "Bash(python -m ruff check rocketpy/plots/flight_plots.py)", + "Bash(python -m ruff format --check rocketpy/plots/flight_plots.py)", + "Bash(python -m pytest tests/unit/test_plots.py -k \"animate_trajectory or animate_rotate\" -p no:cacheprovider -q)", + "Bash(python -m pytest tests/unit/test_plots.py -p no:cacheprovider -q)" + ] + } +} diff --git a/docs/development/pro_tips.rst b/docs/development/pro_tips.rst index 465ff7982..9ff491c4b 100644 --- a/docs/development/pro_tips.rst +++ b/docs/development/pro_tips.rst @@ -53,13 +53,25 @@ productive. Code assistance --------------- -Artificial Intelligence (AI) assistance has becoming more and more common in +Artificial Intelligence (AI) assistance has become more and more common in software development. Some editors have AI assistance built-in. -Famous options are GitHub Copilot, JetBrains AI and TabNine. - -At this repo, the use of AI tools is welcome, we don't have any restrictions -against it. +Famous options are Google Antigravity, GitHub Copilot, Claude Code, +JetBrains AI, and TabNine. + +In this repository, the use of AI tools is welcome; we don't have any +restrictions against it. To help AI tools perform better and follow our +standards, we provide pre-configured instructions and skill files within +the repository: + +* **GitHub Copilot**: Uses ``.github/copilot-instructions.md`` (general + codebase rules). +* **Google Antigravity**: Uses the ``.agents/`` folder, containing general + workspace rules (``.agents/AGENTS.md``) and contextual workflows + (``.agents/skills/``) for simulation safety, test authoring, + documentation, and code review. +* **Claude / Claude Code**: Permissions configured via + ``.claude/settings.json``. A few possible applications of AI tools are: @@ -69,11 +81,9 @@ A few possible applications of AI tools are: .. tip:: - As of today, November 2024, GitHub Copilot still provides free access for \ - university email addresses. We can't guarantee this will still be the case \ - when you are reading this, so check the GitHub Copilot website for more \ - information. - + Using these pre-configured rules ensures that your AI assistant adheres + to RocketPy's style guides (snake_case, NumPy docstrings, 88-char line + limits) and testing conventions (AAA structure). If you are against the use of AI tools, do not worry, you can still contribute to the project without using them.