Skip to content

Epic: native Android rewrite — Compose mobile + Android TV from one codebase #14

Description

@altaywtf

Program root for the native Android rewrite (Compose mobile + Android TV). Every launch-gating work item is a native sub-issue here — the tree and progress bar span this repo and putio-sdk-kotlin. Post-v1 upgrades live under #52 and do not gate this epic. Cross-program console: Frontend project. Sibling programs: Apple · TV web · www.

Current rollout status: 2026-10-01

Everything an agent can finish without an owner call is merged; what's left waits on Altay, hardware or credentials.

Autonomous batch: 2026-09-29 → 2026-10-01 (done)

Every batch PR merged; none open or abandoned:

Each item: one worker in its own worktree, ./gradlew verify plus both debug assembles, emulator proof attached to the PR, merge after green CI and a clean Codex review (bot, or local slopguard with Codex gpt-6.1-sol when the bot was out of quota).

UX audit: 2026-09-30

Every Android flow compared with app.put.io (putio-web apps/app @ 48f14ef), apps/tv-native / tv-vite, and putio-ios main @ 9c7264f. Findings cite file:line in each issue. References answer two former owner calls:

Wave 6 (agent-ready, TV release blockers first):

Scope notes from the audit:

Waiting on Altay

Still open from the batch

Item Status Next
#185 needs Altay URL source and VLC key pins (above)
#123 needs Altay ruling on structural findings, then extend detekt to every source root
#107 blocked one human devs-auto Auth Tab sign-in on the API 37 emulator, then record proof
#34 L6 blocked on #51 Fire TV remote smoke and oracle 17–31 parity; closes #9
#45 blocked on #51 audio passthrough only
#173 / #148 blocked on putdotio/putio-sdk-kotlin#43 pin io.put:putio-sdk-kotlin, drop the sibling checkout
#278 agent-ready check whether put.io refuses a move into a descendant; if not, needs SDK breadcrumbs

Outcome

One putio-android codebase ships two first-party surfaces:

  • Android mobile (phone + tablet): a new Jetpack Compose app with feature parity against the parallel iOS rewrite's product contract, adapted to Android platform conventions (Material navigation, AndroidX Auth Tab auth, share target, downloads, system media controls)
  • Android TV / Fire TV: a Compose TV app with behavior parity against the current React Native tv-native Android TV surface, replacing it on the existing Play listing

Both are backed by putio-sdk-kotlin as the only API boundary and themed from @putdotio/design tokens through a generated Compose adapter.

Decisions (settled)

Decision Choice
Sequencing vs ADR 0005 Android runs in parallel with the Apple loop; ADR 0005's "Apple first" gate is superseded (decision record to be written, tracked below)
feature/android-tv-full-parity branch Delete — clean slate. Never compiled, 3 months stale, AGP major behind. tv-native source + the 34-capture oracle are the only references
Order inside this repo Mobile first, then TV (after shared foundation + design adapter)
Play identity One package, one listing: both form factors ship as io.put.putio on the existing listing; TV versionCode must exceed 91
Offline downloads Lean core in mobile v1.0 (download, local availability, offline playback); queue-management polish fast-follows — iOS ships the fuller bar, delta recorded in the shared contract (#19)
Chromecast In mobile v1 (#36, after the core player) — iOS v1 ships Cast and it matters more on Android
Appearance Dark-only on both form factors — the cross-app contract (putio-ios#82): product apps are dark-only, only the public web surfaces (www, auth.put.io) may ship light; the token adapter keeps the light palette available for a future flip
Telemetry Sentry may ship in v1 only behind the approved diagnostics_enabled control and redaction boundary; PostHog/product analytics is out of v1 entirely
i18n strings.xml discipline from day one, English-only at launch; no putio-i18n commitment
Shared contract #19 produces a versioned v1 matrix; scope changes update both epics (#14 ↔ putio-ios#123) or neither
Release owner Altay — Play Console access, signing lineage, production rollout approval
tv-native Frozen: security/P0-playback-only hotfixes; all other defects route here (e.g. #45)
Visual source of truth @putdotio/design DTCG tokens (dist/tokens.dtcg.json, light/dark + tv group). tv-native is a behavior oracle only
API boundary putio-sdk-kotlin via composite build; no app-local HTTP without a documented SDK gap
Icons / fonts Phosphor icons and GT America via locked, drift-gated pipelines (mirror the putio-ios scripts); no committed font binaries

Rules of the program

  1. Agent-readiness first. Nothing ships before the harness workstream (W0) makes this repo autonomously workable by agents: environment bootstrap on a MacBook/devbox (cloud-friendly), emulator/device proof, putio CLI auth for live checks, and evidence capture built in.
  2. Definition of done, every child issue: repo verification green (./gradlew verify + flavor assembles), the behavior exercised on the local harness (emulator or device), and visual proof (screenshots or screen recording) uploaded to the PR with gh pr comment <n> --attach <file> (gh 2.99+); never commit proof media.
  3. Screenshot/behavior parity gates for TV come from putio-web apps/tv-native/docs/captures/ (34 Android TV captures) and the TV interface spec (Notion Frontend hub, page TV interface); mobile gates come from the shared mobile product contract.

Completion criteria

This epic closes when all of the following are true:

  • W0–W2 foundations, agent readiness, design adapter, and SDK prerequisites are complete
  • The Compose mobile app is released on the existing Play listing with the W3 v1 scope
  • The Compose Android TV app replaces tv-native on Play and has a verified Fire TV distribution path
  • Release, rollback, Sentry, signing, and physical-device proof paths are documented and exercised
  • Every remaining launch child is complete or closed with a recorded decision

Post-v1 work in #52 is explicitly outside this completion boundary.

Execution order

Every issue below is a native sub-issue of this epic, so this page tracks live progress across both repos. Steps run left to right; issues inside a step run in parallel. An issue starts when its step is reached and its named blockers are closed.

Step 0 — start today, all parallel

Step 1 — when #15 closes

Step 2 — mobile core (needs #20 + #19; auth also needs #47)

Step 3 — mobile surfaces, all parallel (need #22 + #23)

Step 4 — mobile media (need #24; playback needs sdk#23, downloads need sdk#24)

Step 5 — mobile ship (needs everything in steps 2–4)

Step 6 — TV, starts once the shared core is stable (~step 3), trails mobile

Post-v1 follow-up

Critical path to mobile v1: #15 → #20 → #23 → #24 → #27 → #31, with #46/#47 as the human-gated joins.
Critical path to TV cutover: #15 → #20 → #32 → #33 → #34 → #35.

Workstreams

Ordering: W0 → W1 unlock everything; W2 runs in parallel from day one; W3 (mobile) leads, W4 (TV) follows behind it reusing the shared core.

W0 — Foundation and agent readiness

Access, credentials, and release infrastructure (nothing lives only as an inline stop condition anymore):

W1 — Design system adapter

W2 — SDK hardening (putio-sdk-kotlin)

W3 — Mobile app v1 (leads)

W4 — Android TV parity (follows)

W5 — Audit hardening (2026-09-29)

Post-v1 follow-up

Deferred Android and SDK upgrades are native sub-issues of #52. They remain visible in the Frontend project with Program: Android and Phase: Post-v1; assigning a Wave is the scheduling decision.

Existing issues mapping

Key references

  • Kickoff assessment: Notion Frontend hub
  • TV product packet + parity oracle: Notion Frontend hub, pages TV app and TV interface; captures in putio-web apps/tv-native/docs/captures/
  • Mobile product packet: Notion Frontend hub, page Mobile app
  • Behavior reference app: putio-web/apps/tv-native (routes, playback architecture, OAuth ids: Android TV 6221, Fire TV 6233)
  • Design tokens: the @putdotio/design npm release pinned in design/putio-design.lock.json, fetched by scripts/sync-design-assets.sh and generated by :app:generateDesignTokens (build(design): fetch design assets from a locked @putdotio/design release #218)
  • SDK: putio-sdk-kotlin (12 namespaces including deviceCodeAuth and sharing; composite build wiring in this repo's settings.gradle.kts)

Risks and stop conditions

Verification

  • ./gradlew verify, :app:assembleMobileProductionDebug, :app:assembleTvProductionDebug green in CI
  • Every mobile slice proven on a phone emulator/device; every TV slice proven on a TV emulator plus Fire TV remote checks where behavior differs
  • TV screens count as done only with a native capture matching the corresponding oracle screenshot's route/state

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions