feat: deliver module database ABI by manifest
CI / verify (pull_request) Successful in 1m0s
CI / infrastructure-smoke (pull_request) Successful in 36s
CI / migration-smoke (pull_request) Successful in 1m53s
CI / image-build (pull_request) Successful in 23s
CI / deploy-smoke (same-origin) (pull_request) Successful in 50s
CI / deploy-smoke (split) (pull_request) Successful in 1m30s

This commit is contained in:
ekklesia
2026-10-07 17:29:32 -05:00
parent a1cdcb3ad1
commit 49b4d4165d
60 changed files with 948 additions and 237 deletions
+17 -9
View File
@@ -68,6 +68,14 @@ const moduleStorageSchema = z
.strict()
.default(() => ({ buckets: [] }));
/** The database contract Core delivers to this module. Omitted means the temporary ADR 0016
* legacy facade; ABI v1 is the stable SQL boundary from ADR 0050. */
export const moduleDatabaseDeclarationSchema = z
.object({
abi: z.literal(1),
})
.strict();
/**
* A module's optional full-viewport display UI. The artifact is kept beside its access policy so a
* display can never be declared without saying which one of the module's own permissions protects
@@ -122,9 +130,9 @@ function reportDuplicates(
}
/**
* The one manifest shape Core accepts. Version 6's strict top-level object rejects `contributions`,
* so the static browser-contribution declaration is an incompatible shape change and the canonical
* manifest moves to `manifestVersion: 7` rather than silently reinterpreting version 6.
* The one manifest shape Core accepts. Version 7's strict top-level object rejects `database`, so
* the static ABI declaration is an incompatible shape change and the canonical manifest moves to
* `manifestVersion: 8` without silently reinterpreting version 7.
*
* Configuration is declared **statically, in this inert document**, rather than registered by
* executable module code, for one decisive reason: the platform validates a module's configuration
@@ -133,14 +141,13 @@ function reportDuplicates(
* inside its own `start` hook. Discovery, `pnpm modules:validate`, and Doctor all read this without
* importing a single line of module code, exactly as they always have.
*
* Version 6, and every other version, fails validation: there is no compatibility adapter, no
* Version 7, and every other version, fails validation: there is no compatibility adapter, no
* automatic conversion, and no dual acceptance, exactly as version 1 was rejected by version 2
* (ADR 0006), version 2 by version 3 (ADR 0014), version 3 by version 4 (ADR 0021), and version 5
* by version 6 (ADR 0033). One manifest document can therefore never be read as two different
* versions. Upgrading a version 6 manifest is a one-character edit for a module that contributes
* nothing: the new field defaults to empty.
* (ADR 0006), version 2 by version 3 (ADR 0014), version 3 by version 4 (ADR 0021), and version 7
* by version 8 (ADR 0050). One manifest document can therefore never be read as two different
* versions. A version 7 package must be rebuilt; omitting `database` selects the legacy facade.
*/
export const MODULE_MANIFEST_VERSION = 7;
export const MODULE_MANIFEST_VERSION = 8;
export const moduleManifestSchema = z
.object({
@@ -163,6 +170,7 @@ export const moduleManifestSchema = z
* module code during discovery. A module that needs nothing configured omits the field. */
configuration: z.array(moduleConfigurationDeclarationSchema).default(() => []),
storage: moduleStorageSchema,
database: moduleDatabaseDeclarationSchema.optional(),
/** Compiled browser renderers this module offers to capabilities **other** modules provide
* (ADR 0041). Inert data: Core validates identity, compatibility, and the artifact path, and
* never learns what a contribution renders. A module that contributes nothing omits the field. */