diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml index 540375d..9b2563d 100644 --- a/.github/workflows/publish-packages.yml +++ b/.github/workflows/publish-packages.yml @@ -7,7 +7,7 @@ name: Publish packages # request or push can start it. It needs the version-set commit of a release (`version` must equal # the platform version there), and the repository secret EKKLESIA_PACKAGES_PUBLISH_TOKEN, a token of # the dedicated publisher account with only the `write:package` scope. Packages are publicly -# readable; publishing is what this protects. +# readable (ADR 0054); publishing is what this protects. on: workflow_dispatch: diff --git a/README.md b/README.md index 352a936..34a77cd 100644 --- a/README.md +++ b/README.md @@ -68,8 +68,10 @@ a curated `@ekklesia/module-sdk`, `@ekklesia/module-database`, the UI packages, packaging tools. They are released as one coordinated train of tarballs with a release manifest, and CI proves on every run that two builds of a commit are byte-identical and that a module outside the repository installs, builds, packages, and verifies from those artifacts alone. A manual -workflow publishes exactly those artifacts to the public npm registry, verifying every package byte -for byte; the first train published will be the next platform release +workflow, the only way to publish, publishes exactly those artifacts to the npm registry and +verifies every package byte for byte. Anyone may read and install the packages before launch +([ADR 0054](docs/architecture/decisions/0054-public-package-reads-before-launch.md)). The first train +published will be the next platform release ([Releases and the public package train](docs/development/releases.md)). Phase 4A added Core-owned identity foundations: a Core-owned Better Auth database schema diff --git a/docs/architecture/decisions/0053-standalone-module-development-packages.md b/docs/architecture/decisions/0053-standalone-module-development-packages.md index bcc1b14..9122d3d 100644 --- a/docs/architecture/decisions/0053-standalone-module-development-packages.md +++ b/docs/architecture/decisions/0053-standalone-module-development-packages.md @@ -2,6 +2,8 @@ - Status: Accepted - Date: 2026-10-07 +- Superseded in part by: [0054](0054-public-package-reads-before-launch.md) — only where this ADR + describes the package phase before launch as private, or requires authenticated package reads. - Extends: [0049](0049-module-package-v1.md). This is the step ADR 0049 deferred: "publishing the Ekklesia SDK packages for module builds outside a platform workspace". A registry is used only to build a module. Installing one stays registry-free: an installed package is self-contained, as ADR diff --git a/docs/architecture/decisions/0054-public-package-reads-before-launch.md b/docs/architecture/decisions/0054-public-package-reads-before-launch.md new file mode 100644 index 0000000..fc23a58 --- /dev/null +++ b/docs/architecture/decisions/0054-public-package-reads-before-launch.md @@ -0,0 +1,85 @@ +# 0054: Ekklesia's module-development packages are publicly readable before launch + +- Status: Accepted +- Date: 2026-10-08 +- Supersedes (partial): [0053](0053-standalone-module-development-packages.md) — only where it + describes the package phase before launch as private: "Gitea may host the private phase", the + read credential for module CI in "Registry access and the private phase", and its requirement + that packages not be served anonymously while Ekklesia is not public. Every other part of that ADR + remains accepted and unchanged: the npm registry protocol, the public package set and its + boundaries, the curated SDK, the dependency rules, the coordinated package train, exact release + artifacts, standalone module builds, provider portability, supply chain and immutability, and the + credential handling for publishing. +- Related: [ADR 0049](0049-module-package-v1.md) + +## Context + +ADR 0053 decided how Ekklesia's module-development packages (`@ekklesia/*`) are built, released, and +distributed over the npm registry protocol. It assumed that the phase before Ekklesia's public +launch would be private: module CI would carry a read credential where reads needed one, and the +first publication had to make sure the registry would not serve the packages anonymously. + +Checking the chosen host before the first publication showed what keeping the packages private would +take: + +- Gitea 1.27.2 decides package read access by the package **owner's** visibility, never a + repository's. The `River_of_Glory_Church` owner is a public organization, so its packages are + readable anonymously. +- That organization's repositories, Ekklesia's source among them, are already publicly readable. +- The instance allows self-registration, so "limited" visibility, readable by any signed-in user, + is readable by anyone who creates an account. +- Private packages would therefore need a separate private package owner, plus reader accounts and + read tokens for every module repository, every module's CI, and every developer. + +The project owner has decided that Ekklesia is not secret. Its source is public; the project is +simply not being launched or promoted yet. Hiding the packages built from that public source would +protect nothing, and would still cost every module author an account and a token. + +## Decision + +1. **Ekklesia's module-development packages may be anonymously readable before the project's public + launch.** This covers the public package set of ADR 0053: search, metadata, and download. +2. **Readability is not a launch, and promises nothing more.** Public readability does not mean: + - that Ekklesia has been publicly launched; + - that the APIs are stable beyond the project's pre-1.0 SemVer policy; + - that third-party production use is supported; + - that a marketplace or public module ecosystem exists. +3. **Reading needs no authentication in this phase.** Installing `@ekklesia/*` needs no account, + reader account, read token, or authenticated install workflow. A module repository configures only + the scope's registry. +4. **Publication stays authenticated and tightly controlled.** Only Ekklesia's release process + publishes, with one dedicated publisher credential that holds nothing beyond package write + access, used only by that process, as ADR 0053's credential handling for publishing already + requires. +5. **Published versions stay immutable by Ekklesia policy.** A published version is never deleted or + republished with other bytes, whatever the registry technically allows. +6. **The current Gitea owner is an acceptable host.** The `River_of_Glory_Church` package namespace + on the current Gitea may host this phase, as long as publishing permission stays restricted to + the publisher. No private package organization is needed. +7. **A public launch is a separate decision.** Launching or promoting Ekklesia publicly, and anything + that changes for its packages then, is a product and release decision this ADR does not make. + +## Consequences + +- **Module authors and module CI need no Ekklesia credential.** The committed `.npmrc` scope mapping + is the whole registry configuration. ADR 0053's example of a read credential in user or CI + configuration is no longer needed in this phase. +- **ADR 0053's pre-publication access check changes meaning.** It now confirms that anonymous reads + work as intended and that publishing is refused without the publisher's permission, rather than + that reads are private. The disposable-registry suite proves both, and the publication tool can + require an anonymous download to match each published artifact. +- **Restricting publishing is now the whole access boundary**, so the publisher credential's scope, + where it is held, and who can reach it matter all the more. +- **Making the packages private again would be a new decision.** Package names, versions, and + contents already published stay public, because a published version is never deleted. + +## Alternatives considered + +- **A private package organization on the same Gitea.** Rejected: it hides nothing that is not + already public in the source, and it requires reader accounts and tokens for every module + repository, its CI, and every developer. +- **"Limited" package visibility.** Rejected: with self-registration open, anyone can read anyway, + while the configuration suggests otherwise. +- **Requiring sign-in for the whole instance.** Rejected: it would also hide the public + repositories. +- **Another registry for a private phase.** Unnecessary once reads are public. diff --git a/docs/architecture/decisions/README.md b/docs/architecture/decisions/README.md index a0d8c8e..0efa5b9 100644 --- a/docs/architecture/decisions/README.md +++ b/docs/architecture/decisions/README.md @@ -62,3 +62,4 @@ ADRs capture durable choices that affect more than one package or phase. - [0051: Module packages declare their own license and carry its text](0051-module-package-license-material.md) — Accepted - [0052: Reviewed license supplements cover redistributed dependencies whose packages omit required material](0052-reviewed-license-supplements.md) — Proposed - [0053: A module builds outside the monorepo, from Ekklesia packages published over the npm registry protocol](0053-standalone-module-development-packages.md) — Accepted +- [0054: Ekklesia's module-development packages are publicly readable before launch](0054-public-package-reads-before-launch.md) — Accepted diff --git a/docs/development/releases.md b/docs/development/releases.md index e1c486c..968dc31 100644 --- a/docs/development/releases.md +++ b/docs/development/releases.md @@ -6,12 +6,13 @@ release happens in and the public package train ([ADR 0053](../architecture/decisions/0053-standalone-module-development-packages.md)): how its artifacts are produced, what proves them, and how exactly those artifacts are published. -> **The packages are publicly readable, on purpose.** Anyone can search, read, and install -> `@ekklesia/*` from the registry with no account and no token, like any public npm package. That is -> not a public launch: Ekklesia's source is already publicly readable, and the project is simply not -> promoted yet. Only **publishing** is restricted, to one manual, authenticated workflow. Before -> 1.0, the APIs may change between versions under the project's SemVer policy: a 0.x minor version -> may break them. +> **The packages are publicly readable, on purpose** +> ([ADR 0054](../architecture/decisions/0054-public-package-reads-before-launch.md)). Anyone can +> search, read, and install `@ekklesia/*` from the registry with no account and no token, like any +> public npm package. That is not a public launch: Ekklesia's source is already publicly readable, +> and the project is simply not promoted yet. Only **publishing** is restricted, to one manual, +> authenticated workflow. Before 1.0, the APIs may change between versions under the project's +> SemVer policy: a 0.x minor version may break them. ## Where each step sits diff --git a/docs/module-development/README.md b/docs/module-development/README.md index e9570b0..740b94d 100644 --- a/docs/module-development/README.md +++ b/docs/module-development/README.md @@ -82,8 +82,10 @@ A module does not need an Ekklesia checkout. Do not clone Ekklesia and put your `modules/` directory: your module is its own repository, and it depends on Ekklesia's module-development packages like any other npm packages. -The packages are **publicly readable**: installing them needs no account, no token, and no access -to Ekklesia's Gitea. Only Ekklesia's release workflow can publish them. Point the `@ekklesia` scope at +The packages are **publicly readable** +([ADR 0054](../architecture/decisions/0054-public-package-reads-before-launch.md)): installing them +needs no account, no token, and no access to Ekklesia's Gitea. That is not a public launch, and it +promises no API stability beyond the pre-1.0 SemVer policy. Only Ekklesia's release workflow can publish them. Point the `@ekklesia` scope at the registry in your repository's committed `.npmrc`; that is all the configuration there is: ```ini