Contributing¶
Migration status¶
The repository recently completed a clean-room rewrite: the production
implementation is vmex.core (~30 focused modules, one concern per
file — see Architecture), and the vmec CLI runs on it end to end.
The remaining top-level legacy modules are being removed in an ongoing
deletion sweep; new code, tests, and documentation should target
vmex.core only. Every core module was validated by A/B equivalence
tests against the parity-proven legacy implementation
(tests/) and end to end against VMEC2000 golden runs.
Workflow¶
Add or extend a kernel with a focused API in the matching
vmex.coremodule; the module header docstring names the VMEC2000 counterpart file it ports — keep that cross-reference current.Add a regression test under
tests/(fast, offline where possible); parity-sensitive changes need a check against the golden VMEC2000 fixtures.Keep JAX gotchas in mind:
jitted functions should only take arrays / pytrees (static config stays hashable and out of traced signatures),
solver functions are pure
state -> state— no hidden host state,float64 is mandatory (enforced at solver import).
Development install and checks:
pip install -e .[dev]
ruff check .
pytest -q
Documentation builds must pass strict mode:
python -m sphinx -W -j auto -b html docs docs/_build/html
Releasing¶
Releases are cut from main:
Move the
Unreleasedentries inCHANGELOG.mdunder a new version heading and record the version and date.Bump
versioninpyproject.toml(semantic versioning).Tag the commit (
vX.Y.Z) and publish a GitHub Release. Thepublish-pypiworkflow validates that the tag matches the project version and uploads the wheel and sdist to PyPI.
Keep CHANGELOG.md current as part of each change rather than at release
time: add a bullet under Unreleased in the same PR that makes the change.