fix(display): Stage 0 display continuity, revocation, and kiosk recovery #92

Open
ekklesia-bot wants to merge 7 commits from stage0/display-runtime-continuity into main
Showing only changes of commit 06bad2fe36 - Show all commits
+57 -15
View File
@@ -6,27 +6,60 @@ contents, because restated details drift.
## What this repository is ## What this repository is
Ekklesia is a modular, self-hosted church platform built as a strictly layered pnpm/TypeScript Ekklesia is a modular, self-hosted church platform. **This repository is the platform** — Core, the
monorepo: API, the Dashboard and display shell, and the public `@ekklesia/*` module-development packages — built
as a strictly layered pnpm/TypeScript monorepo:
- **Core** (`core/`) owns platform infrastructure: identity, database connectivity, migration - **Core** (`core/`) owns platform infrastructure: identity, database connectivity, migration
execution, module discovery/lifecycle, and other feature-agnostic services. Core never imports a execution, module discovery/lifecycle, devices, and other feature-agnostic services. Core never
feature module, a surface, or an app. imports a feature module, a surface, or an app.
- **Modules** (`modules/*`, template at `templates/module`) are independently versioned product - **Modules** are independently versioned product packages. First-party modules live in **their own
packages. They own their own data and migrations, declare capabilities/permissions through repositories** (Signage is `Zayin/Signage`), build against the published `@ekklesia/*` packages
`@ekklesia/contracts` and `@ekklesia/module-sdk`, and must never import Core, another module, or a (ADR 0053), and reach an installation as a Module Package (ADR 0049) installed into module storage
surface directly. Per ADR 0021 a module owns its UI; manifest v7 permits independently optional outside the image (ADR 0048). No module source lives in this repository; `templates/module` is the
primary and full-viewport display artifacts, authored in React against the same role-neutral example, and `modules/` is only an optional, ignored local installed-modules directory. A module owns
`@ekklesia/module-ui-sdk` ABI. Ekklesia mounts each through a separate surface role, while its data, migrations, and **its own domain UI** (ADR 0021), declares capabilities/permissions through
`pnpm boundaries` still rejects every non-React UI framework and non-`.tsx` presentation source. `@ekklesia/contracts` and `@ekklesia/module-sdk`, and never imports Core, another module, or a
surface. Manifest v8 permits independently optional primary and full-viewport display artifacts,
authored in React against the role-neutral `@ekklesia/module-ui-sdk` ABI; database access is the
Module Database ABI v1 (ADR 0050).
- **Surfaces** (`surfaces/*`) own the containing application shell, navigation, and every - **Surfaces** (`surfaces/*`) own the containing application shell, navigation, and every
presentation concern a module does not. They consume public API/client contracts only, never Core presentation concern a module does not. The shell **hosts** module UI through the generic loader;
or module internals directly. it never rebuilds a module's domain screens. Surfaces consume public API/client contracts only.
These boundaries are enforced by `pnpm boundaries` (`scripts/check-boundaries.ts`), not just These boundaries are enforced by `pnpm boundaries` (`scripts/check-boundaries.ts`), not just
documented. Read `docs/architecture/repository-boundaries.md` and documented. Read `docs/architecture/repository-boundaries.md` and
`docs/architecture/platform-architecture.md` before proposing any change that crosses a layer. `docs/architecture/platform-architecture.md` before proposing any change that crosses a layer.
## Product direction lives beside this repository
The current roadmap and product/interface design contract are `ROADMAP.md` and `DESIGN.md` in the
parent development directory (`../ROADMAP.md` and `../DESIGN.md` from a checkout in the standard
`~/development/ekklesia/` layout). They are deliberately **not** committed here; do not copy them into
this repository to make them available. They are authoritative for product direction: read the
relevant stages and sections before designing a change. If this repository's documentation disagrees
with them, flag the conflict, correct the repository-local documentation where appropriate, and never
silently follow the stale text. Architectural decisions still change only through ADRs (below).
Rules from those documents that every change here must respect:
- **Ownership.** Modules own their domain data, behaviour, and UI. Shared resources — displays and
devices, accounts and identity, roles and authorization, branding, mail, push, storage providers,
and module installation/lifecycle — belong to the platform, and modules consume them.
- **Branding.** Normal user-facing UI never hard-codes "Ekklesia"; product identity comes from
installation branding (ADR 0046). Package names, diagnostics, logs, and developer tooling may.
Existing hard-coded shell strings are known debt for Stage 1, not a pattern to copy.
- **Visual direction.** Simple, minimal, and calm; responsive for phone, tablet, and desktop; light,
dark, and system modes. Normal UI colours come only from the shared design tokens
(`@ekklesia/design-tokens`, ADR 0039) — never a hard-coded colour.
- **No browser-native dialogs.** `window.alert`, `window.confirm`, and `window.prompt` are prohibited
in product UI. Destructive actions use in-product confirmation proportional to their impact.
- **Displays are transitional.** Displays are platform-owned. Today's device pairing (the Dashboard
sidebar's *Display devices* panel) and Signage's own display roster are a transitional
implementation that Stage 1 migrates to **Settings → Displays**. Fix defects in them, but do not
build the Stage 1 Settings, global Displays, theme editor, module installer, or responsive shell
redesign early, and keep existing paired displays working across any change.
## ADRs are authoritative ## ADRs are authoritative
`docs/architecture/decisions/` records durable architectural decisions. **Accepted ADRs are `docs/architecture/decisions/` records durable architectural decisions. **Accepted ADRs are
@@ -43,6 +76,7 @@ At minimum, read the current versions of:
- `docs/architecture/decisions/README.md` and every ADR relevant to your change - `docs/architecture/decisions/README.md` and every ADR relevant to your change
- `docs/architecture/platform-architecture.md` and `docs/architecture/repository-boundaries.md` - `docs/architecture/platform-architecture.md` and `docs/architecture/repository-boundaries.md`
- `README.md` (current platform status — what is and is not implemented) - `README.md` (current platform status — what is and is not implemented)
- `../ROADMAP.md` and `../DESIGN.md` (current product direction; see above)
- `docs/development/repository-workflow.md` and `docs/development/testing.md` - `docs/development/repository-workflow.md` and `docs/development/testing.md`
- `CONTRIBUTING.md` - `CONTRIBUTING.md`
@@ -52,8 +86,16 @@ your own memory of a prior session** — treat stale assumptions as a bug to cat
## Working conventions ## Working conventions
- Work on a clean branch off an up-to-date `main`; never commit or push directly to `main`; never - The canonical repositories are on the church Gitea under the `Zayin` organization:
change branch-protection settings. `ssh://[email protected]:2222/Zayin/Ekklesia.git` (this one), `Zayin/Signage.git`, and
`Zayin/Classroom_Desktop.git`. A local clone may be behind the server: `git fetch --prune --tags`
and branch from `origin/main`, never from whatever is checked out.
- One branch per PR, off an up-to-date `origin/main`. Never commit or push directly to `main`, never
merge your own PR, and never change branch-protection settings.
- Never create or push a release tag. Release tags belong to the human maintainer.
- A change that needs both a platform contract change and a module change is two PRs: Core first, on
its own branch, with the compatibility boundary stated explicitly; then the module. Do not copy
platform logic into a module to avoid making the correct Core change.
- Keep PRs focused on one bounded slice. Record major architectural changes in an ADR rather than - Keep PRs focused on one bounded slice. Record major architectural changes in an ADR rather than
burying them in an implementation. burying them in an implementation.
- Add or update tests when you change a contract or architectural rule. New behavior needs new - Add or update tests when you change a contract or architectural rule. New behavior needs new