# Architecture decision records ADRs capture durable choices that affect more than one package or phase. - Filenames use a four-digit sequence followed by a short kebab-case title. - Status is `Proposed`, `Accepted`, `Superseded`, or `Rejected`. - Accepted ADRs are immutable except for status and cross-reference corrections. - A changed decision receives a new ADR that links to and supersedes the old one. ## Index - [0001: Four-layer platform boundary](0001-four-layer-platform-boundary.md) — Accepted - [0002: pnpm workspace and strict TypeScript](0002-pnpm-workspace-and-typescript.md) — Accepted - [0003: Development infrastructure](0003-development-infrastructure.md) — Accepted - [0004: Replace unmaintained MinIO baseline](0004-replace-unmaintained-minio.md) — Accepted - [0005: Static module manifests and atomic discovery](0005-static-module-manifests.md) — Superseded - [0006: Versioned capabilities and compiled module runtime](0006-versioned-capabilities-and-compiled-module-runtime.md) — Accepted - [0007: Module-owned Drizzle schemas and table isolation](0007-module-owned-drizzle-schemas.md) — Accepted - [0008: Module-owned migration contracts and offline validation](0008-module-owned-migration-contracts.md) — Accepted - [0009: Transactional module migration execution](0009-transactional-module-migrations.md) — Accepted - [0010: Core identity architecture and Better Auth adoption](0010-core-identity-and-better-auth-adoption.md) — Accepted - [0011: Identity HTTP transport and public enrollment policy](0011-identity-http-transport-and-public-enrollment.md) — Accepted - [0012: Production-equivalent identity origin/CSRF protection under test](0012-identity-origin-csrf-protection-under-test.md) — Accepted - [0013: Core authorization, permission registry, and platform-owner bootstrap](0013-core-authorization-and-owner-bootstrap.md) — Accepted - [0014: Module permission declarations and platform permission registry](0014-module-permission-declarations-and-platform-registry.md) — Accepted - [0015: Static module HTTP routing and production runtime lifecycle](0015-static-module-http-routing-and-runtime-lifecycle.md) — Accepted - [0016: Module database access](0016-module-database-access.md) — Accepted - [0017: Public request perimeter hardening — client address, signup gating, body limits, timeouts](0017-public-request-perimeter-hardening.md) — Accepted - [0018: Identity session resolution, canonical public origins, and PostgreSQL transport policy](0018-identity-session-resolution-and-database-transport.md) — Accepted - [0019: Durable authorization history and grant management](0019-durable-authorization-history-and-grant-management.md) — Accepted - [0020: Module runtime and migration execution hardening](0020-module-runtime-and-migration-execution-hardening.md) — Accepted - [0021: Modules as independently hostable products](0021-modules-as-hostable-products.md) — Accepted - [0022: Module UI authoring model and host contract](0022-module-ui-authoring-and-host-contract.md) — Accepted - [0023: Module UI build pipeline](0023-module-ui-build-pipeline.md) — Accepted - [0024: Browser-safe module UI SDK and the generic host loader](0024-browser-safe-ui-sdk-and-host-loader.md) — Accepted - [0025: Trusted module UI asset publication](0025-trusted-module-ui-asset-publication.md) — Accepted - [0026: The minimal Ekklesia module UI host](0026-minimal-ekklesia-module-ui-host.md) — Accepted - [0027: Dashboard navigation is presentation configuration, and modules stay flat](0027-dashboard-navigation-and-flat-modules.md) — Accepted - [0028: Module operational lifecycle — enablement, eligibility, and what "running" means](0028-module-operational-lifecycle.md) — Accepted - [0029: Module configuration is manifest-declared, host-resolved, and secret-free at rest](0029-module-configuration-and-secrets.md) — Accepted - [0030: Modules declare logical buckets; hosts provide object storage](0030-host-provided-module-object-storage.md) — Accepted - [0031: Browsers fetch objects directly, through opaque temporary read URLs](0031-direct-object-delivery.md) — Accepted - [0032: Native module realtime is scoped snapshot state over SSE](0032-native-module-realtime-transport.md) — Accepted - [0033: Display UI is a separate, permission-gated module entrypoint](0033-display-kiosk-host-contract.md) — Accepted - [0034: Dashboard browser authentication is host-owned and principal-first](0034-host-owned-browser-authentication.md) — Accepted - [0035: The first platform owner is created by an operator command, never by a browser](0035-initial-platform-owner-bootstrap.md) — Accepted - [0036: A display device is its own principal, paired by an administrator](0036-managed-device-identity-and-pairing.md) — Accepted - [0037: Outbound email is a host-provided transport, and SMTP is its first provider](0037-host-provided-outbound-email.md) — Accepted - [0038: Email verification and password recovery, with a trusted-bootstrap exception](0038-email-verification-and-password-recovery.md) — Accepted - [0039: Shared design tokens and foundational elements](0039-shared-design-tokens-and-elements.md) — Accepted - [0040: Module stylesheets, and every browser artifact gets an isolated root](0040-module-stylesheets-and-artifact-isolation.md) — Accepted - [0041: One module may contribute a browser renderer to another module's capability](0041-module-browser-contributions.md) — Accepted - [0042: Explicit, bounded streaming request bodies](0042-bounded-streaming-request-bodies.md) — Accepted - [0043: The display caches its shell and declared code, and nothing else](0043-display-offline-code-fallback.md) — Accepted - [0044: Ekklesia ships one self-hosted reference deployment, composed from pinned sources](0044-self-hosted-reference-deployment.md) — Accepted - [0045: The Dashboard and the API may live on separate origins](0045-split-dashboard-and-api-origins.md) — Accepted - [0046: Ekklesia's branding is never forced on an installation](0046-installation-owned-branding.md) — Proposed - [0047: Every module proves itself inside Ekklesia, with one harness the platform publishes](0047-module-ci-harness.md) — Proposed - [0048: Ekklesia ships one generic image, and installed modules live outside it](0048-generic-image-and-installed-module-storage.md) — Accepted - [0049: A module release is one immutable, self-contained package: Ekklesia Module Package v1](0049-module-package-v1.md) — Accepted - [0050: Module Database ABI v1: modules and Core exchange SQL, never ORM objects](0050-module-database-abi-v1.md) — Accepted - [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