feat: Module Package v1 carries the module's own license (ADR 0051) #74

Merged
Zayin_Admin merged 1 commits from feat/module-package-v1-licensing into main 2026-10-08 00:03:02 +00:00
Member

Implements ADR 0051: every Module Package v1 declares the module's own license and carries its text. packageFormat stays 1, and pre-ADR-0051 metadata fails closed.

Changes

  • Contracts. ekklesia.package.json requires an SPDX license expression, validated with spdx-expression-parse. UNLICENSED, empty and malformed expressions are refused, and files must list exactly one non-empty root LICENSE.
    • Package contracts move to the @ekklesia/contracts/module-package subpath. The module SDK re-exports the contracts root into every module bundle, and spdx-exceptions (CC-BY-3.0) and spdx-license-ids (CC0-1.0) ship no licence files. Bundling them would make every module fail notices generation.
    • The template test asserts that no SPDX code reaches a bundle or THIRD_PARTY_NOTICES. Only Core and module-pack used those names; Signage doesn't.
  • Packager.
    • The license comes from the source package.json's string declaration and is never invented.
    • --license-file is required: a non-empty regular file, with no symlinks, parent search or download.
    • Its bytes are copied unchanged to LICENSE, listed with size and SHA-256, and covered by the archive digest.
    • THIRD_PARTY_NOTICES stays third-party only, and bundled Ekklesia code stays in incorporates.
  • Verifier. Rejects missing or invalid license metadata, and a missing, unlisted, duplicated or corrupted LICENSE, through the schema plus the existing strict inventory.
  • Template. Packaged as AGPL-3.0-or-later with the repository's canonical LICENSE, passed explicitly in the package Dockerfile, the smoke script and the docs.
  • ADR 0051 → Accepted.

Work was started by Codex, then reviewed and completed in Claude Code. The additions are refusing an empty license file, requiring a non-empty LICENSE entry in the schema, and empty-file and symlink tests.

Verification

  • Focused tests: contracts 43, Core package verification/CLI/discovery 105, module-pack 50 (including the template package): all pass.

  • Deterministic package: the template packed twice gives byte-identical archives (sha256 8dc5055f…). The packaged LICENSE equals the repository AGPL text (sha256 0d96a4ff…), and license is AGPL-3.0-or-later.

  • EKKLESIA_SMOKE_TOPOLOGY=split pnpm deploy:smoke: passed. The template was packaged with --license-file, verified by the image's own verifier (14 files), installed, removed and reinstalled, and the whole lifecycle succeeded.

  • pnpm verify: one run on this branch. Format, lint, boundaries, typecheck and build passed, and every package's tests passed except 3 Core import-safety tests, which hit their 5 s timeout:

    • cli-bootstrap-platform-owner.test.ts
    • doctor-import.test.ts
    • module-http-import.test.ts

    These tests spawn a fresh import and time out only under the full parallel pnpm verify load. After the smoke, the four known import-safety files (5 tests, the three above plus cli-create-initial-owner.test.ts) passed in isolation in about 1 s.

    • This is a known, pre-existing flake. It has hit 3 of the last 4 full runs across recent branches, on unchanged test code.
    • Full verify was not rerun locally; CI provides the next full run.
    • The flake deserves its own small fix, such as a longer timeout for these import tests.

Not changed: Signage, the database ABI, packageFormat 2, marketplace policy, image licensing and rog-ekklesia-instance.

🤖 Generated with Claude Code

Implements **ADR 0051**: every Module Package v1 declares the module's own license and carries its text. `packageFormat` stays 1, and pre-ADR-0051 metadata fails closed. ## Changes - **Contracts.** `ekklesia.package.json` requires an SPDX `license` expression, validated with `spdx-expression-parse`. `UNLICENSED`, empty and malformed expressions are refused, and `files` must list exactly one non-empty root `LICENSE`. - Package contracts move to the **`@ekklesia/contracts/module-package` subpath**. The module SDK re-exports the contracts root into every module bundle, and `spdx-exceptions` (CC-BY-3.0) and `spdx-license-ids` (CC0-1.0) ship no licence files. Bundling them would make every module fail notices generation. - The template test asserts that no SPDX code reaches a bundle or `THIRD_PARTY_NOTICES`. Only Core and module-pack used those names; Signage doesn't. - **Packager.** - The license comes from the source `package.json`'s string declaration and is never invented. - `--license-file` is required: a non-empty regular file, with no symlinks, parent search or download. - Its bytes are copied unchanged to `LICENSE`, listed with size and SHA-256, and covered by the archive digest. - `THIRD_PARTY_NOTICES` stays third-party only, and bundled Ekklesia code stays in `incorporates`. - **Verifier.** Rejects missing or invalid license metadata, and a missing, unlisted, duplicated or corrupted `LICENSE`, through the schema plus the existing strict inventory. - **Template.** Packaged as `AGPL-3.0-or-later` with the repository's canonical `LICENSE`, passed explicitly in the package Dockerfile, the smoke script and the docs. - **ADR 0051 → Accepted.** Work was started by Codex, then reviewed and completed in Claude Code. The additions are refusing an empty license file, requiring a non-empty `LICENSE` entry in the schema, and empty-file and symlink tests. ## Verification - **Focused tests:** contracts 43, Core package verification/CLI/discovery 105, module-pack 50 (including the template package): all pass. - **Deterministic package:** the template packed twice gives byte-identical archives (sha256 `8dc5055f…`). The packaged `LICENSE` equals the repository AGPL text (sha256 `0d96a4ff…`), and `license` is `AGPL-3.0-or-later`. - **`EKKLESIA_SMOKE_TOPOLOGY=split pnpm deploy:smoke`:** passed. The template was packaged with `--license-file`, verified by the image's own verifier (14 files), installed, removed and reinstalled, and the whole lifecycle succeeded. - **`pnpm verify`:** one run on this branch. Format, lint, boundaries, typecheck and build passed, and every package's tests passed except **3 Core import-safety tests**, which hit their **5 s timeout**: - `cli-bootstrap-platform-owner.test.ts` - `doctor-import.test.ts` - `module-http-import.test.ts` These tests spawn a fresh import and time out only under the full parallel `pnpm verify` load. After the smoke, the four known import-safety files (5 tests, the three above plus `cli-create-initial-owner.test.ts`) passed in isolation in about 1 s. - This is a known, pre-existing flake. It has hit 3 of the last 4 full runs across recent branches, on unchanged test code. - Full verify was not rerun locally; CI provides the next full run. - The flake deserves its own small fix, such as a longer timeout for these import tests. **Not changed:** Signage, the database ABI, packageFormat 2, marketplace policy, image licensing and rog-ekklesia-instance. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ekklesia-bot added 1 commit 2026-10-07 23:56:14 +00:00
feat: Module Package v1 carries the module's own license (ADR 0051)
CI / verify (pull_request) Successful in 58s
CI / infrastructure-smoke (pull_request) Successful in 35s
CI / migration-smoke (pull_request) Successful in 1m53s
CI / image-build (pull_request) Successful in 30s
CI / deploy-smoke (same-origin) (pull_request) Successful in 50s
CI / deploy-smoke (split) (pull_request) Successful in 1m32s
85fae9e07e
Every Module Package v1 now declares the module's license and carries its
text. packageFormat stays 1; pre-ADR-0051 metadata fails closed.

- Contracts: ekklesia.package.json requires an SPDX `license` expression,
  validated with spdx-expression-parse, with UNLICENSED and non-expressions
  refused. The `files` list must hold exactly one non-empty root LICENSE.
  The package contracts move to the @ekklesia/contracts/module-package
  subpath, so the SPDX parser and its data (spdx-exceptions and
  spdx-license-ids ship no licence files) never reach a module bundle
  through the SDK's re-export of the contracts root.
- Packager: reads the source package.json's string SPDX declaration and
  never invents one. It requires an explicit --license-file (a non-empty
  regular file, no symlink, no parent search, no download) and copies its
  bytes unchanged to LICENSE, listed with size and SHA-256 and covered by
  the archive digest. THIRD_PARTY_NOTICES stays third-party only, and
  bundled Ekklesia code stays in `incorporates`.
- Verifier: rejects missing or invalid license metadata, and a missing,
  unlisted, duplicated, or corrupted LICENSE, through the schema and the
  existing strict inventory.
- Template: packaged as AGPL-3.0-or-later with the repository's canonical
  LICENSE, passed explicitly (Dockerfile, smoke, docs). Packing it twice
  gives byte-identical archives.

Started by Codex; reviewed and completed in Claude Code (empty license-text
refusal, schema non-empty LICENSE, symlink and empty-file tests).

ADR 0051 is Accepted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Zayin_Admin merged commit b1e3244c1d into main 2026-10-08 00:03:02 +00:00
Zayin_Admin deleted branch feat/module-package-v1-licensing 2026-10-08 00:03:02 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Zayin/Ekklesia#74