CI / verify (pull_request) Successful in 1m0s
CI / infrastructure-smoke (pull_request) Successful in 34s
CI / image-build (pull_request) Canceled after 0s
CI / deploy-smoke (same-origin) (pull_request) Canceled after 0s
CI / deploy-smoke (split) (pull_request) Canceled after 0s
CI / migration-smoke (pull_request) Canceled after 1m10s
When a redistributed dependency's own package omits licence material that redistribution requires, the canonical packager may use a checked-in, reviewed supplement. The motivating case is @img/[email protected]: LGPL-3.0-or-later, and its shared library contains about 29 libraries, but it ships no licence text or notice for any of them. ADR 0052 decides: - package-provided material stays the preferred source and is never replaced; - a supplement matches exact package name, version, and a packager-computed content integrity; any mismatch fails closed, with no fallback; - supplements are immutable, reviewed build inputs with no network access during packaging; - they may carry licence texts, copyright and attribution notices, provenance, corresponding-source information, and other accompanying material; - merging is deterministic, and supplement material is labelled; - a supplement never overrides a dependency's declared licence; a disagreement fails packaging; - the mechanism is generic, with no package-specific code; - missing material with no exact supplement still fails packaging; - packageFormat stays 1. It extends ADR 0049 only in the collection rule that ADR delegated to the implementation. Legal and source-obligation determinations for LGPL, MPL, and similar binaries are explicitly deferred: no written offer, URL, or mirror is asserted to satisfy any licence. Status Proposed. No implementation, no libvips supplement, and no Signage change. Co-Authored-By: Claude Opus 5.5 <[email protected]>
219 lines
12 KiB
Markdown
219 lines
12 KiB
Markdown
# 0052: Reviewed license supplements cover redistributed dependencies whose packages omit required material
|
|
|
|
- Status: Proposed
|
|
- Date: 2026-10-07
|
|
- Extends: [0049](0049-module-package-v1.md), 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](0048-generic-image-and-installed-module-storage.md),
|
|
[ADR 0051](0051-module-package-license-material.md)
|
|
|
|
## 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.md`
|
|
- `versions.json`
|
|
- `lib/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 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. The implementation defines this value as a digest
|
|
that the packager computes from the package files it reads and redistributes. The algorithm is
|
|
documented and 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.** `packageFormat` stays **1**. A supplement changes only the content of
|
|
`THIRD_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_NOTICES` can 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.
|