docs: propose ADR 0046, installation-owned branding #53

Merged
Joey merged 2 commits from docs/adr-0046-installation-branding into main 2026-10-03 18:54:46 +00:00
Member

docs: propose ADR 0046, installation-owned branding

Stacked on #51 (ADR 0045): both append to the ADR index on adjacent lines. Until #51 merges, this diff also shows #51's two commits; after that it is this one commit.

ADR 0046 records a core principle: Ekklesia's branding is never forced on an installation. Anything a member, visitor or volunteer can see is configurable by the installation and removable entirely.

  • Exempt: internal identifiers, operator tooling (CLIs, Doctor, logs) and developer-only diagnostics.
  • Default: with no name configured, wording is neutral ("Sign in", not "Sign in to Ekklesia"). The default therefore names nothing, and a test can enforce it.
  • Modules follow the same rule.

Report only; implementation is its own slice.

Audit: every user-visible "Ekklesia" in the platform (at 481e801, main)

Smallest settings

  1. EKKLESIA_INSTALLATION_NAME (new, optional, 1–80 characters, no control characters). Unset means neutral wording.
    • Browser pages: the API renders it into the Dashboard and display HTML at startup (the <title>, plus a <meta name="ekklesia-installation-name"> the shell reads). This is the same mechanism as ADR 0045's API-origin meta tag, so the image stays generic.
    • Emails: passed to the identity notification templates.
  2. EKKLESIA_SMTP_FROM_NAME (exists). When unset it falls back to EKKLESIA_INSTALLATION_NAME, else no display name. Stop suggesting "Ekklesia" in the examples.

No other setting is needed; every string below becomes "{name}" or neutral wording.

Dashboard (browser)

File:line Today With a name / without
surfaces/shell/index.html:6 <title>Ekklesia</title> {name} / Dashboard
surfaces/shell/src/browser/HostApp.tsx:470 Loading Ekklesia… Loading {name}… / Loading…
surfaces/shell/src/browser/HostApp.tsx:517 Ekklesia could not be reached. {name} could not be reached. / The server could not be reached.
surfaces/shell/src/browser/HostApp.tsx:530 button "Return to Ekklesia" Return to {name} / Return to the Dashboard
surfaces/shell/src/browser/HostApp.tsx:535 Ekklesia could not sign you out. Try again. Signing out did not finish. Try again. (no name needed)
surfaces/shell/src/browser/HostApp.tsx:564 page heading Ekklesia {name} / Dashboard
surfaces/shell/src/browser/LoginForm.tsx:114 Sign in to Ekklesia Sign in to {name} / Sign in
surfaces/shell/src/browser/LoginForm.tsx:115 Use your existing Ekklesia account. Use your existing {name} account. / Use your existing account.
surfaces/shell/src/browser/ForgotPasswordForm.tsx:33 If an Ekklesia account exists for that address… If a {name} account exists… / If an account exists…
surfaces/shell/src/browser/ForgotPasswordForm.tsx:55 …your Ekklesia account… …your {name} account… / …your account…
surfaces/shell/src/browser/ResetPasswordForm.tsx:46 …every existing Ekklesia session… …every existing session… (no name needed)
surfaces/shell/src/browser/VerificationScreens.tsx:38 If an unverified Ekklesia account exists… If an unverified {name} account exists… / If an unverified account exists…
surfaces/shell/src/browser/VerificationScreens.tsx:119 Sign in to Ekklesia to continue. Sign in to {name} to continue. / Sign in to continue.
surfaces/shell/src/browser/VerificationScreens.tsx:140 …and Ekklesia will send a new one. …and a new one will be sent. (no name needed)
surfaces/shell/src/browser/VerificationScreens.tsx:141 …and Ekklesia will send a new one. as above
surfaces/shell/src/host-protocol.ts:66–69 HOST_* messages ("…the Ekklesia Dashboard", "Ekklesia could not be reached", …) Latent: the shell renders codes, not these messages, but module code and the console can see them. Neutral wording, no name needed.

Display screens

File:line Today With a name / without
surfaces/shell/src/display/DisplayApp.tsx:92 Offline — showing the last downloaded Ekklesia display Offline — showing the last downloaded display (no name needed)
surfaces/shell/src/display/DisplayApp.tsx:93 Offline — waiting for Ekklesia Offline — waiting for {name} / Offline — waiting for the server
surfaces/shell/src/display/PairingScreen.tsx:140 Enter this code in the Ekklesia dashboard… Enter this code in the {name} Dashboard… / Enter this code in the Dashboard…
surfaces/shell/display.html:6 <title>Display</title> Already neutral; optionally {name}

Emails

File:line Today With a name / without
core/src/identity/notifications.ts:185 subject: Verify your Ekklesia email address Verify your email address for {name} / Verify your email address
core/src/identity/notifications.ts:188, 195 …sign in to Ekklesia. (HTML / text) …sign in to {name}. / …sign in.
core/src/identity/notifications.ts:209 subject: Reset your Ekklesia password Reset your {name} password / Reset your password
core/src/identity/notifications.ts:212, 219 …this Ekklesia account. (HTML / text) …this {name} account. / …this account.
Sender display name No default; examples suggest "Ekklesia": deploy/env/ekklesia.env.example:67, .env.example:83, docs/development/email.md:95 Falls back to EKKLESIA_INSTALLATION_NAME; examples drop "Ekklesia"

Exempt under the ADR (listed for completeness)

  • Operator tooling:
    • core/src/cli/create-initial-owner.ts:198 ("You can now sign in to the Ekklesia dashboard." Suggest the neutral "You can now sign in to the Dashboard.", no setting.)
    • core/src/cli/bootstrap-platform-owner.ts:61
    • core/src/cli/doctor.ts:124
    • core/src/diagnostics/doctor-report.ts:56
    • core/src/diagnostics/doctor.ts:624
    • core/src/migrations/runner.ts:130–131
    • apps/api/src/server.ts:794, 808
    • surfaces/shell/scripts/build-browser.mjs:80, 88
  • Developer-only thrown errors:
    • surfaces/shell/src/browser/main.tsx:35
    • surfaces/shell/src/display/main.tsx:17
    • surfaces/shell/src/display/offline-cache.ts:252
    • surfaces/shell/src/display/sw.ts:73
    • packages/contracts/src/module-runtime.ts:117
    • packages/contracts/src/module-http.ts:466
    • packages/contracts/src/module-schema.ts:83
    • packages/contracts/src/module-realtime.ts:107
    • packages/module-ui-build/src/build-module-ui.ts:53, 148 (module-author diagnostics)
  • Identifiers: element ids (ekklesia-host, ekklesia-display), cookie names, CSS custom properties, data- attributes, test ids, asset paths, cache, storage and database names.

Not present

No logo, favicon, icon, web app manifest, "powered by" text, or API-rendered HTML error page exists. API errors are JSON codes.

Modules (outside the platform, same rule)

  • Ekklesia_Signage v0.1.1 src/browser/desktop-gate.tsx:23: "Open the Ekklesia Dashboard on a display at least … pixels wide…" → "Open the Dashboard on…"

🤖 Generated with Claude Code

## docs: propose ADR 0046, installation-owned branding **Stacked on #51 (ADR 0045):** both append to the ADR index on adjacent lines. Until #51 merges, this diff also shows #51's two commits; after that it is this one commit. ADR 0046 records a core principle: **Ekklesia's branding is never forced on an installation.** Anything a member, visitor or volunteer can see is configurable by the installation and removable entirely. - **Exempt:** internal identifiers, operator tooling (CLIs, Doctor, logs) and developer-only diagnostics. - **Default:** with no name configured, wording is neutral ("Sign in", not "Sign in to Ekklesia"). The default therefore names nothing, and a test can enforce it. - **Modules** follow the same rule. Report only; implementation is its own slice. ## Audit: every user-visible "Ekklesia" in the platform (at `481e801`, `main`) ### Smallest settings 1. **`EKKLESIA_INSTALLATION_NAME`** (new, optional, 1–80 characters, no control characters). Unset means neutral wording. - **Browser pages:** the API renders it into the Dashboard and display HTML at startup (the `<title>`, plus a `<meta name="ekklesia-installation-name">` the shell reads). This is the same mechanism as ADR 0045's API-origin meta tag, so the image stays generic. - **Emails:** passed to the identity notification templates. 2. **`EKKLESIA_SMTP_FROM_NAME`** (exists). When unset it falls back to `EKKLESIA_INSTALLATION_NAME`, else no display name. Stop suggesting "Ekklesia" in the examples. No other setting is needed; every string below becomes "{name}" or neutral wording. ### Dashboard (browser) | File:line | Today | With a name / without | |---|---|---| | `surfaces/shell/index.html:6` | `<title>Ekklesia</title>` | `{name}` / `Dashboard` | | `surfaces/shell/src/browser/HostApp.tsx:470` | Loading Ekklesia… | Loading {name}… / Loading… | | `surfaces/shell/src/browser/HostApp.tsx:517` | Ekklesia could not be reached. | {name} could not be reached. / The server could not be reached. | | `surfaces/shell/src/browser/HostApp.tsx:530` | button "Return to Ekklesia" | Return to {name} / Return to the Dashboard | | `surfaces/shell/src/browser/HostApp.tsx:535` | Ekklesia could not sign you out. Try again. | Signing out did not finish. Try again. (no name needed) | | `surfaces/shell/src/browser/HostApp.tsx:564` | page heading `Ekklesia` | {name} / Dashboard | | `surfaces/shell/src/browser/LoginForm.tsx:114` | Sign in to Ekklesia | Sign in to {name} / Sign in | | `surfaces/shell/src/browser/LoginForm.tsx:115` | Use your existing Ekklesia account. | Use your existing {name} account. / Use your existing account. | | `surfaces/shell/src/browser/ForgotPasswordForm.tsx:33` | If an Ekklesia account exists for that address… | If a {name} account exists… / If an account exists… | | `surfaces/shell/src/browser/ForgotPasswordForm.tsx:55` | …your Ekklesia account… | …your {name} account… / …your account… | | `surfaces/shell/src/browser/ResetPasswordForm.tsx:46` | …every existing Ekklesia session… | …every existing session… (no name needed) | | `surfaces/shell/src/browser/VerificationScreens.tsx:38` | If an unverified Ekklesia account exists… | If an unverified {name} account exists… / If an unverified account exists… | | `surfaces/shell/src/browser/VerificationScreens.tsx:119` | Sign in to Ekklesia to continue. | Sign in to {name} to continue. / Sign in to continue. | | `surfaces/shell/src/browser/VerificationScreens.tsx:140` | …and Ekklesia will send a new one. | …and a new one will be sent. (no name needed) | | `surfaces/shell/src/browser/VerificationScreens.tsx:141` | …and Ekklesia will send a new one. | as above | | `surfaces/shell/src/host-protocol.ts:66–69` | HOST_* messages ("…the Ekklesia Dashboard", "Ekklesia could not be reached", …) | **Latent:** the shell renders codes, not these messages, but module code and the console can see them. Neutral wording, no name needed. | ### Display screens | File:line | Today | With a name / without | |---|---|---| | `surfaces/shell/src/display/DisplayApp.tsx:92` | Offline — showing the last downloaded Ekklesia display | Offline — showing the last downloaded display (no name needed) | | `surfaces/shell/src/display/DisplayApp.tsx:93` | Offline — waiting for Ekklesia | Offline — waiting for {name} / Offline — waiting for the server | | `surfaces/shell/src/display/PairingScreen.tsx:140` | Enter this code in the Ekklesia dashboard… | Enter this code in the {name} Dashboard… / Enter this code in the Dashboard… | | `surfaces/shell/display.html:6` | `<title>Display</title>` | Already neutral; optionally `{name}` | ### Emails | File:line | Today | With a name / without | |---|---|---| | `core/src/identity/notifications.ts:185` | subject: Verify your Ekklesia email address | Verify your email address for {name} / Verify your email address | | `core/src/identity/notifications.ts:188, 195` | …sign in to Ekklesia. (HTML / text) | …sign in to {name}. / …sign in. | | `core/src/identity/notifications.ts:209` | subject: Reset your Ekklesia password | Reset your {name} password / Reset your password | | `core/src/identity/notifications.ts:212, 219` | …this Ekklesia account. (HTML / text) | …this {name} account. / …this account. | | Sender display name | No default; examples suggest "Ekklesia": `deploy/env/ekklesia.env.example:67`, `.env.example:83`, `docs/development/email.md:95` | Falls back to `EKKLESIA_INSTALLATION_NAME`; examples drop "Ekklesia" | ### Exempt under the ADR (listed for completeness) - **Operator tooling:** - `core/src/cli/create-initial-owner.ts:198` ("You can now sign in to the Ekklesia dashboard." Suggest the neutral "You can now sign in to the Dashboard.", no setting.) - `core/src/cli/bootstrap-platform-owner.ts:61` - `core/src/cli/doctor.ts:124` - `core/src/diagnostics/doctor-report.ts:56` - `core/src/diagnostics/doctor.ts:624` - `core/src/migrations/runner.ts:130–131` - `apps/api/src/server.ts:794, 808` - `surfaces/shell/scripts/build-browser.mjs:80, 88` - **Developer-only thrown errors:** - `surfaces/shell/src/browser/main.tsx:35` - `surfaces/shell/src/display/main.tsx:17` - `surfaces/shell/src/display/offline-cache.ts:252` - `surfaces/shell/src/display/sw.ts:73` - `packages/contracts/src/module-runtime.ts:117` - `packages/contracts/src/module-http.ts:466` - `packages/contracts/src/module-schema.ts:83` - `packages/contracts/src/module-realtime.ts:107` - `packages/module-ui-build/src/build-module-ui.ts:53, 148` (module-author diagnostics) - **Identifiers:** element ids (`ekklesia-host`, `ekklesia-display`), cookie names, CSS custom properties, `data-` attributes, test ids, asset paths, cache, storage and database names. ### Not present No logo, favicon, icon, web app manifest, "powered by" text, or API-rendered HTML error page exists. API errors are JSON codes. ### Modules (outside the platform, same rule) - `Ekklesia_Signage` v0.1.1 `src/browser/desktop-gate.tsx:23`: "Open the Ekklesia Dashboard on a display at least … pixels wide…" → "Open the Dashboard on…" 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Zayin_Admin added 3 commits 2026-10-03 18:29:20 +00:00
Records how an installation runs the Dashboard and the API on sibling
hostnames (dash./api.) beside the default same-origin topology, from one
image: the API origin reaches the Dashboard at run time in a meta element,
the display host stays on the API's origin (device cookies and the offline
code cache depend on it), the API trusts its own origin as Better Auth
already does, cookies stay host-only, CORS stays narrow and becomes part of
the module UI contract, the reference proxy gains per-hostname routing, and
the deploy smoke test proves both topologies, the split one in a real
browser.

Amends ADR 0034 and extends ADR 0044.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
docs: state exactly what ADR 0045's browser smoke proves
CI / verify (pull_request) Successful in 51s
CI / infrastructure-smoke (pull_request) Successful in 13s
CI / migration-smoke (pull_request) Successful in 1m48s
CI / image-build (pull_request) Successful in 18s
CI / deploy-smoke (pull_request) Successful in 42s
55accd0e65
Co-Authored-By: Claude Opus 5.5 <[email protected]>
docs: propose ADR 0046, installation-owned branding
CI / verify (pull_request) Successful in 51s
CI / infrastructure-smoke (pull_request) Successful in 21s
CI / migration-smoke (pull_request) Successful in 1m40s
CI / image-build (pull_request) Successful in 18s
CI / deploy-smoke (pull_request) Successful in 48s
8ea4d4d2e4
Records a core principle: Ekklesia's branding is never forced on an
installation. Anything a member, visitor, or volunteer can see (titles,
sign-in and auth screens, emails, display and offline screens, error
messages, app names and icons, attribution) is configurable and removable
entirely. With no name configured, wording is neutral, so the default
names nothing and the rule is testable. Internal identifiers, operator
tooling, and developer diagnostics are exempt. Modules follow the same
rule.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Zayin_Admin force-pushed docs/adr-0046-installation-branding from 5b78ee0ffb to 8ea4d4d2e4 2026-10-03 18:29:20 +00:00 Compare
Joey approved these changes 2026-10-03 18:42:48 +00:00
Joey added 1 commit 2026-10-03 18:43:03 +00:00
Merge branch 'main' into docs/adr-0046-installation-branding
CI / verify (pull_request) Successful in 52s
CI / infrastructure-smoke (pull_request) Successful in 12s
CI / migration-smoke (pull_request) Successful in 1m48s
CI / image-build (pull_request) Successful in 7s
CI / deploy-smoke (pull_request) Successful in 42s
38cf52757d
Author
Member

Rebased onto main after #52 (b642d8f), stacked on the rebased #51, and force-pushed. Until #51 merges, the diff also shows #51's two commits; this PR's own commit is 8ea4d4d.

CI is green on 8ea4d4d: verify, infrastructure-smoke, migration-smoke, image-build, deploy-smoke.

Rebased onto `main` after #52 (`b642d8f`), stacked on the rebased #51, and force-pushed. Until #51 merges, the diff also shows #51's two commits; this PR's own commit is `8ea4d4d`. CI is green on `8ea4d4d`: verify, infrastructure-smoke, migration-smoke, image-build, deploy-smoke.
Joey merged commit cbf5962d04 into main 2026-10-03 18:54:46 +00:00
Joey deleted branch docs/adr-0046-installation-branding 2026-10-03 18:54:46 +00:00
Sign in to join this conversation.
No Reviewers
No labels
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Zayin/Ekklesia#53