Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
018c6a8
E: dexd — the player, its documentation and the checks that keep both…
eins78 Aug 19, 2026
164fed8
E: dexd and dex-loop cannot be co-installed — declare it
eins78 Aug 24, 2026
29fda90
E: the auto-mode warning names both ways it fails
eins78 Aug 24, 2026
023d2a4
D: the display-mode traps a deployed card found
eins78 Aug 24, 2026
47dff50
E: the example video is artwork.265 everywhere
eins78 Aug 24, 2026
90d4315
E: docs-lint — a cross-reference that does not resolve is an error
eins78 Aug 24, 2026
0200980
E: CI asserts the package declares its conflict with dex-loop
eins78 Aug 24, 2026
7fcee51
D: /opt/dex is a directory on the player, not a partition in a laptop
eins78 Aug 24, 2026
e737cc7
D: the two dead ends a reader hits first
eins78 Aug 24, 2026
2fac036
D: three pieces of advice that produce the fault they cure
eins78 Aug 24, 2026
f7b9020
E: the writing check reads the workflow that runs it
eins78 Aug 24, 2026
b134ec2
D: the facts the set disagreed with itself about
eins78 Aug 24, 2026
90b1958
D: the two journeys reach an end
eins78 Aug 24, 2026
fc1b39c
D: the video plays at the wrong size, not the artwork
eins78 Aug 24, 2026
4264866
D: the last read before this is public
eins78 Aug 24, 2026
64ac58b
D: the partition claim had three more places to hide
eins78 Aug 24, 2026
35b4908
D: dexOS already has the data partition; a dexd card does not
eins78 Aug 24, 2026
6f97b27
D: the releases page is where releases are; dexd has not had one
eins78 Aug 24, 2026
7e61897
D: a measured label that the measurement record cannot support
eins78 Aug 24, 2026
26cedb0
D: six vocabulary decisions, taken by the owner
eins78 Aug 24, 2026
56c6fcf
D: the conservation vocabulary, a documentation index, and two measur…
eins78 Aug 24, 2026
ee311ac
E: the setup guide becomes Install dexOS
eins78 Aug 24, 2026
0b949d2
E: docs-lint — a workflow's names are prose, and a path is not
eins78 Aug 24, 2026
68af979
E: a deployed card runs read-only; say so, and what it costs an edit
eins78 Aug 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# The glossary and the writing rules are approved by the project owner, entry by entry.
# Branch protection requires a code-owner review for these paths, so no change lands without him.
docs/glossary.md @eins78
docs/lint-coinages.tsv @eins78
docs/lint-allow.txt @eins78
AGENTS.md @eins78
544 changes: 544 additions & 0 deletions .github/workflows/dexd.yml

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
[submodule "packages/pi-gen"]
path = packages/pi-gen
url = https://github.com/eins78/pi-gen
[submodule "packages/dexd"]
path = packages/dexd
url = https://github.com/eins78/dexd
[submodule "packages/branding"]
path = packages/branding
url = https://github.com/KTE/dex-branding
Expand Down
224 changes: 224 additions & 0 deletions AGENTS.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
136 changes: 73 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,82 @@
# `dex` project
# dex

packages:
dexd is built to play the video of an installation on a Raspberry Pi, unattended, for weeks. This repository
holds dexd and the parts around it.

* [dex OS](./packages/dex-os/README.md)
* [example content](./packages/example-content/README.md)
* [branding](./packages/branding/README.md)
If you are setting up a player, start with [What dexd is](docs/guides/what-dexd-is.md). [The documentation index](docs/README.md) maps both sets of pages, for a technician and for a developer.

## getting started
## Packages

Build a dex player by flashing the image to an SD card,
using the official [Raspberry Pi Imager](https://www.raspberrypi.org/software/).
| Path | What it is |
|---|---|
| [`packages/dexd`](packages/dexd/README.md) | The player: gapless 4K HEVC looper for Raspberry Pi 4, shipped as a Debian package. Documentation in `docs/guides/` and `docs/design/`. |
| `packages/dex-os` | dexOS, dex's own Raspberry Pi OS image; it currently plays videos with pi_video_looper, not dexd. |
| `packages/example-content` | The test cards: short videos with a frame counter, colour bars and a checkerboard border. They show whether a player displays the picture correctly and loops gaplessly. |
| `packages/branding` | The project's colour palette and design sketches. |
| `packages/website` | The project site, <https://dex.ars.is>. |
| `packages/pi-gen` | Raspberry Pi's official tool for building OS images in stages; dexOS is a pi-gen build. |
| `packages/pi_video_looper` | Adafruit's Python video-looping framework. |

Then boot the Raspberry Pi with the SD card.
It it worked, it will show a 2-second demo video loop.

### advanced

For customizing the player/operating system,
ssh access needs to be enabled.

This can be done using the "customization" feature of the Raspberry Pi Imager,
choosing "Enable SSH" in the "Advanced Options". It is recommended to use key-based authentication.
The user name in the image is `dex` should not be changed, the default password is also `dex` and should be changed if SSH login is enabled and password authentication is used.

Then, after booting the Raspberry Pi, ssh into it:

```sh
ssh dex@dexpi # or another hostname if you changed it in the customization
```

## development

### creating patches

Upstream repos like `pi-gen` are not forked directly,
rather a series of patches is maintained.
This makes the list of changes we make self-documenting,
and over time should be easier than maintaining a regular fork using `git`.

Good tutorials on using `quilt`:

* <https://raphaelhertzog.com/2012/08/08/how-to-use-quilt-to-manage-patches-in-debian-packages/>
* <https://wiki.debian.org/UsingQuilt>

```sh
quilt new "99-name-of-my-patch"
quilt add ./packages/some-upstream-code/some-file
# edit ./packages/some-upstream-code/some-file
quilt refresh # patchfile is added to ./patches and patch name is added to ./patches/series
quilt rename "99-better-name-of-my-patch"
```

editing existing patches:
The player, the OS image and the website live in this repository, so one commit changes the player,
its packaging and the OS image together. The other four — `branding`, `example-content`, `pi-gen`
and `pi_video_looper` — are git submodules, pointers to separate repositories. Clone the
repository, then fill the submodules in:

```sh
PATCH_NAME="project/99-name-of-my-patch"
quilt add -P "$PATCH_NAME" ./packages/some-upstream-code/some-file
# edit ./packages/some-upstream-code/some-file
quilt refresh "$PATCH_NAME" # patchfile is updated in ./patches
git clone https://github.com/KTE/dex.git
cd dex
git submodule update --init
```

## housekeeping

### update pi-gen repo

```sh
cd packages/pi-gen
git remote add upstream https://github.com/RPi-Distro/pi-gen
git fetch upstream
git push --mirror origin
```
## Guides

Read these to build a player and keep it running. They assume you can use a terminal, and nothing
about video or Linux.

1. [What dexd is](docs/guides/what-dexd-is.md) — what the player does and what it needs.
2. [Install dexOS](docs/guides/install-dexos.md) — from a blank SD card to a booted player.
3. [Prepare your video](docs/guides/prepare-video.md) — turning the video you exported into the `.265` file and sidecar dexd accepts.
4. [Configure the exhibit](docs/guides/configure-exhibit.md) — the one file that names the video, the display mode and the connector.
5. [Run, check, troubleshoot](docs/guides/run-check-troubleshoot.md) — starting the player, reading the system log, and going from a symptom to a fix.
6. [Reference](docs/guides/reference.md) — config keys, sidecar keys, exit codes, file paths and every refusal message with its fix.

The package installs man pages for `dexd`, `dex-exhibit-apply` and `dex-wait-hdmi`. Build
`dex-sidecar` from source on the computer where you prepare the video; from the repository root,
read its page with `man ./packages/dexd/deploy/man/dex-sidecar.1`.

## Design documents

Read these to change the player. They assume a Linux or Rust developer who has not seen the
project.

| Page | Subject |
|---|---|
| [Architecture](docs/design/architecture.md) | The layers from Rust down to the display. |
| [The endless stream](docs/design/endless-stream.md) | How playback repeats without reaching the end of the file. |
| [Startup checks](docs/design/startup-checks.md) | What dexd verifies before it plays, and the exit codes. |
| [Failure handling](docs/design/failure-handling.md) | How a running player detects that it stopped showing pictures, and what it does then. |
| [The systemd unit](docs/design/service-unit.md) | Every setting in `dexd.service` and the scripts around it. |
| [Asset binding](docs/design/sidecar.md) | The sidecar file that records the video's frame rate and checksum, and the check that reads it. |
| [Exhibit config](docs/design/exhibit-config.md) | The per-installation file: grammar, refusals and the kernel command line `dex-exhibit-apply` derives from it. |
| [Packaging](docs/design/packaging.md) | What the `.deb` contains, and where it installs. |
| [Continuous integration](docs/design/ci.md) | What the workflow builds and asserts. |
| [Building and testing dexd](docs/design/development.md) | Build commands, test layers and their safety rules. |
| [Raspberry Pi media capability](docs/design/pi-capability.md) | What each Raspberry Pi generation can decode and display. |
| [Roadmap](docs/design/roadmap.md) | What is decided but not built, and what is out of scope. |
| [Measurement record](docs/design/measurements.md) | Every number the documentation relies on, and how it was established. |

## Vocabulary

[docs/glossary.md](docs/glossary.md) is the term list for this repository. Entries marked *user*
are the technical words the guides use without explaining them; entries marked *developer* are used
only in the pages under `docs/design/`. A word in neither list is plain English or is explained
where it is used. The writing rules are in [AGENTS.md](AGENTS.md).

## Licence

dexd's source, packaging and documentation are under the MIT-0 licence. The project's content —
test cards, video masters, branding — is under CC0-1.0. Both allow any use, with no attribution and no
conditions. Because the installed package links Debian's mpv library, the binary you install ships
under GPL-3+ — see [Packaging](docs/design/packaging.md). The submodules that point at other
projects, `pi-gen` and `pi_video_looper`, carry their own upstream licences, which the lines above
do not cover.
59 changes: 59 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# dexd documentation

Two sets of pages, for two readers.

[Guides](guides/) are for a venue technician: someone setting up a player, with no Rust
and no video engineering assumed. They run in order, and each says what it needs from the
one before.

[Design](design/) is for a developer new to the project: how the player is built, what
each decision rests on, and what is still open. They can be read in any order; the grouping
below is the order that needs the least backtracking.

The [glossary](glossary.md) defines every term either set uses that is not plain
English, marked by which reader it is for.

## Guides, in order

1. [What dexd is](guides/what-dexd-is.md) — what the player does, what it needs, and what it does not do.
2. [Install dexOS](guides/install-dexos.md) — from a blank SD card to a booted player.
3. [Prepare your video](guides/prepare-video.md) — turning the file the artist gave you into the `.265` and its sidecar.
4. [Configure the exhibit](guides/configure-exhibit.md) — the one file naming the video, the display mode and the connector.
5. [Run, check, troubleshoot](guides/run-check-troubleshoot.md) — starting the player, reading the system log, and going from a symptom to a fix.
6. [Reference](guides/reference.md) — every config key, exit code, file path and refusal message, with its fix.

## Design

### The shape of it

- [Architecture](design/architecture.md) — the layers from decoder to screen, and why the frame never leaves the plane.
- [Building and testing dexd](design/development.md) — the two machines, what each can run, and what a change must satisfy before it lands.

### How the loop holds

- [The endless stream](design/endless-stream.md) — why the video is fed as a stream that never ends rather than looped by the player.
- [The sidecar check](design/sidecar.md) — how a video is bound to its frame rate and checksum, and what happens when they disagree.
- [Startup checks](design/startup-checks.md) — everything dexd refuses to start on, in the order it checks.

### How it stays up

- [Failure handling](design/failure-handling.md) — what answers a fault, in order, and which of them are built.
- [The systemd unit](design/service-unit.md) — what starts the player, restarts it, and keeps the console off the display.

### How it is configured

- [Exhibit config](design/exhibit-config.md) — the file's grammar, the decision tables behind it, and the checks it feeds.

### How it ships

- [Packaging](design/packaging.md) — what the `.deb` contains, what it depends on, and what it does not install.
- [Continuous integration](design/ci.md) — which jobs run when, and what a green run does and does not prove.

### What the claims rest on

- [Measurement record](design/measurements.md) — every number the other pages cite, with the conditions it was taken under.
- [Raspberry Pi media capability](design/pi-capability.md) — what each board can decode and present, with the sources.

### What is not settled

- [Roadmap and open questions](design/roadmap.md) — what is planned, what is undecided, and what was rejected.
Loading
Loading