Skip to content

feat: add profile-scoped Recent channels v10 - #107

Merged
MrFr3di merged 48 commits into
mainfrom
feat/recent-channels-v10
Aug 5, 2026
Merged

feat: add profile-scoped Recent channels v10#107
MrFr3di merged 48 commits into
mainfrom
feat/recent-channels-v10

Conversation

@MrFr3di

@MrFr3di MrFr3di commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Scope

Implement R2 of #29: bounded profile-scoped Recent channels whose only write trigger is the service-owned accepted first-rendered-frame signal.

Implementation plan: docs/superpowers/plans/2026-08-05-recent-channels-v10.md.

Product contract

Durable profile-scoped history

  • identity is (profileId, canonicalChannelId);
  • write occurs only after accepted first rendered frame;
  • newer success timestamp wins; older/equal delivery is idempotently ignored;
  • retention is transactionally bounded to 50 rows/profile with deterministic tie-break;
  • only a missing profile rejects a trusted first-frame write;
  • logical canonical identity intentionally has no physical channel FK, so source refresh/catalog cleanup cannot destroy a legitimate first-frame event.

Active/profile-visible read truth

A Recent row is projected only when that canonical identity currently has a stream variant from the source's activeRevision and is not hidden for the selected profile. Hidden or temporarily inactive history remains bounded internally and may reappear only when the same canonical identity becomes active/visible again.

Playback ownership

  • RecentPlaybackObserver consumes the existing direct first-frame observer fan-out;
  • exact profile/channel identity is preserved;
  • wall-clock history time is captured only after first frame;
  • persistence runs on a process-lifetime supervised IO scope;
  • persistence failure cannot break playback or sibling observers;
  • Media3 remains independent from Room.

TV surface

  • Channels supports Все / Избранное / Недавние;
  • Recent keeps repository newest-first ordering;
  • bounded copy says Показано, never claims an exact total;
  • filter/row D-pad graph is deterministic;
  • empty Recent recovers to All;
  • Recent → Player → Back restores canonical focus.

Room v10

  • migration 9→10 creates recent_channels;
  • exact generated schema is committed at core/database/schemas/app.muxtv.database.MuxTvDatabase/10.json;
  • version 10;
  • identity hash f6625d546ddfbad62e4e33340b17f490;
  • SHA-256 809c0bfa812e5a86a5a84d97fe4f48f1d9ac71e515c5745ef222f24689e926c4;
  • temporary schema-publishing files/workflow were removed and are absent from the final diff.

Defect found and fixed during acceptance

The first old-edge Product matrix exposed migration-test harness drift: EpgMigration4To5Test validated 4→5, then opened current Room v10 while registering migrations only through 8→9. Commit 9492702 adds production MIGRATION_9_10 to that current-schema open without destructive fallback or runtime migration changes.

Final exact-head acceptance

Exact head: d095fb0e99485f93f9dbed8675c13b0f5ac52537.

Android TV product DeviceMatrix 31027992936 — success against a conflict-free merge with accepted main@158210876251a95869463208da9491d7f46f0663.

The matrix includes its own Full host acceptance before AVD execution and then runs all connected product suites sequentially on exact Android TV API26 and API36 profiles.

Per profile:

  • database instrumentation: 120 tests, 0 failures/errors/skips;
  • application instrumentation: 26 tests, 0 failures/errors/skips;
  • Media3 instrumentation: 12 tests, 0 failures/errors/skips;
  • credentials instrumentation: 4 tests, 0 failures/errors/skips;
  • importer EPG integration: 1/1;
  • remote EPG integration: 1/1.

Schema evidence is byte-identical on host, API26 and API36:

  • SHA-256 809c0bfa812e5a86a5a84d97fe4f48f1d9ac71e515c5745ef222f24689e926c4;
  • identity f6625d546ddfbad62e4e33340b17f490.

Separate Self-hosted Full 31027992891 and Database DeviceMatrix 31027992820 were queued by path ownership, but are redundant independent invocations of the host/database work already executed successfully inside the exact-head Product DeviceMatrix. They are not treated as missing evidence.

Final semantic/privacy review:

  • public playback always performs profile-aware active-channel lookup before variant lookup;
  • Recent stores no locator, headers, credential, provider/source identity or programme text;
  • filter changes invalidate old Guide generation/state;
  • final diff contains only product code, tests, exact schema and implementation plan;
  • unresolved review threads: 0.

Non-goals

No Home shelf, full Guide, fallback/Doctor, alternate player, M3U conditional validators, CI Phase 2, Paging3, Rust/UniFFI, speculative indexes or secret-bearing Recent state.

MrFr3di added 30 commits August 5, 2026 01:44

@MrFr3di MrFr3di left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static execution checkpoint while self-hosted CI is disabled:

  • keep this PR draft/unmerged;
  • complete only R2/Recent semantics, schema and Channels integration here;
  • do not add Home/Guide/FFmpeg/CI Phase 2 to this branch;
  • exact-head Full + DB old-edge/current + Product old-edge/current remain mandatory before ready-for-review/merge;
  • current known-red root cause is stale test references to removed RecentChannelWriteResult.TargetUnavailable; production API already uses ProfileUnavailable.

@MrFr3di MrFr3di left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static review after fixing the two stale enum fixtures on head b268557de3ab9dc23b721c8f0e1efd7abb2aa0a4:

  • Room entity, MIGRATION_9_10, DAO semantics and the previously generated Room v10 artifact agree on the intended schema: composite (profileId, canonicalChannelId) key, profile FK only, no canonical FK.
  • Historical generated v10 identity hash: f6625d546ddfbad62e4e33340b17f490.
  • Current read path preserves active/current-revision + non-hidden truth and repository newest-first order.
  • Channels filter/focus wiring remains stable-key based for restoration and first-row Up targets the selected filter.
  • MainActivity -> AppNavigation -> ChannelsRoute carries the same required Recent repository; Media3 remains independent of Room through the app observer boundary.

No additional runtime semantic change is proposed from this static pass. Remaining hard blockers are generated 10.json commit and exact-head build/device validation once a build environment/self-hosted runner is available. Keep draft/unmerged.

@MrFr3di MrFr3di left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Execution boundary while self-hosted CI is off: do not add Home/Guide/transport/FFmpeg work to #107. Finish R2 as persistence + Channels only; generated schema and exact-head Full/DB/Product gates remain mandatory before merge.

@MrFr3di MrFr3di left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next accepted sequence after #107 (separate clean branches from accepted main, never stacked): #110 compressed EPG transport -> #114 catalog truth invariants -> bounded Guide/#29 -> #108 transport classification -> #109 measured buffering -> #117 FFmpeg audio spike only on codec evidence -> #30 fallback/Doctor -> #111/#116/#113/#118 hardening -> #31 alpha/release. CI #101 remains a separate optimization and is not the product critical path.

@MrFr3di MrFr3di left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Runner-off checklist for the next resume:

Can complete now by source/static work: stale call-site cleanup, schema/entity/migration semantic comparison, DI/navigation/focus review, privacy review, PR scope cleanup.

Must wait for build environment: commit/re-generate exact Room 10.json, run JVM/Android compile, migration matrix, API old-edge/current TV journeys, release/lint checks.

Do not interpret absence of new CI failures while the runner is offline as success.

@MrFr3di MrFr3di left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static privacy boundary remains unchanged: Recent persists only profile ID, canonical channel ID and successful-playback timestamp; no URL, header, credential, query, provider locator, programme title or raw exception is added to persistence/diagnostics by this PR.

@MrFr3di MrFr3di left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plan document updated at commit 35f9f853c01ffee5b9d2bf8191b1d3361fc463e0: docs/superpowers/plans/2026-08-05-recent-channels-v10.md now records completed source work, generated-schema blocker, runner-off restrictions, Home R2B split and final acceptance order.

MrFr3di commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

Current exact-head update after device-evidence review:

  • exact head: 949270283c60f3939c91d449a761e09b4f1a334d;
  • prior product matrix exposed a real old-edge test-harness drift: EpgMigration4To5Test opened the current Room schema with migrations only through 8→9, so Room v10 correctly rejected the missing 5→10 path;
  • commit 9492702 adds production MIGRATION_9_10 to that current-schema test open without destructive fallback or runtime migration changes;
  • final-head product matrix 31021435642 — success on the old-edge/current AVD path;
  • final-head database migration matrix 31021436448 — queued on the single self-hosted runner at this check;
  • final-head Full 31021437239 — queued at this check;
  • unresolved review threads — 0 at this check.

The exact generated Room v10 artifact remains the explicit unclosed static merge gate. Verified generated artifact: version 10, identity hash f6625d546ddfbad62e4e33340b17f490, SHA-256 809c0bfa812e5a86a5a84d97fe4f48f1d9ac71e515c5745ef222f24689e926c4.

Keep draft/unmerged until the exact 10.json is committed and the remaining final-head gates are green.

@MrFr3di
MrFr3di marked this pull request as ready for review August 5, 2026 17:18
@MrFr3di
MrFr3di merged commit 7af053c into main Aug 5, 2026
2 of 3 checks passed
@MrFr3di
MrFr3di deleted the feat/recent-channels-v10 branch August 11, 2026 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant