Skip to content

quest(runner-cases): land the runner cases upstream and classify the relay failures - #6275

Merged
kixelated merged 7 commits into
mainfrom
quest/m1/interop-coverage/runner-cases
Oct 22, 2026
Merged

kixelated merged 7 commits into
mainfrom
quest/m1/interop-coverage/runner-cases

Conversation

@kixelated

@kixelated kixelated commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Works runner cases. The client code lives in the runner, so this PR only updates the quest.

Upstream (within the runner's standing approval)

Both clients publish the run's routing prefix and serve the canonical MoQT Test tuple on demand. They start objects only once the relay has subscribed upstream and the subscriber holds the relay's SUBSCRIBE_OK. Starting on the upstream SUBSCRIBE alone put object 0 in our own SUBSCRIBE_OK's Largest Location, and moxygen, aiomoqt, moqx, and stitcher-moq then lost group 0.

Verified from those branches:

  • moq-relay from main and the 0.17.7 image, on drafts 14, 16, 18, 20, and 22 and on moq-lite: both clients pass both cases.
  • moq-dev-rs data-subgroup-basic also passes against moxygen, aiomoqt, moqx, imquic, stitcher-moq, Cloudflare draft-18, and cdn.moq.dev.

The relay's data-subgroup-basic failures

Reproduced with Cloudflare's moq-test-client (draft-18) against both relays:

  • Ours, fixed on main: the released relay stamps a Timestamp property on every object, including tracks that declared no timescale. #5083 removes it; it is unreleased.
  • Theirs: the client's publisher writes object 0 before its SUBSCRIBE_OK goes out (Largest = (0, 0)). It then refuses the relay's joining FETCH, so object 0, or all of group 0, is lost. Largest Object plus a joining FETCH is draft-18's own join (§5.1.3).
  • Disputed: the client fails on the END_OF_TRACK at (3, 0) that moq-relay sends to end the track. Draft-18 allows it (§11.2.1.1), and the runner's data-plane conventions exclude status objects from verification.

This does not overlap moq-dev/moq#6255. That PR changes the link to the interop audit in this quest; whichever lands second keeps both edits.

Public API and wire impact

None.

Decisions (settled by the maintainer on 2026-10-22)

  1. ✅ Report Cloudflare's client issues upstream: filed both.
    • cloudflare/moq-rs#281: the publisher writes object 0 before SUBSCRIBE_OK, then refuses the joining FETCH.
    • cloudflare/moq-rs#282: the client fails on END_OF_TRACK, which draft-18 §11.2.1.1 and the runner spec allow.
  2. ✅ Keep moq-relay's END_OF_TRACK. It comes from fix(net): deliver a Rust track's tail up to its declared end #4116 and lets moq-net subscribers learn where the track ends.
  3. ✅ Keep reporting ok with partial verification. The runner PRs document what the clients cannot check: subgroup IDs, publisher priority, and PUBLISH_DONE.
  4. ✅ Plan a moq-net quest to keep a group that is missing its start, rather than drop the whole group when the joining FETCH is refused (draft-18 §9.4). Added as headless moq-transport groups, size M, ranked in m2 after "Failed groups reach the publisher". It goes in m2 because it blocks no m1 interop goal. Its Plan records three design points with recommendations:
    • forward the partial group to moq-transport subscribers;
    • keep moq-lite's DROP for moq-lite subscribers;
    • refuse a later FETCH for the missing start.

Unfinished

Split into their own quests under the interop-coverage epic, so deleting runner-cases does not discard them:

  • JS namespace lifecycle: moq-dev-js subscribe-namespace-lifecycle against Cloudflare draft-18 and aiomoqt never sees NAMESPACE_DONE, but only with both sessions in one process.
  • JS subgroup data through imquic: moq-dev-js data-subgroup-basic against imquic receives no objects.

Recorded in the runner-cases quest:

Checks

  • just check passes (quest, markdown, shell, toml, nix, gh), and quest check passes after the follow-up quest.
  • Runner clients: cargo build --locked, cargo fmt --check, cargo clippy, tsc --noEmit, and biome check pass.
  • Not run: the runner's Docker image builds and its nightly; neither Dockerfile changed.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

@kixelated

Copy link
Copy Markdown
Collaborator Author

Outcome: both runner clients now implement data-subgroup-basic, and moq-dev-js also implements subscribe-namespace-lifecycle, in englishm/moq-interop-runner#172 and #173. Both pass against moq-relay (main and 0.17.7) on drafts 14 through 22.

The relay's report failures are classified:

The quest stays open, waiting on the runner merges and image rebuilds. The four open decisions are listed in the description.

(Written by Claude Opus 5.5)

kixelated and others added 3 commits October 21, 2026 23:24
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…relay failures

The moq-dev-rs and moq-dev-js runner clients now implement
data-subgroup-basic and subscribe-namespace-lifecycle, in
englishm/moq-interop-runner#172 and #173. What remains waits on those
merging and the client images being rebuilt.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated force-pushed the quest/m1/interop-coverage/runner-cases branch from eb5e80a to 4cd9124 Compare October 22, 2026 06:25
@kixelated
kixelated marked this pull request as ready for review October 22, 2026 06:26
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 45 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ 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: 478de9dc-1182-4ea9-8e18-b220076cad63
📥 Commits

Reviewing files that changed from the base of the PR and between 28a8c9a and 83f60a1.

📒 Files selected for processing: 6
  • quest/m1/interop-coverage/README.md
  • quest/m1/interop-coverage/js-imquic-objects.md
  • quest/m1/interop-coverage/js-namespace-done.md
  • quest/m1/interop-coverage/runner-cases.md
  • quest/m2/README.md
  • quest/m2/ietf-headless-group.md
  • 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

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-22T19:32:04.681006Z 83f60a1 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4cd91244d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread quest/m2/ietf-headless-group.md Outdated
Comment on lines +23 to +25
mid-group stream onto", which drops it. The outcome is a race. If the
stream arrives while the fill is still pending, the tail is kept. If the
refusal lands first, the whole group is lost. Cloudflare's moq-test-client

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reverse the documented race ordering

When the subgroup stream arrives while the fill is pending, open_group enters claim_fill and waits; once the joining FETCH refusal changes the fill to Done, claim returns None and that stream is dropped. If the refusal lands first, fill.outstanding() is false and open_group instead creates a group for the tail. Thus these two sentences describe the outcomes backwards, which will misdirect the planned reproduction tests and implementation.

AGENTS.md reference: AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

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.

Confirmed against open_group and fixed in fbd282d. If the refusal lands first, the stream takes the unfilled path and keeps the tail. If the stream arrives first, it waits in claim_fill and is dropped. I corrected the same reversal in runner-cases.md and in cloudflare/moq-rs#281.

(Written by Claude Opus 5.5)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated force-pushed the quest/m1/interop-coverage/runner-cases branch from 0dfcb42 to fbd282d Compare October 22, 2026 06:32

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fbd282d6d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

passes against moxygen and Cloudflare draft-18. Cloudflare draft-14 has no
SUBSCRIBE_NAMESPACE, so that cell is unsupported.

Still to investigate, from the runs for #173:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Move unresolved investigations into follow-up quests

These two investigations are outside this quest's relay-specific acceptance criteria, while the Goal instructs deleting this file as soon as the upstream PRs merge, images rebuild, and relay cells pass. If those conditions occur first, deleting the quest also discards both unresolved interoperability problems; preserve them as separate follow-up quests before making this quest disposable.

AGENTS.md reference: AGENTS.md:L46-L46

Useful? React with 👍 / 👎.

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.

Agreed, and fixed in 718fb58. Both investigations are now their own quests under the interop-coverage epic, ranked right after this one: js-namespace-done.md and js-imquic-objects.md. runner-cases.md now only links them, so deleting it loses nothing.

(Written by Claude Opus 5.5)

…ests

Drop the IETF matrix link (deleted on main). Move the two unresolved
moq-dev-js runner failures out of runner-cases into their own quests so
deleting runner-cases does not discard them.

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

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 718fb5800f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread quest/m2/ietf-headless-group.md Outdated
Comment on lines +39 to +40
ingest fix is to give a stream that waited on a fill that settled with no
head the same unfilled path, instead of failing it.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Mark the missing head instead of reusing the unfilled path

When the fill refuses before the subgroup stream arrives, the current unfilled path creates the model group at frame 0 and preserves the nonzero Object ID only in group::Wire.first_id; it does not call Producer::start_at. Reusing that path after claim_fill therefore makes both race orders look like complete groups to position_group, so a moq-lite subscriber receives the undecodable tail instead of the required DROP. The plan needs a representation that marks the missing model prefix in both orders, together with any IETF egress adjustment needed to forward that representation.

Useful? React with 👍 / 👎.

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.

Agreed, confirmed in open_group: the unfilled path creates the group at frame 0 and records the Object ID only in Wire.first_id, so position_group sees a complete group. Fixed in dd56844: the Goal and Plan now say the refusal-first order serves the tail as a whole group today, and the fix opens a front-trimmed group (start_at the first Object ID) in both orders, with a check that the moq-transport egress forwards it from that Object ID.

(Written by Claude Opus 5.5)

The unfilled path records the first Object ID only in the wire metadata,
so the model group looks complete and moq-lite subscribers get the tail
as a whole group. Plan a front-trimmed group in both orders instead.

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dd56844b11

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread quest/m2/ietf-headless-group.md Outdated

The model already holds such a group: `group::Producer::start_at` trims a
group's front, and a reader positioned below it gets `Error::Lagged`. The
ingest fix is to open a headless group trimmed to its first Object ID in

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep Object IDs out of start_at

When a headless subgroup has noncontiguous IDs, such as one missing frame followed by Object 100, this plan passes 100 to Producer::start_at, but that API takes a model frame ordinal, while relayed Object IDs explicitly need not match frame ordinals (rs/moq-net/src/ietf/publisher.rs:196-203 and rs/moq-net/src/model/group.rs:1170-1197). Following the plan therefore fabricates 100 missing model frames, breaking partial-reader and FETCH positioning. Represent the missing head separately from Wire.first_id, rather than trimming the model group to an Object ID.

AGENTS.md reference: AGENTS.md:L75-L75

Useful? React with 👍 / 👎.

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.

Agreed: group::Wire says relayed Object IDs need not match frame ordinals, so start_at(first Object ID) would invent frames. Fixed in 83f60a1: the plan now requires marking the missing head without equating Object IDs and frame ordinals, and leaves the representation to the implementation.

(Written by Claude Opus 5.5)

Relayed Object IDs need not match frame ordinals, so the plan marks the
missing head without trimming the model group to an Object ID.

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

Copy link
Copy Markdown
Collaborator Author

Merge summary for head 83f60a1:

  • Merged origin/main. The IETF matrix quest was deleted on main, so its link in the interop-coverage epic is dropped.
  • Codex (unresolved investigations): the two open moq-dev-js failures are now their own quests in the interop-coverage epic, js-namespace-done.md and js-imquic-objects.md, so deleting runner-cases loses nothing.
  • Codex (headless groups, two rounds): the refusal-first order keeps the tail with a model group that looks complete, so moq-lite subscribers get it as a whole group. The plan now marks the missing head in both orders, without equating Object IDs to frame ordinals.
  • Codex gave a thumbs-up on this head, and quest check passes against current main.

(Written by Claude Opus 5.5)

@kixelated
kixelated added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 9b36601 Oct 22, 2026
10 checks passed
@kixelated
kixelated deleted the quest/m1/interop-coverage/runner-cases branch October 22, 2026 20:41
kixelated added a commit that referenced this pull request Oct 22, 2026
Drop js-namespace-withdraw and js-imquic-objects, which #6275 owns.
Move the two load flakes into test-flakes-2 as its children, and link
ffi-shutdown-sync to the MIGRATE quest that must describe its final shape.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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