Skip to content

Latest commit

 

History

History
143 lines (122 loc) · 17 KB

File metadata and controls

143 lines (122 loc) · 17 KB

Spec Overview

The map to specs/. Each module spec is the source of truth for its area — this page is the map, not the territory.

For what is still unfinished and in what order to close it, see gap-closure-plan.md (Apple TV tracked separately in specs/1000-apple-tv/).

Structure & numbering

Specs are organized as one durable spec per module, mirroring the Swift packages. There is no chronological feature numbering anymore; a single concern lives in exactly one spec.

  • Hundreds-block per topic. Each module owns a Nxx block: 100, 200, … 700.

  • Sub-spec room. N10, N20, … inside a block are reserved for sub-specs (a deferred or spun-off capability of that topic). Example: 110-shared-album-link is a sub-spec of the 100 data-access topic.

  • Requirement IDs carry the full spec number: FR-<specnum>-NN and SC-<specnum>-NN (e.g. FR-700-03, SC-200-05). This keeps a sub-spec's IDs from colliding with its parent block and makes any ID self-locating.

  • Deferred capabilities are not deleted: each topic spec ends with a Roadmap / Deferred section, and substantial future work gets a reserved sub-spec number (and, where it already has a real outline, its own Status: Deferred spec).

  • Supporting processes get a separated four-digit block. The 100–1200 blocks are product modules that mirror Swift packages. Some durable concerns are not modules at all — they govern how the product is presented rather than what it does. Those live in a clearly separated 9000 block, far above the module range so the two can never be confused, and they use the same N / N10 / N20 sub-spec convention scaled to four digits: 9000-design-language is the topic, 9010-store-presentation its sub-spec. The requirement-ID rule is unchanged — they read FR-9000-NN / SC-9000-NN and FR-9010-NN / SC-9010-NN, so an ID still locates its own spec. Such a spec's Package column names the surfaces it governs, not a package it owns.

When a genuinely new module appears, give it the next free hundreds-block. A new capability of an existing module becomes a sub-spec (N10, N20, …) or amends the module spec directly.

Topics

# Spec Package Purpose Status
100 immich-client ImmichClient REST data access: albums, album assets, preview/original/thumbnail image data, errors. Active
110 shared-album-link ImmichClient (sub-spec of 100) Play a shared/public Immich link (+ optional password) as a source. Active
120 source-library ImmichClient (sub-spec of 100) Save several switchable sources (albums + shared links); one active. Active
130 immich-api-v3 ImmichClient (sub-spec of 100) v3-only API baseline: album assets via metadata search, shared-link assets via /me, shared-link password in body, outdated-server (v<3) notice. Drops v2. Active
200 connection-onboarding OnboardingKit First-run setup, in-place connection editing, and the Settings-screen structure. Active
210 shared-link-onboarding OnboardingKit (sub-spec of 200) Choice-first onboarding, shared-link-only setup (no API key), iOS Share Sheet acceptance, resolve-first/password-when-needed, one searchable/subscrollable album picker shared by onboarding + Settings. Active
220 onboarding-welcome OnboardingKit (sub-spec of 200) Welcome-screen overhaul: iCloud album at the top, camera QR scan for shared links, and three friction-ordered options with light decoration; reuses the 900 photoLibrary source. Camera end-to-end is a device gate. Merged to main (2026-07-18); camera QR end-to-end (SC-220-07) still a device gate
300 slideshow SlideshowKit Fullscreen playback engine + Liquid Glass UI: chrome, gestures, album browser, info. Active
310 slideshow-resilience SlideshowKit (sub-spec of 300) Auto-retry with backoff + periodic source refresh — unattended frame survival. Active
320 disk-image-cache SlideshowKit (sub-spec of 300) Byte-capped disk cache + remembered source list — whole-album offline survival incl. relaunch; budget in Settings (500 MB default). Active
400 power-manager PowerKit Keep the display awake and dim brightness while the slideshow runs in the foreground. Active
410 brightness-mode PowerKit + app target (sub-spec of 400) Automatic (iOS decides, OwnFrame never writes) by default; Fixed holds a remembered level for a frame whose light sensor is covered; a free night window keeps nights very dim; Home Assistant/Shortcuts set session-only overrides, last event wins. Built 2026-09-28 — device checks open (SC-410-06/07)
500 display-options ThemeKit User-configurable order/duration/transition/Ken Burns/fit/quality/clock, applied live. Active
510 clock-overlay ThemeKit + app target (sub-spec of 500) Rendered clock overlay: Digits/Pill/Analog styles, six places + Random, Room/Cozy sizes, yields while chrome shows; off by default. tvOS rendering rides 1000 (FR-1000-10 pixel-shift — not started). Implemented (iOS/iPadOS, 2026-07-18)
600 broker-setup BrokerSetupKit Enter and persist MQTT broker credentials (Keychain) so 700 has something to connect to. Active
700 ha-control HAControlKit Remote control via MQTT/HA: availability + pause/play + brightness + album (730 deferred). Amended 2026-07-21: frame identity (US3, FR-700-16…22, SC-700-11…14) — identity must survive reinstall and is split from a user-editable frame name; documents a live-verified defect against FR-700-06. Active — identity amendment implemented + merged to main (2026-07-21, PR #19); issue #15 closed
710 ha-full-control HAControlKit (sub-spec of 700) Read/set every display setting, next/previous, current-photo image + metadata, and diagnostics over MQTT. Active
800 app-intents app target (+ AppIntentsKit) Shortcuts/Siri/personal-automation control via App Intents — second front-end to 700's command surface. Merged to main (2026-07-18); device gate T029 (SC-800-02/03) pending
900 photo-library-source PhotoLibraryKit (new) Apple Photos / iCloud albums (incl. Shared Albums) as a source, behind a backend-neutral source protocol. Amended 2026-07-16: full-access gate, shared-album quality ceiling, iOS 27 rebuild risk. Merged to main (2026-07-18); device/beta gates pending
1000 apple-tv tvOS app target (new) Apple TV port: same packages/engine on tvOS 17+, purgeable-storage discipline, config sync (non-secrets via KVS, secrets E2E via CloudKit encrypted fields — constitution III v1.1.0), remote-first chrome, HA device parity. Merged to main (2026-07-18): all four user stories implemented + sim-verified. US1 (frame plays, real demo-link end-to-end), US2 (onboarding + real-source routing + KVS prefill/restore + secret hydration seam), US3 (purge-tolerance), US4 (HA adapter + coordinator with distinct identity + broker onboarding). All packages tvOS + new ConfigSyncKit; software-dim, remote chrome, FR-1000-07 bypass removed; iPad companion publishes full payload on launch/foreground; ThemeSettings Codable. Ken Burns redesigned here (2026-07-18 micro-judder fix): shared scoped-animation KenBurnsMotionModifier + DecodedImageStore decode-ahead — motion contract unchanged, swap decode-stalls eliminated (see 1000 tasks.md Status). Remaining (device-gated): real MQTT/CloudKit, tvOS clock + FR-1000-10 pixel-shift, real-hardware gates (SC-1000-02/05/06/08 + CloudKit-on-tvOS proof + 24h soak).
1100 purchase-gate app targets (package decided at plan time) Purchase gate: free core stays whole (all sources + core playback + basic transitions); a single one-time Supporter Unlock grants every gated capability at once (ambience — Ken Burns + clock, never-publicly-shipped rule — plus HA/MQTT + App Intents); no tiers, no bundle; offline entitlement caching for unattended frames; Family Sharing + universal purchase (incl. tvOS); never-claw-back; gated build must be the first public release (v1.0 b8 stays unreleased). No price points in-repo by design. Merged to main (2026-07-20, PR #14; tiers collapsed into the single Supporter Unlock 2026-07-23, PR #40): entitlement model + all US1–US6 gates/UI + US5 broker degradation + the real StoreKit adapter + the tvOS unlock surface green (measured 2026-07-25: PurchaseKit 106 host, full iOS suite 163/0/5; the 5 skips = ASC-screenshot + live-smoke + 3 device-rig items). tvOS surface Apple-TV-simulator screenshot-verified. Remaining: T042 only — the manual ASC day (create the IAPs, sandbox purchase/restore/Family-Sharing/universal checks, release sequencing FR-1100-17), blocked on ASC access.
1200 observed-fixes OnboardingKit + app UI, SlideshowKit, HAControlKit Work-order bundle of three fixes observed on the running frame: Album-tab no-server guidance instead of a dead-end load error (FR-210-30), Ken Burns honors the Fit setting instead of forcing Fill (FR-500-20), battery + charging as free read-only HA telemetry (FR-710-23). Defines no new durable FR-1200 IDs. Merged to main via PR #39 (2026-07-22); live MQTT/HA + perceived-motion checks ride the device day
9000 design-language cross-cutting: both app targets + every String Catalog (no package of its own) Supporting process, not a module. The governing design language for app UI and store copy, so the two cannot drift: always-dark appearance, the SF Pro type scale, the surface palette and the single declared accent, the content-column/inset-grouped/photographic-row layout rules, and the DE/EN vocabulary that retires "API key", "server address", "instance" and "Add a source" from the first-run path. Written after the design canvas of 2026-09-01 as the record of what it converged on, in the same relationship quiet-glass has to 500/510. Owns no screen: the UI overhaul applies it and amends 210 (album picker) and 220 (welcome). Active — specced 2026-09-01; accent landed (AccentColor declares Messing #E3A857, FR-9000-14, 7eba377), one name per source and dark app-wide landed (73ff5f0); empty/error-state layouts still open (see its Roadmap)

How they connect

100 ImmichClient ──> 200 Connection & Onboarding ──> 300 Slideshow (engine + UI)
        │                                                  │
        │                          400 PowerManager <──────┤  (foreground brightness / idle)
        │                          500 Display Options <───┘  (order/duration/transition/clock)
        │
       110 Shared Album Link (source kind) ──┐
       120 Source Library (switchable list) ─┴─> surfaced in 200 (onboarding/Settings) + 700 (select)

600 Broker Setup ──> 700 HA Control (MQTT remote control)
                              ├─ active: pause/play, brightness, source-select (120)
                              ├─ active: 710 full control (settings, photo, diagnostics)
                              └─ reserved: 730 sleep/wake

310 Slideshow Resilience ──> 300 (auto-retry + periodic refresh; implemented 2026-07-09)
320 Disk Image Cache ─────> 300 + 310 (offline photo survival; implemented 2026-07-09)
510 Clock Overlay ────────> 500 (styles/places/sizes) + 300 (renders in the ambient layer)
                             + 710 (HA-wired); tvOS rendering owned by 1000
800 App Intents ──> 700's command surface (Shortcuts/Siri/automations, no MQTT; merged 2026-07-18)
900 Photo Library Source ──> 120 source library (new kind) + a source-neutral data
                             protocol that 100 and PhotoKit both implement (merged 2026-07-18)
1000 Apple TV ──> second app target reusing every package: 210 onboarding semantics,
                  320 purge tolerance (as the normal case), 400 seam (software dim),
                  600/700/710 parity as a distinct HA device (merged 2026-07-18;
                  Photos source on tvOS still roadmap with 900)
  • 200 owns the Settings-screen surface; it surfaces the 600 (Broker) and 500 (Display) sections and the 400 (brightness) control without re-specifying their behavior.
  • 210 evolves 200's onboarding (choice-first entry, shared-link-only path, Share Sheet, the searchable album picker) and reuses 120's source library + shared-link secret store and 100/110's shared-link resolution; it adds no new backend behavior.
  • 300 consumes 500 (option values), 400 (brightness), 100/110 (sources) and delegates reset to 200 — it does not redefine them.
  • 9000 / 9010 sit outside the module graph and own no behaviour. 9000 constrains how every screen above reads and looks (appearance, type, layout, vocabulary); 9010 applies that same language to the store page. When applying 9000 turns up a behaviour change, it is specced in the owning module — for the current UI overhaul, 210 (album picker) and 220 (welcome screen).

Reading order

Core path: 100 → 200 → 300, then 400 / 500 as the slideshow's foreground-power and display layers, then 600 → 700 → 710 for the Home Assistant remote-control path. 110 feeds 120's source kinds — read it alongside 120.

Before touching any user-visible surface — a screen, a string, or a store asset — read 9000 first, and 9010 as well if the work touches the store page. They are short, they are binding on everything above, and they are the reason a reviewer can cite a requirement instead of taste.

Reserved / deferred (roadmap)

Recorded in each owning topic's Roadmap / Deferred section. 110/120/710 shipped and are Active above. 310, 320 and 510 are implemented. 800, 900, 220 and 1000 are no longer deferred — all four are implemented (see their table rows); what remains for each is real-hardware verification, which shares a single device day (docs/manual-verification.md). 900 and 1000 interlock: 1000 reuses 900's source protocol, and the Photos source on tvOS is prototype-gated in both roadmaps.

Reserved sub-specs / future sources:

  • 730 HA sleep/wake driven by an HA presence signal (pairs with the 400 sleep/wake roadmap item).
  • Multi-source pooling (merge into one stream) and Memories as sources (topic 100 roadmap) — 120 covers switching between sources, not pooling.

Specified but not yet built (carried over from old "extended/added" notes, deferred during the overhaul so every Active requirement maps to real, tested code):

  • Disk image cache + size limit + Clear-cache action — promoted to sub-spec 320-disk-image-cache, implemented 2026-07-09.
  • Auto-retry with backoff / periodic source refresh — promoted to sub-spec 310-slideshow-resilience, implemented 2026-07-09.
  • Rendered clock overlay — design agreed 2026-07-18 (500, FR-500-12/17/18/19: Digits/Pill/Analog, six places + Random, Room/Cozy sizes, yields while chrome shows); promoted to sub-spec 510-clock-overlay, implemented on iOS/iPadOS 2026-07-18. Still open: tvOS rendering + the FR-1000-10 pixel-shift contract, both owned by 1000.
  • Settings/onboarding source management — now built: 120 owns the source library and 210 delivers the choice-first onboarding, shared-link-only setup, iOS Share Sheet acceptance, and the shared searchable album picker (onboarding + Settings). Remaining 210 work is polish + a device Share-Sheet pass, not new surface.