Skip to content

Declare GPL-2.0-or-later, not GPL-2.0-only - #24

Merged
remislp merged 1 commit into
masterfrom
license-or-later
Sep 11, 2026
Merged

remislp merged 1 commit into
masterfrom
license-or-later

Conversation

@remislp

@remislp remislp commented Sep 11, 2026

Copy link
Copy Markdown
Member

The metadata over-claimed restriction relative to the code it describes.

No file in scalcs/ carries a licence notice of any kind, and LICENSE.MD
is the bare GPL version 2 text — whose own section 9 says that where a program
specifies no version number, a recipient may choose any version the FSF has
published. The "only" existed in pyproject.toml and nowhere else.

Why it stopped being cosmetic

The fitting layer is going into HJCFIT, which is GPL-3.0-or-later and now
needs SCALCS for mechanism handling. GPL-2.0-only and GPL-3.0 are mutually
incompatible
— the combination could not have been distributed at all.

MIT was considered and rejected

Three independent reasons, any one of which would be enough:

  1. SCALCS is not one person's copyright — 70 commits from Christoph
    Schmidt-Hieber and one from Jens Hedegaard Nielsen. A permissive relicence
    needs their agreement: a conversation, not a commit.
  2. Parts are re-implemented from the GPL'd DCPROGS Fortran. popen.py:195
    says so of HJC_HILL.FOR. MIT would assert none of that is a derivative
    work, which is the stronger claim to have to defend.
  3. It buys nothing here. GPL-3.0-or-later HJCFIT can consume
    GPL-2.0-or-later without difficulty. MIT's benefit is to third parties
    outside the GPL world — worth revisiting on its own terms, not as a side
    effect of a dependency decision.

Verified

The built wheel's metadata reads License-Expression: GPL-2.0-or-later, and
twine check --strict passes on both artifacts. 617 passing.

The README now states the version where a reader will look, since no source file
does.

🤖 Generated with Claude Code

The metadata over-claimed restriction relative to the code it describes. No
file in scalcs/ carries a licence notice of any kind, and LICENSE.MD is the
bare GPL version 2 text whose own section 9 says that where a program
specifies no version number, a recipient may choose any version the Free
Software Foundation has published. The "only" existed in pyproject.toml and
nowhere else.

It became a real constraint rather than a cosmetic one when the fitting layer
was placed in HJCFIT, which is GPL-3.0-or-later and now needs SCALCS for
mechanism handling. GPL-2.0-only and GPL-3.0 are mutually incompatible, so the
combination could not have been distributed at all.

MIT was considered and rejected, for three independent reasons. SCALCS is not
one person's copyright -- 70 commits from Christoph Schmidt-Hieber and one from
Jens Hedegaard Nielsen -- so a permissive relicence needs their agreement,
which is a conversation rather than a commit. Parts of the package are
re-implemented from the DCPROGS Fortran, which is GPL, and popen.py says so of
HJC_HILL.FOR; MIT would assert that none of that is a derivative work, which
is the stronger claim to have to defend. And it buys nothing for this
architecture, since GPL-3.0-or-later HJCFIT can consume GPL-2.0-or-later
without difficulty. The benefit of MIT would be to third parties outside the
GPL world, which is worth revisiting on its own terms rather than as a side
effect of a dependency decision.

The README now states the version where a reader will look, since no source
file does.

Verified: the built wheel's metadata reads License-Expression:
GPL-2.0-or-later, and twine check passes on both artifacts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@remislp
remislp merged commit 117d472 into master Sep 11, 2026
9 checks passed
@remislp
remislp deleted the license-or-later branch September 11, 2026 10:30
remislp added a commit that referenced this pull request Sep 11, 2026
Seven merged pull requests have been waiting since 1.1.0, and one of them is
now blocking work elsewhere: HJCFIT's fitting layer is duck-typed on a
mechanism and needs Rate.is_free, which exists here on master and not in the
published 1.1.0. Its [fitting] extra pins scalcs>=1.1.0, which is too loose --
the integration tests fail on the released wheel with "'Rate' object has no
attribute 'is_free'".

A minor rather than a patch release, because it corrects computed values as
well as adding API.

  #17  root bracketing for the asymptotic pdf. Counts were not recomputed when
       a search bound moved, widening happened once where it needed to repeat,
       and the upper bound was compared against the wrong state count. det[W(s)]
       is also unusable at large |s|, where it is of order 1e53 and changes sign
       hundreds of times in noise, so roots are now refined by bisecting the
       eigenvalue count where the determinant cannot be trusted. Roots are
       validated before being returned.
  #18  scsim re-exports burst segmentation from dcio; one implementation in the
       stack rather than two.
  #20  the dARSdS sign. exact_mean_open_shut_time was too large by exactly
       twice the dead time and the conditional means by once. This changes
       numbers a caller will have seen.
  #21  impose_resolution checked against RESHJC2.FOR interval for interval.
  #22  the simulator checked against Q-matrix theory for multi-state
       mechanisms, not only the two-state case where a reciprocal rate is the
       answer.
  #23  qmatlib.H inverted sI - QFF directly, which fails where the root search
       walks. The singularity is removable; only the factored form has a pole.
  #24  GPL-2.0-or-later rather than GPL-2.0-only, without which HJCFIT
       (GPL-3.0-or-later) could not depend on this at all.

Both version files are bumped; the versions-agree gate added in #16 is what
makes that hard to get wrong. Verified: the built wheel reports 1.2.0, carries
its three data files, declares GPL-2.0-or-later, and Rate.is_free is present
when installed from it into a clean environment.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant