Contributing#
Thank you for contributing to GeoPrior-v3.
GeoPrior-v3 is both:
a scientific Python package,
a staged workflow framework,
and a reproducible research software project.
That means good contributions are not only about “making the code run.” A strong contribution should also respect:
the scientific meaning of the model,
the workflow boundaries between stages,
the public API and CLI surface,
and the reproducibility story of the project.
This page explains how to contribute changes cleanly and in a way that keeps the codebase coherent.
Contribution philosophy#
GeoPrior-v3 is organized around a few strong principles.
1. Keep responsibilities separated
scientific model logic belongs in the model stack,
workflow orchestration belongs in the CLI layer,
figure and manuscript logic belongs in
scripts/.
2. Prefer explicit contracts
If a change affects:
scaling,
configuration,
manifests,
saved payloads,
or exported CSV/JSON outputs,
then it is usually a workflow contract change, not a small local tweak.
3. Documentation is part of the contribution
A change is usually not complete until the relevant docs are updated as well.
4. Preserve reproducibility
A contribution should make the workflow easier to rerun, audit, and interpret — not harder.
A useful summary is:
good contribution
= correct code
+ clear boundaries
+ updated docs
+ preserved reproducibility
What kinds of contributions are welcome#
GeoPrior-v3 benefits from several kinds of contributions, including:
bug fixes,
documentation improvements,
workflow and CLI improvements,
model and physics improvements,
diagnostics and export improvements,
tuning and transfer workflow improvements,
reproducibility and figure-generation improvements.
Examples of especially valuable contributions include:
fixing wrong assumptions in stage handoff logic,
improving scaling or unit safety,
clarifying docs for scientific formulas,
improving public API clarity,
making figure scripts more artifact-driven,
tightening model serialization and payload export.
Before you start#
Before making a non-trivial change, it helps to identify what kind of change it is.
Ask these questions first:
Does this belong in the model layer, the CLI layer, the utility layer, or the scripts layer?
Does it change public behavior?
Does it affect saved artifacts?
Does it affect the scientific interpretation of the model?
Does it require documentation updates?
A small bug fix may touch only one file.
A workflow or physics change often requires updates in several places, such as:
code,
docs,
tests,
release notes.
Where to make changes#
Use the package structure intentionally.
Model and scientific changes#
If the change affects:
the flagship model,
physics closures,
scaling,
identifiability,
residual assembly,
stability behavior,
then it likely belongs under:
geoprior/models/subsidence/
Do not put scientific model logic into the CLI wrappers.
Workflow and CLI changes#
If the change affects:
stage entry points,
command dispatch,
config bootstrap,
CLI arguments,
family routing,
then it likely belongs under:
geoprior/cli/
Try to keep this layer thin. It should orchestrate and forward, not absorb the scientific core.
Workflow-facing utilities#
If the change is reusable across stages or scripts and does not belong tightly inside one model module, it likely belongs under:
geoprior/utils/
Examples include:
artifact discovery,
forecast formatting,
holdout helpers,
config loading,
audit helpers.
Resources and templates#
If the change affects packaged templates or static runtime resources, it likely belongs under:
geoprior/resources/
Keep resource files simple and renderable.
Paper and figure scripts#
If the change is mainly for:
plotting,
manuscript figures,
reproducibility scripts,
paper-facing summaries,
then it likely belongs under:
scripts/
Do not move paper-specific logic into the reusable package unless it has become genuinely general-purpose.
General workflow for a contribution#
A good contribution flow looks like this:
identify the correct layer for the change;
make the smallest clean change that solves the real problem;
update docs if behavior or usage changed;
add or update tests if behavior changed;
update release notes if the change is user-visible;
make sure the change still fits the package structure.
A compact version is:
understand the change
↓
edit the right layer
↓
update docs and notes
↓
verify behavior
↓
submit cleanly
Coding style and formatting#
GeoPrior-v3 benefits from a consistent, disciplined coding style.
Current project preferences include:
Black-formatted code,
relatively short lines,
focused modules with clear responsibilities,
explicit naming over cleverness,
high-quality docstrings.
For this project, shorter lines are especially helpful in:
docstrings,
equations,
dense scientific parameter lists,
code that is frequently reviewed inside docs.
A good rule is:
write for clarity and maintainability first.
Docstrings#
Prefer well-structured docstrings for public classes, functions, and methods.
Especially for scientific code, docstrings should make clear:
what the object does,
what the inputs mean physically,
what the outputs represent,
and whether units, shapes, or conventions matter.
A strong docstring is often the first line of defense against misuse in a scientific workflow.
Naming#
Prefer names that make the role of the object clear.
Examples of good naming habits:
use
stagelanguage for workflow wrappers,use physics-aware names for physical quantities,
keep helper names close to the scientific or workflow idea they implement,
avoid ambiguous abbreviations unless they are standard in the domain.
A good rule is:
if a future contributor cannot guess the module’s purpose from its name, the name may be too vague.
Documentation expectations#
Documentation is not optional for significant changes.
When you change code, ask which docs need to move with it.
If you change the CLI#
Update pages such as:
user_guide/cli.rstuser_guide/configuration.rstrelevant stage pages
api/cli.rst
If you change the model or scientific logic#
Update pages such as:
scientific_foundations/geoprior_subsnet.rstphysics_formulation.rstresidual_assembly.rstlosses_and_training.rstdata_and_units.rstscaling.rstidentifiability.rstapi/subsidence.rst
If you change tuning or transfer workflows#
Update pages such as:
applications/tuner_workflow.rstuser_guide/stage3.rstuser_guide/stage5.rstapi/tuner.rst
If you change reproducibility or plotting behavior#
Update pages such as:
applications/reproducibility_scripts.rstapplications/figure_generation.rstrelevant CLI or API pages
A good rule is:
if users would notice the change, the docs should notice it too.
How to treat scientific changes#
Scientific changes deserve extra care.
Examples include changes to:
physical formulas,
scaling conventions,
timescale priors,
bounds semantics,
drawdown logic,
uncertainty interpretation,
identifiability regimes.
These are not just implementation changes. They can alter the meaning of trained models and exported artifacts.
So when making scientific changes:
explain the motivation clearly,
update the relevant scientific docs,
check whether saved artifacts or configs remain compatible,
record user-visible impact in the release notes.
A good rule is:
if the change affects interpretation, document it like a scientific change, not only like a refactor.
How to treat workflow contract changes#
Some changes affect the workflow contract even if they do not change the model equations directly.
Examples include changes to:
Stage-1 manifest structure,
config fields,
payload formats,
evaluation JSON schemas,
output CSV conventions,
CLI argument meaning.
These changes require extra care because they can break:
downstream scripts,
figure pipelines,
saved-model reuse,
or cross-stage compatibility.
When making this kind of change:
keep backward compatibility where reasonable;
if not possible, document the break clearly;
update any affected docs and examples;
note it in release notes.
Tests and validation#
When behavior changes, the contribution should be verified.
The exact verification depends on the type of change.
For model changes#
Useful validation often includes:
shape and forward-pass checks,
serialization / deserialization checks,
stability checks,
regime- or closure-related behavior checks.
For workflow changes#
Useful validation often includes:
config resolution,
stage handoff behavior,
artifact generation,
CLI argument behavior,
manifest consistency.
For docs changes#
Useful validation includes:
confirming Sphinx references resolve,
checking code paths in examples,
verifying that
literalincludepaths are correct,ensuring page navigation still makes sense.
A good rule is:
verify the layer you changed and any layer it directly affects.
Backward compatibility#
Not every contribution must preserve every old path, but contributors should think about compatibility explicitly.
Try to preserve compatibility when the change affects:
public imports,
CLI command names,
stage entry patterns,
output artifact naming,
saved model reload behavior.
If a break is unavoidable:
keep it as small as possible,
document it clearly,
update release notes,
update examples and docs.
This is especially important in GeoPrior-v3 because the package serves both:
interactive users,
and longer-lived reproducibility workflows.
How to contribute docs#
Documentation-only contributions are valuable and encouraged.
Good documentation improvements include:
clarifying scientific assumptions,
fixing stale links,
improving page structure,
updating imports and code examples,
exposing comments or source listings more clearly,
improving migration and developer guidance.
A good docs contribution should aim to make the next contributor faster and less confused.
How to contribute CLI improvements#
CLI contributions are especially useful when they improve:
discoverability,
consistency,
argument clarity,
stage-to-stage continuity,
config override behavior.
But keep the CLI layer disciplined.
A good CLI contribution should:
preserve the thin-wrapper philosophy,
avoid dragging in scientific logic,
update user-guide and API docs together,
keep aliases and help text coherent.
How to contribute model improvements#
Model contributions are especially valuable when they improve:
scientific clarity,
numerical stability,
interpretability,
identifiability,
uncertainty handling,
or serialization robustness.
But model changes should stay modular.
A good model contribution should avoid:
turning
models.pyinto a monolith,hiding scientific assumptions in obscure helpers,
adding configuration behavior without documenting it,
creating silent differences between training and inference-time interpretation.
Pull request checklist#
Before submitting, check the following.
Code and structure#
the change lives in the correct package layer
module boundaries still make sense
naming is clear
formatting is clean
Behavior#
the intended behavior is verified
no unrelated behavior changed accidentally
public API changes are deliberate
Documentation#
relevant docs were updated
examples still make sense
API pages remain aligned
developer notes were updated if needed
Release notes#
user-visible changes are recorded
breaking or behavior-changing updates are explained
A compact checklist is:
right layer?
right behavior?
docs updated?
notes updated?
easy to review?
Common mistakes#
Putting scientific logic in the CLI layer
This makes the workflow wrappers harder to maintain.
Using top-level utils as a dumping ground
A helper should live where its real responsibility belongs.
Changing a public workflow contract without updating docs
This creates silent confusion for users.
Making a scientific change sound like a refactor
Interpretation-changing changes should be documented explicitly.
Updating code but not release notes
This weakens project history and migration clarity.
Writing docs as an afterthought
For a scientific workflow package, docs are part of the product.
Review mindset#
When reviewing your own contribution, ask:
Would a new contributor know where this code belongs?
Does this preserve the structure explained in Package structure?
If a user reads the docs, will they understand the new behavior?
If someone reruns an old workflow, what changes?
Is the scientific meaning clearer or more ambiguous after this change?
These questions are often more useful than only asking whether the code “works.”
Best practices#
Best practice
Make the smallest clean change that solves the real problem.
Small, clear contributions are easier to review and easier to trust.
Best practice
Keep boundaries intact.
GeoPrior-v3 stays maintainable because the model, CLI, utilities, resources, and scripts layers remain distinct.
Best practice
Update docs and release notes together with user-visible changes.
This prevents silent drift between code and documentation.
Best practice
Treat scientific assumptions as public behavior.
If a change affects interpretation, document it clearly.
Best practice
Prefer artifact-driven and reproducible workflows.
Avoid contributions that hide important work behind side effects or implicit state.
A compact contribution map#
Contributing to GeoPrior-v3 can be summarized as:
identify the right layer
↓
implement a clean, focused change
↓
verify behavior
↓
update docs
↓
update release notes if needed
↓
keep the workflow reproducible and interpretable
Relationship to the rest of the developer docs#
This page explains how to contribute well.
The surrounding developer pages explain:
Package structure where different kinds of code should live;
Migration from FusionLab how to handle older documentation context and stale references;
Release Notes how to record changes cleanly in project history.