Contributing to SIMPLE¶
Bug reports, questions, documentation fixes and pull requests are welcome. SIMPLE is maintained by a research group; there is no guaranteed response time. Contributions are distributed under the MIT License.
Issues¶
Use the issue tracker with the template for a bug report, feature request or question. Search existing issues first. A bug report contains:
the commit (
git rev-parse --short HEAD) or release tag,the build command and options (
CONFIG,FLAGS,LIBNEO_REF, CUDA),compiler and operating system (
gfortran --version,uname -a),the
simple.inand how to obtain the field input,expected and actual behaviour with the relevant output,
the smallest reproducer: few particles, short
trace_time,deterministic = .true..
Do not attach unpublished or confidential equilibria; describe how a similar case can be produced.
Build and test¶
Dependencies and CMake options are in the installation guide. For development, from the repository root:
make CONFIG=Fast # build in build/
./setup-venv.sh # once: .venv with test dependencies and pysimple
source .venv/bin/activate
make test-fast # before every push
Select dependencies on the first configuration with
make LIBNEO_REF=<branch|tag|sha> or make LIBNEO_PATH=/path/to/libneo;
run make clean before changing them or the compiler. To change the profile
of an existing build, run make reconfigure CONFIG=Debug before make.
Run make test as well for Python changes and make test-regression for any
change that can move numerical output. The
testing guide
lists all targets and labels, the oracle and tolerance rules and the
invariants a change must keep.
Pull requests¶
Branch from current
main, one purpose per branch. Stage files explicitly.Add a test that fails without the change (testing guide).
Follow the coding standard. CI checks formatting of changed lines; run
python tools/check_changed_lines.py(needsfprettifyandruff).Open the pull request against
mainand fill in the template. Open it as a draft while work is in progress; CI runs on pull requests that are ready for review.Answer review with new commits. A maintainer merges.
Before marking a PR ready, compare the final diff with the issue and PR contract. Remove unrelated work, redundant tests/docs, transient generated data and accidental large result sets. Squash fixups or reorganize commits into a few meaningful steps; preserve rejected scientific approaches only when their history is useful evidence. Do not rewrite shared, stacked or queued branches without coordinating with their users.
Each pull request carries one risk tier, set by its highest-risk part. The tier sets the depth of review and the evidence required:
Label |
Scope |
Evidence |
|---|---|---|
|
documentation, comments, small build metadata |
docs or build check |
|
refactor without intended behaviour change |
golden records or bitwise output unchanged |
|
local numerical logic, interpolation, coordinate utilities |
unit tests plus property or roundtrip tests |
|
physics, output meaning, wall losses, collisions, coordinate conventions |
independent comparison and golden-record explanation |
|
parallelism, GPU, dependencies, CI, security-sensitive build logic |
several platforms, determinism or statistical checks, performance |
It also carries one size label for the changed lines: size/XS (≤ 10),
size/S (≤ 100), size/M (≤ 300), size/L (≤ 1000) or size/XL.
Maintainers add labels if you cannot.
The template asks for the intended change, behaviour that must not change, coordinate and unit conventions, numerical invariants, tests, golden-record impact and failure modes. State testable claims; a summary is not evidence. Split mixed work by risk: feature logic, caller integration, plotting, test-performance changes and build or dependency changes go into separate pull requests.
A change of golden-record output is a scientific change. The pull request names the affected cases, the expected sign and magnitude, the physical or numerical reason and whether the old behaviour was a bug. Do not regenerate reference output without that explanation.
Merging¶
Pull requests, including every layer of a stacked PR, run the fast CI tier. Label a PR
full-cito run the full tier on it before queueing.Review and land a stack bottom-up, one squashed commit per layer. Keep each layer’s independent diff and its own pull request.
Use “Merge when ready” (or
gh pr merge --squash --auto). The squash merge queue runs the full CI tier on the exact merge result.mainitself is not re-tested on push.Record
<old-lower-head>before the bottom layer squashes. Fetchmain, then rebase the next layer withgit rebase --onto origin/main <old-lower-head>and retarget it tomain. Recheck that layer’s final diff and affected tests before queueing it.Merge current
maininto an independent PR before its final validation. Coordinate before rewriting a shared or queued branch.
The required repository-hygiene workflow scans the PR commit range for secrets,
files over 1 MiB, data/archive types and aggregate additions over 5 MiB. The
pinned shared checker
also runs offline on staged changes through the prompts global hook, before
this repository’s pre-commit hooks. Install pre-commit and its existing quick
mechanical checks before committing. Reuse valid test evidence; builds,
numerical tests and optional AI review do not belong in ordinary commit hooks.
Artifact exceptions require a tracked .repo-hygiene-allow: repository-relative
path glob, TAB, one-line provenance/reason. There is no environment override.
Never commit non-public machine, experiment or collaborator data as fixtures
(ITER/TC24/IMAS, AUG shots, JT-60SA inputs included). Use synthetic or published
data with provenance. Keep campaign results externally with checksums.
Heavy CI runs only in public repositories. Private repositories validate via
cluster jobs, with job IDs, revision, commands and results recorded in the PR.
Commit messages¶
Use a lower-case type prefix and an imperative summary of at most about 72
characters, for example fix: drop the RK momentum gate on accepted symplectic steps. Types: feat, fix, perf, refactor, test, docs, build,
ci, research. The body says why the change is needed and what supports it;
reference issues as #123.
Documentation¶
Update documentation in the same pull request as the code:
Change |
Update |
|---|---|
|
|
coordinates, fields, |
|
modules, data flow, extension points |
|
output files or columns |
|
Python API |
docstrings in |
results may differ for the same input |
one row in |
Source comments explain intent, units, coordinate conventions and non-obvious numerics, not history. Angles are in radians and are not wrapped during integration.