v1.108.289 — A licence you can point at, and one you cannot churn
A licensing release, no behaviour change. 1.108.288 was the first version to publish a licence identifier at all; this is the one that makes it stable.
The identifier tracks the major version only
License-Expression: LicenseRef-jCodeMunch-Dual-Use-1
A minor licence bump — a typo fix, a clarification that grants and removes nothing — cannot invalidate a downstream allowlist. A major bump means the terms changed substantively and must. Requested by @marcelruhf, who operates an allowlist against this identifier and proposed the major-only form; reviewed and approved by @georgebashi.
⚠ Allowlist >=1.108.289. 1.108.288 carries -1.1 and keeps it permanently, since PyPI metadata is immutable per version. It is the only release that will ever have it.
Why the promise is pinned rather than stated
A major-only identifier is a promise: the version moves when the terms move. We had already broken it once, and checking the history before agreeing is what found it — commit f3c925c (2026-07-10) added a redistribution and attribution obligation to condition 2 while the header stayed at Version 1.1 — effective 2026-06-30. Nothing failed, because a version line is a convention and conventions do not fail builds. Under this identifier, a licensee would have been told the terms were unchanged.
So the LICENSE text is now pinned by digest. Any edit fails the build, and clearing the failure means choosing: substantive (bump the major version, the identifier, and the digest) or editorial (update the digest alone). The test cannot make that judgement and does not try — it forces the judgement to happen where the text moves, rather than be discovered by a licensee later.
The digest is taken over the normalised text. The first version hashed raw bytes and was red on all four Ubuntu legs while green on all four Windows legs — git rewrites line endings on checkout, and a licence says the same thing in either encoding.
The aside came out of the LICENSE
He's kinda full of himself. sat inside condition 2, in the middle of the derivation-and-attribution obligation. It stays in the README, where it reads as the author's voice. A licence is the document a customer's counsel reads before allowlisting, and a joke inside an operative clause makes a reader stop and work out whether it is operative.
That edit was the first exercise of the digest pin and it routed correctly: it grants and removes nothing, so it is editorial — the digest moved, the identifier did not, and no downstream allowlist was churned. Had the identifier kept the full version, a tone edit would have invalidated one.
Also removed from jdocmunch-mcp and jdatamunch-mcp, where the same line sat in the same clause.
Suite: 8084 passed, 17 skipped, 0 failed — same 8101 total and the same skip split on 3.10 and on the 3.13 CI environment. ruff check src/ clean. All 9 CI jobs green on the release commit.