Files
Ekklesia/packages/module-pack/license-supplements/@img/sharp-libvips-linux-x64/1.3.3/PROVENANCE.md
T
ekklesiaandClaude Opus 5.5 44d385cd7f
CI / verify (pull_request) Successful in 1m6s
CI / infrastructure-smoke (pull_request) Successful in 27s
CI / migration-smoke (pull_request) Successful in 1m54s
CI / image-build (pull_request) Successful in 29s
CI / deploy-smoke (same-origin) (pull_request) Successful in 43s
CI / deploy-smoke (split) (pull_request) Successful in 1m30s
feat: native linux-x64-glibc module packages and reviewed license supplements (ADR 0049, ADR 0052)
Implements ADR 0049's deferred native target and ADR 0052's reviewed
license supplements. The proof case is a real module using sharp.
packageFormat stays 1, and `any` is unchanged.

Packager (@ekklesia/module-pack):
- --target linux-x64-glibc. Native or platform-specific packages, found by
  the same generic rule that refuses them in `any`, stay outside the bundle.
- Each native package's production closure is walked through its own
  dependencies, installed optionalDependencies that match the target, and
  required peers. It is copied as real files flat under node_modules/<name>,
  with no links, dev dependencies, declarations, source maps, or other
  platforms' packages. Missing or foreign-platform required dependencies,
  version conflicts, links, foreign machines, and Node.js range conflicts
  fail closed.
- runtime.nodeApi, nodeAbi, and libcVersion are read from the binaries by a
  small ELF reader: the addon's node_api_module_get_api_version_v1 and the
  newest GLIBC_ symbol version needed. No shelling out. A native target with
  no addon is refused.
- ADR 0052 supplements: package-provided material stays primary. An exact
  match on name, version, and ekklesia-content-v1 digest (sorted normalized
  paths with each file's size and SHA-256; no metadata) adds labelled
  material after the package's own. Any mismatch, a declared-licence
  conflict, or a malformed or unreviewed supplement file fails. Missing
  material with no supplement still fails.

Supplement for @img/[email protected]:
- 184 components and 143 unique texts, assembled from the exact upstream
  sources sharp-libvips v1.3.3 builds linux-x64 from: 27 C/C++ libraries,
  glib's gvdb, librsvg's Rust crates (reproduced with cargo tree), the Rust
  standard library at the rustc commit recorded in the binary, plus the
  LGPL-3.0, GPL-3.0, and MPL-2.0 texts. Each source is recorded with its
  SHA-256 in PROVENANCE.md.
- It pins digest ekklesia-content-v1:sha256:50647b0b…, which is identical
  from the installed copy and from the registry tarball.
- LGPL/MPL source-availability determinations stay open, as ADR 0052
  states. Nothing claims they are met.

Verifier (Core):
- linux-x64-glibc is accepted only on a host whose platform, arch, glibc
  family and version, and Node-API version (from Node itself) match.
- Every ELF file must be x86-64; every .node must be an ELF object.
- `any` packages now also refuse node_modules/ and ELF files.
- Contract: native metadata must state nodeApi or nodeAbi, and Linux targets
  libcVersion (ADR 0049).

Proof:
- A checked-in AGPL native fixture packs byte-identically from unrelated
  copies (8.86 MB) and verifies with Core's verifier.
- Extracted elsewhere, it runs a sharp resize and PNG round trip in an
  empty-environment process. Every resolution stays in the package, and
  only the package's addon and libvips plus host system libraries load.

Signage is untouched.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 20:16:53 -05:00

161 lines
11 KiB
Markdown

# Provenance: license supplement for `@img/[email protected]`
This is the human-readable record of how the reviewed material in `supplement.json` was assembled
(ADR 0052). The packager does not read this file. It reads only `supplement.json` and the texts that
file lists, each one named by its SHA-256.
Review of this supplement is project and code review of a build input. It checks that the material
matches the sources named below. **It is not legal review.** It does not establish that every
redistribution obligation for this binary is met. In particular, it does not decide whether or how
the source-availability obligations of its LGPL and MPL components are met, which remains open.
## The package
| Field | Value |
| --- | --- |
| Package | `@img/sharp-libvips-linux-x64` 1.3.3, from the npm registry |
| npm integrity | `sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==` |
| Declared licence | `LGPL-3.0-or-later` |
| Content digest | `ekklesia-content-v1:sha256:50647b0b1e0b99943f24e4a1580650c0d8fe7744779b0f16271dcd2d59a7678c` |
The content digest is over the six files the packager copies: `README.md`, `package.json`,
`versions.json`, `lib/index.js`, `lib/glib-2.0/include/glibconfig.h`, and
`lib/libvips-cpp.so.8.18.6`. It was computed twice and gave the same result both times: once from
the copy pnpm installed, and once from the registry tarball extracted directly.
The package ships no licence text and no notices. Its README lists 29 libraries and the licence each
is used under, mostly as links. `lib/libvips-cpp.so.8.18.6` is one shared object with those
libraries built into it.
## What was built into the binary
The build is sharp-libvips v1.3.3:
- source: `https://github.com/lovell/sharp-libvips/archive/refs/tags/v1.3.3.tar.gz`;
- sha256: `544ebd8e34be4baf751cc26c8691a46eddbb56183ead1b20ca5b737e93482d86`.
The build is defined by `build/posix.sh`, `platforms/linux-x64/Dockerfile`, and
`versions.properties`. Its `versions.properties` matches the package's own `versions.json`.
- **C and C++ libraries.** 27 libraries are built from the upstream archives below, at exactly the
URLs `build/posix.sh` fetches.
- `proxy-libintl` is listed in `versions.json` but is built only for musl and macOS, not for
linux-x64 (glibc). It is therefore not a component of this binary.
- Highway is built, because `WITHOUT_HIGHWAY` is unset for linux-x64.
- **gvdb.** glib is configured with `--force-fallback-for=gvdb`, so the gvdb subproject shipped
inside glib's archive is built in. Its LGPL-2.1-or-later files are taken from that archive.
- **librsvg's Rust crates.**
- **What the build does.** It edits `rsvg/Cargo.toml` and `librsvg-c/Cargo.toml`, dropping the
`gif` and `webp` image features and the `pdf` and `ps` cairo features. It runs
`cargo update --workspace`, then builds `librsvg-c` with
`cargo cbuild --locked --release --target x86_64-unknown-linux-gnu`, with neither the AVIF nor
the pixbuf feature (no dav1d, pixbuf disabled).
- **How it was reproduced.** In `rust:1-slim` (cargo 1.99.0), with the same edits, librsvg
2.62.91's shipped `Cargo.lock` was updated with `cargo update --workspace`.
- That removed only the crates the edits drop (gif, image-webp, color_quant, and their
dependencies). It changed no other version, so the compiled set follows from the shipped
lockfile.
- The resulting `Cargo.lock` has sha256
`5ea585dbbcce18a8e74e094a383c4ca2f133102464bd3c9169636a485bf362c2`.
- **The crate set.** `cargo tree -p librsvg-c --features capi --target x86_64-unknown-linux-gnu -e
normal` lists the crates. Procedural-macro crates are included, which is conservative.
- **Where the files come from.** Each crate's licence files are taken from its published `.crate`
file. The crate's sha256 is the `checksum` from that `Cargo.lock`.
- **Exceptions.**
- `selectors` 0.40.0 (MPL-2.0) ships no licence file, so it carries the standard MPL-2.0 text.
- `mutants` 0.0.4 (MIT) ships no licence file. It is a no-op attribute macro that runs only at
compile time and contributes no code to the binary, so it is not a component.
- **The Rust standard library.**
- The binary records `/rustc/787af2b8c80638c51a4fc8e44f84e6891f243ec7/…` paths. That is a nightly
rustc commit, merged on 2026-08-25, two days before the package was built.
- Its std lockfile pins the five crate versions that are visible in the binary's strings:
addr2line 0.27.1, gimli 0.34.0, hashbrown 0.17.1, miniz_oxide 0.9.1, and rustc-demangle 0.1.28.
- **Where the files come from.** `COPYRIGHT`, `LICENSE-APACHE`, `LICENSE-MIT`, and
`library/compiler-builtins/LICENSE.txt` are taken from that commit.
- **The crates covered.** These are std's crates.io dependencies for x86_64-unknown-linux-gnu, read
from `library/std/Cargo.toml`'s target sections at that commit:
- addr2line, adler2, cfg-if, foldhash, gimli, hashbrown, libc, memchr, miniz_oxide, object, and
rustc-demangle;
- each with its `.crate` file's licence files.
- **Not covered**, because it is not linked into this target:
- build-only: cc, shlex, find-msvc-tools;
- test-only: rand, rand_core, rand_xorshift;
- other platforms: dlmalloc, fortanix-sgx-abi, hermit-abi, moto-rt, r-efi, r-efi-alloc, unwinding,
vex-sdk, wasip1, wasip2, wasip3, wit-bindgen.
- **Not redistributed here.** The binary dynamically links the host's `libstdc++.so.6`,
`libgcc_s.so.1`, and glibc libraries. They come from the system that loads the package, so they
are not part of this package.
## Standard texts added
| Text | Source | sha256 |
| --- | --- | --- |
| GNU LGPL 3.0, for the package's declared `LGPL-3.0-or-later` | https://www.gnu.org/licenses/lgpl-3.0.txt | `e3a994d82e644b03a792a930f574002658412f62407f5fee083f2555c5f23118` |
| GNU GPL 3.0, which the LGPL 3.0 incorporates | https://www.gnu.org/licenses/gpl-3.0.txt | `3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986` |
| MPL 2.0 | https://www.mozilla.org/MPL/2.0/ (text file `index.f75d2927d3c1.txt`) | `3f3d9e0024b1921b067d6f7f88deb4a60cbe7a78e76c64e3f1d7fc3b779b9d04` |
The MPL 2.0 text is carried for two components:
- **cairo.** cairo ships the LGPL-2.1 and MPL-1.1 texts. sharp-libvips states that cairo is used
under MPL 2.0.
- **selectors**, which ships no licence file.
Licence names in `supplement.json` are as sharp-libvips's `THIRD-PARTY-NOTICES.md` states them for
each library, and as each crate's `Cargo.toml` declares it. They are recorded, not determined.
## Upstream archives (C and C++ libraries)
Each archive was downloaded from exactly the URL `build/posix.sh` uses for the versions in
`versions.properties`:
| Archive | sha256 |
| --- | --- |
| `cairo-1.18.4.tar.xz` | `445ed8208a6e4823de1226a74ca319d3600e83f6369f99b14265006599c32ccb` |
| `cgif-0.5.3.tar.gz` | `dcc7731e974ee77db75df26c99aca4d95f11ca2d267d870d42bce1e0d1e1e75f` |
| `expat-2.8.3.tar.xz` | `f6256df90c906773d344da084402b7d3e4f22ed41b1a59c989098a83d3ea0c85` |
| `fontconfig-2.18.3.tar.gz` | `9ae01e1d53acdef56010c5451cd34aa41d325b2faccd8606448d8fa01b2496b3` |
| `freetype-2.14.3.tar.gz` | `dc49de6b01a266eef4876a4dd34d9842c475d3e28ff2eff63bd2fb760ab56261` |
| `fribidi-1.0.16.tar.xz` | `1b1cde5b235d40479e91be2f0e88a309e3214c8ab470ec8a2744d82a5a9ea05c` |
| `glib-2.89.4.tar.xz` | `1cdbb799f558832e6f14b8337b5fd599c6918ab144977b55e05e00a5e2e84a2c` |
| `harfbuzz-14.3.1.tar.gz` | `05e602daf0846d7497d842807766ea32ca270f3e2c9284ce03811a2a1ed669c9` |
| `highway-1.4.0.tar.gz` | `e72241ac9524bb653ae52ced768b508045d4438726a303f10181a38f764a453c` |
| `lcms2-2.19.1.tar.gz` | `bfc54f7bab59fbc921012014a8032e4cba4abd46db47d46b76416a8c0b2815c8` |
| `libaom-3.15.0.tar.gz` | `ea08c38ecc078bc85bb1b691020e52b06250f1a81fe7ca5b624629225081af96` |
| `libarchive-3.8.9.tar.xz` | `888c934f9d95648ecb9163dc8e23ab80a476ecb81a8f1154704a227b5b676dde` |
| `libexif-0.6.26.tar.xz` | `4a055ed6575e61ca46c3172be3c753cc16c9becd0f99ec71d58dd0e471476c0c` |
| `libffi-3.8.0.tar.gz` | `7da3e2d9a171eb0a038f592ecad3ff2bb2550f3496d87b3b29ad0cf4430c0db4` |
| `libheif-1.23.2.tar.gz` | `8bd5d41d19dc84536d118b04774709f244df6104ef66d623dad5fa4650143405` |
| `libimagequant-2.4.1.tar.gz` | `47d2a84b7b1052975c9d50a3d4e3cacbf57b43d84a4c3131210848ead9964dfb` |
| `libpng-1.6.58.tar.gz` | `a9d4df463d36a6e5f9c29bd6f4967312d17e996c1854f3511f833924eb1993cf` |
| `librsvg-2.62.91.tar.xz` | `6caeae129d40dd88f8ec49436fd89bfe4ada716a125187a7fa0def8fcaa0b250` |
| `libtiff-v4.7.2.tar.gz` | `62b15f44c10106065211efa22a2dc77937bd97ee1f6e3afd2c9659010de112eb` |
| `libultrahdr-2.0.2.tar.gz` | `aa8d193bb887c348c419780511dd03b374f4e07af8812b6d3f80c8537cf1ef2c` |
| `libwebp-1.6.0.tar.gz` | `e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564` |
| `libxml2-2.15.3.tar.xz` | `78262a6e7ac170d6528ebfe2efccdf220191a5af6a6cd61ea4a9a9a5042c7a07` |
| `mozjpeg-0826579.tar.gz` | `b680167bd5d9afebdd576a12f8c49d2c9066a3b92ef96a2b2c5f7829b8600fe5` |
| `pango-1.58.2.tar.xz` | `342385b6ca3b7c73455d7c80a13b7dbe4489e00bc3bd4c5bd6ed4dce421e374a` |
| `pixman-0.46.4.tar.gz` | `d09c44ebc3bd5bee7021c79f922fe8fb2fb57f7320f55e97ff9914d2346a591c` |
| `vips-8.18.6.tar.xz` | `3c41e1d5458081bfa4a5bc54e116c46259c75c6760a18027764555632b9dda3e` |
| `zlib-ng-2.3.3.tar.gz` | `f9c65aa9c852eb8255b636fd9f07ce1c406f061ec19a2e7d508b318ca0c907d1` |
## Rust standard library sources
| File at rustc `787af2b8c80638c51a4fc8e44f84e6891f243ec7` | sha256 |
| --- | --- |
| `COPYRIGHT` | `172020dbfd5b53a226dfde77616190a48dcff519b0bc0e6deb91a8450782c4af` |
| `LICENSE-APACHE` | `62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a` |
| `LICENSE-MIT` | `b71bd43a069ca0641a9ecfe585ca7b3c53b5cc1608f8b68321168698e28b5ea1` |
| `library/compiler-builtins/LICENSE.txt` | `ab6eec6caf0fa5775e411c7a8bc6a45c4ef2956b0980b157ab74fc5cd62a928b` |
| `library/Cargo.lock` | `fc922f114685e5cbdb3dce572cb7e3b7023a45b57e3a436e23abf35d240c5d9f` |
Each crate's `.crate` source and sha256 are recorded in that crate's `source` in `supplement.json`.
## Open questions this supplement does not answer
- **Source availability.** The LGPL components (libvips, glib, gvdb, pango, fribidi, libexif,
libheif, librsvg, cairo under the LGPL alternative) and the MPL components (cairo and the MPL Rust
crates) carry source-availability obligations. Whether and how those are met when this binary is
redistributed has not been determined. Recording the upstream source locations above does not
determine it.
- **Upstream accuracy.** The licence each library is used under is sharp-libvips's statement. For
example, it states that the LGPL libraries are used under LGPLv3 through the "any later version"
clause, and that cairo is used under MPL 2.0. These statements are recorded, not verified.