Skip to content

feat(net)!: remove epochs from moq-transport - #7239

Merged
moq-bot[bot] merged 16 commits into
mainfrom
quest/m1/ietf-epoch-cut
Nov 1, 2026
Merged

moq-bot[bot] merged 16 commits into
mainfrom
quest/m1/ietf-epoch-cut

Conversation

@kixelated

@kixelated kixelated commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

moq-transport's unused MoQ Epoch extension adds negotiation, request pinning, and advertisement replacement machinery. No third party implements it. The quest (decided with the maintainer 2026-10-28) removes it and keeps moq-lite 07 epochs.

Approach

  • Remove Rust and JS EPOCH SETUP negotiation, message parameters, capability state, and the epoch-specific replacement, refusal, and pinning paths. An inbound EPOCH parameter follows the existing unknown-parameter rules.
  • Remove the extension settings and Ietf.Epoch, and regenerate the JS public API report.
  • Keep moq-lite and the shared model's epochs, including local epoch pinning when a publisher resolves its own track listing.
  • Update the replacement, pending-catalog, route-change, multi-CDN, browser identity, and cross-language GOAWAY scenarios for epochless moq-transport restarts.
  • Correct existing docs inline, including doc/concept/identity.md and the takeover paragraph in doc/concept/moq-lite.md from main.
  • Keep the epoch draft as an unimplemented proposal, with the cluster and hang references intact.
  • Merges with main brought in draft 20 (moq-dev/moq#7190), announce takeover (moq-dev/moq#6994), and new tests that assumed epochs over moq-transport. The merges resolve them as follows:
    • drop EPOCH from main's new request-stream code, FETCH/SUBSCRIBE/TRACK_STATUS codecs, and the draft-20 parameter allow-list;
    • delete main's MoQ Epoch extension tests (an_epoch_crosses_only_when_both_offer_it, the pinned-request publisher tests, and the draft-20 epoch.test.ts change);
    • expect End+Start instead of an in-place restart over moq-transport in moq-net-tests restart.rs (dynamic_epoch, priority_update) and moq-cli epochs.rs;
    • drop flaps_ietf_22 and ietf_*_resumes_after_a_lagging_route_dies, which assert a cross-route resume that needs the epoch. Epochless moq-transport route loss stays covered by route_change::pinned_tests (ietf_18, ietf_22).
  • The e2ee transport test now asserts moq-transport delivers no route epoch.
  • The merge with main at 50c4efdbc0 removed the moq-transport epoch code main added since the last merge:
    • the EPOCH Setup Option in main's single-pass SETUP parser (moq-dev/moq#7354);
    • the request epoch in the kio Resolve machine (moq-dev/moq#7284) and in the FETCH sent alongside TRACK_STATUS (moq-dev/moq#7332);
    • the previous-epoch request retention in the credit-free advertisement loop (moq-dev/moq#7414), with its a_stalled_epoch_replacement_is_bounded_and_withdrawn test. The loop's generic one-opening-advertisement gate and early-OK hold stay;
    • main's kio ports of the already-deleted MoQ Epoch tests stay deleted, and this branch's restart tests moved from moq_clock to kio::clock (moq-dev/moq#7027).
  • The JS moq-transport publisher's #resolve drops its unused epoch parameter.
  • Finishes the quest: deletes quest/m1/ietf-epoch-cut.md and its links. The prose reference in quest/m1/announce-takeover.md now points at this PR.

Impact

  • Breaking API/config: removes Rust setup::Extensions::epoch and JS extensions.epoch. Delete every epoch extension setting, including epoch = false and extensions.epoch = false, from application and relay configuration. Rust rejects the old setting at startup (deny_unknown_fields). Remove any Ietf.Epoch imports.
  • Wire: moq-transport no longer offers SETUP option 0x40B68 and never sends or interprets parameter 0x40B69. Every moq-transport hop is epochless, so replacement sessions and publisher-instance changes need readers to follow the announcement and request the path again. Use moq-lite 07 on every hop for epoch continuity.
  • moq-lite wire format, epoch APIs, and shared routing semantics are unchanged. No package versions or migration files change; the release cut writes MIGRATE.md from this section.

Validation

All suites ran locally through quest gate.

  • just ci origin/main passed on 6fed26889f, after merging main at 50c4efdbc0 (Rust and JS check/test, markdown, quest, shell, gh). It passed earlier on the merge head 3cf8b71065.

  • just ci origin/main: every module passed on 2be80f17c4, including Rust check, test, and feature shapes, JS check and test, markdown, quest, and shell. It passed again on the final head f169a9457a.

  • just test interop --all: 182 passed, 0 failed.

  • just test interop --all --versions moq-transport-18,moq-transport-20,moq-transport-22: 214 passed, including every goaway and reverse-goaway case on all three drafts.

    • The browser js -> js case failed on drafts 20 and 22, timing out on "resumed playback" after the relay answered the re-subscribe with PUBLISH_DONE … internal error.
    • This is pre-existing: main's scheduled Interop fails the same cell on moqt-22 with the same error (run 41075505055, run 40896908858).
  • just test wire-compat: the token, session, catalog, and container lanes passed. 72 session cells ran; the 49 skips are the planned lite-07 breaks. The compat matrix covers only moq-lite.

  • Two earlier interop/wire-compat attempts failed only because mbx pruned the shared target/ mid-run. Wire-compat passed with a worktree-local CARGO_TARGET_DIR.

Review

  • Codex (quest review, gpt-6.1-sol, medium effort) on 6fed26889fe8680ec78f51617cc6e9193c5ed665: 0 findings (round 2 of a new session; round 1 on the merge commit b21ab7422f also reported 0). The merge with main at 50c4efdbc0 resolved nine files by hand: rs/moq-net/src/ietf/{peer,publisher,session,subscriber}.rs, js/e2ee/src/transport.test.ts, and the extensions, multi_cdn, replacement, and route_change integration tests.
  • Previous round: Codex (gpt-6.1-sol, medium) reported 0 findings on 3cf8b710651f31cadc2d3c1a1190b4a6a07e8ac2, after merging main with moq-dev/moq#7236 and moq-dev/moq#7329.
  • CodeRabbit's request to update or remove the epoch draft is refuted in the thread: the draft stays as an unimplemented proposal, and its wire format is unchanged.
  • Earlier rounds: Codex (--deep, gpt-6-astra) reported 0 findings on 60c8cd3425 and 46249bbadb. A Claude Opus 5.5 reviewer on 2be80f17c4 raised three findings: the e2ee test fix (fixed), the dropped flap/lagging-route tests (refuted: covered epochless by route_change::pinned_tests), and the solicit = false restart reordering (accepted and deferred to per-announcement identity, quest/m1/api-audit/route/identity.md).

Choices made without asking

  • Took main's newer plan text when the quest file conflicted, then deleted the quest as the brief asked.
  • Deleted rather than rewrote the moq-transport resumption tests that main added after this branch was cut, since the behavior they assert no longer exists.
  • Left the solicit-off reordering above to the identity quest rather than adding interim epochless restart detection here.
  • Deleted main's a_stalled_epoch_replacement_is_bounded_and_withdrawn with the previous-epoch retention it tested, rather than rewriting it epochless: an epochless restart withdraws before it re-advertises, and stalled_advertisements_observe_local_and_peer_ends still covers withdrawal under stalled credit.

Follow-ups

  • The browser js -> js moq-transport 20/22 resume failure (PUBLISH_DONE internal error on re-subscribe) is pre-existing on main, and no quest owns it yet. It belongs under Interop and Video pass on main.
  • moq-dev/moq#7420 (quest-plan/route-origin-api) plans the epoch's split into identity and epoch and builds on this cut: moq-transport carries no identity, and a receiving session mints one. It still links /quest/m1/ietf-epoch-cut.md in several places, which this PR deletes. Whichever lands second must replace those links, for example with this PR's URL, or quest check fails.
  • moq-dev/moq#7236 still overlaps this PR's publisher and subscriber edits. Whichever lands second reconciles them. moq-dev/moq#7204 and moq-dev/moq#7089 have merged and are reconciled here.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

kixelated and others added 3 commits October 29, 2026 07:01
Quest-Claim: a5c32d05d9bb8b26
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
@kixelated kixelated changed the title moq-transport carries no epoch feat(net)!: remove epochs from moq-transport Oct 29, 2026
kixelated and others added 7 commits October 30, 2026 21:45
Drop the EPOCH fields from main's new request-stream code, and update main's dynamic-epoch restart test and identity guide for epochless moq-transport.
Main's joining-FETCH test and the moq-transport-18 e2ee transport case still
expected an epoch over moq-transport, and the priority-update restart reads
lite-07 alone as in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's moq-cli replacement and route-change suites asserted an in-place restart
or a cross-route resume over moq-transport, which carried the epoch until this
cut. Epochless moq-transport route loss stays covered by the pinned cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep draft 20 and announce takeover from main without their EPOCH parameter, and drop main's MoQ Epoch extension tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review October 31, 2026 09:57
@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

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: 59f914c6-2295-448e-877e-caa9c17ebe9b
Commits

Reviewing files that changed from the base of the PR and between 846eb14 and 3cf8b71.

Files selected for processing: 9
  • js/net/src/ietf/parameters.ts
  • js/net/src/ietf/publisher.test.ts
  • js/net/src/ietf/publisher.ts
  • js/net/src/ietf/subscriber.test.ts
  • quest/m1/README.md
  • rs/moq-cli/tests/integration/epochs.rs
  • rs/moq-net/src/ietf/publisher.rs
  • rs/moq-net/src/ietf/subscriber.rs
  • rs/moq-net/src/ietf/subscriber/tracks.rs
Files with no reviewable changes: 2
  • quest/m1/README.md
  • rs/moq-net/src/ietf/subscriber/tracks.rs

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

Walkthrough

The changes remove MoQ Epoch negotiation and message handling from JavaScript and Rust moq-transport. Publisher and subscriber routing no longer uses epochs to pin requests or identify publisher instances. Namespace restarts withdraw the old advertisement before announcing the new one. Tests and documentation now state that epochs cross links only with opt-in moq-lite 07; moq-transport and older moq-lite versions use end-and-start behavior.

Merge Risk: Moderate · up to 3cf8b

Clarify the retained draft’s status before merging so readers do not mistake the removed moq-transport epoch extension for a supported wire contract.

Pre-merge checks: Passed 4 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Inconclusive Docstring coverage is 65.63% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely states the main change: removing epochs from moq-transport.
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 description states the PR removes the unused MoQ Epoch extension from moq-transport. It lists the Rust and JS settings, APIs, wire changes, tests, docs, and validation runs. The description matche…
Full details: Description check

Explanation

The description states the PR removes the unused MoQ Epoch extension from moq-transport. It lists the Rust and JS settings, APIs, wire changes, tests, docs, and validation runs. The description matches the changeset's scope, so the check passes.

Full details: Docstring Coverage

Explanation

Docstring coverage is 65.63% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 32 functions across 30 files. (2 skipped: 2 too large.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

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

@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: f169a94.

Direction: removing the unused wire extension is a worthwhile simplification; retaining local/moq-lite epochs and changing moq-transport replacement tests to End+Start matches that boundary. No additional actionable bugs found in the inspected changes.

Known finding, not new: I agree with the solicit=false reordering issue already recorded in this PR's Review section. In rs/moq-net/src/ietf/subscriber.rs:2415–2431 and js/net/src/ietf/subscriber.ts:424–430, an overlapping replacement remains an update (or a no-op for equal routes), so a restart can retain the old consumer/cache. This now also affects our formerly epoch-capable peers. Carry the per-announcement-identity fix and a regression that delivers the new advertisement before the old reset into the follow-up; the ordered solicited path does not exercise it. Referencing the existing finding rather than duplicating an inline comment.

Verification: static inspection of Rust/JS negotiation, codecs, publisher/subscriber replacement and request paths, and changed restart/route/GOAWAY tests. I did not run tests or independently verify the reported CI/local test results.

@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 — the full diff (66 files) removing the MoQ Epoch extension from moq-transport in Rust and JS, plus the doc/test/quest fallout.

  • Wire and codecs. Deletes SETUP option 0x40B68 and parameter 0x40B69 from the Rust (ietf/epoch.rs, epoch entries in mod.rs/parameters.rs/peer.rs/session.rs) and JS (ietf/epoch.ts, setup_options.ts, parameters.ts, connection/handshake.ts, connection/extensions.ts) surfaces. All message codecs (subscribe, fetch, track, publish_namespace, subscribe_namespace) drop their epoch field and parameter paths.
  • Publisher/subscriber logic. Removes in-place replacement (Publisher::replaces, #replace, select's epoch forwarding), request epoch pinning, and the gained/lost-epoch violation. Replacement is now uniformly withdraw-then-advertise. I traced each removed branch (select, apply_update, updateAnnounce/#settleAnnounce, #updateAnnounce's newest-splice, aliases.ts) and confirmed the epoch was always None on these paths once negotiation is gone, so the simplifications are behavior-preserving for moq-transport.
  • API/config. setup::Extensions.epoch and JS extensions.epoch deleted (JS api report regenerated); Ietf.Epoch unexported.
  • Model epochs retained. crate::Epoch, origin::Route::epoch, js/net/src/epoch.ts, and the local epoch pinning for the publisher's own track listing (Rust publisher/tracks.rs, JS #listBroadcast → #resolve) are untouched, matching the stated boundary.
  • Tests/docs/quest. Epoch-over-moq-transport cases converted to epochless End+Start expectations; docs trimmed in nine files; the quest file deleted and back-links repointed.

Verification I ran: a repo-wide sweep for dangling references (extensions.epoch, epoch = false, Ietf.Epoch, moq-epoch, 0x40b68/9, ietf-epoch-cut) found none in code, config, or docs, and confirmed the one remaining /draft/moq-epoch mention is the intentional "unimplemented proposal" note in doc/concept/standard.md. I did not run CI.

The only behavioral consequence I found is the solicit=false reordering already recorded in the PR's Review section and re-flagged by the prior reviewer: a restart whose new PUBLISH_NAMESPACE overtakes the old reset is folded into the same route as an update. It is pre-existing for third-party peers, is now reachable by our own epochless peers, and is scoped to the per-announcement-identity follow-up (#7420). Nothing to change here.

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

@kixelated

Copy link
Copy Markdown
Collaborator Author

Landing summary for f169a9457a952243ad8ec9d669e03dc287488da0:

  • Removes the MoQ Epoch extension (SETUP option 0x40B68, parameter 0x40B69) from Rust and JS moq-transport; moq-lite 07 and model epochs stay. Breaking: setup::Extensions::epoch, JS extensions.epoch, and Ietf.Epoch are gone.
  • Checks: all 13 required checks pass. Reviews on this head (OpenAI review, pullfrog) report no new findings; the local Codex round 2 on 46249bbadb reported 0 findings, and f169a9457a is a conflict-free merge of main (tree identical to a clean merge of its parents). quest check --base origin/main passes.
  • Decision carried, not fixed here: the solicit = false reordering (a restart's new PUBLISH_NAMESPACE overtaking the old reset folds into an update) goes to the per-announcement identity work planned in moq-dev/moq#7420.
  • Coordination: moq-dev/moq#7420 still links /quest/m1/ietf-epoch-cut.md, which this PR deletes. Whichever lands second must repoint those links (e.g. to this PR) for quest check to pass.

(Written by Claude Opus 5.5)

@moq-bot

moq-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

quest land removed this pull request from the queue: Conflicts with the base: quest/m1/announce-takeover.md, rs/moq-net/src/ietf/publisher.rs
.

@moq-bot
moq-bot Bot enabled auto-merge (squash) November 1, 2026 04:06
@moq-bot moq-bot Bot added the quest:merge label Nov 1, 2026
@kixelated
kixelated enabled auto-merge (squash) November 1, 2026 05:00
@moq-bot
moq-bot Bot disabled auto-merge November 1, 2026 05:15
@moq-bot moq-bot Bot removed the quest:merge label Nov 1, 2026
@moq-bot

moq-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

quest land removed this pull request from the queue: Conflicts with the base: js/net/src/ietf/subscriber.test.ts, rs/moq-net/src/ietf/publisher/tracks.rs
.

…79e0eb2452b

# Conflicts:
#	js/net/src/ietf/subscriber.test.ts
#	rs/moq-net/src/ietf/publisher/tracks.rs
@kixelated

Copy link
Copy Markdown
Collaborator Author

Merged main at 44e85d8efb and resolved two conflicts against moq-dev/moq#7236 and moq-dev/moq#7329:

  • rs/moq-net/src/ietf/publisher/tracks.rs: deleted, since main removed it. This branch had only dropped epoch arguments there.
  • js/net/src/ietf/subscriber.test.ts: kept main's controlled-time imports and this branch's removal of the MoQ Epoch extension tests.

just ci origin/main and quest check passed on 3cf8b71065. The Codex local review reported 0 findings. I refuted CodeRabbit's epoch-draft comment in its thread: the draft stays as an unimplemented proposal. No ietf-epoch-cut links remain after moq-dev/moq#7420. Landing.

(Written by Claude Opus 5.5)

@kixelated
kixelated enabled auto-merge (squash) November 1, 2026 05:25
@moq-bot

moq-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

codex / Codex land fixer: PR was picked again while fixing; keeping the newer pick. Recommendation: run /quest-iterate before picking it again.

 		ietf::Negotiated {
 			cluster: self.peer.negotiated(),
-			epoch: self.epochs,
 		}
 	}
 
@@ -938,7 +931,6 @@ impl Publisher {
 		&self,
 		stream: &mut Stream<Transport, Version>,
 		path: &crate::Path,
-		epoch: Option<crate::Epoch>,
 	) -> Result<Option<crate::broadcast::Consumer>, Error> {
 		let Some(origin) = self
 			.until_withdrawn(stream, |waiter| self.poll_serving_origin(waiter))
@@ -947,7 +939,7 @@ impl Publisher {
 			return Ok(None);
 		};
 		// The immediate lookup: answering a peer never starts discovery of its own.
-		let requesting = origin.lookup(path.clone(), epoch.as_ref());
+		let requesting = origin.lookup(path.clone(), None);
 		self.until_withdrawn(stream, |waiter| requesting.poll_ok(waiter))
 			.await
 			.transpose()
@@ -985,42 +977,32 @@ impl Publisher {
 	///
 	/// The origin's announce cursor already filters routes through the peer
 	/// (control-plane split horizon); this only shapes what the wire can carry.
-	/// `epochs` says the peer negotiated MoQ Epoch, so the route's instance travels too.
-	fn select(&self, route: &crate::origin::Route, peer: &cluster::Peer, epochs: bool) -> Advert {
+	fn select(&self, route: &crate::origin::Route, peer: &cluster::Peer) -> Advert {
 		// A route that already passed through us is a reflection. The origin
 		// filters these on receive, so this is defensive.
 		if self.self_origin != crate::Hop::UNKNOWN && route.hops.contains(&self.self_origin) {
 			return Advert::None;
 		}
 
-		// Forwarded unchanged, and never invented for a route that arrived without one.
-		let epoch = route.epoch.clone().filter(|_| epochs);
 		if !peer.negotiated() {
-			return Advert::Some(ietf::AdvertParams { cluster: None, epoch });
+			return Advert::Some(ietf::AdvertParams { cluster: None });
 		}
 
 		let cost = route.cost.value();
 		// Our own Hop ID is always the last entry, so the peer reconstructs the full
 		// path. A chain with no room left is a loop in all but name.
 		match cluster::Advert::forward(&route.hops, cost, self.self_origin) {
-			Ok(advert) => Advert::Some(ietf::AdvertParams {
-				cluster: Some(advert),
-				epoch,
-			}),
+			Ok(advert) => Advert::Some(ietf::AdvertParams { cluster: Some(advert) }),
 			Err(_) => Advert::None,
 		}
 	}
 
 	/// Handle an incoming bidi stream dispatched by the session.
-	///
-	/// `epochs` says both sides negotiated MoQ Epoch: a request naming an instance on a
-	/// session that did not breaks the session.
 	pub fn handle_stream(
 		&self,
 		id: u64,
 		body: ietf::Body,
 		stream: Stream<Transport, Version>,

codex
Both conflicts are resolved, and the whitespace check passes. Tests are blocked by missing local dependencies: Bun cannot resolve `@moq/clock`, and Cargo lacks the cached `uniffi` Git dependency. I’ll commit the merge resolution and write the result file.

exec
/bin/bash -lc "git -c core.hooksPath=/dev/null commit -m \"Merge base and preserve epoch removal across test and publisher deletions\"
python3 - <<'PY'
import json, subprocess
from pathlib import Path
head=subprocess.check_output(['git','rev-parse','pr-7239'],text=True).strip()
subprocess.run(['git','merge-base','--is-ancestor','846eb146c',head],check=True)
subprocess.run(['git','merge-base','--is-ancestor','base',head],check=True)
assert subprocess.check_output(['git','rev-parse','batch'],text=True).strip().startswith('846eb146c')
Path('quest-land-result.json').write_text(json.dumps([{'number':7239,'action':'fixed','head':head,'reason':'Merged base; retained epoch-test removal and base deletion of the Rust track publisher.'}],indent=2)+'\\n')
PY
 git status --short; git log -1 --format='%H %P'; git diff HEAD --check" in /work
 succeeded in 0ms:
[pr-7239 254250c58] Merge base and preserve epoch removal across test and publisher deletions
?? quest-land-result.json
254250c58de3245351ac470e224af8aab6f48f3f 846eb146cf1a3927e03327c06630eaecf14c2cf0 44e85d8efb8e47aaefedc49dfd2519fa995fda6b

codex
Fixed PR #7239 by merging base and resolving both conflicts mechanically.

Head: `254250c58de3245351ac470e224af8aab6f48f3f`

[quest-land-result.json](/work/quest-land-result.json) is uncommitted. Whitespace checks passed; tests were blocked by missing local dependencies.
tokens used
47,263
Fixed PR #7239 by merging base and resolving both conflicts mechanically.

Head: `254250c58de3245351ac470e224af8aab6f48f3f`

[quest-land-result.json](/work/quest-land-result.json) is uncommitted. Whitespace checks passed; tests were blocked by missing local dependencies.
fixer result written

(written by codex / Codex)

@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 — the delta since the prior pullfrog review at 846eb146 (the 3cf8b7106 merge of main at 44e85d8).

  • Merged main and re-applied the epoch removal. Net effect of the merge for every touched file is exactly main plus the MoQ Epoch removal. A sweep of rs/moq-net/src/ietf/ and js/net/src/ietf/ finds no epoch/Epoch/0x40B68/0x40B69 left except the unrelated auth epoch: u64 permit and model crate::Epoch in tests; the epoch: None fields remaining in fuzz.rs, test_interop.rs, and path/mod.rs are lite:: (moq-lite) types that intentionally keep epochs.
  • Reconciled the IETF epoch tests with main's controlled clock. js/net/src/ietf/subscriber.test.ts keeps main's Elapsed/sleep/timeout/yieldNow imports (nextStream now uses timeout) while the branch's deletion of the six MoQ Epoch extension tests and their inlineEpoch/publishEpoch helpers survives; every imported helper is still used.
  • Kept main's deletion of the track-listing publisher. rs/moq-net/src/ietf/publisher/tracks.rs stays deleted (removed by #7236), so the branch's epoch-only edits there are gone rather than reintroduced.
  • No dangling links. A repo-wide sweep finds no reference to the deleted quest/m1/ietf-epoch-cut.md, nor to extensions.epoch, epoch = false, Ietf.Epoch, or 0x40b68/9; the /draft/moq-epoch mention in doc/concept/standard.md is the intentional "unimplemented proposal" note.

The known solicit=false restart-ordering risk remains deferred to the per-announcement-identity follow-up (#7420), unchanged by this merge.

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

@moq-bot

moq-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

quest land removed this pull request from the queue: Conflicts with the base: js/e2ee/src/transport.test.ts, rs/moq-net/src/ietf/peer.rs, rs/moq-net/src/ietf/publisher.rs, rs/moq-net/src/ietf/session.rs, rs/moq-net/src/ietf/subscriber.rs, rs/moq-net/tests/integration/extensions.rs, rs/moq-net/tests/integration/multi_cdn.rs, rs/moq-net/tests/integration/replacement.rs, rs/moq-net/tests/integration/route_change.rs
.

@moq-bot

moq-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

codex / Codex land fixer: Base conflicts with epoch removal in nine files; new publisher tests require EPOCH instance pinning and rejection without negotiation, whereas this PR removes EPOCH and treats it as unknown, requiring. Recommendation: Have the author reconcile base's new epoch-specific request and replacement handling with extension removal, update the affected tests, and rerun Rust and JavaScript checks.

futures = { workspace = true, optional = true }
hashbrown = { workspace = true }
hashlink = { workspace = true }
kio = { workspace = true, features = ["macros"] }
moq-pattern = { workspace = true, features = ["serde"] }
num_enum = { workspace = true }
rand = { workspace = true }
rangemap = { workspace = true }
serde = { workspace = true }
slab = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }
uuid = { workspace = true }

[dev-dependencies]
criterion = { package = "bench-harness", path = "../bench-harness" }
futures = { workspace = true }
# The tests' executor, with simulated time.
kio = { path = "../kio", features = ["runtime", "sim"] }
proptest = { workspace = true }
serde_json = { workspace = true }
# The benches run on tokio. test-util (tokio::time::pause/advance) is test-only, so
# it must not leak into the normal dependency feature set.
tokio = { workspace = true, features = ["rt", "test-util", "time"] }
tracing-test = { workspace = true }

# Optional per-thread CPU timing in the session benchmark.
[target.'cfg(unix)'.dev-dependencies]
libc = { workspace = true }

# Writes the generated fuzzer corpus to disk. Needs the `fuzz` feature, so a default
# `--all-targets` build skips it rather than failing to find the module.
[[example]]
name = "fuzz-seeds"
path = "examples/fuzz-seeds.rs"
required-features = ["fuzz"]

# Lands peer claims through the hidden `fuzz` module, as a session does.
[[bench]]
name = "origin"
harness = false
required-features = ["fuzz"]

# Reaches the crate-private session view of an origin through the hidden `fuzz` module.
[[bench]]
name = "viewers"
harness = false
required-features = ["fuzz"]

# Reaches the private announce codec through the hidden `fuzz` module.
[[bench]]
name = "announce"
harness = false
required-features = ["fuzz"]

# Reaches the crate-private session snapshot through the hidden `fuzz` module.
[[bench]]
name = "synced"
harness = false

codex
The conflicts include a behavioral decision: base adds tests requiring EPOCH requests to enforce instance pinning and reject use without negotiation, while #7239 removes that extension and treats EPOCH as unknown. Resolving this would require choosing protocol behavior, so I’ll hand back the PR and leave its branch unchanged.

exec
/bin/bash -lc 'git merge --abort; git rev-parse pr-7239; git status --short; git log base --oneline -8' in /work
 succeeded in 4333ms:
Updating files:  34% (272/780)
Updating files:  35% (273/780)
Updating files:  36% (281/780)
Updating files:  37% (289/780)
Updating files:  38% (297/780)
Updating files:  39% (305/780)
Updating files:  40% (312/780)
Updating files:  41% (320/780)
Updating files:  42% (328/780)
Updating files:  43% (336/780)
Updating files:  44% (344/780)
Updating files:  45% (351/780)
Updating files:  46% (359/780)
Updating files:  47% (367/780)
Updating files:  48% (375/780)
Updating files:  49% (383/780)
Updating files:  50% (390/780)
Updating files:  51% (398/780)
Updating files:  52% (406/780)
Updating files:  53% (414/780)
Updating files:  54% (422/780)
Updating files:  55% (429/780)
Updating files:  56% (437/780)
Updating files:  56% (440/780)
Updating files:  57% (445/780)
Updating files:  58% (453/780)
Updating files:  59% (461/780)
Updating files:  60% (468/780)
Updating files:  61% (476/780)
Updating files:  62% (484/780)
Updating files:  63% (492/780)
Updating files:  64% (500/780)
Updating files:  65% (507/780)
Updating files:  66% (515/780)
Updating files:  67% (523/780)
Updating files:  68% (531/780)
Updating files:  69% (539/780)
Updating files:  70% (546/780)
Updating files:  71% (554/780)
Updating files:  72% (562/780)
Updating files:  73% (570/780)
Updating files:  74% (578/780)
Updating files:  75% (585/780)
Updating files:  76% (593/780)
Updating files:  77% (601/780)
Updating files:  78% (609/780)
Updating files:  79% (617/780)
Updating files:  80% (624/780)
Updating files:  81% (632/780)
Updating files:  82% (640/780)
Updating files:  83% (648/780)
Updating files:  84% (656/780)
Updating files:  85% (663/780)
Updating files:  86% (671/780)
Updating files:  87% (679/780)
Updating files:  87% (682/780)
Updating files:  88% (687/780)
Updating files:  89% (695/780)
Updating files:  90% (702/780)
Updating files:  91% (710/780)
Updating files:  92% (718/780)
Updating files:  93% (726/780)
Updating files:  94% (734/780)
Updating files:  95% (741/780)
Updating files:  96% (749/780)
Updating files:  97% (757/780)
Updating files:  98% (765/780)
Updating files:  99% (773/780)
Updating files: 100% (780/780)
Updating files: 100% (780/780), done.
3cf8b710651f31cadc2d3c1a1190b4a6a07e8ac2
f194edc23 fix(bench): isolate comparison worktrees from Cargo configuration (#7445)
664b1aad2 perf(net): skip refusal for group ranges; attribute the paired bench regressions (#7253)
32391c452 perf(net): park memory-transport reads and writes on the close only when they wait (#7262)
8ff7c311d Probing beside Cubic meets the deadline budget (#7429)
090fec2e4 feat(relay): one TCP port for HTTP, RTMP, RTMPS, and tls:// (#7362)
caef9b3fc quest: plan the land gate's CI follow-ups (#7456)
08e71cd3d fix(net): keep DYNAMIC_GROUPS through an opted-out draft-22 resume (#7383)
68fb455ba fix(net): take a reserved group without asking its cursor again (#7032)

exec
/bin/bash -lc "python3 - <<'PY'
import json
result = [{\"number\":7239,\"action\":\"handback\",\"diagnosis\":\"Base conflicts with epoch removal in nine files; new publisher tests require EPOCH instance pinning and rejection without negotiation, whereas this PR removes EPOCH and treats it as unknown, requiring a protocol behavior decision.\",\"recommendation\":\"Have the author reconcile base's new epoch-specific request and replacement handling with extension removal, update the affected tests, and rerun Rust and JavaScript checks.\"}]
with open('quest-land-result.json','w') as f:
    json.dump(result,f,indent=2)
    f.write('\\n')
PY
 git status --short" in /work
 succeeded in 0ms:
?? quest-land-result.json

codex
PR #7239 handed back: base’s new EPOCH enforcement conflicts with the PR’s extension removal and requires a protocol behavior decision.

Branch unchanged. Diagnosis and recommendation written to [quest-land-result.json](/work/quest-land-result.json), left uncommitted.
tokens used
48,378
PR #7239 handed back: base’s new EPOCH enforcement conflicts with the PR’s extension removal and requires a protocol behavior decision.

Branch unchanged. Diagnosis and recommendation written to [quest-land-result.json](/work/quest-land-result.json), left uncommitted.
fixer result written

(written by codex / Codex)

kixelated and others added 2 commits November 1, 2026 03:13
Drop the moq-transport epoch code main added since the last merge: the
EPOCH Setup Option in the new SETUP parser, the epoch in the kio Resolve
machine and the alongside-TRACK_STATUS FETCH, and the previous-epoch
request retention (and its test) from the credit-free advertisement loop.
Main's ported MoQ Epoch tests stay deleted.

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

The JS moq-transport publisher's #resolve kept an epoch parameter no caller
passes since requests no longer carry EPOCH.

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

Copy link
Copy Markdown
Collaborator Author

Merged main at 50c4efdbc0 to clear the merge_conflict stop and removed the moq-transport epoch code main had added since: the EPOCH Setup Option in the single-pass SETUP parser (moq-dev/moq#7354), the request epoch in the kio Resolve machine (moq-dev/moq#7284) and the alongside-TRACK_STATUS FETCH (moq-dev/moq#7332), and the previous-epoch request retention plus its test in the credit-free advertisement loop (moq-dev/moq#7414). Also dropped the JS IETF #resolve's unused epoch parameter.

just ci origin/main passed on 6fed26889f; Codex (gpt-6.1-sol, medium) reported 0 findings on it. Landing this head.

(Written by Claude Opus 5.5)

@kixelated
kixelated enabled auto-merge (squash) November 1, 2026 11:22

@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 — the delta since the prior pullfrog review at 3cf8b71: the b21ab7422 merge of main at 50c4efdbc0 and the 6fed268 fix.

  • Merged main and re-applied the epoch removal. The reconciliation drops main's newer MoQ Epoch additions: the EPOCH SETUP option, the request epoch in the kio Resolve machine and in the FETCH alongside TRACK_STATUS, and the previous-epoch request retention in the advertisement loop. NamespaceRequest has no previous field and Resolve::new/origin.lookup take no epoch.
  • Dropped the unused epoch parameter from the JS publisher's #resolve. All three call sites pass only name/signal, so local(name) and demand(name, undefined, signal) are behavior-preserving.
  • Reconciled the epoch tests. replacement.rs renames epoch_ietf to epoch_is_stripped_ietf and extends epochless_ietf to draft 18; route_change.rs moves ietf_18/ietf_22 into pinned_tests and drops the epoch-only flap/lagging-route cases; extensions.rs deletes an_epoch_crosses_only_when_both_offer_it; restart.rs/epochs.rs expect End+Start for every non-lite-07 wire.
  • Kept the e2ee assertion. The transport matrix takes main's lite-05 timed=true change while keeping routed=false for moq-transport-18, so it still asserts no route epoch over moq-transport.

Verification I ran: cargo check -p moq-net --tests passes on 6fed268, and repo-wide sweeps for 0x40b68/9, Ietf.Epoch, extensions.epoch, and epoch = false return nothing. The known solicit=false restart-ordering risk remains deferred to the per-announcement-identity follow-up (#7420), unchanged by this merge.

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

@moq-bot
moq-bot Bot merged commit 3292489 into main Nov 1, 2026
1 check passed
@moq-bot
moq-bot Bot deleted the quest/m1/ietf-epoch-cut branch November 1, 2026 11:53
kixelated added a commit that referenced this pull request Nov 1, 2026
Main's #7239 removes MoQ Epoch from moq-transport. The conflicts in
fetch.rs, publisher.rs and subscriber.rs keep this PR's request tokens and
namespace verification state and drop the epoch parameters, the restart
replacement check and the epoch tests with main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit to Dryvnt/moq that referenced this pull request Nov 1, 2026
moq-dev#7239 merged, so route_dies_without_an_epoch's pinned tests
already run moq-transport 18 and 22 epochless through the shared
topology. The Plan's "whichever lands first" and "lite-04 to 06 alone"
lines were stale. Only lite-07-wip needs the epochless topology.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant