Files
Ekklesia/CONTRIBUTING.md
T
ekklesia a8c7c50b4d
CI / verify (pull_request) Successful in 38s
CI / infrastructure-smoke (pull_request) Successful in 12s
CI / migration-smoke (pull_request) Successful in 1m0s
feat: add browser auth shell
2026-08-23 22:01:26 -05:00

3.9 KiB

Contributing

Ekklesia is being built in verified, reviewable phases. Changes should preserve the dependency boundaries described in repository-boundaries.md.

Before opening a change, run:

pnpm verify

Migration-runner changes and changes to identity/authentication or the API's session transport also require the disposable live PostgreSQL suite:

pnpm test:migrations:integration

See the testing guide for the distinction between unit and live evidence and for credential-safe troubleshooting.

When adding or changing a module manifest, also run pnpm modules:validate directly for focused, path-aware discovery errors. It is included in pnpm verify.

If Docker is available, also validate the development infrastructure:

pnpm infrastructure:config

Package rules

  • Use strict TypeScript for production packages.
  • Expose supported entry points through package exports; do not import another package's private source paths.
  • Use workspace: ranges for internal package dependencies.
  • Modules own their own UI and author it in React and TypeScript (ADR 0022). A module package may contain .tsx and depend on react, react-dom, and @ekklesia/module-ui-sdk. Every other UI framework, .jsx, stylesheets, and other presentation formats remain rejected by pnpm boundaries. Primary and display sources live at the exact src/ui/index.tsx and src/display/index.tsx conventions; one pnpm build invocation atomically compiles every role the v6 manifest declares via @ekklesia/module-ui-build (ADR 0023/0033). Module authors write no bundler configuration, and styling is React inline style objects only for now. Both roles use the same UI SDK context with no presentation-mode flag.
  • Module UI reaches its host only through @ekklesia/module-ui-sdk — never @ekklesia/module-ui-host, which is the host-side loader — and asks the host for its own API by relative path — never by constructing /api/v1/modules/<id>/..., which is Ekklesia's private deployment detail and would break standalone hosting.
  • The containing application shell, navigation, global theme, and platform policy belong to Core and the host application, never to a module. Ekklesia's own shell is surfaces/shell; it discovers primary module UIs through GET /api/v1/dashboard/navigation, resolves a dedicated display through GET /api/v1/module-displays/<module-id>, mounts both with @ekklesia/module-ui-host, and statically imports no module (ADR 0026/0033).
  • Dedicated displays are module-owned renderers mounted by a separate full-viewport surface at /display/<module-id>, never Dashboard UI with hidden chrome. Its page and descriptor require the module-owned, non-public permission declared by entrypoints.display; artifact bytes remain anonymous trusted code. Public/device identity, display inventory, and variants are deferred.
  • Dashboard groups are presentation configuration, never module structure. Do not add a parent module, child module, owning module, or group-derived dependency: real module relationships are the dependency contract's job alone, and grouping must never influence discovery, dependency ordering, startup, or authorization (ADR 0027). A module declares its display name (manifest.name); the Dashboard owns where it appears.
  • A surface is browser code. It may depend on browser-safe shared roles only — never @ekklesia/contracts or @ekklesia/module-sdk, whose type graphs pull Node's globals into the browser — and it reaches the server over HTTP.
  • Add or update tests when changing a contract or architectural rule.
  • Record major architectural changes in an ADR rather than burying them in an implementation.

Runtime registries and aggregate schemas will be produced by later phases. Do not add a manually maintained feature-module registry; discovery starts from validated ekklesia.module.json files.