Skip to content

chore(license): SPDX headers PMPL-1.0-or-later → MPL-2.0 (Closes #301)#304

Merged
hyperpolymath merged 1 commit into
mainfrom
relicense-pmpl-to-mpl2
May 20, 2026
Merged

chore(license): SPDX headers PMPL-1.0-or-later → MPL-2.0 (Closes #301)#304
hyperpolymath merged 1 commit into
mainfrom
relicense-pmpl-to-mpl2

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Closes #301. Sweeps SPDX surfaces from PMPL-1.0-or-laterMPL-2.0 across the affinescript repo while keeping the PMPL narrative intact in LICENSE. Option 3 of the three options in #301 — machine-readable side becomes SPDX-recognised everywhere (JSR, opam, SBOM tooling); human-readable preference for PMPL survives in the licence file's body.

Why this shape

Root LICENSE is explicit (and was already this way):

PMPL-1.0-or-later is the primary/preferred licence
MPL-2.0 is the fallback (legally-recognised) licence
"MPL-2.0 was chosen as the fallback because PMPL-1.0-or-later is explicitly based on and extends MPL-2.0"

So PMPL was never the only licence — it's the preferred name for a licence that legally falls back to MPL-2.0 wherever PMPL isn't recognised. SPDX/JSR/opam tooling never recognised PMPL and the fallback was already what applied at those surfaces. This change makes that fact explicit in the SPDX headers (where tools look) without altering the human-readable preference.

Scope (673 files, +1127 / −711)

  • SPDX headers, 1116 sitesSPDX-License-Identifier: PMPL-1.0-or-laterMPL-2.0. Mechanical sed; touches source/.adoc/.md/.yml/.a2ml/.affine/.toml/.sh/.rs/.ml/.idr/.mjs/... uniformly.
  • Excluded — vendored sister-repo subtrees road-skate/ and affinescript-vite/ (they carry their own licensing decisions).
  • Code generators that emit SPDX strings in writeln!/Buffer.add_string/echo — newly scaffolded source files will now carry MPL-2.0 by default.
  • Machine-readable license: / license = fields in .machine_readable/6a2/META.a2ml, .machine_readable/svc/k9/examples/project-metadata.k9.ncl, and affinescriptiser/.machine_readable/6a2/META.a2ml.
  • dune-project(license "MIT OR AGPL-3.0-or-later") (a stale OCaml-project-template leftover that didn't match anywhere) → (license "MPL-2.0"). affinescript.opam regenerated by dune accordingly.
  • LICENSES/LICENSE-MPL-2.0 — added (canonical 373-line Mozilla text from https://www.mozilla.org/media/MPL/2.0/index.txt).

Deliberately preserved

  • Root LICENSE body — full PMPL preferred-licence narrative + MPL-2.0 fallback explanation stay verbatim. Only the file's own SPDX header flipped.
  • LICENSES/LICENSE-PMPL-1.0 — kept (PMPL is still narrated as preferred).
  • Narrative references to PMPL in ALPHA-1-RELEASE-NOTES.md, BACKEND-IMPLEMENTATION.md, EXPLAINME.adoc, GAME-BUNDLING-STRATEGY.md, etc. — historical / architectural context, not machine-readable licence data.

Heads-up — dune-project symlink

Pre-existing layout had top-level dune-project as a symlink to .build/dune-project. The sed -i follow-up broke the symlink (atomic temp+rename overwrites the symlink with a regular file). Both files are now real files with identical content (license + version 0.1.1). If the symlink was load-bearing for some build-output relocation scheme, you may want to restore it as a separate small fix; build + tests pass either way.

Verification

  • dune build --release clean.
  • dune runtest --force295/295 green.
  • Binary --version0.1.1.
  • Shim deno test6/6 green.
  • grep -rl 'SPDX-License-Identifier: PMPL-1.0-or-later' (excl. vendored subtrees) → empty.
  • grep '^license' affinescript.opamlicense: "MPL-2.0".

Test plan

  • Build + tests green locally
  • CI: governance / Hypatia / etc. should remain green — the SPDX flip is uniform; no policy bans MPL-2.0.

Closes #301.

🤖 Generated with Claude Code

Sweeps SPDX surfaces to MPL-2.0 across the affinescript repo while
keeping the PMPL narrative intact in `LICENSE`. Option 3 of the three
choices in #301 — preserves the PMPL-preferred + MPL-2.0-fallback
intent the root LICENSE has always documented, while making the
machine-readable side SPDX-recognised everywhere it matters (JSR, opam,
SBOM tooling).

Why this shape
--------------
The root `LICENSE` is explicit:

  PMPL-1.0-or-later is the PRIMARY/PREFERRED licence
  MPL-2.0 is the FALLBACK (legally-recognised) licence
  "MPL-2.0 was chosen as the fallback because PMPL-1.0-or-later
   is explicitly based on and extends MPL-2.0"

So PMPL was never the only licence — it's the preferred name for a
licence that legally falls back to MPL-2.0 wherever PMPL isn't
recognised. Practically: SPDX/JSR/opam tooling never recognised PMPL
and the fallback was already what applied at those surfaces. This
change makes that fact explicit in the SPDX headers (where tools look)
without altering the human-readable preference.

Scope
-----
- **SPDX headers, 1116 files:** `SPDX-License-Identifier: PMPL-1.0-or-later`
  → `SPDX-License-Identifier: MPL-2.0`.  Mechanical sed; touches
  source/.adoc/.md/.yml/.a2ml/.affine/.toml/.sh/.rs/.ml/.idr/.mjs.../*
  uniformly.  Excludes vendored sister-repo subtrees (`road-skate/`,
  `affinescript-vite/`) which carry their own licensing decisions.
- **Code generators** that emit SPDX strings (lib/error.ml,
  lib/lexer.ml, lib/protobuf.ml, lib/lua_codegen.ml, lib/cuda_codegen.ml,
  lib/cafe_face.ml, lib/pseudocode_face.ml, lib/c_codegen.ml,
  lib/why3_codegen.ml, lib/rescript_codegen.ml, and the Rust
  affinescriptiser sources): the emitted SPDX literal in
  `writeln!`/`Buffer.add_string`/`echo` follows the same change.  Newly
  scaffolded source files will now carry MPL-2.0 by default.
- **Machine-readable license fields:** `.machine_readable/6a2/META.a2ml`,
  `.machine_readable/svc/k9/examples/project-metadata.k9.ncl`,
  `affinescriptiser/.machine_readable/6a2/META.a2ml` — `"PMPL-1.0-or-later"`
  → `"MPL-2.0"`.
- **dune-project:** `(license "MIT OR AGPL-3.0-or-later")` → `(license "MPL-2.0")`.
  The pre-existing MIT/AGPL string was a stale OCaml-project-template
  leftover that didn't match either the PMPL preference or the SPDX
  headers anywhere else in the repo.  `affinescript.opam` regenerated
  by dune accordingly (now `license: "MPL-2.0"`).  Note: the top-level
  `dune-project` had diverged from `.build/dune-project` (the latter is
  no longer the symlink target it used to be); both updated in lockstep.
- **LICENSES/LICENSE-MPL-2.0:** added (canonical Mozilla 373-line text
  fetched from https://www.mozilla.org/media/MPL/2.0/index.txt).
  `LICENSES/LICENSE-PMPL-1.0` and the root `LICENSE` (its PMPL narrative)
  are intentionally retained.

Preserved deliberately
----------------------
- Root `LICENSE` body text — full PMPL preferred-licence narrative and
  the MPL-2.0 fallback explanation stay verbatim.  Only the file's own
  SPDX header (which describes the file's own license, not its contents)
  flipped.
- Narrative references to PMPL in `ALPHA-1-RELEASE-NOTES.md`,
  `BACKEND-IMPLEMENTATION.md`, `EXPLAINME.adoc`,
  `GAME-BUNDLING-STRATEGY.md`, the AGENTIC.a2ml comment — historical /
  architectural context, not machine-readable license data.

Verification
------------
- `dune build --release`: clean.
- `dune runtest --force`: 295/295 tests pass.
- Binary `--version`: 0.1.1.
- Shim `deno test`: 6/6 green.
- `grep -rl 'SPDX-License-Identifier: PMPL-1.0-or-later'` (excl. vendored
  subtrees) → empty.
- `grep '^license' affinescript.opam` → `license: "MPL-2.0"`.

Closes #301.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
Comment thread runtime/src/gc.rs
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
Comment thread runtime/src/ffi.rs
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
Comment thread runtime/src/alloc.rs
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
Comment thread runtime/src/ffi.rs
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
Comment thread runtime/src/gc.rs
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
Comment thread runtime/src/panic.rs
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// SPDX-License-Identifier: MPL-2.0
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 42 issues detected

Severity Count
🔴 Critical 13
🟠 High 17
🟡 Medium 12

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Stray AI.a2ml in root -- use 0-AI-MANIFEST.a2ml only",
    "type": "banned",
    "file": "AI.a2ml",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "high"
  },
  {
    "reason": "Superseded by 0-AI-MANIFEST.a2ml",
    "type": "banned",
    "file": "AI.djot",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "high"
  },
  {
    "reason": "Issue in quality.yml",
    "type": "missing_workflow",
    "file": "quality.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in security-policy.yml",
    "type": "missing_workflow",
    "file": "security-policy.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action actions/checkout@v4 needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action denoland/setup-deno@v2 needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/example/smoke_driver.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/cli.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath merged commit 3170a6b into main May 20, 2026
15 of 16 checks passed
@hyperpolymath hyperpolymath deleted the relicense-pmpl-to-mpl2 branch May 20, 2026 08:14
hyperpolymath added a commit that referenced this pull request May 20, 2026
…retirement (#305)

Follow-up to #303.  Captures the ledger deltas that happened after
#303 merged but in the same session:

- #297 closed (#300 merged): single-source-of-truth Version module
  in `lib/version.ml`; release.yml sed-bakes the tag value into both
  `lib/version.ml` and `dune-project` before `dune build --release`.
  Binary `--version` now self-reports the release tag.
- #301 in flight as #304: repo-wide PMPL-1.0-or-later → MPL-2.0
  SPDX-surface relicense (Option 3 of the three in the issue —
  machine-readable headers/fields flip, root LICENSE narrative
  retains PMPL as the preferred licence).  673 files, 1116 SPDX
  headers, opam regenerated, LICENSES/LICENSE-MPL-2.0 added, no
  behaviour change.
- #302 closed: GitLab + Bitbucket mirroring confirmed intentionally
  off by owner; Codeberg + Radicle are the active forges.
- `repos-monorepo` retirement decided: snapshot tarred to
  `/mnt/c/Users/USER/Downloads/repos-monorepo-snapshot-2026-05-20.tar.gz`
  (23 MB gzip / 144 MB extracted / 23,970 entries / canonical
  origin/main / .git excluded) for owner upload to Google Drive, then
  `gh repo delete`.  Once deleted, `repos-monorepo#9` (the nested
  casket-ssg mirror coherence fix) becomes moot — the standalone
  hyperpolymath/casket-ssg repo's own merged fix (casket-ssg#8) +
  its own `instant-sync.yml` cover forge propagation.

Changes
- `docs/TECH-DEBT.adoc` INT-04 line: appended `#297/#300 fix` and
  `#301/#304 sweep` notes alongside the existing "first JSR publish
  landed" entry.
- `.machine_readable/6a2/STATE.a2ml` adds
  `session-note-2026-05-20-pm` following the existing
  `session-note-YYYY-MM-DD` (with optional `-suffix`) convention.
  STATE.a2ml file remains marked STALE (mirrors, doesn't lead).

No code change.  TECH-DEBT.adoc remains the authoritative ledger;
STATE.a2ml is the machine-readable mirror.

Refs #297 (closed), #300 (merged), #301 (in-flight #304), #302
(closed), #303 (merged — this is its follow-up).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 20, 2026
The relicense sweep (#304) used `sed -i` which atomic-rename-replaces
the target file, breaking the symlink: `dune-project` flipped from
mode 120000 (symlink) to 100644 (regular file).  Both files have been
content-identical since, so nothing's broken — but the symlink was
the original repo layout (presumably so dune's per-package
`(version …)` + opam regeneration lives under `.build/` alongside
other build-output staging).

Restore it: `dune-project` is once again a symlink to
`.build/dune-project`.  Verified post-restore: `dune build --release`
clean, binary `--version` reports `0.1.1`.  Single behavioural change
is that an edit to either path now propagates to the other again, as
originally intended.

If a future bulk sed across the repo encounters this symlink again,
the safe pattern is to operate on `git ls-files` (which lists each
symlink only once via its declared path) — or to edit `.build/dune-project`
directly, which keeps the symlink intact.

Co-authored-by: Claude Opus 4.7 (1M context) <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.

Wider PMPL → MPL-2.0 relicense — decision needed

2 participants