feat: build Signage on its own from the published Ekklesia 0.2.0 packages
CI / lint (pull_request) Successful in 11s
CI / typecheck (pull_request) Successful in 11s
CI / test (pull_request) Successful in 17s
CI / build (pull_request) Successful in 12s
CI / integration (pull_request) Skipped

Signage no longer needs an Ekklesia checkout. A clean clone installs with
`pnpm install --frozen-lockfile` and runs lint, typecheck, test, build, and validate by itself, taking
Ekklesia's module-development packages from Ekklesia's public registry (ADRs 0053 and 0054).

- Dependencies: every `workspace:*` becomes `^0.2.0`. @ekklesia/module-pack is added as a
  devDependency pinned exactly to 0.2.0, as ADR 0053 requires; it is not invoked yet. No
  @ekklesia/contracts dependency. drizzle-orm stays a direct dependency, satisfying the adapter's
  optional peer.
- .npmrc points the @ekklesia scope at
  https://git.riverofglorymn.org/api/packages/River_of_Glory_Church/npm/ with no credential, because
  reading needs none.
- pnpm-workspace.yaml holds this repository's pnpm settings only:
  - `allowBuilds: esbuild: true`, as the platform's standalone fixture does;
  - exact-version minimumReleaseAgeExclude entries for the 0.2.0 train, which pnpm 11 otherwise holds
    back on its release day;
  - the platform's narrowly scoped override for GHSA-67mh-4wv8-2f99 (esbuild via drizzle-kit), which
    Signage inherited while it built inside Ekklesia's workspace.
- engines.node `>=24.11.0 <25` and packageManager `[email protected].0`, both from Ekklesia 0.2.0. Node
  24.18.0 goes in .node-version for CI, as in Ekklesia.
- biome.json carries the platform's Biome configuration, which `biome lint` used to pick up from the
  workspace root, so lint rules are unchanged.
- pnpm-lock.yaml is Signage's own: registry tarballs with integrity hashes, and no workspace or file
  links.
- `prepack` runs this package's own build instead of the workspace root's turbo.
- `pnpm validate` (scripts/validate-module.mjs) checks the built package and its migrations with the
  published SDK parsers only:
  - the manifest, its identity, and its entrypoints;
  - that the built runtime's id, version, and database ABI match the manifest;
  - that the built schema metadata is plain, namespaced, and has module-internal foreign keys;
  - the SDK compatibility range;
  - that the migration journal and policy agree.

  Core's own `modules:validate` and `migrations:validate` are not published. What only an Ekklesia
  installation can check is named in the script.

Removed: ci/assemble.sh, ci/platform.env, ci/pnpm-lock.yaml, ci/update-lock.sh. The lint, typecheck,
test, and build jobs check out only this repository; build also runs `pnpm validate`. The integration
job stays disabled. Its first step is now an explicit placeholder rather than the deleted assembly,
and its explanation says it returns when Signage is a canonical linux-x64-glibc Module Package
installed into Ekklesia's generic image.

No source, behaviour, schema, or version change: Signage stays 0.1.2.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ekklesia
2026-10-08 20:49:17 -05:00
co-authored by Claude Opus 5.5
parent fefe34be03
commit 33bb146349
16 changed files with 2888 additions and 4731 deletions
+42 -41
View File
@@ -51,70 +51,71 @@ Mounting requires an authenticated module descriptor, and Core does not yet cach
cold start depends on a Core-provided authorized offline display descriptor or lease; until that
exists, this module does not claim it. See ADR 0006.
## Developing against Ekklesia
## Developing Signage
Signage is developed **inside the authoritative Ekklesia workspace**, checked out at the path it will
eventually be installed at:
Signage builds and tests on its own. You need no Ekklesia checkout and no Ekklesia account:
- **Node.js** in the range `engines.node` declares (`>=24.11.0 <25`); `.node-version` names the
version CI uses.
- **pnpm** at the version `packageManager` pins, through Corepack (`corepack enable`).
```bash
git clone <ekklesia> ekklesia
git clone <this repository> ekklesia/modules/signage
cd ekklesia
pnpm install
git clone <this repository> signage
cd signage
corepack enable
pnpm install --frozen-lockfile
```
`modules/*` is an Ekklesia workspace glob, so the checkout is picked up with no registry edit,
no second copy of Ekklesia, and no vendored SDK. `@ekklesia/module-sdk`, `@ekklesia/module-database`,
`@ekklesia/module-ui-sdk`, `@ekklesia/design-tokens`, `@ekklesia/ui`, and `@ekklesia/module-ui-build`
all resolve through the workspace as `workspace:*` dependencies.
Ekklesia's module-development packages (`@ekklesia/module-sdk`, `@ekklesia/module-database`,
`@ekklesia/module-ui-sdk`, `@ekklesia/ui`, `@ekklesia/design-tokens`, `@ekklesia/module-ui-build`,
`@ekklesia/module-pack`, `@ekklesia/typescript-config`) come from Ekklesia's public package registry.
The committed `.npmrc` points the `@ekklesia` scope at it, and reading it needs **no token** and no
login (platform ADRs 0053 and 0054); never add a credential to that file. Everything else comes from
the public npm registry. `package.json` takes the Ekklesia packages as `^0.2.0` ranges, except
`@ekklesia/module-pack`, which is pinned exactly; `pnpm-lock.yaml` pins every package's exact version
and integrity, so always install with `--frozen-lockfile` unless you mean to change a dependency.
Two consequences worth knowing:
`pnpm-workspace.yaml` holds this repository's own pnpm settings: it allows esbuild's install script,
exempts exactly the Ekklesia package train in the lockfile from pnpm's minimum release age, and keeps
one narrowly scoped advisory override. It does not make Signage part of any other workspace.
- Ekklesia uses a shared workspace lockfile, so installing here writes an importer entry for
`modules/signage` into Ekklesia's `pnpm-lock.yaml`. That entry belongs to whoever maintains the
Ekklesia checkout; it is not committed from this repository.
- Signage requires Ekklesia 0.2: manifest version 8 and the Module Database ABI v1 (platform ADR
0050), on top of the prerequisites for shared design tokens, module stylesheets, browser
contributions, bounded streaming request bodies, and display offline code (ADRs 0039–0043). An
older Ekklesia checkout cannot build or validate this module.
- Signage reaches PostgreSQL only through the ABI v1 executor the platform hands it, with its own
Drizzle tables and the module-side adapter from `@ekklesia/module-database/drizzle`. Core receives
SQL text, bound values, and plain schema metadata, never a Drizzle object.
Signage requires Ekklesia 0.2: manifest version 8 and the Module Database ABI v1 (platform ADR 0050).
It reaches PostgreSQL only through the ABI v1 executor the platform hands it, with its own Drizzle
tables and the module-side adapter from `@ekklesia/module-database/drizzle`. Core receives SQL text,
bound values, and plain schema metadata, never a Drizzle object.
### Commands
Run from the **Ekklesia repository root**:
```bash
pnpm --filter @ekklesia/signage build # tsc + the canonical module UI build
pnpm --filter @ekklesia/signage test # unit and browser-artifact tests
pnpm --filter @ekklesia/signage typecheck # node, browser, and browser-test projects
pnpm --filter @ekklesia/signage lint
pnpm boundaries # four-layer boundary enforcement
pnpm modules:validate # static manifest, entrypoint, and schema validation
pnpm migrations:validate # migration journal, policy, ordering, and checksums
pnpm verify # the full Docker-free gate
pnpm lint # Biome, with this repository's biome.json
pnpm typecheck # node, browser, and browser-test projects
pnpm test # unit, browser-artifact, and display contract tests (vitest.config.ts)
pnpm build # tsc, then the canonical module UI build of the primary and display artifacts
pnpm validate # after build: the built package and its migrations, as the platform reads them
```
Signage's tests are its own: `pnpm test` here runs `vitest` against this package's `vitest.config.ts`,
which includes `.test.tsx` as well as `.test.ts`. The workspace-root config includes only `.test.ts`,
so a browser test added here without that config would be silently skipped.
CI runs exactly these, from a clean checkout.
Never run `pnpm migrations:apply` against a persistent database while developing this module. Signage
reads no environment variable, constructs no database client, configures no object storage, hardcodes
no Ekklesia URL, opens no socket of its own, and applies no migration: every one of those reaches it
`pnpm validate` uses only the published SDK parsers. It cannot check what only an Ekklesia
installation knows: compatibility with that installation, other installed modules' capabilities and
dependencies, or a migration's checksum against a database's applied history. Ekklesia checks those
when Signage is installed.
Never run a migration against a persistent database while developing this module. Signage reads no
environment variable, constructs no database client, configures no object storage, hardcodes no
Ekklesia URL, opens no socket of its own, and applies no migration: every one of those reaches it
through the host.
### Changing the schema
```bash
pnpm --filter @ekklesia/signage migration:generate # drizzle-kit, into drizzle/
pnpm migration:generate # drizzle-kit, into drizzle/
```
`tests/schema.test.ts` pins the checksum of the generated SQL, so a regenerated migration fails the
suite until the pin is updated deliberately. `drizzle/meta/_ekklesia.json` declares the migration
non-destructive; `pnpm migrations:validate` enforces that.
non-destructive: `tests/schema.test.ts` asserts it, and Ekklesia's own migration validation enforces
it when Signage is packaged and installed.
### Verifying what only a browser can show