feat: initial Signage 0.1.0

This commit is contained in:
ekklesia
2026-08-28 16:41:54 -05:00
parent 20756f11af
commit 92bef4c7aa
107 changed files with 24397 additions and 0 deletions
@@ -0,0 +1,62 @@
# 0004: A channel group is one clock; an audience channel is one rendering of it
- Status: Accepted
- Date: 2026-08-27
- Related: [0002](0002-content-provider-contract.md), [0005](0005-authoritative-playback.md)
## Context
A church wants the lobby screens, the sanctuary side screens, and the online stream overlay to be on
the same slide at the same moment — but the online audience should see "watching from home" wording
where the room sees "welcome in". That is one program with two renderings, not two programs.
It also wants the nursery hallway to run a completely different loop. That *is* two programs.
## Decision
**A channel group owns exactly one authoritative timeline clock.** It has one active timeline, one
current slot, one start instant, one deadline, one pause state, one blackout state, and one pending
activation. Everything a group's channels do, they do together.
**A channel is an audience within a group.** Each has a `key` (`default`, `in-person`, `online`, …),
and exactly one channel per group is the default. Channels differ in exactly one way: which variant of
a resolved selection they render.
- Signage resolves **one logical selection per slot occurrence**, for the whole group.
- The provider is asked once, with every audience key the group has.
- Each channel renders the variant matching its key, or the default variant if the provider offered
none.
A truly independent clock requires another channel group. There is no per-channel pause, no
per-channel skip, and no per-channel timeline — and no route that could express one.
**One default channel is created automatically**, and no other. `in-person` and `online` are examples
in a document, not rows in a migration: a church that never needs a second audience never sees one.
**A viewer never chooses its channel.** A display registers with its persistent viewer identity and
joins the default channel of the default group; an administrator moves it from the management
dashboard. A public display that could pick its own channel would let anyone who reaches the page
select what a screen shows.
## Consequences
- Two viewers that connected minutes apart render the same slot with the same deadline, because both
read the same persisted absolute instants rather than counting from when they arrived.
- Adding an audience is additive: the provider starts returning a second variant, and the default
channel is unaffected.
- A provider that returns no variant for `online` is not a failure and produces no warning. Returning
the default is the contract.
- "Pause the lobby but not the sanctuary" is impossible by construction, and correctly so — those are
two groups.
## Alternatives
- **One clock per channel, synchronized by convention.** Rejected: two clocks drift, and no amount of
correction makes two televisions in one room agree.
- **Per-channel timelines with a shared cursor.** Rejected: the cursor is only meaningful against one
pattern; two patterns of different length make "the same slot" undefined.
- **Let the display pick its audience from a query parameter.** Rejected: it is an unauthenticated
content selector on a screen in a public hallway.
- **Create `in-person` and `online` channels on install.** Rejected: it presumes a broadcast ministry
every church does not have, and an unused channel is a thing an operator has to understand and
ignore forever.