Files
Ekklesia/docs/architecture/decisions/0052-reviewed-license-supplements.md
T
ekklesiaandClaude Opus 5.5 99f145a80c
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
docs: propose ADR 0052, reviewed license supplements for redistributed dependencies
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]>
2026-10-07 19:37:11 -05:00

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.