Every decision in ADR 0052 is implemented and tested in @ekklesia/module-pack: - package material first, and a supplement only adds to it; - reviewed, generic supplement data, checked in with the packager; - an exact name, version, and content-digest match, failing closed on any mismatch; - the documented, host-independent digest; - a deterministic, labelled merge; - no licence override, with a consistency check; - no network during packaging; - packageFormat 1. The libvips 1.3.3 and 1.3.4 supplements are curated and shipped. The source-obligation determination it deferred is now decided by ADR 0055. Only the status line and the index entry change; the decision text is untouched. Co-Authored-By: Claude Opus 5.5 <[email protected]>
13 KiB
0052: Reviewed license supplements cover redistributed dependencies whose packages omit required material
- Status: Accepted
- Date: 2026-10-07
- Extends: 0049, in one respect only. ADR 0049 left exactly how licence
and notice material is collected to the packager's implementation. That implementation, and the
module development guide, then took material only from a redistributed package's own files, or
from a predefined standard licence text that needs no project-specific lines. This ADR adds one
further source: a reviewed supplement. Everything else in ADR 0049 is unchanged, as is
packageFormat. - Related: ADR 0048, ADR 0051, ADR 0055 (decides the source-obligation policy deferred below)
Context
ADR 0049 requires every Module Package v1 to carry THIRD_PARTY_NOTICES: the licence and notice
material that redistributing its third-party code requires. It also states that no package is a
distributable release until licence and notice collection is proven. The canonical packager collects
material from two places:
- the licence, copying, copyright, and notice files a redistributed package ships at its root;
- the standard text of the package's declared licence, but only when that text is complete without project-specific lines (Apache-2.0 today).
A package that has neither stops packaging. That is fail-closed by design: an MIT or BSD package without its file is refused, because its copyright line exists only in that file.
The first native-target module package needs a dependency that this rule cannot handle.
@img/[email protected] is the prebuilt libvips that sharp loads on Linux x64 with
glibc. It declares LGPL-3.0-or-later. The package itself, like its latest release 1.3.4, contains
only these files:
README.mdversions.jsonlib/index.js- one glib header
- one shared library
That shared library includes about 29 libraries. Its README names each one and the licence it is used under, mostly with a link:
- LGPL components, such as libvips, glib, and pango;
- cairo, under MPL-2.0;
- many BSD-, MIT-, zlib-, IJG-, and FreeType-licensed libraries.
The package ships no licence text and no copyright notice for any of them. No standard text can stand in for that material: it includes per-project copyright notices and several different licences.
Options that were ruled out before this decision:
- Downloading material while packaging. Packaging must stay offline and deterministic (ADR 0049, ADR 0051).
- Inventing material. A packager that guesses notices produces artifacts that look compliant and may not be.
Ekklesia needs a way to carry material that a dependency's own package omits. It has to be reviewed by people, tied to exactly the bytes it was reviewed for, and fail closed whenever that tie breaks.
Some of these licences may also impose obligations beyond carrying text: the LGPL and the MPL can require recipients to be able to obtain corresponding source. Whether and how such an obligation is met for a particular redistributed binary is a legal and compliance determination. This decision does not make that determination.
Decision
Package-provided material stays the preferred source
The licence, copying, copyright, and notice material that a redistributed package ships remains the primary source, collected exactly as it is today. Nothing in this ADR removes, replaces, or rewrites package-provided material. A supplement only adds to it.
A reviewed supplement fills what a package omits
When a redistributed dependency omits material that redistribution requires, the canonical Ekklesia packager may use a license supplement: a checked-in, reviewed record of that material for one exact dependency.
- Where supplements live. In the Ekklesia repository, as part of the canonical packager's own versioned inputs. A supplement enters only through Ekklesia's normal reviewed change process, and the change that adds it is its review. A given packager version therefore always carries the same supplements.
- What that review is. Repository review of a supplement is project and code review of a build input: whether its content, its exact match, and its provenance are what the change says they are. It is not legal review, and it does not prove that any redistribution obligation is satisfied.
- What a supplement may contain:
- licence texts;
- copyright and attribution notices;
- provenance: where each piece of material was obtained, and which upstream component versions it covers;
- corresponding-source information, such as where upstream source for the exact build is published;
- other material that accompanies the dependency's redistribution.
- Generic by construction. Supplements are data. The mechanism contains no package-specific code and treats every supplement identically, whether it is for libvips or for any other dependency.
A supplement matches one exact package, or it fails closed
A supplement names exactly one redistributed package:
- its package name;
- its exact version;
- an integrity value for the package's contents: a digest the packager computes from the package's
redistributed files.
- Deterministic. It covers exactly each redistributed file's normalized relative path within the package and its bytes, combined in an order defined by the paths themselves.
- Host-independent. It excludes filesystem metadata, timestamps, ownership, permissions, and the order in which files were extracted or listed. The same package contents always give the same digest, wherever and however they were installed.
- Documented. The implementation defines and documents the exact algorithm, which does not depend on any package manager.
The packager uses a supplement only when all three match the package it is about to redistribute.
- A mismatch on any of the three fails packaging. This covers, for example, a supplement whose name and version match but whose integrity differs. It never falls back to a nearby version, and it never silently skips the supplement.
- Every match is used. A supplement that matches is always merged into the notices, including when the package also ships some material of its own.
- Gaps still fail. If a dependency lacks required material and no exact supplement matches, the packager stops, exactly as it does today.
Supplements are immutable build inputs
- Immutable. A supplement is never edited in place to cover a different build. A changed package, a new version, or different contents need a new supplement, reviewed again.
- No network. Packaging reads supplements from the packager's own inputs and never downloads anything. Assembling a supplement's content is a separate, offline-reviewed curation step done when the supplement is authored, never during packaging.
Merging is deterministic and labelled
The notice generator merges package-provided material and supplement material deterministically. The
same packager version and the same inputs still produce a byte-identical THIRD_PARTY_NOTICES
(ADR 0049).
- Order. Within a dependency's entry, package-provided material comes first, then supplement material.
- Labelling. Supplement material is marked as supplied by Ekklesia's reviewed supplement, never presented as if it came from the package.
- No other change. Dependencies are still sorted, line endings normalized, and each dependency keeps its own entry, exactly as before.
A supplement never changes a dependency's declared licence
THIRD_PARTY_NOTICES keeps reporting the licence the dependency itself declares.
- No override. A supplement can add material about the components a dependency contains, but it cannot replace, override, or rewrite the dependency's declared licence.
- Consistency check. A supplement records the declared licence it was reviewed against. If that disagrees with the package's actual declaration, packaging fails.
Legal and compliance determinations are not made here
A supplement can record corresponding-source information, but this ADR does not decide what satisfies any licence's source obligation, and neither does the mechanism:
- the mechanism never asserts that a written offer, a source URL, a mirror, or any other arrangement satisfies a licence;
- carrying a supplement shows that the reviewed material is present in the package. It does not certify that the package is compliant;
- for every redistributed binary under the LGPL, the MPL, or any other licence with source or similar obligations, the determination of whether and how those obligations are met is deferred. It must be made, and verified, separately.
ADR 0049's release gate still applies. A package that redistributes such a binary does not become a distributable release just because its supplement was merged. It becomes one only once that binary's compliance determination has been made and verified.
Scope
- Third-party code only. Supplements apply only to redistributed third-party dependencies,
whether bundled or copied into the package. They never apply to the module's own licence or
LICENSE(ADR 0051), or to incorporated Ekklesia packages. - No package format change.
packageFormatstays 1. A supplement changes only the content ofTHIRD_PARTY_NOTICES, which is already a listed, digested payload file. No metadata field, archive rule, or verifier contract changes.
The motivating case
@img/[email protected] is the first dependency expected to need a supplement. This ADR
does not curate it. Its supplement will be assembled, reviewed, and merged separately, together with
the native-target packaging work that redistributes it. The source-obligation determination for its
LGPL and MPL components remains open, as above.
Consequences
- A dependency whose package omits required material can be redistributed after review, offline and deterministically, instead of making native packaging impossible.
- Each supplement is tied to exact package bytes, so a changed or unexpected dependency fails packaging rather than inheriting material reviewed for something else.
- Ekklesia takes on reviewing and maintaining supplements. Every version bump of a supplemented dependency needs a new reviewed supplement before packaging works again.
THIRD_PARTY_NOTICEScan now contain material that did not come from the dependency's package. It is always labelled.- Carrying material and meeting obligations stay separate. Source-availability questions remain open until they are determined per binary.
Alternatives
- Download licence material while packaging. Rejected: packaging must stay offline, deterministic, and independent of a mutable remote source (ADR 0049, ADR 0051).
- Extend the standard-text list. Rejected: standard texts only work when the licence needs no project-specific line. Bundled native libraries need per-project copyright notices, and several different licences.
- Match supplements by name and version alone. Rejected: identical versions can differ in content across registries or rebuilds, and the material was reviewed for specific bytes.
- Fall back to the nearest supplemented version. Rejected: material reviewed for one build says nothing reliable about another.
- Let a supplement restate a dependency's licence. Rejected: the declaration belongs to the dependency's publisher. A supplement that could override it could misrepresent what is being redistributed.
- Per-package special cases in the packager (for example, code that knows about libvips). Rejected: every supplemented dependency would need new code, and review would be split between code and data.
- Treat a recorded source URL or written offer as satisfying copyleft obligations. Rejected for this ADR: that is a legal determination that has to be verified per binary, not assumed by a build mechanism.
- Supplements provided by module authors. Not adopted now: the canonical packager uses only supplements reviewed into Ekklesia. Whether module repositories may contribute their own reviewed supplements is deferred.
Deferred
- Implementing the mechanism in the canonical packager: the supplement format and storage location, the integrity algorithm, the matching, the merge, and the tests.
- Curating and reviewing the supplement for
@img/[email protected]. - The legal and compliance determination of source obligations for each redistributed binary, and how a determination is recorded.
- Whether the packager should refuse, or flag, packages whose supplements note an open determination.
- Supplements provided by module repositories.
- Recording which supplements were used in
ekklesia.package.json, should that ever be needed.