Contributor workflow¶
This page is for contributors and maintainers changing Morana’s source code, tests, documentation, examples, or build dependencies. Package users do not need these checks to run Morana; start instead with installation and quickstart.
Development disclosure¶
Generative-AI coding tools assist Morana development. Project maintainers remain responsible for design decisions, review, testing, documentation, and released code. This disclosure does not alter the Apache-2.0 license or its warranty disclaimer; it records the maintainers’ responsibility for reviewing and releasing AI-assisted contributions.
Development environment¶
Use the editable Conda environment described in installation and quickstart. Update it after dependency or documentation-tool changes:
The development environment includes Python VTK so tests can reopen Morana’s VTU and VTM output. Morana’s export implementation does not depend on VTK at runtime.
Checks before submitting changes¶
After changing Python source, run:
Run reuse lint after adding, moving, or renaming repository files and before
every completed milestone handoff:
After changing tracked documentation, public NumPy-style docstrings, exported API declarations, or MkDocs configuration, build the complete site strictly:
mkdocs build --strict
python scripts/check_internal_links.py --site-path /morana/
python scripts/check_reference_exports.py
python scripts/check_spelling_and_terms.py
The link check scans the generated HTML, verifies every local href target,
and requires each URL fragment to match an ID in its target page. It therefore
catches stale heading anchors that the strict MkDocs build does not reject.
The reference-export check compares the runtime __all__ declarations of
morana, morana.solvers.finite_volume, and morana.operators with exact
mkdocstrings IDs in their generated reference pages, rejecting missing runtime
attributes, missing anchors, and duplicate anchors.
The spelling and terminology check scans authored documentation, public source
and docstrings, maintained examples, and maintenance scripts. Add legitimate
technical words to scripts/spelling_vocabulary.txt; keep discouraged forms
and their canonical replacements in scripts/terminology_rules.toml.
After a substantial change, also run every maintained example in scope. The routine suite is:
Computationally expensive staged workflows, such as the OpenMC comparison, document their own reproduction commands and are run separately when in scope.
Continuous integration¶
Verification is local-first. Run the commands on this page before integration
or release work. Pull requests and pushes to main run tests on Python 3.12,
3.13, and 3.14, plus static, licensing, spelling, terminology, documentation,
internal-link, and reference-export checks. The protected main branch
requires every hosted check on an up-to-date pull request and allows
squash-merging only.
Morana currently uses sole-maintainer release approval. The maintainer may approve publication without a second-person review, but the protected pull-request and verification gates still apply.
Publishing a source release¶
Morana releases are currently published from one exact commit through GitHub and Zenodo.
Prepare a release through a pull request that updates the package version,
dated changelog, citation metadata, installation guidance, and public URLs.
The Zenodo version DOI must already be present in the source. After the pull
request is squash-merged, update local main without creating another commit
and record the exact release commit:
The status output must be empty. Run the complete local verification suite from this page, including all maintained routine examples and the strict documentation checks. Confirm that the hosted verification and documentation workflows also pass on the same commit. Any failure requires a new pull request and a complete rerun on its merged commit.
Build the release archive from the verified commit rather than from the working
directory. Replace <VERSION> with the version being published and
<RELEASE_COMMIT> with the recorded full commit hash before running each
command block:
release_version="<VERSION>"
release_commit="<RELEASE_COMMIT>"
archive_name="morana-${release_version}.tar.gz"
mkdir -p dist
test ! -e "dist/${archive_name}"
test ! -e "dist/${archive_name}.sha256"
git archive \
--format=tar.gz \
--prefix="morana-${release_version}/" \
--output="dist/${archive_name}" \
"$release_commit"
cd dist
sha256sum "$archive_name" > "${archive_name}.sha256"
cd ..
Inspect the archive before publication:
release_version="<VERSION>"
archive_name="morana-${release_version}.tar.gz"
tar -tzf "dist/${archive_name}"
gzip -dc "dist/${archive_name}" | git get-tar-commit-id
cd dist
sha256sum --check "${archive_name}.sha256"
cd ..
It must have one morana-<VERSION>/ top-level directory and contain the
package source, pyproject.toml, README, citation metadata, canonical license
files, documentation, examples, and tests. It must exclude generated sites,
caches, local environments, result archives, raw study data, and other
untracked artifacts.
Clean-install and test the archive outside the repository before tagging:
release_version="<VERSION>"
archive_name="morana-${release_version}.tar.gz"
archive_path="$(pwd)/dist/${archive_name}"
release_test_dir="$(mktemp -d)"
python -m venv "$release_test_dir/venv"
"$release_test_dir/venv/bin/python" -m pip install "$archive_path"
"$release_test_dir/venv/bin/python" -c \
'import sys; from importlib.metadata import version; import morana; assert version("morana") == sys.argv[1]' \
"$release_version"
"$release_test_dir/venv/bin/python" examples/quickstart.py
"$release_test_dir/venv/bin/python" examples/result_archive.py \
--output-dir "$release_test_dir/output"
Create a signed tag if signing is configured; otherwise create an annotated
tag. The tag must point to release_commit and must never be moved after
publication:
release_version="<VERSION>"
release_commit="<RELEASE_COMMIT>"
git tag -a "v${release_version}" "$release_commit" \
-m "Morana ${release_version}"
git show --no-patch --decorate "v${release_version}"
During one coordinated release window:
- Push the verified commit and
v<VERSION>tag. - Upload
morana-<VERSION>.tar.gzand its SHA-256 file to the prepared Zenodo draft, then publish it and verify the version DOI. - Create the GitHub release from the same tag, attach the identical two files, link the Zenodo record and documentation, and use the dated changelog as the release-note basis.
- Verify the deployed documentation and clean-install again from the published GitHub release archive.
- Record Zenodo’s concept DOI for project-level citation links while retaining the version DOI for citations of the specific release.
Do not use automatic GitHub-release ingestion: the archived source must already contain its version DOI. Do not publish either channel after a failed gate, rebuild the archive between channels, replace an accepted archive, reuse the version, or move the public tag.
Licensing files and dependencies¶
Morana source code, authored documentation, tests, examples, and ordinary
project assets are Apache-2.0. The root CONTRIBUTING.md records the
contribution agreement. The root LICENSE is the canonical project license,
pyproject.toml declares the package license, and LICENSES/ contains
canonical SPDX license texts.
REUSE.toml supplies copyright and SPDX license annotations for the
repository paths. When adding or moving a file:
- Check whether its new path is covered by the intended
REUSE.tomlannotation. Extend the path list or add an explicit annotation when it is not. - For third-party, generated, or separately licensed material, record its
actual provenance, copyright holder, and SPDX identifier with a
higher-precedence override. Do not let it inherit Morana’s authored-file
annotation merely because it sits under
docs/or another covered path. - Preserve the upstream license and required notices. Add a canonical text
under
LICENSES/when the SPDX license is not already present; keep bundled asset licenses with the assets when upstream distribution requires it. - If an asset or frontend component is copied into the generated site, update licenses and third-party notices so deployed documentation carries the required notice. Merely declaring a Python dependency does not make its source part of Morana’s distributed documentation.
- Run
reuse lintand inspect its file count and license summary before handing off the change.
The Morana logo is the exception to the authored Apache-2.0 default:
REUSE.toml records its ChatGPT provenance and CC0-1.0
dedication. Vendored MathJax has its own Apache-2.0 override under The MathJax
Consortium. Keep these overrides synchronized with the assets they cover.
Previewing documentation¶
The generated site/ directory is an untracked build artifact. The tracked
Markdown and source docstrings remain the documentation sources. The build uses
flat .html links, so site/index.html and its navigation also work when
opened directly through a local file:// URL without a web server.
Use the live local preview while reviewing interactive documentation features:
Open the local address printed by MkDocs (normally http://127.0.0.1:8000/)
and stop the preview with Ctrl+C. Material for MkDocs 9.x
provides the responsive light theme, navigation, search presentation, and code
controls. Morana-specific colors, content width, table treatment, and
generated-signature styling live in docs/stylesheets/extra.css; keep those
overrides small and verify the light presentation after changing them. The
generated site includes the required
third-party notices for Material for MkDocs and MkDocs.
Regenerating authored figures¶
The maintained verification examples generate their tracked result figures when given the documentation asset directory:
python examples/one_group_keff.py --documentation-assets-dir docs/assets
python examples/fixed_source_mms.py --documentation-assets-dir docs/assets
python examples/keff_mms.py --documentation-assets-dir docs/assets
python examples/openmc_comparison/plot_documentation.py \
--documentation-assets-dir docs/assets
Each owning verification page documents which figures and numerical evidence its command regenerates. The OpenMC comparison command additionally requires the complete local CE and Morana study records described by the comparison workflow. Review the numerical output before accepting an asset change.
The affine-Robin parameter figure has a separate Matplotlib generator. After changing the boundary equations or figure presentation, run:
This deterministically rewrites the tracked Matplotlib-generated image
docs/assets/boundary_parameter_relations.png. The script also accepts
--output path.png for inspection copies.
Regenerating the synthetic OpenMC MGXS fixture¶
The checked-in OpenMC runtime-MGXS fixture is a small integration artifact for the material-data importer and is exercised by its routine tests. Regenerate it only when intentionally changing its synthetic arrays or updating the documented OpenMC writer version:
Replace OPENMC_ENVIRONMENT with a separately managed environment that
provides OpenMC. It is used solely for fixture generation; Morana’s importer
and normal development environment do not depend on OpenMC. Review the
generated HDF5 change, update the OpenMC version recorded in the generator and
REUSE provenance when appropriate, and run reuse lint.
Maintaining the documentation toolchain¶
The tasks in this section are for maintainers changing documentation dependencies or vendored rendering assets. Routine prose and docstring changes do not require refreshing the toolchain.
The active documentation toolchain is deliberately constrained to MkDocs 1.x
(>=1.6,<2) and Material for MkDocs 9.x. Do not upgrade to MkDocs 2 without a
separately verified migration: the source-derived reference depends on the
MkDocs plugin interface through mkdocstrings-python.
Mathematics uses pymdownx.arithmatex and the pinned MathJax 4.1.3 component,
New Computer Modern font ranges, and boldsymbol extension under
docs/assets/mathjax/ (Apache-2.0; see its bundled license). Upgrade those
assets together. Do not replace them with a CDN reference: the complete
rendered site must retain equation support when opened through file://
without network access.
Refresh the selected component and font assets with an exact matching release:
The script downloads mathjax and @mathjax/mathjax-newcm-font from npm,
stages only the component, boldsymbol extension, license, and CommonHTML
font files used by this site, then synchronizes that selection into
docs/assets/mathjax/. When changing the version, update the pin in this
section and the MathJax comment in REUSE.toml, then run the applicable checks
on this page. The site retains semantic MathJax markup but disables the optional
speech and braille worker, which is not vendored.
Documentation rendering smoke check¶
After building the site, run the offline browser check when changing the theme, representative content structures, generated reference, equations, MathJax configuration, or vendored frontend assets:
It opens the built home, quickstart, core-reference, and theory pages directly
from file:// with host-name resolution disabled. The check verifies Material
JavaScript initialization, representative content and code-copy controls,
mkdocstrings signatures, and the project-status presentation. On the theory
page it additionally confirms that every arithmatex expression becomes a
MathJax container, rejects MathJax errors and literal \boldsymbol text, and
verifies retained TeX annotations plus semantic, keyboard-accessible MathJax
markup.
Where documentation changes belong¶
Use these ownership rules when adding or revising user-facing information. Verify technical claims against the relevant implementation, tests, and project README. Documentation ownership determines where to explain that behavior; it does not make another documentation page evidence for an implementation claim.
Documentation ownership¶
- The modeling and solver workflow owns the implemented capability inventory, cross-object behavior, result conventions, and capability boundaries.
- The geometry, theory, and output pages own their named conventions; the examples page alone catalogs maintained runnable workflows.
- The OpenMC MGXS import guide owns its accepted external artifact, selection, conversion, warnings, units, and interoperability limits.
- The OpenMC–Morana comparison page owns its physical model, published numerical evidence, figures, interpretation, and references. The OpenMC comparison workflow owns reproduction commands and artifact handling; the example README links to both pages.
- The verification page owns test-coverage claims and the distinction between verification and experimental validation.
- The licenses page owns notices for assets distributed with the generated
site;
REUSE.tomlowns repository file annotations. - The changelog owns dated release notes; it does not duplicate the modeling and solver workflow’s capability inventory.
- The README and documentation home provide concise summaries and route readers to these owners without duplicating detailed capability contracts.
docs/reference/is rendered from explicit__all__declarations, type annotations, and NumPy-style public docstrings usingmkdocstrings-python.- Generated HTML is never edited directly.
Writing and navigation¶
Use sentence case for page and section headings: capitalize the first word and retain capitals only for proper nouns and established acronyms such as Morana, OpenMC, API, VTK, and MathJax.
Use lowercase snake-case filenames that describe the rendered page purpose.
Every tracked Markdown page under docs/ must appear in mkdocs.yml
navigation. Prefer relative Markdown links between sources; MkDocs produces
the flat .html targets.
Link the first explanatory mention of a public Python object in each section
to its exact anchor in docs/reference/ when readers may need its constructor,
attributes, or methods. Do not mechanically link repeated mentions or code
examples. Keep cross-object behavior in the modeling and solver workflow, and
link to the owning geometry, theory, output, or verification page when that
context matters more than the object interface.
Document externally defined theory and interoperability conventions with
open-access technical references or official project documentation where
available. State clearly which conclusions come from those sources and which
are Morana-specific numerical or API conventions. Reproducible authored
figures should keep their generator scripts under scripts/ and document the
regeneration command on this page.
Citations and references¶
Use a direct inline link for official project documentation or an authoritative online reference work when it supports a specific API, file-format, interoperability, definition, or formula claim. Link to the relevant stable page or section, not a search result or a project home page.
For a technical paper, report, textbook, or other scholarly source, use an
author–year citation at the claim and link it to a page-local ## References
section. Give each cited work a stable anchor and a complete bibliographic
record, including authors, title, venue or report number, publisher or
institution, and year as applicable. Include a link to open full text; a DOI or
publisher record may accompany it but is not a substitute for open access.
Name the supporting figure, section, or page when that specificity matters.
Pages that cite at least one technical source must include this bibliography;
pages that only link to official project documentation need not add one.
See verification and comparisons for numerical and file-format test coverage.