Skip to content

quest: plan HLS listing of catalog contributions - #7645

Merged
kixelated merged 2 commits into
mainfrom
quest-plan/hls-contributions
Nov 3, 2026
Merged

kixelated merged 2 commits into
mainfrom
quest-plan/hls-contributions

Conversation

@kixelated

@kixelated kixelated commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

A catalog can list whole contribution broadcasts in its root contributions map (moq-dev/moq#7312), and @moq/watch opens one lazily. moq-hls ignores them, so an HLS-only viewer cannot reach a contribution's renditions, such as an on-demand transcode ladder, from the broadcast's master playlist. No quest owns this.

Approach

Plans HLS lists contributions in m0, after HLS export on a declared grid, which it requires: the master reads each contribution's catalog and lists its renditions, while each contribution rendition's media is subscribed only once a player requests it and released once players stop fetching.

Choices made while planning, for review:

  • The master reads the contribution's catalog (maintainer decision, 2026-11-02). The maintainer accepted that the master reads each contribution's catalog when it's served, because it needs bandwidth and codecs. Only the contribution's media waits for a player's media playlist request, and a catalog read starts no encoding. The Plan records this as decided. The draft gains a rule that an HLS master selects every contribution it lists, and one that an on-demand publisher answers the catalog without starting media, as moq-transcode already does.
  • Contributions are followed, not bound. Source::bind never re-resolves a path after a replacement (rs/moq-mux/src/source.rs:326-327). So each contribution is followed with Source::follow, and each instance gets its own moq_mux::Source, pinning that instance's reads. An entry that names an instance follows only that stream.
  • Idle release of a contribution rendition's subscription, derived from the RFC 8216 reload interval and measured from the last finished request. A request still in progress keeps the demand. Without the release, an on-demand encode would never stop once one player fetched it.
  • Shared grid required. A contribution with another media.join.interval is left out, since players switch variants by segment number.
  • DASH and the recorder stay out, with reasons in the quest.
  • Searched the tree and history first: moq-dev/moq#7312 deleted the contribution-ref quest it finished, and no open quest or PR covers HLS.

Impact

None; quest files only. The planned work is additive in moq-hls and adds a rule to the hang draft.

Alternatives

  • Listing contribution renditions without reading their catalogs: HLS requires BANDWIDTH per variant.
  • Subscribing every contribution rendition with the master, like the broadcast's own: starts every on-demand encode for any viewer.

Follow-ups

None.

Review

  • Reviewer: Codex, gpt-6.1-sol, medium effort (quest review --base origin/main, round 1 of session 01a19f17-58f3-70e3-9a7b-97469d71b0fc)
  • Head: 5fe085a
  • Findings: none
  • Online review findings on d5785f7, all fixed in 5fe085a:
    • CodeRabbit r4449591760 and the OpenAI P2 review: Source::bind never follows a restart. Fixed: the plan now uses Source::follow, with a Source for each instance.
    • CodeRabbit r4449591765: the idle release ignored a request still in progress. Fixed: a request in progress keeps the demand, and the window is measured from the last finished request.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

  • New quest quest/m0/hls-contributions.md — plans moq-hls listing each root-catalog contributions entry's renditions in the master playlist, reading a contribution's catalog for BANDWIDTH while subscribing no media, with lazy per-rendition subscription and RFC 8216 6.3.4 idle release.
  • quest/m0/README.md index bullet — adds the quest to the m0 Required list.

I verified the plan's load-bearing claims and cross-links against the head tree:

  • moq-dev/moq#7312 matches the cited "list whole contribution broadcasts in the catalog" work (merged 2026-11-01, adds lazy Broadcast.contribution), and rs/moq-hls has no contribution handling today.
  • moq_mux::Source binding is real: rs/moq-mux/src/source.rs:336 (bind) is what rs/moq-hls/src/export/rendition.rs:148 uses, matching the "resolve like a rendition's reference" plan.
  • The hang draft's ## Contributions section exists (drafts/draft-lcurley-moq-hang.md:213) and already says a consumer opens a contribution's catalog only on selection, so the planned draft addition is a genuine rule, not a restatement.
  • moq-transcode only encodes on rung demand (rs/moq-transcode/src/rung.rs:3), supporting the on-demand-publisher claim.
  • RFC 8216 §6.3.4 is "Reloading the Media Playlist File", so the idle-release citation is correct.
  • Cross-links resolve: quest/m0/hls-media-grid.md, quest/m2/hls-follow-once.md, and doc/bin/hls.md all exist, and no other quest plans HLS contribution listing.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@kixelated kixelated 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.

Automated review by review (OpenAI)

Reviewed commit: d5785f7

  • P2 — Reconcile contribution following with pinned bindings (quest/m0/hls-contributions.md:25–31). The plan mandates Source::bind and its pinning while promising restarted contributions follow the new instance. rs/moq-mux/src/source.rs:206–235,321–341 keeps the first resolved broadcast, including after replacement. A contribution restarting while its parent remains live would remain attached to the ended publisher. Use the existing Source::follow lifecycle for contributions intended to follow, while keeping rendition reads pinned to their selected instance. Explicitly instance-bound contributions must not switch streams.

Catalog-only discovery and demand-driven media are a sensible way to expose on-demand ladders without starting every encode; reuse the existing follower rather than adding another resolver.

Verification: static review of the plan, grid prerequisite, source resolution, HLS routes/master, contribution semantics and tests, and transcoder catalog construction. No builds, tests, or playback checks run.

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The change adds an HLS contribution-listing requirement and a proposal. The proposal covers catalog-based listing, reference resolution, rendition compatibility, demand-based media subscriptions, idle release, URL and naming rules, and test and documentation updates. DASH listing and recorder behavior remain out of scope.

Merge Risk: Low · up to d5785

This planning-only change has no immediate runtime impact. Clarify catalog restart handling and demand retention during outstanding requests before implementing the proposal.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: planning HLS listing of catalog contributions.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The pull request description directly explains the quest files, the planned HLS contribution listing behavior, subscription lifecycle, scope, and motivation. It matches the changeset.
Finishing Touches
Simplify code
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 078bbea3-f157-413d-8079-5493b0f5c36f
Commits

Reviewing files that changed from the base of the PR and between c68c931 and d5785f7.

Files selected for processing: 2
  • quest/m0/README.md
  • quest/m0/hls-contributions.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 1 remain after this review.

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread quest/m0/hls-contributions.md Resolved
Comment thread quest/m0/hls-contributions.md Resolved
Records the maintainer's 2026-11-02 decision that the master reads each
contribution's catalog. Replaces Source::bind, which never follows a
restart, with Source::follow and a per-instance Source. Keeps a
rendition's demand while a request is still in progress.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@kixelated kixelated 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.

Automated review by review (OpenAI)

Reviewed commit: 5fe085a

The previous bind-versus-follow finding is fixed: contributions now use Source::follow, with per-instance sources pinning catalog and media reads; explicitly named instances cannot switch streams. The idle-release change preserves demand throughout in-progress requests and measures inactivity after completion, addressing the independent slow-response finding.

No new actionable bugs found. Reusing the existing follower keeps the approach appropriately scoped.

Verification: static incremental comparison and inspection of the existing follower implementation and tests. This changes the plan only; no builds, tests, or playback checks run.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

Since the last Pullfrog review (d5785f7), the quest was revised on 5fe085a:

  • Catalog read recorded as a maintainer decision — the plan now states the 2026-11-02 decision that the master reads each contribution's catalog when served while only the media waits, and notes the draft rule that an on-demand publisher answers the catalog without starting media.
  • Source::bind → Source::follow — replaces the previous "resolve like a rendition's reference" approach. Each contribution entry is followed with Source::follow (moq_mux::follow::Instances) and a moq_mux::Source is built per handed-out instance, so catalog and media reads stay pinned; a new instance replaces the renditions and an ended one drops them.
  • Idle-release refinement — release now requires no request in progress and none finished within the window; a slow response (a first media playlist waiting on an on-demand encode) keeps the subscription.
  • Test plan additions — a request in progress past the idle window keeps demand, a restarted contribution follows onto its new instance, and one naming an instance does not.

I verified the new technical claims against the head tree:

  • Source::bind pins the path's first answer and never re-resolves after a replacement (rs/moq-mux/src/source.rs:326), and a sibling-bound Media ends when the bound broadcast closes (rs/moq-hls/src/export/rendition.rs:179), which is the premise for switching to follow.
  • Source::follow returns crate::follow::Instances (source.rs:380), public via pub mod follow (lib.rs:38); follow.rs:39-41 documents the exact planned pattern (follow the broadcast, build a Source per instance).
  • Instances with a named instance skips another-instance broadcasts and reports End rather than substituting (follow.rs:82-88), matching the draft's instance rules (draft-lcurley-moq-hang.md:717).

This delta directly addresses the prior automated review (kixelated/OpenAI P2) asking for Source::follow over Source::bind, plus the CodeRabbit idle-release fix. The plan is coherent with the code and the hang draft; no actionable issues.

(Written by deepseek-v4.1-flash)

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@kixelated
kixelated added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 349f21f Nov 3, 2026
6 of 9 checks passed
@kixelated
kixelated deleted the quest-plan/hls-contributions branch November 3, 2026 01:53
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