feat: transition module packages to database ABI v1
CI / verify (pull_request) Successful in 1m1s
CI / infrastructure-smoke (pull_request) Successful in 36s
CI / migration-smoke (pull_request) Successful in 1m54s
CI / image-build (pull_request) Successful in 31s
CI / deploy-smoke (same-origin) (pull_request) Successful in 52s
CI / deploy-smoke (split) (pull_request) Successful in 1m32s

This commit is contained in:
ekklesia
2026-10-07 18:00:04 -05:00
parent 20ad1ae208
commit 70854d234c
20 changed files with 274 additions and 115 deletions
+16 -18
View File
@@ -138,18 +138,15 @@ The archive holds one directory named with your module id:
- **Deterministic.** The same packager version and the same built inputs produce the same archive,
byte for byte, wherever the checkout is.
**Drizzle, for now.** You define tables with your own copy of Drizzle, and Core runs your queries
through the platform's Drizzle instance (see [Database access](#database-access)). Objects from two
copies interoperate only when the copies are interchangeable, so the current implementation requires
**exactly the Drizzle version the platform uses**: the one `@ekklesia/module-sdk` depends on. The
package records it under `transitional`, and an installation refuses a package whose Drizzle differs.
This is a constraint of today's implementation, not a permanent contract.
**Database ABI v1 is the current path.** A module that declares `"database": { "abi": 1 }` keeps
Drizzle and its exact version inside its own bundle as an implementation detail. Its package omits
`transitional.databaseRuntime`; Core validates the module's plain schema metadata and never compares
the bundled Drizzle version with its own. The canonical template demonstrates this path with
`@ekklesia/module-database/drizzle`.
`@ekklesia/module-database` now contains the module-side ABI v1 adapters that remove that coupling,
but deployed modules cannot receive an ABI v1 executor yet. Manifest v8 and per-module runtime
service delivery are separate later work. Until those land, the current transitional package rule
and database service above remain authoritative; neither Module Package v1 nor the template changed
with the adapter package.
A manifest-v8 module that omits `database` remains on the temporary legacy facade. Only that legacy
package records bundled Drizzle under `transitional.databaseRuntime`, and the verifier continues to
require exact agreement with Core. The legacy facade has not been removed.
#### Verifying a package
@@ -1468,9 +1465,10 @@ export default defineConfig({
```
Keep `tables.ts` limited to Drizzle declarations so the stable generator can load it without
executing the ESM Module SDK wrapper. `src/schema/index.ts` remains the production compiled schema
entrypoint and wraps those same exported table objects with `defineModuleSchema`; tables are not
declared twice.
executing the ESM module wrapper. For an ABI-v1 module, `src/schema/index.ts` remains the production
compiled schema entrypoint and converts those same table objects to plain metadata with
`moduleDrizzleSchemaMetadata`; tables are not declared twice. A legacy-v8 module continues to wrap
them with `defineModuleSchema` while that facade exists.
Run the module's `migration:generate` script with a lowercase snake-case name, review the generated
SQL and snapshot, and add the matching entry to `drizzle/meta/_ekklesia.json`. Every entry must
@@ -1587,10 +1585,10 @@ The result is `{ moduleId, tables: [{ name, foreignKeys: [{ table }] }] }`. Core
prefixes, duplicates, and same-module foreign-key targets from those strings and never inspects an
ABI module's ORM objects.
The canonical module template has moved to manifest version 8 but intentionally omits `database`,
so it remains on the legacy facade for one more slice. The packager still emits ADR 0049's
`transitional.databaseRuntime`; the next package-transition change will remove that fact for ABI
packages and migrate the template at the same time.
The canonical module template declares ABI v1, uses the module-side Drizzle adapter, and exports
plain schema metadata derived with `moduleDrizzleSchemaMetadata`. Its Module Package v1 still
bundles Drizzle, but carries no `transitional.databaseRuntime`: that version belongs to the module,
not Core.
## Legacy database access