Files
OrbitTv/docs/roadmap.md
T
pauljdandClaude Opus 5.5 a90d6f7204
pauljd/davidson-ci: Davidson CI / quality (push) Failing after 2m2s
pauljd/davidson-ci: Davidson CI / ai-review (push) Successful in 52s
Add approved roadmap, programming bible and references
Roadmap, programming bible, metadata and matching design and asset
inventory, as approved by Paul on 1 November 2026. Keeps both source
briefs and the line-up concept sheet in the project, since their only
copies were in Codex's working folders.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-01 18:00:02 +00:00

11 KiB

Orbit TV roadmap

Approved by Paul on 1 November 2026. Companion documents: programming bible, metadata and matching, asset inventory. Source briefs are in briefs.

Decisions

Paul approved these on 1 November 2026.

Conflict found What the sources say Decision
103 name Installed as "Toonami". The bible has Vortex, and 103's search list also holds titles the bible now gives to Heroes and Orbit X. Rename the display to Vortex, keep 103 and its lineup. Toonami is a third-party brand, and the creative brief bars those as default branding.
101 name Installed as "Orbit One", bible says "Orbit 1". Use Orbit 1 on screen, keep 101.
Box office and game names The app and its artwork say OrbOffice and OrbHive. Both briefs say OrbitOffice and OrbitHive. Use OrbitOffice and OrbitHive going forward. Rename the app and artwork in a later build.
Orbit X and Ring X look Both call for silver or chrome with an aggressive red X, and the bugs will sit on the same screen. Keep the red X for Orbit X's cartoon slash. Give Ring X a distinct silhouette, decided when its board arrives.
102 content Built from Horror, Thriller and Science Fiction film searches. The bible separates Orbit Horror and defines After Dark as cult and late-night. Keep 102 as built. Change its rules when presets arrive, and don't claim adult controls before profiles exist.
Title moves Toy Story moves from Wonder to PixelZ. Batman Beyond and The Powerpuff Girls drop off Vortex in the new table. Latest table wins. Batman Beyond stays a permitted crossover and The Powerpuff Girls moves to Rewind. Existing 103 choices stay.
Order of work Your earlier order had controlled refresh and the grid guide. The new priority list names neither. Keep both, as shown in section E.
Profiles Listed as a later priority, yet matching treats audience suitability as a required filter. Capture ratings early and show them. Treat real enforcement as a gate before anyone outside your household uses mature channels.

Current status

The status below comes from the source code, the verification notes and Paul's reports from the box. The roadmap update's list of working features is right in spirit, but discovery and channel generation are much narrower than it implies.

Implemented

These are working, with Paul's confirmation noted where given.

Feature Actual extent Confirmed by
Emby sign-in and remembered login One fixed provider. Encrypted saved token, no saved password. Paul, on 0.14
Metadata access Hand-triggered, small queries: 20 items per page, 10 series per search, 5 episodes per series. No full library read. Paul, on 0.3
Clock-driven channels Repeating UTC timeline. Joins in progress, real Now and Next, automatic rollover. Paul, on 103
101 Orbit One Built from the checked sample, up to three titles. Partly: built and saved
103 Toonami One to three approved series, up to five episodes each, from a 23-title search list. Paul
102 Orbit After Dark Two or three approved films from genre searches. Paul: played, with a tuning-screen issue
After Dark artwork in the app Compact logo and lit-window background, on the review and guide screens. Paul
Programme strip and channel switching Strip hides after five seconds. Switching works between built channels. Paul for the strip; switching not separately reported
Demo guide grid, ticket previews, Services page Fictional data, not connected to Emby. Paul, on 0.2

0.16 replaces the blue tuning panel and passes 87 tests and lint. It was installed on the box on 1 November 2026, and Paul's test of it is outstanding.

Approved direction

  • The 25-channel lineup in section A, as presets matched against each user's library, never bundled content.
  • Tick-based selection: available titles can be ticked, and missing titles stay visible, unticked and marked unavailable.
  • The clock-driven schedule stays, and new work plugs into it.
  • Original Orbit assets only. Concept art is reference, and After Dark is the reference workflow.
  • Optional, explainable personalisation, with no mandatory AI or cloud service.
  • OrbitOffice as occasions, not a catalogue.

Proposed

These need technical review: sections B, C and F, time-of-day and weekly programming, repeat rules, and the catalogue storage choice.

Future

Profiles and PINs, more providers, authorised IPTV and external guide data, themes, Catch Up, OrbitHive Bedlam, OrbText, first-run onboarding, self-hosting and public distribution.

Blocked or uncertain

  • Metadata quality: unknown until tested. Nobody has measured how much of it the provider returns.
  • Provider load: the provider's rate limits and any rules on full library reads are unknown.
  • Playability at scale: each title needs its own playback check, and only direct-play sources work because transcoding is off.
  • Names and rights: clearance isn't established for Orbit or any channel name. Curated title lists and references to other brands need review before public release.
  • Transparent video idents: support is unproven on the box, and current idents are opaque H.264.
  • New concept boards: the eight new boards haven't been received.

Roadmap changes

The roadmap gains two steps the update doesn't name, the metadata audit and a generic channel list, and keeps every earlier milestone. P1 to P6 are your priorities, and arrows show what must exist first. Branding can run alongside the other work once channels exist.

flowchart TD
  fix["Now: 0.16 tuning fix, test on 102"] --> audit["Metadata audit"] --> cat["P1 Catalogue and refresh"]
  cat --> preset["P2 Preset matching"]
  cat --> list["Generic channel list"]
  preset --> rec["P5 Recommendations"]
  list --> grid["Grid guide restored"] --> brand["P4 Branding rollout"]
  list --> sched["P3 Schedule quality"] --> office["P6 OrbitOffice"]

Gate before mature channels reach other households: profiles and enforced ratings.

Later: more providers, IPTV, themes, Catch Up, OrbitHive Bedlam, OrbText, public release.

The grid guide comes before most new channels, because switching one at a time gets unwieldy past a handful. That follows your earlier request to bring the guide back as channels grow.

What each step needs from today's code

The clock engine stays. These limits are the parts that have to change, and only the last row changes how the clock behaves.

Today Why it matters Needed for
Queries capped at 20 items, by hand No library-wide view P1
512 KiB saved state, fixed channel slots, numbers 101 to 103 only Can't store a catalogue or a fourth channel P1, channel list
Channel lineups of 2 to 15 unique titles Too small for real channels, and blocks intentional repeats P3
One repeating loop anchored to UTC No concept of weekday, evening, local time or daylight saving Dark Files, Ring X, OrbitOffice

For that last row, I'd keep the loop as the default and add an optional local-time block layer that hands each block a lineup. It needs its own design and your approval before any work starts. That also meets your rule against replacing the engine.

Earlier milestones kept

Milestone Where it now sits
Original channel set: 101, 102, 103 Done, pending the 0.16 test
Controlled refresh, previewing additions and removals without shifting what's playing P1
Reusable and custom channel creation with ticks P2 and channel list
Grid guide with real Now and Next After channel list
Bottom-left bug, off by default P4
Optional idents with reduced-motion setting, never delaying the clock P4
Dashboard: On now, Coming up, OrbitOffice presents With P5 and P6
First-run onboarding and more providers Later, Emby preserved
Profiles, Kids, PIN Later, with the gate shown above
Themes, Catch Up, Games, OrbText Later, unchanged
Seasonal programming and themed weekends P3 and P6

The gate only applies once someone else's household is involved, so it doesn't hold up your own box. Until then, Orbit shouldn't describe any channel as age-protected.

Next development step

I recommend a read-only metadata coverage check as 0.17, after you've confirmed 0.16 on the box. It answers the question every later decision depends on: how much usable metadata does your provider return? Nothing gets built on guesses, and your channels are untouched.

Scope

  • Entry point: a new "Check metadata coverage" action under Menu, Connect Emby.
  • Requests: one sample each of films, series and episodes, at most 20 items each, and only when you press it.
  • Result: counts only, such as "Genres 18 of 20", for each field in section B. No titles are shown.
  • Sampling: existing queries sort by name, which favours titles starting with A. This one should take a spread across the library and label itself a sample.

It won't save anything, change a channel or schedule, classify titles, or build the catalogue.

Files likely to be involved

File Change
MetadataAudit.kt (new) Build the requests, count field coverage
EmbyConnectionScreen.kt The action and the results screen
MetadataAuditTest.kt (new) Fixture tests
app/build.gradle.kts, EmbyClient.kt, SecureMediaDataSource.kt Version bump, as in past releases
VERIFICATION-0.17.0.md (new) Release notes and evidence

Risks

Risk Handling
Provider load or rate limits Three small requests, only on demand. Existing cooldown applies, and a rate-limit reply stops the check.
Oversized replies from extra fields Existing 2 MiB response cap, with a clear message if hit
Sample misleads Label results as a sample, not a library total
A field name differs from Emby's documentation Check the documentation first, and report a missing field as zero, not as an error
Private catalogue exposure Counts only, nothing saved or logged

Acceptance criteria

  • One press sends at most three requests, each capped at 20 items.
  • The screen shows coverage counts for each item type and field, with no titles.
  • 101, 102 and 103 keep their lineups and timing, and saved setup is byte-for-byte unaffected by the check.
  • An expired login or rate limit gives a clear message and stops.
  • You can run it with the remote, then read or photograph the result for me.

Tests

Fixture tests cover the request limits and the token staying in the header, not the URL. They also cover missing and malformed fields, a server ignoring the limit, rate-limit and expired-login stops, and no saved-state writes. The full 87 existing tests and lint must still pass, and you then run it on the box.

Rollback

Reinstall the 0.16 APK kept in outputs/revision-0.16.0. The saved data format doesn't change, so your login and channels should survive, which I'd confirm during the test.

The project is now in git, so each release can also be rolled back from its commit, which the channel-list migration will need later.