<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Decisions on EdS</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/</link><description>Recent content in Decisions on EdS</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://cdeever.github.io/eds/docs/architecture/decisions/index.xml" rel="self" type="application/rss+xml"/><item><title>ADR-0001: The Stand Renders Effects</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0001-device-renders-effects/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0001-device-renders-effects/</guid><description>&lt;h1 id="adr-0001-the-stand-renders-effects-locally-and-never-receives-frames"&gt;ADR-0001: The Stand Renders Effects Locally and Never Receives Frames&lt;a class="anchor" href="#adr-0001-the-stand-renders-effects-locally-and-never-receives-frames"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-09-07&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What travels from &lt;code&gt;lightd&lt;/code&gt; to a stand, and where animation happens.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Backfilled&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Decided with the first firmware and argued in &lt;code&gt;firmware/lp-stand/README.md&lt;/code&gt;; written up here on 2026-10-10.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0002-gamma-in-firmware/"&gt;ADR-0002&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/reference/scene-descriptor/"&gt;Scene Descriptor&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The stand is an ESP32 driving an addressable strip over WiFi from a broker it&#10;does not control. The light has to look deliberate at all times, including&#10;when the network is slow or gone, and the stand is meant to sit on a shelf&#10;unattended.&lt;/p&gt;</description></item><item><title>ADR-0002: Gamma Belongs to the Firmware</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0002-gamma-in-firmware/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0002-gamma-in-firmware/</guid><description>&lt;h1 id="adr-0002-gamma-belongs-to-the-firmware-not-the-wire"&gt;ADR-0002: Gamma Belongs to the Firmware, Not the Wire&lt;a class="anchor" href="#adr-0002-gamma-belongs-to-the-firmware-not-the-wire"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-09-07&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Which layer makes which color decision between a cover image and the strip.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Backfilled&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Decided with the first vertical and argued in the project READMEs and &lt;a href="https://cdeever.github.io/eds/docs/architecture/boundaries/"&gt;Boundaries&lt;/a&gt;; written up here on 2026-10-10.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Corrected&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-13: the consequence about OKLab said the conversion is implemented three times, in Python, Go and C. It is in two, and never was in the firmware. The decision is unchanged.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0001-device-renders-effects/"&gt;ADR-0001&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;A color passes through three programs on its way from a sleeve to a strip:&#10;&lt;code&gt;palette&lt;/code&gt; extracts it, &lt;code&gt;lightd&lt;/code&gt; turns swatches into a scene, and the firmware&#10;drives the LEDs. Several corrections have to happen somewhere along the way —&#10;rejecting dull swatches, boosting chroma, mapping into the strip&amp;rsquo;s gamut, and&#10;gamma, because WS2812 output is linear in duty cycle and perception is not.&lt;/p&gt;</description></item><item><title>ADR-0003: The Broker Is Deevnet IoTaaS's</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0003-broker-is-the-substrates/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0003-broker-is-the-substrates/</guid><description>&lt;h1 id="adr-0003-the-mqtt-broker-is-deevnet-iotaass-not-a-tenant-vm"&gt;ADR-0003: The MQTT Broker Is Deevnet IoTaaS&amp;rsquo;s, Not a Tenant VM&lt;a class="anchor" href="#adr-0003-the-mqtt-broker-is-deevnet-iotaass-not-a-tenant-vm"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-09-07&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where EdS&amp;rsquo;s MQTT broker runs, and so how devices and services meet.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Backfilled&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Decided when the tenant was first written and argued in &lt;code&gt;infra/deevnet-tenant-eds/README.md&lt;/code&gt;; written up here on 2026-10-10.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Deevnet ADR-0001, ADR-0003 and ADR-0012 (&lt;a href="https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/"&gt;deevnet-docs&lt;/a&gt;)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;EdS&amp;rsquo;s services run on a workload in its own tenant on Deevnet IoTaaS.&#10;Its devices are ESP32s on Deevnet IoTaaS&amp;rsquo;s IoT network. Both need a broker.&lt;/p&gt;</description></item><item><title>ADR-0004: Firmware Secrets Are NVS-Only</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0004-firmware-secrets-nvs-only/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0004-firmware-secrets-nvs-only/</guid><description>&lt;h1 id="adr-0004-firmware-secrets-are-nvs-only-and-the-brokers-ca-is-provisioned"&gt;ADR-0004: Firmware Secrets Are NVS-Only, and the Broker&amp;rsquo;s CA Is Provisioned&lt;a class="anchor" href="#adr-0004-firmware-secrets-are-nvs-only-and-the-brokers-ca-is-provisioned"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where a device&amp;rsquo;s WiFi key, broker password and broker CA come from.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0001-lp-stand-joins-its-tenant/"&gt;CHG-0001&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/guide/provisioning/"&gt;Provisioning a Stand&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The stand needs a WiFi key and a broker password, both issued by the EdS&#10;tenant, and the CA that the broker&amp;rsquo;s certificate is verified against. The&#10;repository is public, and the firmware image gets built, cached and copied.&lt;/p&gt;</description></item><item><title>ADR-0005: Device Events Over MQTT</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0005-device-events-over-mqtt/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0005-device-events-over-mqtt/</guid><description>&lt;h1 id="adr-0005-a-device-reports-key-events-over-mqtt-not-its-serial-log"&gt;ADR-0005: A Device Reports Key Events Over MQTT, Not Its Serial Log&lt;a class="anchor" href="#adr-0005-a-device-reports-key-events-over-mqtt-not-its-serial-log"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How an EdS device says what it is doing once the USB cable is gone, and how that is read.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0017-an-agent-pi-is-a-registered-device/"&gt;ADR-0017&lt;/a&gt;: an agent Pi is registered as a device and reports the same way&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0001-lp-stand-joins-its-tenant/"&gt;CHG-0001&lt;/a&gt;, Deevnet ADR-0027 and CHG-0021 (&lt;a href="https://deevnet.github.io/deevnet-docs/"&gt;deevnet-docs&lt;/a&gt;), &lt;a href="https://cdeever.github.io/eds/docs/reference/mqtt-topics/"&gt;MQTT Topics&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;A stand on a shelf has no console. It fails soft by design, which makes its&#10;failures quiet: one that keeps showing the last good scene looks, from the&#10;room, exactly like one that was sent nothing.&lt;/p&gt;</description></item><item><title>ADR-0006: Now Playing Is a Bus of Small Drivers</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/</guid><description>&lt;h1 id="adr-0006-now-playing-is-a-bus-of-small-drivers-behind-one-contract"&gt;ADR-0006: Now Playing Is a Bus of Small Drivers Behind One Contract&lt;a class="anchor" href="#adr-0006-now-playing-is-a-bus-of-small-drivers-behind-one-contract"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How EdS learns what is playing across several players, and how that knowledge reaches whatever reacts to it.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;: a controller may send a command for the current track, and a driver that can carry one out reads its own command topic&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0003-broker-is-the-substrates/"&gt;ADR-0003&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0007-drivers-are-portable-go/"&gt;ADR-0007&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;, and one record per player: &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0011-itunes-by-remote-pairing/"&gt;0011&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/"&gt;0012&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0013-musicbee-by-remote-protocol/"&gt;0013&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0014-tidal-by-lastfm/"&gt;0014&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The stand lights from a cover image, but nothing tells EdS what is playing.&#10;&lt;code&gt;lightd&lt;/code&gt; has carried &lt;code&gt;POST /v1/cover&lt;/code&gt; since the first vertical as &amp;ldquo;the&#10;interface the future album-cover resolver will call&amp;rdquo;; this is what sits&#10;upstream of it.&lt;/p&gt;</description></item><item><title>ADR-0007: Drivers Are Portable Go</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0007-drivers-are-portable-go/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0007-drivers-are-portable-go/</guid><description>&lt;h1 id="adr-0007-drivers-are-portable-go-in-one-agent-binary"&gt;ADR-0007: Drivers Are Portable Go, in One Agent Binary&lt;a class="anchor" href="#adr-0007-drivers-are-portable-go-in-one-agent-binary"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The language and packaging of the now-playing drivers and backend.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The players run on Windows 11, which pulls toward Windows tooling. But&#10;development happens on a Mac against the Deevnet Mobile site, some drivers&#10;will run on a Raspberry Pi and some on the tenant workload, and &lt;code&gt;lightd&lt;/code&gt; is&#10;already Go.&lt;/p&gt;</description></item><item><title>ADR-0008: nowplayd Picks the Track and Guarantees the Fields</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/</guid><description>&lt;h1 id="adr-0008-nowplayd-picks-the-current-track-and-guarantees-title-album-and-art"&gt;ADR-0008: nowplayd Picks the Current Track and Guarantees Title, Album and Art&lt;a class="anchor" href="#adr-0008-nowplayd-picks-the-current-track-and-guarantees-title-album-and-art"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What turns several sources&amp;rsquo; states into one current track, and who is responsible for the fields subscribers rely on.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt;: a source can be named as reported without its cover, and then the promise of art does not apply to it&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0009-lightd-takes-covers-from-a-topic/"&gt;ADR-0009&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Several drivers may report at once: a paused iTunes, a Spotify playing on a&#10;phone. Subscribers want one answer. They also need a title, an album and a&#10;cover, and the drivers cannot all supply those: TIDAL through Last.fm arrives&#10;with no art, and a locally read TIDAL has no album.&lt;/p&gt;</description></item><item><title>ADR-0009: lightd Takes Covers From a Topic</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0009-lightd-takes-covers-from-a-topic/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0009-lightd-takes-covers-from-a-topic/</guid><description>&lt;h1 id="adr-0009-lightd-takes-covers-from-a-topic-as-a-second-input"&gt;ADR-0009: lightd Takes Covers From a Topic as a Second Input&lt;a class="anchor" href="#adr-0009-lightd-takes-covers-from-a-topic-as-a-second-input"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How the current track&amp;rsquo;s cover reaches &lt;code&gt;lightd&lt;/code&gt;.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0019-an-album-can-have-a-look-of-its-own/"&gt;ADR-0019&lt;/a&gt;: a cover may arrive with the name of a look, which &lt;code&gt;lightd&lt;/code&gt; draws in place of the cover&amp;rsquo;s own colors&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0002-gamma-in-firmware/"&gt;ADR-0002&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;nowplayd&lt;/code&gt; publishes the current cover as image bytes on&#10;&lt;code&gt;eds/nowplaying/current/art&lt;/code&gt;. &lt;code&gt;lightd&lt;/code&gt; turns image bytes into a scene, and&#10;today takes them only over HTTP, at &lt;code&gt;POST /v1/cover&lt;/code&gt;. Something has to carry&#10;the bytes from the topic to &lt;code&gt;lightd&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>ADR-0010: A Dual-Homed Pi Relays the Home LAN</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/</guid><description>&lt;h1 id="adr-0010-home-lan-drivers-reach-the-broker-through-a-dual-homed-mobile-pi"&gt;ADR-0010: Home-LAN Drivers Reach the Broker Through a Dual-Homed Mobile Pi&lt;a class="anchor" href="#adr-0010-home-lan-drivers-reach-the-broker-through-a-dual-homed-mobile-pi"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How a driver that must be near a player on the home LAN reaches the broker at the Deevnet Mobile site.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0015-eds-builds-its-own-pi-images/"&gt;ADR-0015&lt;/a&gt;: the image is EdS&amp;rsquo;s own, and a relay is a way of configuring it&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0003-broker-is-the-substrates/"&gt;ADR-0003&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;, the Deevnet network segmentation standard (&lt;a href="https://deevnet.github.io/deevnet-docs/"&gt;deevnet-docs&lt;/a&gt;)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The Windows PCs that run iTunes and MusicBee sit on a home LAN. The broker&#10;is inside the Deevnet Mobile site. There is no path from the home LAN into&#10;the site, and the site&amp;rsquo;s workloads cannot reach private addresses outside&#10;it. The iTunes and MusicBee drivers speak network protocols to their&#10;players, and pairing with iTunes needs multicast, so they have to be on the&#10;players&amp;rsquo; LAN.&lt;/p&gt;</description></item><item><title>ADR-0011: iTunes by Remote Pairing</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0011-itunes-by-remote-pairing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0011-itunes-by-remote-pairing/</guid><description>&lt;h1 id="adr-0011-itunes-is-read-by-remote-pairing-the-way-the-phone-remote-does-it"&gt;ADR-0011: iTunes Is Read by Remote Pairing, the Way the Phone Remote Does It&lt;a class="anchor" href="#adr-0011-itunes-is-read-by-remote-pairing-the-way-the-phone-remote-does-it"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10; 2026-10-10, after pairing with the real iTunes; see &lt;a href="#evidence"&gt;Evidence&lt;/a&gt;. Opened the same day as &lt;code&gt;Proposed&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How the iTunes driver learns of track changes and gets artwork.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;: the pairing is also used to play, pause, skip and set the volume&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0007-drivers-are-portable-go/"&gt;ADR-0007&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/"&gt;ADR-0010&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The PCs run &lt;strong&gt;classic iTunes for Windows&lt;/strong&gt;, not the Microsoft Store build and&#10;not the newer Apple Music app. A phone remote app already sees and controls&#10;it, after a one-time pairing and with no Apple ID sign-in. That pairing has to&#10;keep working for as long as Apple supports it.&lt;/p&gt;</description></item><item><title>ADR-0012: Spotify by the Web API</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/</guid><description>&lt;h1 id="adr-0012-spotify-is-read-from-the-account-through-the-web-api"&gt;ADR-0012: Spotify Is Read From the Account, Through the Web API&lt;a class="anchor" href="#adr-0012-spotify-is-read-from-the-account-through-the-web-api"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10; 2026-10-11, once the driver had run against the account; two observations are still wanted, under &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How the Spotify driver learns what is playing.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Amended&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-11, before it was accepted: where the driver runs, how it is authorized, which devices count, and that it takes no artwork. The text below is the amended decision; &lt;a href="#what-changed-on-2026-10-11"&gt;What changed&lt;/a&gt; lists the differences&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0031-spotify-is-shown-like-itunes/"&gt;ADR-0031&lt;/a&gt;: the driver takes the album&amp;rsquo;s picture after all, from the answer it already asks for. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0032-spotify-takes-commands/"&gt;ADR-0032&lt;/a&gt;: the authorization also allows changing playback, and the driver carries out commands&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0007-drivers-are-portable-go/"&gt;ADR-0007&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Spotify knows what an account is playing wherever it plays: start a track on&#10;the desktop and the phone shows it. Spotify must also work when the rack is&#10;away from the house, which rules out anything that depends on the home LAN.&lt;/p&gt;</description></item><item><title>ADR-0013: MusicBee by the Remote Plugin's Protocol</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0013-musicbee-by-remote-protocol/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0013-musicbee-by-remote-protocol/</guid><description>&lt;h1 id="adr-0013-musicbee-is-read-through-the-musicbee-remote-plugins-protocol"&gt;ADR-0013: MusicBee Is Read Through the MusicBee Remote Plugin&amp;rsquo;s Protocol&lt;a class="anchor" href="#adr-0013-musicbee-is-read-through-the-musicbee-remote-plugins-protocol"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — the protocol has been read and does what is needed; it has not been tried against a real MusicBee. See &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How the MusicBee driver learns of track changes and gets artwork.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0007-drivers-are-portable-go/"&gt;ADR-0007&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/"&gt;ADR-0010&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0011-itunes-by-remote-pairing/"&gt;ADR-0011&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;MusicBee plays local files and has no cloud. Anything that reads it runs on&#10;or near the PC. Its extension point is a plugin: a .NET DLL loaded into&#10;MusicBee, with a notification when the track changes.&lt;/p&gt;</description></item><item><title>ADR-0014: TIDAL by Last.fm</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0014-tidal-by-lastfm/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0014-tidal-by-lastfm/</guid><description>&lt;h1 id="adr-0014-tidal-is-read-through-lastfm-because-nothing-better-is-offered"&gt;ADR-0014: TIDAL Is Read Through Last.fm, Because Nothing Better Is Offered&lt;a class="anchor" href="#adr-0014-tidal-is-read-through-lastfm-because-nothing-better-is-offered"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until it has been tried against the account; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How the TIDAL driver learns what is playing.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Priority&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The lowest of the four players, by the owner&amp;rsquo;s choice. Built last.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0007-drivers-are-portable-go/"&gt;ADR-0007&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/"&gt;ADR-0012&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The wish was for TIDAL to work like Spotify: ask the account, from the cloud,&#10;with nothing on the PC, so that it also works away from home.&lt;/p&gt;</description></item><item><title>ADR-0015: EdS Builds Its Own Pi Images</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0015-eds-builds-its-own-pi-images/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0015-eds-builds-its-own-pi-images/</guid><description>&lt;h1 id="adr-0015-eds-builds-its-own-pi-images-on-deevnet-iotaass-base"&gt;ADR-0015: EdS Builds Its Own Pi Images, on Deevnet IoTaaS&amp;rsquo;s Base&lt;a class="anchor" href="#adr-0015-eds-builds-its-own-pi-images-on-deevnet-iotaass-base"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where the definition of an EdS Raspberry Pi image lives, what it is built from, and what &amp;ldquo;the relay&amp;rdquo; is.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/"&gt;ADR-0010&lt;/a&gt;, which decided there would be a dual-homed Pi and did not say whose image it would run&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0004-firmware-secrets-nvs-only/"&gt;ADR-0004&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0002-relay-pi-and-now-playing-accounts/"&gt;CHG-0002&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The Pi that carries now-playing reports from the home LAN to the broker needed&#10;an image. Deevnet IoTaaS has an image factory that builds Raspberry Pi images,&#10;and the first relay image was built there, as a new variant beside&#10;Deevnet IoTaaS&amp;rsquo;s own.&lt;/p&gt;</description></item><item><title>ADR-0016: A Source Can Be Reported Without Its Cover</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/</guid><description>&lt;h1 id="adr-0016-a-source-can-be-reported-without-its-cover-and-spotify-is"&gt;ADR-0016: A Source Can Be Reported Without Its Cover, and Spotify Is&lt;a class="anchor" href="#adr-0016-a-source-can-be-reported-without-its-cover-and-spotify-is"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-11&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Whether everything that is reported as playing also lights the stand.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;, which promised that &lt;code&gt;current&lt;/code&gt; carries a cover whenever something is playing&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/"&gt;ADR-0028&lt;/a&gt;: a source can also be reported with its cover and still not lit, by a look that says so. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0031-spotify-is-shown-like-itunes/"&gt;ADR-0031&lt;/a&gt;: Spotify is no longer reported this way. It has its cover, and is kept off the stand as iTunes is; the setting remains, with no source in it&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0009-lightd-takes-covers-from-a-topic/"&gt;ADR-0009&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/"&gt;ADR-0012&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The stand was built to stand beside a record that is playing. iTunes plays a&#10;library of albums the owner chose, and the stand follows it.&lt;/p&gt;</description></item><item><title>ADR-0017: An Agent Pi Is a Registered Device</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0017-an-agent-pi-is-a-registered-device/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0017-an-agent-pi-is-a-registered-device/</guid><description>&lt;h1 id="adr-0017-an-agent-pi-is-a-registered-device-and-reports-its-events-like-one"&gt;ADR-0017: An Agent Pi Is a Registered Device, and Reports Its Events Like One&lt;a class="anchor" href="#adr-0017-an-agent-pi-is-a-registered-device-and-reports-its-events-like-one"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-11&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How the now-playing agent&amp;rsquo;s key events reach the tenant&amp;rsquo;s log store, and what the Pi it runs on is to the tenant.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0005-device-events-over-mqtt/"&gt;ADR-0005&lt;/a&gt;, which gave devices a way to report and said a program that is not a device &amp;ldquo;needs another route&amp;rdquo;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0015-eds-builds-its-own-pi-images/"&gt;ADR-0015&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/"&gt;ADR-0010&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The stand reports its key events to the tenant&amp;rsquo;s log store, and they are read&#10;on a dashboard. The agent Pi reported nothing: what it saw playing, and&#10;whether its drivers were working, was in its own journal, reached by SSH&#10;through the Builder.&lt;/p&gt;</description></item><item><title>ADR-0018: A Console of EdS's Own</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0018-a-console-of-eds-own/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0018-a-console-of-eds-own/</guid><description>&lt;h1 id="adr-0018-eds-has-a-console-of-its-own-fed-from-the-bus-and-it-only-looks"&gt;ADR-0018: EdS Has a Console of Its Own, Fed From the Bus, and It Only Looks&lt;a class="anchor" href="#adr-0018-eds-has-a-console-of-its-own-fed-from-the-bus-and-it-only-looks"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10; 2026-10-11, once it had been watched in a browser on the site with tracks changing&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Amended&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-11, before it was accepted: served over TLS, not in the clear. When this was written nothing on the site would certify a name a tenant serves; Deevnet ADR-0037 has since given tenants a CA to ask. &lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0007-the-console-over-tls/"&gt;CHG-0007&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-11&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where a person looks to see what EdS is doing: what is playing, what the stand is showing, and whether the parts are up.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0039-the-console-can-light-the-stand-for-every-source/"&gt;ADR-0039&lt;/a&gt;: its first control, which switches the stand between records and every source&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0005-device-events-over-mqtt/"&gt;ADR-0005&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0009-lightd-takes-covers-from-a-topic/"&gt;ADR-0009&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;What EdS is doing was visible in three places, none of them a picture: the&#10;tenant&amp;rsquo;s Grafana dashboard, which lists events; &lt;code&gt;mosquitto_sub&lt;/code&gt;; and the&#10;services&amp;rsquo; journals. The stand has no LEDs attached yet, so nothing at all&#10;showed its colors.&lt;/p&gt;</description></item><item><title>ADR-0019: An Album Can Have a Look of Its Own</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0019-an-album-can-have-a-look-of-its-own/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0019-an-album-can-have-a-look-of-its-own/</guid><description>&lt;h1 id="adr-0019-an-album-can-have-a-look-of-its-own-named-on-the-music-side-and-drawn-on-the-light-side"&gt;ADR-0019: An Album Can Have a Look of Its Own, Named on the Music Side and Drawn on the Light Side&lt;a class="anchor" href="#adr-0019-an-album-can-have-a-look-of-its-own-named-on-the-music-side-and-drawn-on-the-light-side"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until the first one has been seen on the stand&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-11&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How one particular album gets a scene that is not derived from its cover, without the part that makes scenes learning what an album is.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0009-lightd-takes-covers-from-a-topic/"&gt;ADR-0009&lt;/a&gt;, which gave &lt;code&gt;lightd&lt;/code&gt; covers and kept tracks and albums on the other side of the topic&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/"&gt;ADR-0028&lt;/a&gt;: a look can name no cover, and is then the look of there being none. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0030-a-piece-of-music-can-have-a-look-from-any-source/"&gt;ADR-0030&lt;/a&gt;: a single piece of music can have one too, by its title&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0001-device-renders-effects/"&gt;ADR-0001&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Every scene so far is made the same way: the cover&amp;rsquo;s colors, picked by&#10;&lt;code&gt;palette&lt;/code&gt;, turned into a scene by &lt;code&gt;lightd&lt;/code&gt;. That is right for almost every&#10;record and wrong for a few. &lt;em&gt;The Dark Side of the Moon&lt;/em&gt; is a black sleeve with&#10;a thin spectrum across it. The colors a fair extraction finds on it are not&#10;what anyone would light a room with for that album, and what they would light&#10;it with is obvious: the spectrum.&lt;/p&gt;</description></item><item><title>ADR-0020: A Touch Screen That Can Change What Plays</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/</guid><description>&lt;h1 id="adr-0020-a-touch-screen-shows-the-cover-and-can-change-what-plays-by-asking-nowplayd"&gt;ADR-0020: A Touch Screen Shows the Cover and Can Change What Plays, by Asking nowplayd&lt;a class="anchor" href="#adr-0020-a-touch-screen-shows-the-cover-and-can-change-what-plays-by-asking-nowplayd"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a button on the screen has paused the real iTunes; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-11&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A second device, a small touch screen, that shows the cover of what is playing and has five buttons: play or pause, previous, next, volume up, volume down. This is the first thing in EdS that changes anything outside itself.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;, in which a driver reports and reads nothing, and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0011-itunes-by-remote-pairing/"&gt;ADR-0011&lt;/a&gt;, which paired with iTunes as a remote and used the pairing only to read&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0032-spotify-takes-commands/"&gt;ADR-0032&lt;/a&gt;: Spotify&amp;rsquo;s driver carries the commands out too; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/"&gt;ADR-0040&lt;/a&gt;: a sixth command names an album, and goes to iTunes whatever plays&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/"&gt;ADR-0010&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0018-a-console-of-eds-own/"&gt;ADR-0018&lt;/a&gt;, which said controls would be a decision of their own&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The stand shows a record&amp;rsquo;s colors. A screen beside it can show the cover&#10;itself, and a screen that can be touched is the obvious place for the few&#10;controls a listener reaches for.&lt;/p&gt;</description></item><item><title>ADR-0021: The Turntable Is Identified by Listening</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0021-the-turntable-is-identified-by-listening/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0021-the-turntable-is-identified-by-listening/</guid><description>&lt;h1 id="adr-0021-the-turntable-is-identified-by-listening-with-a-recognizer-that-can-be-replaced"&gt;ADR-0021: The Turntable Is Identified by Listening, With a Recognizer That Can Be Replaced&lt;a class="anchor" href="#adr-0021-the-turntable-is-identified-by-listening-with-a-recognizer-that-can-be-replaced"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a record on the platter has lit the stand; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-11&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A third driver in &lt;code&gt;npagent&lt;/code&gt;, &lt;code&gt;turntable&lt;/code&gt;: it listens to the amplifier&amp;rsquo;s line-level output on the agent Pi, has a recognizer name what it hears, and reports that as a source on the now-playing bus.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt;, which said a turntable that identifies its record would be one more driver, and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0007-drivers-are-portable-go/"&gt;ADR-0007&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/"&gt;ADR-0012&lt;/a&gt; and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0014-tidal-by-lastfm/"&gt;ADR-0014&lt;/a&gt;, which each declined an unpublished interface; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0015-eds-builds-its-own-pi-images/"&gt;ADR-0015&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0017-an-agent-pi-is-a-registered-device/"&gt;ADR-0017&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The stand was built to stand beside a record that is playing. So far it&#10;follows iTunes, because iTunes can be asked what it is playing and a turntable&#10;cannot.&lt;/p&gt;</description></item><item><title>ADR-0022: The Owner's Collection Names the Record</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0022-the-owners-collection-names-the-record/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0022-the-owners-collection-names-the-record/</guid><description>&lt;h1 id="adr-0022-for-a-source-that-plays-the-owners-records-the-owners-collection-names-the-record"&gt;ADR-0022: For a Source That Plays the Owner&amp;rsquo;s Records, the Owner&amp;rsquo;s Collection Names the Record&lt;a class="anchor" href="#adr-0022-for-a-source-that-plays-the-owners-records-the-owners-collection-names-the-record"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a record on the platter has been shown with its own sleeve; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-12&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How nowplayd completes a track from a source that plays physical records: it asks the owner&amp;rsquo;s collection at Discogs before any catalog, and the collection&amp;rsquo;s answer replaces the album the source named.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;, in which a known album is never renamed. For the sources named here, it is.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0021-the-turntable-is-identified-by-listening/"&gt;ADR-0021&lt;/a&gt;, which left this open; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt;, the other setting that treats named sources differently&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The turntable driver names a track by what it sounds like. A recording is&#10;pressed on many records - the album, its reissues, compilations, box sets -&#10;and nothing in the sound says which. The recognizer names an album anyway.&#10;On the bench it called one track of &lt;em&gt;Chicago Transit Authority&lt;/em&gt; a box set,&#10;and a track of &lt;em&gt;No Jacket Required&lt;/em&gt; a singles collection.&lt;/p&gt;</description></item><item><title>ADR-0023: A Source That Is Switched On Holds the Stand</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/</guid><description>&lt;h1 id="adr-0023-a-sources-equipment-can-say-it-is-on-and-a-source-that-is-on-holds-the-stand"&gt;ADR-0023: A Source&amp;rsquo;s Equipment Can Say It Is On, and a Source That Is On Holds the Stand&lt;a class="anchor" href="#adr-0023-a-sources-equipment-can-say-it-is-on-and-a-source-that-is-on-holds-the-stand"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until the beacon has been timed on the switch it shares and a record has been held through its silences; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-12&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How EdS knows the turntable is switched on: a small device on the same switched outlet, whose connection to the broker is the whole of what it says. And what nowplayd does knowing it.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;, whose rule now has one thing before it. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0018-a-console-of-eds-own/"&gt;ADR-0018&lt;/a&gt;: the console reads one more topic, and still only looks.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0021-the-turntable-is-identified-by-listening/"&gt;ADR-0021&lt;/a&gt;, whose driver this is for and whose account of the wiring this corrects; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt; and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0022-the-owners-collection-names-the-record/"&gt;ADR-0022&lt;/a&gt;, the other settings that treat named sources differently&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The turntable driver (&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0021-the-turntable-is-identified-by-listening/"&gt;ADR-0021&lt;/a&gt;)&#10;reports what it hears, and three things it cannot hear are in the way.&lt;/p&gt;</description></item><item><title>ADR-0024: Paused Long Enough Is Not Playing</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0024-paused-long-enough-is-not-playing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0024-paused-long-enough-is-not-playing/</guid><description>&lt;h1 id="adr-0024-a-track-left-paused-is-not-playing-for-ever-and-a-room-with-nothing-playing-is-dim"&gt;ADR-0024: A Track Left Paused Is Not Playing for Ever, and a Room With Nothing Playing Is Dim&lt;a class="anchor" href="#adr-0024-a-track-left-paused-is-not-playing-for-ever-and-a-room-with-nothing-playing-is-dim"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until it has been seen in the room; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-12&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What nowplayd says when the current track has sat paused, or nobody is reporting; how that reaches the stand; what the stand shows then.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;, which left &amp;ldquo;what a subscriber does with stopped&amp;rdquo; to the subscriber and &amp;ldquo;paused on B is more use than silence&amp;rdquo; without an end. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0009-lightd-takes-covers-from-a-topic/"&gt;ADR-0009&lt;/a&gt;: an emptied cover topic now means something to lightd.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/"&gt;ADR-0028&lt;/a&gt;: the idle scene is for a room where something is switched on; with nothing switched on, a room with nothing playing is dark&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt;, whose &amp;ldquo;no cover sent&amp;rdquo; this must not be mistaken for; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/"&gt;ADR-0023&lt;/a&gt;, whose held source is left alone; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;, whose play button must go on working&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Pause iTunes and walk away, and the stand goes on showing the album for as&#10;long as nothing else plays: hours, overnight. The console says &amp;ldquo;Paused on&#10;iTunes&amp;rdquo; over the same sleeve. Neither is false, and neither is what the room&#10;is doing, which is nothing.&lt;/p&gt;</description></item><item><title>ADR-0025: Current Says When There Are No Controls</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0025-current-says-when-there-are-no-controls/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0025-current-says-when-there-are-no-controls/</guid><description>&lt;h1 id="adr-0025-the-current-track-says-when-there-is-nothing-a-controller-could-do"&gt;ADR-0025: The Current Track Says When There Is Nothing a Controller Could Do&lt;a class="anchor" href="#adr-0025-the-current-track-says-when-there-is-nothing-a-controller-could-do"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until the screen has been touched with a record playing; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-12&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;One optional field in &lt;code&gt;current&lt;/code&gt;, said by nowplayd, and what the cover screen does with it.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;, which noted that &amp;ldquo;a source that takes commands does not say so anywhere&amp;rdquo;. Now the current one does.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/"&gt;ADR-0023&lt;/a&gt;, which made the turntable current for as long as it is on, and so made the screen&amp;rsquo;s buttons idle for as long&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Touch the cover screen and five buttons come up. With a record on the&#10;turntable every one of them does nothing: a command goes to the source that&#10;is current, and nothing can skip a record. Since&#10;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/"&gt;ADR-0023&lt;/a&gt;&#10;the turntable is current the whole time it is switched on, so that is the&#10;whole evening. The sleeve is what the screen is for then, and buttons over it&#10;are wrong twice: they hide it, and they lie.&lt;/p&gt;</description></item><item><title>ADR-0026: What Silence Means on the Turntable</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0026-what-silence-means-on-the-turntable/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0026-what-silence-means-on-the-turntable/</guid><description>&lt;h1 id="adr-0026-a-gap-between-tracks-is-listened-for-and-a-silent-turntable-is-idle-in-twenty-seconds"&gt;ADR-0026: A Gap Between Tracks Is Listened For, and a Silent Turntable Is Idle in Twenty Seconds&lt;a class="anchor" href="#adr-0026-a-gap-between-tracks-is-listened-for-and-a-silent-turntable-is-idle-in-twenty-seconds"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a side has been played to it; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-12&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What the turntable driver does with a short silence, and how long nowplayd keeps the cover of a source that is stopped and held.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0021-the-turntable-is-identified-by-listening/"&gt;ADR-0021&lt;/a&gt;, whose &amp;ldquo;no single answer after that&amp;rdquo; now has one exception, and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0024-paused-long-enough-is-not-playing/"&gt;ADR-0024&lt;/a&gt;, whose five minutes for a stopped, held source is taken back&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/"&gt;ADR-0023&lt;/a&gt;, which is why a stopped turntable is still current; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0022-the-owners-collection-names-the-record/"&gt;ADR-0022&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Two things were seen with records playing, on the day the driver went into&#10;service.&lt;/p&gt;</description></item><item><title>ADR-0027: What Is Asked of Outside Services Is Counted</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0027-what-is-asked-of-outside-services-is-counted/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0027-what-is-asked-of-outside-services-is-counted/</guid><description>&lt;h1 id="adr-0027-what-eds-asks-of-other-peoples-services-is-counted-a-minute-at-a-time-and-nowplayd-writes-its-counts-to-the-log-store-itself"&gt;ADR-0027: What EdS Asks of Other People&amp;rsquo;s Services Is Counted, a Minute at a Time, and nowplayd Writes Its Counts to the Log Store Itself&lt;a class="anchor" href="#adr-0027-what-eds-asks-of-other-peoples-services-is-counted-a-minute-at-a-time-and-nowplayd-writes-its-counts-to-the-log-store-itself"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until the counts have been seen on the dashboard; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-12&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Counting the calls &lt;code&gt;npagent&lt;/code&gt; and &lt;code&gt;nowplayd&lt;/code&gt; make to services that are not EdS&amp;rsquo;s; how those counts reach the tenant&amp;rsquo;s log store from each; the dashboard that reads them.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0005-device-events-over-mqtt/"&gt;ADR-0005&lt;/a&gt; and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0017-an-agent-pi-is-a-registered-device/"&gt;ADR-0017&lt;/a&gt;: the agent&amp;rsquo;s counts are one more event. A workload gets a route of its own, which neither gave it.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0021-the-turntable-is-identified-by-listening/"&gt;ADR-0021&lt;/a&gt;, whose recognizer is the service least entitled to be leaned on; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0022-the-owners-collection-names-the-record/"&gt;ADR-0022&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/"&gt;ADR-0012&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;; Deevnet ADR-0027 (the tenant log store) and Deevnet ADR-0024 (dashboards)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;EdS asks things of services that are not its own. The turntable&amp;rsquo;s recognizer&#10;is Shazam&amp;rsquo;s, through an endpoint nobody offered. The owner&amp;rsquo;s collection is&#10;read from Discogs. Spotify&amp;rsquo;s Web API is polled. Covers are looked up at&#10;Deezer, the iTunes Search API, MusicBrainz and the Cover Art Archive.&lt;/p&gt;</description></item><item><title>ADR-0028: The Stand Is for Records</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/</guid><description>&lt;h1 id="adr-0028-the-stand-is-lit-for-records-only-and-is-dim-only-while-the-turntable-is-on"&gt;ADR-0028: The Stand Is Lit for Records Only, and Is Dim Only While the Turntable Is On&lt;a class="anchor" href="#adr-0028-the-stand-is-lit-for-records-only-and-is-dim-only-while-the-turntable-is-on"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until it has been seen in the room; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-13&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Which sources light the stand; what it shows when nothing is playing; and how lightd is told, without learning what a source is.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0024-paused-long-enough-is-not-playing/"&gt;ADR-0024&lt;/a&gt;, whose idle scene is now for one case of two, and whose &amp;ldquo;it is not dark&amp;rdquo; no longer holds for the other. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0019-an-album-can-have-a-look-of-its-own/"&gt;ADR-0019&lt;/a&gt;: a look can be named for there being no cover, and a look can be &amp;ldquo;light nothing&amp;rdquo;. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt;: a second way for a source to be reported and not lit, which keeps its cover. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/"&gt;ADR-0023&lt;/a&gt;: the switch says one thing more.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extended by&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0029-the-stand-starts-dark-and-blinks-what-is-wrong/"&gt;ADR-0029&lt;/a&gt;: the stand is dark from power on too, and blinks when it cannot reach the broker. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0030-a-piece-of-music-can-have-a-look-from-any-source/"&gt;ADR-0030&lt;/a&gt;: one look is shown from a dark source too. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0039-the-console-can-light-the-stand-for-every-source/"&gt;ADR-0039&lt;/a&gt;: records-only is the default, and the console can switch the stand to every source&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0009-lightd-takes-covers-from-a-topic/"&gt;ADR-0009&lt;/a&gt;, whose boundary this keeps; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0026-what-silence-means-on-the-turntable/"&gt;ADR-0026&lt;/a&gt;, whose dimmed room between two sides is the case that stays dim&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0024-paused-long-enough-is-not-playing/"&gt;ADR-0024&lt;/a&gt;&#10;gave a room with nothing playing a scene of its own: steady, warm, at 0.15.&#10;It chose that over dark because &amp;ldquo;a dark stand cannot be told from a dead&#10;one&amp;rdquo;.&lt;/p&gt;</description></item><item><title>ADR-0029: The Stand Starts Dark, and Blinks What Is Wrong</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0029-the-stand-starts-dark-and-blinks-what-is-wrong/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0029-the-stand-starts-dark-and-blinks-what-is-wrong/</guid><description>&lt;h1 id="adr-0029-the-stand-starts-dark-and-says-in-red-blinks-how-far-it-got"&gt;ADR-0029: The Stand Starts Dark, and Says in Red Blinks How Far It Got&lt;a class="anchor" href="#adr-0029-the-stand-starts-dark-and-says-in-red-blinks-how-far-it-got"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until each blink has been seen on the stand; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-13&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What the stand&amp;rsquo;s strip shows from power on until it is sent a scene; what it shows when it cannot get that far; and how it comes on and goes off.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/"&gt;ADR-0028&lt;/a&gt;, which made a room with nothing playing dark and left the stand&amp;rsquo;s own first seconds dim. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0001-device-renders-effects/"&gt;ADR-0001&lt;/a&gt;: the stand now draws one thing nobody sent it.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0005-device-events-over-mqtt/"&gt;ADR-0005&lt;/a&gt;, the stand&amp;rsquo;s other way of saying what happened, which needs the broker this is for the lack of; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0004-firmware-secrets-nvs-only/"&gt;ADR-0004&lt;/a&gt;, whose unprovisioned stand gets a blink of its own&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The firmware has always lit the strip the moment it had power: a dim warm&#10;white, &amp;ldquo;so an unconfigured or unreachable stand looks deliberate rather than&#10;broken&amp;rdquo;. Since&#10;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/"&gt;ADR-0028&lt;/a&gt; the&#10;stand is dark unless a record is on or the turntable is switched on. The&#10;warm white at power on is then the one time the stand is lit with nobody&#10;having asked: for a few seconds on every start, and for as long as the&#10;network is away.&lt;/p&gt;</description></item><item><title>ADR-0030: A Piece of Music Can Have a Look, From Any Source</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0030-a-piece-of-music-can-have-a-look-from-any-source/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0030-a-piece-of-music-can-have-a-look-from-any-source/</guid><description>&lt;h1 id="adr-0030-one-piece-of-music-can-have-a-look-of-its-own-shown-whatever-plays-it-and-the-stand-learns-to-scan"&gt;ADR-0030: One Piece of Music Can Have a Look of Its Own, Shown Whatever Plays It, and the Stand Learns to Scan&lt;a class="anchor" href="#adr-0030-one-piece-of-music-can-have-a-look-of-its-own-shown-whatever-plays-it-and-the-stand-learns-to-scan"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until it has been seen on the stand with the theme playing; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-13&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A look for a single track, known by its title; the one exception to the stand being lit for records only; and a sixth effect in the firmware to draw it with.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0019-an-album-can-have-a-look-of-its-own/"&gt;ADR-0019&lt;/a&gt;, whose looks were albums&amp;rsquo;. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/"&gt;ADR-0028&lt;/a&gt;, whose dark sources now have one thing that lights them. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0001-device-renders-effects/"&gt;ADR-0001&lt;/a&gt;: the stand has one more effect.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0029-the-stand-starts-dark-and-blinks-what-is-wrong/"&gt;ADR-0029&lt;/a&gt;, whose opening and closing are how this comes on and goes off in a dark room&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Its owner wants the stand to do what the front of KITT does while the theme&#10;from &lt;em&gt;Knight Rider&lt;/em&gt; is playing: one red light, going from side to side.&lt;/p&gt;</description></item><item><title>ADR-0031: Spotify Is Shown, Like iTunes</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0031-spotify-is-shown-like-itunes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0031-spotify-is-shown-like-itunes/</guid><description>&lt;h1 id="adr-0031-spotify-is-reported-with-its-cover-and-treated-as-itunes-is"&gt;ADR-0031: Spotify Is Reported With Its Cover, and Treated as iTunes Is&lt;a class="anchor" href="#adr-0031-spotify-is-reported-with-its-cover-and-treated-as-itunes-is"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until the driver has fetched a cover from the real account and the screen has shown it; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-13&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Whether Spotify&amp;rsquo;s track comes with a cover, where the cover is from, and what the stand does for it.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/"&gt;ADR-0012&lt;/a&gt;, whose driver took no artwork and now takes the album&amp;rsquo;s. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt;: a source can still be reported without its cover, and Spotify no longer is. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/"&gt;ADR-0028&lt;/a&gt;: Spotify becomes a dark source, as iTunes is.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0030-a-piece-of-music-can-have-a-look-from-any-source/"&gt;ADR-0030&lt;/a&gt;, whose &amp;ldquo;any source&amp;rdquo; this makes true of Spotify; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0027-what-is-asked-of-outside-services-is-counted/"&gt;ADR-0027&lt;/a&gt;, which counts the new requests; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0018-a-console-of-eds-own/"&gt;ADR-0018&lt;/a&gt;, whose page shows the cover&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0016-a-source-can-be-reported-without-its-cover/"&gt;ADR-0016&lt;/a&gt;&#10;reported Spotify without a cover for two reasons. The owner did not want&#10;the lights to follow it. And Spotify&amp;rsquo;s developer pages have a line about&#10;not synchronizing its recordings with visual media, which&#10;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/"&gt;ADR-0012&lt;/a&gt; left to&#10;the owner&amp;rsquo;s judgment; fetching no artwork and lighting nothing stepped&#10;around it.&lt;/p&gt;</description></item><item><title>ADR-0032: Spotify Takes Commands</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0032-spotify-takes-commands/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0032-spotify-takes-commands/</guid><description>&lt;h1 id="adr-0032-the-spotify-driver-carries-out-commands-with-a-wider-authorization-for-what-is-playing-here"&gt;ADR-0032: The Spotify Driver Carries Out Commands, With a Wider Authorization, for What Is Playing Here&lt;a class="anchor" href="#adr-0032-the-spotify-driver-carries-out-commands-with-a-wider-authorization-for-what-is-playing-here"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a press on the cover screen has paused Spotify; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-13&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Whether a controller&amp;rsquo;s command reaches Spotify, what the agent must be authorized for to carry it out, and which playback a command may touch.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;, whose commands only iTunes carried out. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0012-spotify-by-web-api/"&gt;ADR-0012&lt;/a&gt;, whose authorization only read.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0031-spotify-is-shown-like-itunes/"&gt;ADR-0031&lt;/a&gt;, which put Spotify&amp;rsquo;s sleeve on the cover screen above buttons that did nothing; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0025-current-says-when-there-are-no-controls/"&gt;ADR-0025&lt;/a&gt;, the other answer to that; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0027-what-is-asked-of-outside-services-is-counted/"&gt;ADR-0027&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Since &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0031-spotify-is-shown-like-itunes/"&gt;ADR-0031&lt;/a&gt;&#10;the cover screen shows what Spotify is playing, with the same five buttons&#10;it shows for iTunes. Pressed, they do nothing: &lt;code&gt;nowplayd&lt;/code&gt; passes the command&#10;to the current source&#10;(&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;),&#10;and Spotify&amp;rsquo;s driver reads no command topic. It was built to read, with an&#10;authorization that only reads, and both the code and the broker account say&#10;that changing it is a decision. This is that decision.&lt;/p&gt;</description></item><item><title>ADR-0033: The Whole Back End on One Pi</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0033-the-whole-back-end-on-one-pi/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0033-the-whole-back-end-on-one-pi/</guid><description>&lt;h1 id="adr-0033-the-whole-back-end-can-run-on-one-pi-as-an-image-built-on-deevnets-take-home-one"&gt;ADR-0033: The Whole Back End Can Run on One Pi, as an Image Built on Deevnet&amp;rsquo;s Take-Home One&lt;a class="anchor" href="#adr-0033-the-whole-back-end-can-run-on-one-pi-as-an-image-built-on-deevnets-take-home-one"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a card has been built, booted and run; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-13&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Whether EdS can run with nothing of Deevnet IoTaaS behind it, on one Raspberry Pi; what that Pi&amp;rsquo;s image is built from; how its services run, where its secrets come from, and what its console presents.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0015-eds-builds-its-own-pi-images/"&gt;ADR-0015&lt;/a&gt;: a second image, on a second base. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0003-broker-is-the-substrates/"&gt;ADR-0003&lt;/a&gt;: on Deevnet the broker is still Deevnet&amp;rsquo;s; on this Pi it is the Pi&amp;rsquo;s. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/"&gt;ADR-0010&lt;/a&gt;: this Pi has one leg and is no relay. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0018-a-console-of-eds-own/"&gt;ADR-0018&lt;/a&gt;: the console&amp;rsquo;s certificate, where there is no Tenant Service CA.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0017-an-agent-pi-is-a-registered-device/"&gt;ADR-0017&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0027-what-is-asked-of-outside-services-is-counted/"&gt;ADR-0027&lt;/a&gt;, Deevnet&amp;rsquo;s runbook &amp;ldquo;Convert a Tenant to a Pi Image&amp;rdquo;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;EdS runs in two places. Four services (&lt;code&gt;palette&lt;/code&gt;, &lt;code&gt;lightd&lt;/code&gt;, &lt;code&gt;nowplayd&lt;/code&gt;, the&#10;console) are containers on a workload in the EdS tenant. The agent, &lt;code&gt;npagent&lt;/code&gt;,&#10;is on a Pi with a leg on the home network&#10;(&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/"&gt;ADR-0010&lt;/a&gt;). The broker,&#10;the log store and Grafana are Deevnet IoTaaS&amp;rsquo;s.&lt;/p&gt;</description></item><item><title>ADR-0034: Presence Is Heard, Not Remembered</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0034-presence-is-heard-not-remembered/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0034-presence-is-heard-not-remembered/</guid><description>&lt;h1 id="adr-0034-presence-is-heard-not-remembered-everything-says-it-is-there-every-thirty-seconds"&gt;ADR-0034: Presence Is Heard, Not Remembered: Everything Says It Is There Every Thirty Seconds&lt;a class="anchor" href="#adr-0034-presence-is-heard-not-remembered-everything-says-it-is-there-every-thirty-seconds"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a stand unplugged across a broker restart is seen gray; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-16&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What &lt;code&gt;online&lt;/code&gt; on a &lt;code&gt;…/status&lt;/code&gt; topic means to whoever reads it: the console, and nowplayd for sources and beacons.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/"&gt;ADR-0023&lt;/a&gt;, whose consequence &amp;ldquo;a will needs a broker to send it&amp;rdquo; this removes. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0018-a-console-of-eds-own/"&gt;ADR-0018&lt;/a&gt;: the console now shows a part as up only if it has heard from it lately.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0003-broker-is-the-substrates/"&gt;ADR-0003&lt;/a&gt;, the broker that keeps retained messages across restarts&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Every part of EdS says it is there the same way: on connecting, it publishes&#10;&lt;code&gt;online&lt;/code&gt;, retained, to its status topic, and leaves the broker a last will&#10;of &lt;code&gt;offline&lt;/code&gt;, retained. The broker sends the will when it sees the&#10;connection die.&lt;/p&gt;</description></item><item><title>ADR-0035: Firmware Is Updated Through the Broker</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0035-firmware-is-updated-through-the-broker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0035-firmware-is-updated-through-the-broker/</guid><description>&lt;h1 id="adr-0035-firmware-is-updated-through-the-broker-and-a-build-that-cannot-reach-it-is-undone"&gt;ADR-0035: Firmware Is Updated Through the Broker, and a Build That Cannot Reach It Is Undone&lt;a class="anchor" href="#adr-0035-firmware-is-updated-through-the-broker-and-a-build-that-cannot-reach-it-is-undone"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10; 2026-10-17, after each device was updated over the air, one rolled back by itself, and one refused a build not its own; see &lt;a href="#evidence"&gt;Evidence&lt;/a&gt;. Opened 2026-10-16 as &lt;code&gt;Proposed&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-16&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How a new build reaches the stand, the cover screen and the beacon once each is in place; what a device does with one; and how a bad one is undone.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0029-the-stand-starts-dark-and-blinks-what-is-wrong/"&gt;ADR-0029&lt;/a&gt;: the stand that cannot reach the broker still blinks, and now also gives up a new build that caused it.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0003-broker-is-the-substrates/"&gt;ADR-0003&lt;/a&gt;, why the broker sits where devices can reach it and nothing else of EdS can; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/"&gt;ADR-0023&lt;/a&gt;, the beacon whose connection is its message; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0034-presence-is-heard-not-remembered/"&gt;ADR-0034&lt;/a&gt;, the change that showed why this is wanted&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Every change to a device&amp;rsquo;s firmware has meant a USB cable: the stand&#10;unscrewed from its shelf, the beacon taken off its outlet, and the cover&#10;screen and the beacon taking turns on the Mac&amp;rsquo;s one serial port.&#10;ADR-0034 is the case in point: three devices to flash before three&#10;services could be deployed.&lt;/p&gt;</description></item><item><title>ADR-0036: The Screen Sleeps When Nothing Plays</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0036-the-screen-sleeps-when-nothing-plays/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0036-the-screen-sleeps-when-nothing-plays/</guid><description>&lt;h1 id="adr-0036-the-cover-screen-sleeps-when-nothing-has-played-for-five-minutes-and-wakes-for-music"&gt;ADR-0036: The Cover Screen Sleeps When Nothing Has Played for Five Minutes, and Wakes for Music&lt;a class="anchor" href="#adr-0036-the-cover-screen-sleeps-when-nothing-has-played-for-five-minutes-and-wakes-for-music"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10; 2026-10-17 — slept and woken on the board (&lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0026-the-cover-screen-sleeps/"&gt;CHG-0026&lt;/a&gt;); see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-17&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The cover screen&amp;rsquo;s firmware: when it turns its panel off, and what wakes it. Nothing on the bus changes.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;, the screen itself&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/"&gt;ADR-0023&lt;/a&gt;, which makes a turntable that is switched off not heard; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0024-paused-long-enough-is-not-playing/"&gt;ADR-0024&lt;/a&gt;, which turns a long pause into stopped; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0025-current-says-when-there-are-no-controls/"&gt;ADR-0025&lt;/a&gt;, the last time the screen had to be told something without knowing a source; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0029-the-stand-starts-dark-and-blinks-what-is-wrong/"&gt;ADR-0029&lt;/a&gt;, the stand&amp;rsquo;s dark that is not a fault&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The cover screen is lit all the time. With nothing playing it shows a drawn&#10;record all night, to nobody. Its owner asked first for it to sleep when the&#10;turntable&amp;rsquo;s power, iTunes and Spotify are all gone, and to come back when&#10;one of them is.&lt;/p&gt;</description></item><item><title>ADR-0037: Hand-Kept Secrets Are Encrypted in the Repository</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0037-hand-kept-secrets-are-encrypted-in-the-repository/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0037-hand-kept-secrets-are-encrypted-in-the-repository/</guid><description>&lt;h1 id="adr-0037-the-secrets-nothing-else-can-issue-are-kept-encrypted-in-the-repository-with-sops-and-age"&gt;ADR-0037: The Secrets Nothing Else Can Issue Are Kept Encrypted in the Repository, with sops and age&lt;a class="anchor" href="#adr-0037-the-secrets-nothing-else-can-issue-are-kept-encrypted-in-the-repository-with-sops-and-age"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until the first secrets have moved and a second machine has read them; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-18&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where EdS keeps the secrets it is the only holder of, and how its tools read them. Not the secrets Deevnet IoTaaS issues, and not those made on a device or a card.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0004-firmware-secrets-nvs-only/"&gt;ADR-0004&lt;/a&gt;, whose rule (no secret compiled in) stands; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0022-the-owners-collection-names-the-record/"&gt;ADR-0022&lt;/a&gt;, whose token &amp;ldquo;is never committed&amp;rdquo; in plain text, and now is committed encrypted&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0033-the-whole-back-end-on-one-pi/"&gt;ADR-0033&lt;/a&gt;, whose first card went out without the Discogs token&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;On 2026-10-18 the first backend card was written from a worktree, and went&#10;out with no Discogs settings. &lt;code&gt;make card&lt;/code&gt; looks for &lt;code&gt;deploy/discogs.env&lt;/code&gt; in&#10;the checkout it runs in; the file is gitignored, so a worktree never has it;&#10;and the script says &amp;ldquo;no Discogs settings&amp;rdquo; and carries on, as it should for an&#10;owner who has none. Nothing was wrong except where the secret lived.&lt;/p&gt;</description></item><item><title>ADR-0038: The Turntable's Album Is the Original One the Track Is On</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0038-the-turntable-names-the-original-album-by-what-is-on-it/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0038-the-turntable-names-the-original-album-by-what-is-on-it/</guid><description>&lt;h1 id="adr-0038-the-turntables-album-is-the-one-the-track-is-on-and-the-original-one-not-a-time-since-the-last"&gt;ADR-0038: The Turntable&amp;rsquo;s Album Is the One the Track Is On, and the Original One, Not a Time Since the Last&lt;a class="anchor" href="#adr-0038-the-turntables-album-is-the-one-the-track-is-on-and-the-original-one-not-a-time-since-the-last"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a side of one record and then another by the same artist have been played; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-19&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Which album nowplayd names for a track heard on the turntable, and so which cover lights the room. The turntable driver, nowplayd&amp;rsquo;s resolution for the turntable, and the catalogs it asks.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Supersedes&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0026-what-silence-means-on-the-turntable/"&gt;ADR-0026&lt;/a&gt;&amp;rsquo;s &amp;ldquo;the driver remembers the album for ten minutes&amp;rdquo;; the rest of ADR-0026 stands&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0022-the-owners-collection-names-the-record/"&gt;ADR-0022&lt;/a&gt;, the owner&amp;rsquo;s collection first, which stands and still comes first&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0019-an-album-can-have-a-look-of-its-own/"&gt;ADR-0019&lt;/a&gt;, whose album looks follow the album named; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0027-what-is-asked-of-outside-services-is-counted/"&gt;ADR-0027&lt;/a&gt;, which counts every call this adds&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;On 2026-10-18, the first evening on the home Pi&#10;(&lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0028-the-back-end-on-one-pi-on-dvntm/"&gt;CHG-0028&lt;/a&gt;), &lt;em&gt;The&#10;Dark Side of the Moon&lt;/em&gt; was played, lifted, and &lt;em&gt;Animals&lt;/em&gt; put on 52 seconds&#10;later. The recognizer named &amp;ldquo;Pigs On the Wing, Pt. 1&amp;rdquo; and then &amp;ldquo;Dogs&amp;rdquo;, which&#10;are right. The stand kept &lt;em&gt;Dark Side&lt;/em&gt;&amp;rsquo;s rainbow look for both, because both&#10;were reported as on &lt;em&gt;The Dark Side of the Moon&lt;/em&gt;.&lt;/p&gt;</description></item><item><title>ADR-0039: The Console Can Light the Stand for Every Source</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0039-the-console-can-light-the-stand-for-every-source/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0039-the-console-can-light-the-stand-for-every-source/</guid><description>&lt;h1 id="adr-0039-the-console-can-light-the-stand-for-every-source-until-it-is-switched-back"&gt;ADR-0039: The Console Can Light the Stand for Every Source, Until It Is Switched Back&lt;a class="anchor" href="#adr-0039-the-console-can-light-the-stand-for-every-source-until-it-is-switched-back"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until it has been switched both ways from the console in the room; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-19&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A switch on the console that lights the stand from iTunes and Spotify as well as records; where its state is kept; who may change it.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0018-a-console-of-eds-own/"&gt;ADR-0018&lt;/a&gt;: the console gets its first control, and its account its second topic to publish. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/"&gt;ADR-0028&lt;/a&gt;: records-only stays the default, and becomes a setting that can be changed while running.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;, whose commands are never retained; this is not one of them. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0030-a-piece-of-music-can-have-a-look-from-any-source/"&gt;ADR-0030&lt;/a&gt;, whose any-source look is unchanged. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0009-lightd-takes-covers-from-a-topic/"&gt;ADR-0009&lt;/a&gt;, whose boundary this keeps.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The stand is lit for records only&#10;(&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0028-the-stand-is-for-records/"&gt;ADR-0028&lt;/a&gt;):&#10;&lt;code&gt;NP_DARK_SOURCES=itunes,spotify&lt;/code&gt; makes nowplayd give those sources&amp;rsquo; covers&#10;the look &lt;code&gt;dark&lt;/code&gt;, and lightd draws it as a dark stand. That is right for the&#10;room and stays the default.&lt;/p&gt;</description></item><item><title>ADR-0040: A Request Can Name an Album to Play</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/</guid><description>&lt;h1 id="adr-0040-a-request-can-name-an-album-to-play-and-itunes-plays-it-from-its-own-library"&gt;ADR-0040: A Request Can Name an Album to Play, and iTunes Plays It From Its Own Library&lt;a class="anchor" href="#adr-0040-a-request-can-name-an-album-to-play-and-itunes-plays-it-from-its-own-library"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until &lt;code&gt;play_album&lt;/code&gt; sent to &lt;code&gt;nowplaying/command&lt;/code&gt; has played an album through nowplayd and the driver (the driver&amp;rsquo;s half is shown); see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-23&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A sixth command, &lt;code&gt;play_album&lt;/code&gt;, that names an album rather than pressing a button; which player carries it out; and what the iTunes driver asks of the player&amp;rsquo;s library to do it. The first thing to send it is meant to be a voice (&amp;ldquo;Hey Ed, play Van Halen&amp;rsquo;s first album&amp;rdquo;), which is a decision of its own.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;, whose five commands press buttons on whatever is playing, and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0011-itunes-by-remote-pairing/"&gt;ADR-0011&lt;/a&gt;, whose pairing has only read what plays and pressed those buttons&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0032-spotify-takes-commands/"&gt;ADR-0032&lt;/a&gt;, which added no command; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0038-the-turntable-names-the-original-album-by-what-is-on-it/"&gt;ADR-0038&lt;/a&gt;, which already knows an artist&amp;rsquo;s original albums&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Every command so far is a button. It acts on whatever is playing, so a&#10;controller never needs to say where it is sent, and&#10;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;&#10;made that a rule: a controller never names a source. A request to play an&#10;album is not a button. Nothing may be playing at all, and if something is,&#10;it may be the turntable, which takes no command.&lt;/p&gt;</description></item><item><title>ADR-0041: An Artist's Nth Album Is Counted in MusicBrainz</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0041-an-artists-nth-album-is-counted-in-musicbrainz/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0041-an-artists-nth-album-is-counted-in-musicbrainz/</guid><description>&lt;h1 id="adr-0041-an-artists-first-album-is-their-first-studio-album-counted-in-musicbrainz"&gt;ADR-0041: An Artist&amp;rsquo;s First Album Is Their First Studio Album, Counted in MusicBrainz&lt;a class="anchor" href="#adr-0041-an-artists-first-album-is-their-first-studio-album-counted-in-musicbrainz"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until an album asked for by its place has played; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-24&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What &amp;ldquo;Aerosmith&amp;rsquo;s first album&amp;rdquo; means, where the count comes from, and how the name it gives is made to match a library. Not how a request is heard, nor what plays it.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0038-the-turntable-names-the-original-album-by-what-is-on-it/"&gt;ADR-0038&lt;/a&gt;, whose idea of an original album, a studio album with nothing else to it, is the one counted here&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/"&gt;ADR-0040&lt;/a&gt;, which plays an album by its names and cannot ask the library what it holds; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0022-the-owners-collection-names-the-record/"&gt;ADR-0022&lt;/a&gt;, the owner&amp;rsquo;s Discogs collection&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;A request to play &amp;ldquo;Van Halen&amp;rsquo;s first album&amp;rdquo; has to become the names&#10;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/"&gt;ADR-0040&lt;/a&gt;&#10;plays an album by: the artist, and the album&amp;rsquo;s title, as the iTunes library&#10;writes them. The library cannot be asked which albums it has. Something else&#10;has to know the order of an artist&amp;rsquo;s albums.&lt;/p&gt;</description></item><item><title>ADR-0042: A Request Is Heard on the Workload</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0042-a-request-is-heard-on-the-workload/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0042-a-request-is-heard-on-the-workload/</guid><description>&lt;h1 id="adr-0042-a-spoken-request-is-sent-whole-to-the-workload-written-down-there-and-made-a-command"&gt;ADR-0042: A Spoken Request Is Sent Whole to the Workload, Written Down There, and Made a Command&lt;a class="anchor" href="#adr-0042-a-spoken-request-is-sent-whole-to-the-workload-written-down-there-and-made-a-command"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a request said in the room has played its album; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-24&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How &amp;ldquo;Hey Ed, play Van Halen&amp;rsquo;s first album&amp;rdquo; travels from a microphone to &lt;code&gt;play_album&lt;/code&gt;: what the device sends, where speech becomes words, and how words become a command. Not the device&amp;rsquo;s firmware, which is a decision of its own.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/"&gt;ADR-0040&lt;/a&gt;, whose command this sends, and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0041-an-artists-nth-album-is-counted-in-musicbrainz/"&gt;ADR-0041&lt;/a&gt;, whose count it asks&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0003-broker-is-the-substrates/"&gt;ADR-0003&lt;/a&gt;, the broker as the one way a device reaches EdS; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0034-presence-is-heard-not-remembered/"&gt;ADR-0034&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The microphone is a reSpeaker Lite: an XMOS chip that cleans up what a room&#10;says, and a small ESP32-S3 beside it. The ESP32-S3 can listen for a wake&#10;word and keep a few seconds of audio. It cannot turn speech into words. A&#10;device can reach nothing of EdS&amp;rsquo;s but the broker&#10;(&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0003-broker-is-the-substrates/"&gt;ADR-0003&lt;/a&gt;).&lt;/p&gt;</description></item><item><title>ADR-0043: The reSpeaker Runs Firmware of EdS's Own</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0043-the-respeaker-runs-firmware-of-edss-own/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0043-the-respeaker-runs-firmware-of-edss-own/</guid><description>&lt;h1 id="adr-0043-the-respeaker-runs-firmware-of-edss-own-and-sends-a-request-when-its-button-is-held-then-when-it-hears-its-name"&gt;ADR-0043: The reSpeaker Runs Firmware of EdS&amp;rsquo;s Own, and Sends a Request When Its Button Is Held, Then When It Hears Its Name&lt;a class="anchor" href="#adr-0043-the-respeaker-runs-firmware-of-edss-own-and-sends-a-request-when-its-button-is-held-then-when-it-hears-its-name"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a request said into the reSpeaker has played its album; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-24&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What runs on the reSpeaker Lite&amp;rsquo;s XIAO ESP32-S3: how it hears, when it sends, and how it is provisioned and updated. Not what a request becomes, which is &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0042-a-request-is-heard-on-the-workload/"&gt;ADR-0042&lt;/a&gt;&amp;rsquo;s.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0042-a-request-is-heard-on-the-workload/"&gt;ADR-0042&lt;/a&gt;, whose &lt;code&gt;voice/&amp;lt;device&amp;gt;/utterance&lt;/code&gt; this sends&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0004-firmware-secrets-nvs-only/"&gt;ADR-0004&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0035-firmware-is-updated-through-the-broker/"&gt;ADR-0035&lt;/a&gt;, &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0034-presence-is-heard-not-remembered/"&gt;ADR-0034&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The reSpeaker Lite is two chips. An XMOS XU316 takes two microphones and&#10;gives one cleaned-up voice: echo cancelled, noise suppressed, beam steered.&#10;Its firmware (1.0.8, read over DFU on 2026-10-24) sends that over I2S to a&#10;XIAO ESP32-S3 (8 MB PSRAM, 8 MB flash), which came with an Arduino test&#10;sketch from Seeed. The XIAO is what can be programmed.&lt;/p&gt;</description></item><item><title>ADR-0044: The Music Is Turned Down While a Request Is Heard</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0044-the-music-is-turned-down-while-a-request-is-heard/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0044-the-music-is-turned-down-while-a-request-is-heard/</guid><description>&lt;h1 id="adr-0044-the-music-is-turned-down-while-a-request-is-heard-and-comes-back-by-itself"&gt;ADR-0044: The Music Is Turned Down While a Request Is Heard, and Comes Back by Itself&lt;a class="anchor" href="#adr-0044-the-music-is-turned-down-while-a-request-is-heard-and-comes-back-by-itself"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a request said over the music has been heard to its end and played; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-24&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What happens to what is playing between the wake word and the answer: who says the device woke, which command lowers the music, and what brings it back.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;, whose commands this adds two to; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0042-a-request-is-heard-on-the-workload/"&gt;ADR-0042&lt;/a&gt; and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0043-the-respeaker-runs-firmware-of-edss-own/"&gt;ADR-0043&lt;/a&gt;, whose request it is&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/"&gt;ADR-0040&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The reSpeaker&amp;rsquo;s XMOS chip cancels the echo of its own speaker, not of the&#10;stereo. With an album playing beside it, a request asked over the music was&#10;heard as speech until its six-second limit, sent at twice the size, and&#10;written down with the music in it (CHG-0037). Smart speakers lower their&#10;music while they listen. EdS&amp;rsquo;s music comes from players EdS controls.&lt;/p&gt;</description></item><item><title>ADR-0045: An Nth Album Not Owned Is the Next One That Is</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0045-an-nth-album-not-owned-is-the-next-one-that-is/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0045-an-nth-album-not-owned-is-the-next-one-that-is/</guid><description>&lt;h1 id="adr-0045-an-artists-nth-album-when-the-library-does-not-have-it-is-the-next-of-theirs-it-does"&gt;ADR-0045: An Artist&amp;rsquo;s Nth Album, When the Library Does Not Have It, Is the Next of Theirs It Does&lt;a class="anchor" href="#adr-0045-an-artists-nth-album-when-the-library-does-not-have-it-is-the-next-of-theirs-it-does"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until a first album the library lacks has been asked for and the next one played; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-24&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What &amp;ldquo;Genesis&amp;rsquo; first album&amp;rdquo; plays when the owner&amp;rsquo;s library does not have &lt;em&gt;From Genesis to Revelation&lt;/em&gt;.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0041-an-artists-nth-album-is-counted-in-musicbrainz/"&gt;ADR-0041&lt;/a&gt;, whose count this goes on along; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/"&gt;ADR-0040&lt;/a&gt;, whose command gains alternatives&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&amp;ldquo;Genesis&amp;rsquo; first album&amp;rdquo; was heard right, twice, and counted right: &lt;em&gt;From&#10;Genesis to Revelation&lt;/em&gt;, 1969. The owner&amp;rsquo;s iTunes has it as its reissue,&#10;&lt;em&gt;And the Word Was…&lt;/em&gt;, and so was asked for a title it has not got. With&#10;nothing matched it played the band&amp;rsquo;s other songs from &lt;em&gt;Abacab&lt;/em&gt;, the first by&#10;name, which the driver rightly took for a miss; where nothing at all&#10;matches, having emptied its queue, it stops. The library cannot be asked what it&#10;has (&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/"&gt;ADR-0040&lt;/a&gt;),&#10;so a miss is only found by trying.&lt;/p&gt;</description></item><item><title>ADR-0046: Requests Are Matched Against the Owner's Library</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0046-requests-are-matched-against-the-owners-library/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0046-requests-are-matched-against-the-owners-library/</guid><description>&lt;h1 id="adr-0046-requests-are-matched-against-the-owners-library-as-its-xml-lists-it"&gt;ADR-0046: Requests Are Matched Against the Owner&amp;rsquo;s Library, as Its XML Lists It&lt;a class="anchor" href="#adr-0046-requests-are-matched-against-the-owners-library-as-its-xml-lists-it"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10; — until the requests below play on the first try; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-24&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How voiced turns a heard artist and an album, or an album&amp;rsquo;s place, into the titles &lt;code&gt;play_album&lt;/code&gt; names.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0041-an-artists-nth-album-is-counted-in-musicbrainz/"&gt;ADR-0041&lt;/a&gt;, whose count orders the library&amp;rsquo;s albums; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0045-an-nth-album-not-owned-is-the-next-one-that-is/"&gt;ADR-0045&lt;/a&gt;, whose &lt;code&gt;instead&lt;/code&gt; carries the library&amp;rsquo;s titles now&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Every miss on 2026-10-24 was a guess at how the library spells something.&#10;iTunes will not list its library to EdS&#10;(&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0040-a-request-can-name-an-album-to-play/"&gt;ADR-0040&lt;/a&gt;),&#10;so voiced asked for MusicBrainz&amp;rsquo;s titles and the driver checked what played.&#10;Each fix covered the miss before it: Genesis&amp;rsquo; first is the reissue &lt;em&gt;And The&#10;Word Was&lt;/em&gt; in the library; Skynyrd&amp;rsquo;s is &lt;em&gt;Pronounced leh-nerd skin-nerd&lt;/em&gt;, not&#10;&amp;ldquo;(pronounced &amp;rsquo;lĕh-&amp;rsquo;nérd &amp;lsquo;skin-&amp;rsquo;nérd)&amp;rdquo;; &amp;ldquo;Arrowsmith&amp;rdquo; and &amp;ldquo;Leonard Skinner&amp;rdquo;&#10;are how speech writes two bands down.&lt;/p&gt;</description></item><item><title>ADR-0047: voiced Asks eds-inventory</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0047-voiced-asks-eds-inventory/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0047-voiced-asks-eds-inventory/</guid><description>&lt;h1 id="adr-0047-voiced-asks-eds-inventory-for-the-owners-albums-in-place-of-its-own-index"&gt;ADR-0047: voiced Asks eds-inventory for the Owner&amp;rsquo;s Albums, in Place of Its Own Index&lt;a class="anchor" href="#adr-0047-voiced-asks-eds-inventory-for-the-owners-albums-in-place-of-its-own-index"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10; 2026-10-24 — settled by &lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0041-voiced-asks-eds-inventory/"&gt;CHG-0041&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-24&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where voiced finds the owner&amp;rsquo;s artists and albums when it turns a request into &lt;code&gt;play_album&lt;/code&gt;. Not how it parses a request, or counts an artist&amp;rsquo;s albums in MusicBrainz, which are unchanged.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0046-requests-are-matched-against-the-owners-library/"&gt;ADR-0046&lt;/a&gt;, whose matching moves to the inventory unchanged&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/proposals/music-inventory/"&gt;A Music Inventory&lt;/a&gt;, the proposal this begins; eds-inventory&amp;rsquo;s &lt;a href="https://cdeever.github.io/eds-inventory/docs/architecture/decisions/0002-the-itunes-library-is-collected-from-its-xml/"&gt;ADR-0002&lt;/a&gt; and &lt;a href="https://cdeever.github.io/eds-inventory/docs/architecture/decisions/0003-it-deploys-itself-to-eds-workload/"&gt;ADR-0003&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;voiced matches requests against &lt;code&gt;library.json&lt;/code&gt;, an index of the owner&amp;rsquo;s&#10;iTunes library that EdS makes from the XML and copies to voiced by hand&#10;(ADR-0046). Knowing what the owner has is an inventory concern, and&#10;&lt;a href="https://cdeever.github.io/eds-inventory/"&gt;eds-inventory&lt;/a&gt; now does it: it&#10;collects the same XML, keeps the same albums, and answers the four&#10;questions voiced asks with the same matching and thresholds, carried over&#10;from EdS&amp;rsquo;s &lt;code&gt;internal/library&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>ADR-0048: The Turntable Is Heard on Both Channels</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0048-the-turntable-is-heard-on-both-channels/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0048-the-turntable-is-heard-on-both-channels/</guid><description>&lt;h1 id="adr-0048-the-turntable-is-heard-on-both-channels-and-one-gone-silent-is-said-on-the-console"&gt;ADR-0048: The Turntable Is Heard on Both Channels, and One Gone Silent Is Said on the Console&lt;a class="anchor" href="#adr-0048-the-turntable-is-heard-on-both-channels-and-one-gone-silent-is-said-on-the-console"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10;, until a side has played through with one channel unplugged; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-25&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How many channels the turntable&amp;rsquo;s driver listens to, what it decides from each, and how a channel gone silent is reported: a retained topic beside the source&amp;rsquo;s status, one event, and the console&amp;rsquo;s &amp;ldquo;Song detector&amp;rdquo; line. Not how silence, gaps or stops are timed, which is unchanged.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0026-what-silence-means-on-the-turntable/"&gt;ADR-0026&lt;/a&gt;, whose silence is now the louder channel&amp;rsquo;s, and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0034-presence-is-heard-not-remembered/"&gt;ADR-0034&lt;/a&gt;, whose &amp;ldquo;Song detector&amp;rdquo; pill gains a third color for an input heard on one side only&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0018-a-console-of-eds-own/"&gt;ADR-0018&lt;/a&gt;, the console that only looks; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0021-the-turntable-is-identified-by-listening/"&gt;ADR-0021&lt;/a&gt;, the driver; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0017-an-agent-pi-is-a-registered-device/"&gt;ADR-0017&lt;/a&gt;, the agent&amp;rsquo;s events&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;On the evening of 2026-10-25 (about 01:34 UTC on the 26th) the stand went&#10;to standby in the middle of a side.&lt;/strong&gt; A record was playing, the Eagles'&#10;&lt;em&gt;Live&lt;/em&gt;, and the music could still be heard in the room. The turntable&amp;rsquo;s&#10;driver had heard twenty seconds below -55 dBFS and said &lt;code&gt;stopped&lt;/code&gt;, as&#10;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0026-what-silence-means-on-the-turntable/"&gt;ADR-0026&lt;/a&gt;&#10;has it do, and nowplayd dimmed the room a second later.&lt;/p&gt;</description></item><item><title>ADR-0049: A Device Holds Two Sites, and Is Told Which</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0049-a-device-holds-two-sites-and-is-told-which/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0049-a-device-holds-two-sites-and-is-told-which/</guid><description>&lt;h1 id="adr-0049-a-device-holds-two-sites-settings-and-is-told-which-to-use-by-a-message"&gt;ADR-0049: A Device Holds Two Sites&amp;rsquo; Settings, and Is Told Which to Use by a Message&lt;a class="anchor" href="#adr-0049-a-device-holds-two-sites-settings-and-is-told-which-to-use-by-a-message"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10;, until a device has been switched both ways and has undone a switch it could not complete; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-26&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What a device&amp;rsquo;s &lt;code&gt;creds&lt;/code&gt; partition holds for more than one site, the keys it is held under, the message that switches a device from one site to the other, and what a device does when the switch fails. Not what is in a site&amp;rsquo;s settings, which is unchanged.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0004-firmware-secrets-nvs-only/"&gt;ADR-0004&lt;/a&gt;, whose partition now holds a second site&amp;rsquo;s secrets beside the first&amp;rsquo;s, and &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0035-firmware-is-updated-through-the-broker/"&gt;ADR-0035&lt;/a&gt;, whose topics, sender and undo-it-yourself rule a switch follows&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0033-the-whole-back-end-on-one-pi/"&gt;ADR-0033&lt;/a&gt;, the backend Pi that is the second site; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0034-presence-is-heard-not-remembered/"&gt;ADR-0034&lt;/a&gt;, whose status says where a device is&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;EdS&amp;rsquo;s devices now live at two sites.&lt;/strong&gt; The tenant&amp;rsquo;s broker at Deevnet&#10;IoTaaS&amp;rsquo;s mobile site, on its IoT network, and the backend Pi at home, on the&#10;home network. Each site has its own Wi-Fi, its own broker accounts and, until&#10;the home Pi took a certificate from Deevnet&amp;rsquo;s Tenant Service CA, its own CA.&lt;/p&gt;</description></item><item><title>ADR-0050: How Each Track Was Completed Is Written Down</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0050-how-each-track-was-completed-is-written-down/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0050-how-each-track-was-completed-is-written-down/</guid><description>&lt;h1 id="adr-0050-how-each-tracks-album-and-cover-were-found-is-written-down-one-line-a-track-and-nowplayd-sends-it-to-the-log-store"&gt;ADR-0050: How Each Track&amp;rsquo;s Album and Cover Were Found Is Written Down, One Line a Track, and nowplayd Sends It to the Log Store&lt;a class="anchor" href="#adr-0050-how-each-tracks-album-and-cover-were-found-is-written-down-one-line-a-track-and-nowplayd-sends-it-to-the-log-store"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10;, until the lines have been read on the dashboard from a side of a record; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-27&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What &lt;code&gt;nowplayd&lt;/code&gt; writes down about completing a track: who named its album, where its cover came from, how long each step took and why one gave up; the owner&amp;rsquo;s collection being read; how those lines reach the tenant&amp;rsquo;s log store; the dashboard that reads them. Not how a track is completed, which is unchanged.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0027-what-is-asked-of-outside-services-is-counted/"&gt;ADR-0027&lt;/a&gt;, whose &lt;code&gt;api.calls&lt;/code&gt; was the only line &lt;code&gt;nowplayd&lt;/code&gt; sent to the store&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;, the completing; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0022-the-owners-collection-names-the-record/"&gt;ADR-0022&lt;/a&gt;, the collection; &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0038-the-turntable-names-the-original-album-by-what-is-on-it/"&gt;ADR-0038&lt;/a&gt;, the original album&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;On the evening of 2026-10-26 the turntable played &amp;ldquo;Over the Hills and Far&#10;Away&amp;rdquo;, the recognizer named it, and the stand did not follow it: the track&#10;was published with no cover. Finding out why took the journal. &lt;em&gt;Houses of&#10;the Holy&lt;/em&gt; was not in the owner&amp;rsquo;s Discogs collection; naming its original&#10;album, through Deezer and then MusicBrainz at one call a second, used the&#10;whole lookup time; and the cover&amp;rsquo;s lookup had been given the same time,&#10;already spent. That last fault is fixed (eds#101). Nothing showed any of it.&lt;/p&gt;</description></item><item><title>ADR-0051: Spotify Is Switched On and Off From the Console</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0051-spotify-is-switched-on-and-off-from-the-console/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0051-spotify-is-switched-on-and-off-from-the-console/</guid><description>&lt;h1 id="adr-0051-spotify-is-switched-on-and-off-from-the-console-and-off-asks-spotify-nothing"&gt;ADR-0051: Spotify Is Switched On and Off From the Console, and Off Asks Spotify Nothing&lt;a class="anchor" href="#adr-0051-spotify-is-switched-on-and-off-from-the-console-and-off-asks-spotify-nothing"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;: switched both ways from the console&amp;rsquo;s page on the backend Pi, 2026-10-29 (&lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0044-spotify-is-switched-from-the-backend-pis-console/"&gt;CHG-0044&lt;/a&gt;); see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-28&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A switch for the Spotify driver: where its state is kept, what &amp;ldquo;off&amp;rdquo; stops, who reads it, and the console&amp;rsquo;s second control.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0039-the-console-can-light-the-stand-for-every-source/"&gt;ADR-0039&lt;/a&gt;: a second retained setting, and the console&amp;rsquo;s second control, which that record said would bring back the question of a login.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0024-spotify-turned-off-again/"&gt;CHG-0024&lt;/a&gt;, whose follow-up this is. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0027-what-is-asked-of-outside-services-is-counted/"&gt;ADR-0027&lt;/a&gt;, whose count shows the switch working. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0020-a-touch-screen-that-can-change-what-plays/"&gt;ADR-0020&lt;/a&gt;, whose commands are never retained; this is not one of them. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0034-presence-is-heard-not-remembered/"&gt;ADR-0034&lt;/a&gt;.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The Spotify driver asks Spotify what is playing every ten seconds, all day,&#10;whether or not anything plays. Its owner does not want that all the time,&#10;and does want Spotify followed sometimes.&lt;/p&gt;</description></item><item><title>ADR-0052: Each Pi's iTunes Pairing Is Kept, Encrypted, in the Repository</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0052-each-pis-itunes-pairing-is-kept-encrypted-in-the-repository/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0052-each-pis-itunes-pairing-is-kept-encrypted-in-the-repository/</guid><description>&lt;h1 id="adr-0052-each-pis-itunes-pairing-is-kept-encrypted-in-the-repository-and-a-new-card-starts-paired"&gt;ADR-0052: Each Pi&amp;rsquo;s iTunes Pairing Is Kept, Encrypted, in the Repository, and a New Card Starts Paired&lt;a class="anchor" href="#adr-0052-each-pis-itunes-pairing-is-kept-encrypted-in-the-repository-and-a-new-card-starts-paired"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-green"&gt;Accepted&lt;/span&gt;&#10;: a pairing kept, put on a card&amp;rsquo;s boot partition and taken by the first boot&amp;rsquo;s setup, with nobody at iTunes, 2026-10-29 (&lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0045-the-backend-pis-itunes-pairing-is-kept/"&gt;CHG-0045&lt;/a&gt;); see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-28&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where an agent&amp;rsquo;s iTunes pairing is kept between cards, how it reaches a new card, and one pairing per Pi. Not Spotify&amp;rsquo;s authorization, and not the other hand-kept secrets.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0037-hand-kept-secrets-are-encrypted-in-the-repository/"&gt;ADR-0037&lt;/a&gt;: its &lt;code&gt;secrets/&lt;/code&gt;, its age key and &lt;code&gt;sops&lt;/code&gt; are built here, for this first secret. A pairing is &amp;ldquo;made where it is used&amp;rdquo;, which that record leaves where it is made; this record says why a pairing is kept anyway. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0011-itunes-by-remote-pairing/"&gt;ADR-0011&lt;/a&gt;, whose consequence &amp;ldquo;lose it and pairing is repeated&amp;rdquo; this ends.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/"&gt;ADR-0010&lt;/a&gt;, the relay Pi. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0033-the-whole-back-end-on-one-pi/"&gt;ADR-0033&lt;/a&gt;, the backend Pi.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The iTunes driver controls iTunes as a paired remote (ADR-0011). Pairing&#10;takes a person at the iTunes PC, typing a four-digit code that the Pi&#10;prints. What it leaves behind is one small file on the Pi,&#10;&lt;code&gt;/var/lib/eds-npagent/itunes-pairing.json&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>ADR-0053: A Home Pi Opens a Maintenance Leg for the Van</title><link>https://cdeever.github.io/eds/docs/architecture/decisions/0053-a-home-pi-opens-a-maintenance-leg-for-the-van/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/architecture/decisions/0053-a-home-pi-opens-a-maintenance-leg-for-the-van/</guid><description>&lt;h1 id="adr-0053-a-home-pi-opens-a-maintenance-leg-for-the-van-for-a-while-when-asked-from-inside"&gt;ADR-0053: A Home Pi Opens a Maintenance Leg for the Van, for a While, When Asked From Inside&lt;a class="anchor" href="#adr-0053-a-home-pi-opens-a-maintenance-leg-for-the-van-for-a-while-when-asked-from-inside"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;span class="status-badge inc-orange"&gt;Proposed&lt;/span&gt;&#10;: until a window has been opened, used and closed on the backend Pi; see &lt;a href="#what-would-settle-it"&gt;What would settle it&lt;/a&gt;. It takes effect when the Pi&amp;rsquo;s cable leaves DVNT-CORE&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2026-10-28&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;How the mobile site reaches an EdS Pi that lives at home: a Wi-Fi leg onto the home LAN, off unless opened, and what it admits. The day-2 jobs that use it are named here and decided elsewhere.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Extends&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0010-home-lan-relay/"&gt;ADR-0010&lt;/a&gt;: a second leg, fenced, now off by default and opened for a time. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0033-the-whole-back-end-on-one-pi/"&gt;ADR-0033&lt;/a&gt;: the backend Pi, now at home.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Related&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0042-the-home-pi-becomes-a-deevnet-pi/"&gt;CHG-0042&lt;/a&gt;, which moves the backend Pi home. &lt;a href="https://cdeever.github.io/eds/docs/changes/2026/0028-the-back-end-on-one-pi-on-dvntm/"&gt;CHG-0028&lt;/a&gt;, which chose one address at home. &lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0052-each-pis-itunes-pairing-is-kept-encrypted-in-the-repository/"&gt;ADR-0052&lt;/a&gt;, one of the jobs. Deevnet ADR-0011, ADR-0013, ADR-0020 and ADR-0041, and Deevnet&amp;rsquo;s network segmentation standard.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="context"&gt;Context&lt;a class="anchor" href="#context"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The backend Pi has moved home (CHG-0042), and others may follow. At home&#10;it is on the home LAN, DVNT-CORE (&lt;code&gt;192.168.2.0/23&lt;/code&gt;, behind the home&#10;OPNsense). Its certificate, its tenant&amp;rsquo;s Terraform and the tools that&#10;look after it are on the mobile site, dvntm.&lt;/p&gt;</description></item></channel></rss>