docs: propose ADR 0049, Ekklesia Module Package v1 #65

Merged
Zayin_Admin merged 1 commits from docs/adr-0049-module-package into main 2026-10-07 15:21:30 +00:00
Member

Proposes ADR 0049: Ekklesia Module Package v1, extending ADR 0048. Docs only: no runtime code, packager, installer, Docker, CI, Signage, or instance changes.

What it decides

  • One artifact. A module release is one immutable, deterministic .tar.gz (sorted paths, uid/gid 0, mtime 0, gzip header with no name or time), with its SHA-256 distributed beside it. Identity is the contents, never the transport; Gitea, GitHub, OCI, object storage, offline media, or a marketplace may carry it unchanged.

  • Layout. One top-level directory named with the module id, containing:

    • a generated runtime package.json (name, version, private, "type": "module", layer only);
    • the unchanged manifest and ekklesia.package.json;
    • bundled backend entrypoints and the built browser artifacts;
    • migrations and THIRD_PARTY_NOTICES;
    • node_modules only for native dependencies.

    No source, tests, declarations, source maps, development dependencies, or workspace: references.

  • Backend bundling. Every pure-JavaScript dependency is bundled, including the SDK and contracts. The canonical packager alone decides and validates what stays external (native or platform-specific code); it is not an author-facing choice.

  • Targets. any, or <platform>-<arch>[-<libc>] in Node's own vocabulary, with libc required on Linux. Signage is linux-x64-glibc because of sharp. One target per package; multi-architecture packages deferred.

  • ekklesia.package.json (packageFormat: 1). It records:

    • id, version and target;
    • runtime needs (Node range; Node-API or ABI, and libc version, for native packages);
    • provenance (revision, packager);
    • incorporated SDK and contracts versions;
    • a transitional.databaseRuntime Drizzle requirement;
    • the exact list of payload files, each with size and SHA-256, excluding the metadata file itself.

    Platform and SDK ranges stay only in the manifest.

  • Drizzle. Explicitly a temporary implementation constraint, not the Module Database ABI; a separate ADR will make the platform's ORM an implementation detail.

  • Licences. THIRD_PARTY_NOTICES is mandatory. The packager PR must prove licence preservation before anything counts as a release.

  • Archive safety. No links of any kind in v1, no absolute or .. paths, no special files, no setuid/setgid; extraction normalizes ownership and modes; nothing is executable.

  • Installation lifecycle (intended, not implemented). Verify digest → hidden staging → validate metadata and per-file hashes → target and runtime check → whole candidate inventory → isolated entrypoint load → migration plan → stop API → swap → explicitly approved migrations → restart → readiness.

  • Rollback. Restoring the previous code is supported only before new migrations apply; after that, rollback means restoring the matching backup. No down migrations.

  • Trust. The digest gives integrity, not authenticity. Signing and trust roots are deferred, and modules remain trusted code.

  • Tooling. An Ekklesia-owned packager (proposed packages/module-pack, ekklesia-pack-module). pnpm deploy is explicitly not the mechanism.

Other files

  • docs/architecture/decisions/README.md: index entry.
  • 0047-module-ci-harness.md (Proposed): one header cross-reference saying the harness should consume canonical packages once 0049 is accepted.
  • docs/module-development/README.md: it previously told authors to run pnpm deploy --legacy in their workspace. It now points to ADR 0049 and warns that pnpm deploy rewrites a workspace's install state. This was observed both in scratch workspaces and earlier in a real checkout.

No accepted ADR's text changes; ADR 0048's lifecycle decisions are untouched.

Status

Proposed, following the repository's usual lifecycle (0044, 0045, 0046, 0047): it becomes Accepted with the first implementation.

Verification

  • pnpm verify: passed (core 1015, api 510; boundaries, module and migration validation, identity schema, build).
  • pnpm deploy:config: valid.
  • All 132 relative links and in-page anchors in the changed files resolve.

🤖 Generated with Claude Code

Proposes **ADR 0049: Ekklesia Module Package v1**, extending ADR 0048. **Docs only**: no runtime code, packager, installer, Docker, CI, Signage, or instance changes. ## What it decides - **One artifact.** A module release is one immutable, deterministic `.tar.gz` (sorted paths, uid/gid 0, mtime 0, gzip header with no name or time), with its SHA-256 distributed beside it. Identity is the contents, never the transport; Gitea, GitHub, OCI, object storage, offline media, or a marketplace may carry it unchanged. - **Layout.** One top-level directory named with the module id, containing: - a **generated** runtime `package.json` (name, version, private, `"type": "module"`, layer only); - the unchanged manifest and `ekklesia.package.json`; - bundled backend entrypoints and the built browser artifacts; - migrations and `THIRD_PARTY_NOTICES`; - `node_modules` only for native dependencies. No source, tests, declarations, source maps, development dependencies, or `workspace:` references. - **Backend bundling.** Every pure-JavaScript dependency is bundled, including the SDK and contracts. The canonical packager alone decides and validates what stays external (native or platform-specific code); it is not an author-facing choice. - **Targets.** `any`, or `<platform>-<arch>[-<libc>]` in Node's own vocabulary, with libc required on Linux. Signage is `linux-x64-glibc` because of `sharp`. One target per package; multi-architecture packages deferred. - **`ekklesia.package.json` (`packageFormat: 1`).** It records: - id, version and target; - runtime needs (Node range; Node-API or ABI, and libc version, for native packages); - provenance (revision, packager); - incorporated SDK and contracts versions; - a `transitional.databaseRuntime` Drizzle requirement; - the exact list of payload files, each with size and SHA-256, excluding the metadata file itself. Platform and SDK ranges stay only in the manifest. - **Drizzle.** Explicitly a temporary implementation constraint, **not** the Module Database ABI; a separate ADR will make the platform's ORM an implementation detail. - **Licences.** `THIRD_PARTY_NOTICES` is mandatory. The packager PR must prove licence preservation before anything counts as a release. - **Archive safety.** **No links of any kind in v1**, no absolute or `..` paths, no special files, no setuid/setgid; extraction normalizes ownership and modes; nothing is executable. - **Installation lifecycle (intended, not implemented).** Verify digest → hidden staging → validate metadata and per-file hashes → target and runtime check → whole candidate inventory → isolated entrypoint load → migration plan → stop API → swap → explicitly approved migrations → restart → readiness. - **Rollback.** Restoring the previous code is supported only before new migrations apply; after that, rollback means restoring the matching backup. No down migrations. - **Trust.** The digest gives integrity, not authenticity. Signing and trust roots are deferred, and modules remain trusted code. - **Tooling.** An Ekklesia-owned packager (proposed `packages/module-pack`, `ekklesia-pack-module`). **`pnpm deploy` is explicitly not the mechanism.** ## Other files - `docs/architecture/decisions/README.md`: index entry. - `0047-module-ci-harness.md` (Proposed): one header cross-reference saying the harness should consume canonical packages once 0049 is accepted. - `docs/module-development/README.md`: it previously told authors to run `pnpm deploy --legacy` in their workspace. It now points to ADR 0049 and warns that `pnpm deploy` rewrites a workspace's install state. This was observed both in scratch workspaces and earlier in a real checkout. No accepted ADR's text changes; ADR 0048's lifecycle decisions are untouched. ## Status **Proposed**, following the repository's usual lifecycle (0044, 0045, 0046, 0047): it becomes Accepted with the first implementation. ## Verification - `pnpm verify`: passed (core 1015, api 510; boundaries, module and migration validation, identity schema, build). - `pnpm deploy:config`: valid. - All 132 relative links and in-page anchors in the changed files resolve. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ekklesia-bot added 1 commit 2026-10-07 15:13:54 +00:00
docs: propose ADR 0049, Ekklesia Module Package v1
CI / verify (pull_request) Successful in 52s
CI / infrastructure-smoke (pull_request) Successful in 27s
CI / migration-smoke (pull_request) Successful in 1m50s
CI / image-build (pull_request) Successful in 22s
CI / deploy-smoke (same-origin) (pull_request) Successful in 49s
CI / deploy-smoke (split) (pull_request) Successful in 1m41s
1119cc5fdf
A separately versioned module is distributed as one immutable, self-contained,
deterministic .tar.gz with a separately distributed SHA-256. The package
contract is independent of hosting, registry, transport, and marketplace.

ADR 0049 extends ADR 0048 with:
- the package layout: one top-level module directory with a generated runtime
  package.json, the unchanged manifest, ekklesia.package.json, bundled backend
  entrypoints, built browser artifacts, migrations, THIRD_PARTY_NOTICES, and
  node_modules only for native dependencies;
- backend bundling of all pure-JavaScript dependencies, with externals decided
  and validated by the canonical packager, never by module authors;
- targets: `any`, or <platform>-<arch>[-<libc>] (linux-x64-glibc for Signage);
- ekklesia.package.json (packageFormat 1): id, version, target, runtime needs,
  provenance, incorporated SDK versions, a `transitional` Drizzle requirement
  explicitly not the Module Database ABI, and per-file size and SHA-256;
- archive safety: no links of any kind, no absolute or `..` paths, no special
  files or setuid/setgid; extraction normalizes ownership and modes;
- the intended installation lifecycle and its rollback limit: code-only
  rollback only before new migrations apply, a backup restore after;
- integrity, not authenticity; signing and trust roots deferred;
- pnpm deploy explicitly not the packaging mechanism.

Status Proposed, following the repository's usual lifecycle. ADR 0047 gains a
cross-reference to consume canonical packages. The module development guide no
longer recommends running pnpm deploy in a workspace, which corrupts that
workspace's install state. No runtime, tooling, Docker, CI, Signage, or
instance changes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Zayin_Admin merged commit 45d6506c10 into main 2026-10-07 15:21:30 +00:00
Zayin_Admin deleted branch docs/adr-0049-module-package 2026-10-07 15:21:30 +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#65