Proposal: make `main` the nightly-vetted branch, and gate promotion on a full physics run
Maintainers usually reply within 3 days
@matt-pharr is already working on this.
Since Aug 12, 2026.
Assessment
This issue has not been assessed yet.
Description
Summary
Right now develop is the GitHub default branch, so anyone who clones GPEC gets the
integration branch. Since the package is not registered and the docs install it by
git clone + Pkg.instantiate (docs/src/set_up.md:66), the default branch is our
distribution channel — we are shipping unvetted code to new users by default.
This proposes a three-tier verification model and a redefinition of main:
develop— integration branch. Everything merges here, as today.main— blessed: fast-forward only, and only todevelopcommits that passed the
full front-to-back regression suite. Becomes the GitHub default branch — what users clone
and install.- Version tags on
main— cut intermittently, when maintainers are happy, for citation
and reproducibility.
The verification suite behind it is the golden-value regression overhaul now underway (converged
physics pins on δW, Δ′, perturbed-equilibrium quantities, tearing γ, NTV torque, across
equilibrium scans), which also fixes the harness confounds in #338.
The three tiers
| Tier | Trigger | Where | Contents |
|---|---|---|---|
| 1 — fast | every PR push | GitHub Actions | unit tests + fast analytic golden cases |
| 2 — selective | maintainer label, when ready to merge into develop |
feynman cluster | golden cases selected by what the diff touches |
| 3 — full | every push to develop, nightly as backstop |
feynman cluster | every golden case; a green result is what makes a commit promotable |
Tier 2 exists so that contributors are not made to run the whole suite for a change confined to
one module: a change to the Δ′ calculation need not re-run the kinetic or perturbed-equilibrium
cases, while a change to spline gridding re-runs everything. The selection map fails open
(anything unmapped selects the full tier), and because tier 3 runs on every develop push, the
map validates itself: any case that fails at tier 3 but would have been skipped at tier 2 is a
map bug we can detect and fix automatically.
Tier 3 runs per-push rather than only nightly because attribution is otherwise expensive — if
five PRs land in a day and a nightly goes red, someone owes a bisect at full-suite cost. The
cluster has 50 SLURM CPUs and harness cases are independent processes, so per-push is minutes
of wall time.
Why main should be verification, not releases
Three concerns are usually conflated in one branch:
- Integration — where work lands. Continuous. Needs a branch (
develop). - Verification — "this commit passed the full physics suite." Continuous, mechanical,
automatic. Needs a branch (main). - Release — "maintainers judge this fit to cite and depend on." Discrete, human, semver.
Needs a tag, not a branch.
For a scientific code whose users clone the repo, verification is the property they need
continuously; releases are for papers and reproducibility. So: main moves whenever the full
suite is green, and tags mark the points humans bless.
Alternatives considered
A separate stable branch (vetted) plus main (versioned releases). stable and main
would differ only by whether a version had been cut at that commit — which is exactly what a tag
encodes. The extra long-lived branch adds a second merge path, a drift risk between two branches
that must stay related, and ambiguity about which branch a hotfix targets, in exchange for a
convenience that git checkout v0.3.1 already provides.
Versioning every merge into main. This collides with fast-forward-only promotion: if main
only fast-forwards, no commit can originate there, so a version bump must land on develop and
flow through. Versioning every merge would put a Project.toml bump in every PR. Version bumps
should be deliberate and occasional; verification is the thing that should be continuous.
Backporting (fixing an old release while develop moves on) is the one case that would
justify more branches. It is served by release/0.2.x branches cut on demand, which is
orthogonal to this proposal and can be added later. Do we foresee needing it?
What this requires
- Fast-forward-only promotion to
main.mainadvances to the exact SHA that tier 3
tested — never todevelop's tip at promotion time, and never via a merge commit, which
would publish a tree nothing tested. Requires enablingrequired_linear_historyonmain. - Promotion opens a PR; a human merges it. Keeps
main's existing 2-approval rule and our
human-review policy intact. (Tradeoff: a bot-opened fast-forward PR still needing two
approvals may bottleneck promotion. The alternative — letting automation push to the
public-install branch — seems worse. Opinions welcome.) - Change the default branch to
mainonce it exists in blessed form, and update the clone
instructions indocs/src/set_up.md. - Revise the hotfix workflow. Today
hotfix/branches frommainand merges intomain+
develop(docs/development/git-workflow.md). That puts a commit onmainthat is not an
ancestor ofdevelop, which breaks fast-forward promotion permanently. Revised: branch from
the blessed SHA, PR intodevelop, expedited full-tier run, then normal promotion. A genuine
emergency uses an explicitpromote:unblessedlabel with recorded justification, so an
override is visible rather than silent. - Make a frozen
mainloud. A red tier 3 stops promotion by design. That needs an
auto-opened issue and a "days sincemainadvanced" signal, or a freeze quietly becomes the
status quo. Two documented unblock paths: fix the regression, or — if the change was an
intended physics improvement — regenerate the golden values with convergence evidence. - Contributor-facing rule: a PR that intentionally changes physics regenerates its golden
values in that PR. Otherwise it passes tier 1, turnsdevelopred at tier 3, and freezes
promotion for everyone else.
Unrelated bug found while checking this
develop's branch protection requires the contexts runtests 1.11 - ubuntu-latest and
runtests 1.x - ubuntu-latest. But test.yaml is path-filtered and deliberately publishes a
stable Tests job so that a skipped suite does not block a merge — the workflow says so in a
comment. As configured, a PR that touches no Julia code skips the matrix jobs, their contexts
never report, and the required check stays pending indefinitely. It has not bitten us because
almost every PR touches Julia. Protection should point at Tests instead. Worth fixing before
we add tier checks, or the new tiers inherit the same trap.
Questions for the group
- Does
main-as-blessed vs a separatestablebranch match how people expect to consume GPEC? - Two approvals on an automated fast-forward promotion PR: right, or a bottleneck?
- Do we anticipate backporting fixes to older releases?
- Who owns the feynman-side runner, and do we want a self-hosted GitHub Actions runner there
(integrated status checks, but the repo is public, so fork PRs are a code-execution risk and
the workflow would have to be restricted toschedule/workflow_dispatchwith an ephemeral
runner) or a cron +sbatchjob reporting through the API (safer, less integrated)?
- Dominant language
- Julia
- Stars
- 11
- Forks
- 7
- Avg merge
- 4d 1h
- Merged PRs (30d)
- 68
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from OpenFUSIONToolkit/GPEC
-
Difficulty 1/5 Under an hour Newbie friendliness 82/100
OpenFUSIONToolkit/GPEC#644 ·
Maintainers usually reply within 3 days
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
OpenFUSIONToolkit/GPEC#643 ·
Maintainers usually reply within 3 days
-
PerturbedEquilibrium - FEATURE - Complete the resistive perturbed-equilibrium workflow from Galerkin and matched resultsPossibly taken @matt-pharr claimed this 2 days ago. Openfeature
OpenFUSIONToolkit/GPEC#635 · 1 comment · 1 assignee ·
Maintainers usually reply within 3 days
-
test
Difficulty 4/5 3-5 days Newbie friendliness 25/100
OpenFUSIONToolkit/GPEC#633 · 2 comments ·
Maintainers usually reply within 3 days
-
Tearing - FEATURE - Add a general modified Rutherford equation for island evolutionPossibly taken @StuartBenjamin claimed this 2 days ago. Openfeature
OpenFUSIONToolkit/GPEC#630 · 1 assignee ·
Maintainers usually reply within 3 days
All issues in OpenFUSIONToolkit/GPEC
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Sienna-Platform/InfrastructureSystems.jl#675 ·
Maintainers usually reply within 2 days
-
TargetEncoder reuses the first level's shrinkage factor for all levels when m > 0Possibly taken @parth-patel010 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
JuliaAI/MLJTransforms.jl#95 · 1 comment ·
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
SciML/RecursiveArrayTools.jl#687 ·
Maintainers usually reply within 3 days
-
Difficulty 1/5 Under an hour Newbie friendliness 65/100
SciML/LinearSolve.jl#1412 ·
Maintainers usually reply within 8 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
SciML/Corleone.jl#179 ·
Maintainers usually reply within 1 day