docs: add CLAUDE.md and mark display management as transitional

Signage had no agent guidance at all. Add a CLAUDE.md that records the
standalone-module architecture, that the parent ROADMAP.md and DESIGN.md are
authoritative, the ownership, branding, token, dark-mode, no-native-dialog and
plain-language rules, that display pairing is transitional until Stage 1
Settings -> Displays, and the branch-per-PR, no-push-to-main, no-release-tag
workflow.

The README listed a mobile management UI as out of scope, which contradicts
the design contract's responsive requirement; it is a Stage 1 deferral, and
now says so alongside how displays work today.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ekklesia
2026-10-12 21:32:04 -05:00
co-authored by Claude Opus 5.5
parent 86d49846ff
commit 6bf9167f85
2 changed files with 102 additions and 3 deletions
+82
View File
@@ -0,0 +1,82 @@
# CLAUDE.md
Guidance for Claude Code (and other coding agents) working in this repository. It points at
authoritative sources rather than restating them, because restated details drift. Inspect the actual
source, tests, `package.json`, and CI workflow before relying on anything here or on memory of a
prior session.
## What this repository is
Signage is a first-party Ekklesia **module** in its own repository (`Zayin/Signage`). It is not part of
the platform monorepo and vendors none of it: it builds against the published `@ekklesia/*`
module-development packages (platform ADRs 0053 and 0054), ships as one Ekklesia Module Package
(ADR 0049), and reaches PostgreSQL only through the Module Database ABI v1 executor the host hands it
(ADR 0050). Read `README.md` for what exists and the scope boundaries.
Signage owns its domain: channel groups, audience channels, timelines, slots, signage assignments,
playback rules, native images, and **its own management and display UI**. The platform shell hosts
that UI through the generic module loader and never rebuilds it; do not move Signage screens into the
platform.
## 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` in the standard
`~/development/ekklesia/` layout). They are deliberately **not** committed here; do not copy them in.
They are authoritative for product direction. If this repository's documentation disagrees with them,
flag the conflict and correct the repository-local documentation; never silently follow stale text.
Rules from those documents that apply to every change here:
- **Shared resources belong to the platform.** Displays/devices, identity, branding, mail, storage,
and module lifecycle are the platform's. Signage *consumes* displays; it assigns content to them.
- **The current display management is transitional.** Signage's viewer roster, display naming, and
pairing instructions, together with the platform's sidebar *Display devices* panel, are what exists
today. Stage 1 moves pairing and the one global display name to the platform's
**Settings → Displays**, and Signage then selects an existing display. Fix defects in the current
flow, keep existing paired displays, viewer identities, cached content, and assignments working, and
do **not** implement the Stage 1 Settings/Displays architecture early.
- **Branding.** Normal user-facing UI never hard-codes "Ekklesia" (platform ADR 0046).
- **Visual direction.** Simple and minimal; responsive; light, dark, and system modes. Normal UI
colours come only from the shared design tokens (`@ekklesia/design-tokens`) and shared elements
(`@ekklesia/ui`) — never a hard-coded colour. The display artifact's pure-black stage, blackout,
and slate are content presentation, not themed UI.
- **No browser-native dialogs.** `window.alert`, `window.confirm`, and `window.prompt` are prohibited.
Destructive actions use in-product confirmation proportional to impact: a two-step in-place
confirmation for moderate actions, the shared `Dialog` for significant ones.
- **Plain language.** Normal church staff must understand the UI without implementation terms; do not
expose an internal identifier merely because it exists.
## ADRs
`docs/architecture/decisions/` holds Signage's own ADRs; the platform's ADRs live in the Ekklesia
repository. Accepted ADRs are immutable except for status and cross-reference corrections. A changed
decision gets a new ADR that supersedes the old one; never rewrite a historical ADR to fit a change.
## Working conventions
- Canonical remote: `ssh://[email protected]:2222/Zayin/Signage.git` (the platform is
`Zayin/Ekklesia.git`). Local clones can be behind: `git fetch --prune --tags` and branch from
`origin/main`.
- One branch per PR off an up-to-date `origin/main`. Never push to `main`, never merge your own PR,
and never create or push a release tag — release tags belong to the human maintainer.
- A fix that needs a platform contract change is two PRs: the Ekklesia change first, then Signage,
with the compatibility boundary explicit. Do not copy platform logic into Signage to avoid it.
- Every defect fix gets a regression test. Signage never reads the environment, opens its own socket,
builds an Ekklesia URL, or applies a migration; all of that reaches it through the host.
## Verification
`package.json` and `.gitea/workflows/ci.yml` are the source of truth. From a clean checkout:
```bash
pnpm install --frozen-lockfile
pnpm lint && pnpm typecheck && pnpm test && pnpm build && pnpm validate
bash ci/check-cleanup.sh
```
The CI `integration` job installs the real Module Package into the pinned platform
(`ci/platform.env`) and drives the Dashboard and a kiosk display in real browsers, running the display
scenarios listed in `ci/display-scenarios` (`bash ci/package.sh`, `bash ci/fetch-platform.sh`,
`bash ci/integration.sh`; it needs Docker). Unit tests passing is not evidence that a display or
browser behaviour works: verify display behaviour through the integration harness.
+20 -3
View File
@@ -139,8 +139,25 @@ description of the platform ABI.
| Transitions, offline continuation, playback controls | Dynamic change within one slide |
| The management and display UI | Its own internal multi-stage behaviour |
## Displays today, and what Stage 1 changes
Displays are platform-owned. What exists now is transitional: a screen is paired in the Dashboard
sidebar's *Display devices* panel, and Signage keeps its own roster of the screens that have checked
in — their names, the group and audience each is assigned to, and their health. A running display
follows its assignment as soon as an administrator changes it, and a revoked display returns to its
pairing code. Entries for screens that are offline (a retired television, a test tab) can be removed
from the roster.
The product roadmap moves pairing and the one global display name to the platform's
**Settings → Displays** in Stage 1; Signage will then select an existing display instead of naming its
own. Until then, existing paired displays, their viewer identities, cached content, and assignments are
preserved across every Signage upgrade.
The management screen is currently desktop-only (the narrow-screen notice below 1024 px). The product
design requires phone and tablet administration and dark mode; that arrives with the Stage 1 shared
responsive Dashboard and design system rather than as a Signage-only layout.
## Licence and scope
Deployment, the module store, a theme editor, a mobile management UI, video and audio, MQTT, Home
Assistant, Companion, and any migration of legacy Announcements data are explicitly out of scope for
this repository.
Deployment, the module store, a theme editor, video and audio, MQTT, Home Assistant, Companion, and any
migration of legacy Announcements data are explicitly out of scope for this repository.