Repository navigation
Conversation
Quest-Claim: 311e8f5937987b5b
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Real-session lite-07 fixtures, time mocked: a link flap costs route messages independent of the broadcasts behind it, a stale neighbour in a ring of three cannot revive an ended broadcast, a five-relay ring moves to its backup at once or after the doubt, two relays routing through each other let go on each other's DEAD, and the three prior-art fixtures (a relay noticed a keep-alive apart, a dispute wheel, a primary that returns). A scripted-stream test covers every message naming an unassigned or retired Route ID. Pinned against the contract: a relay whose own session closed with no route left shows its held broadcast offline locally, then starts it again after the retraction quarantine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er route fails over to a wider one Adds rs/moq-net/tests/integration/route_failover.rs: next-hop moves under a live reader, a new next hop whose ROUTE carries none of the read claim, and #4644's live-mesh withdrawal and link-failure tests ported to lite-07 and the path rule. Fixes a reader at a relay losing its subscription when the session serving a claim's narrowest route closes while a wider route still covers it: the origin's reader followed only primary lanes, so it saw no route until the node promoted the wider one, and the claim went Offline, then Start two seconds later. A wider lane now serves, ranked after every primary one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…unt point The worker's answer arrives beneath the mount exactly as it does unmounted, on lite-06 and lite-07, reusing claim_continues' worker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When a lite-07 session's limit widened from one region to the root, the relay reopened its announce request above the region and the peer's claims moved to a route at another prefix, under a bare identity. The replaced request dropped what it served before the new one served it, so readers at the relay saw Offline then Start. The old request's served claims now stay in the origin until the replacement's first outputs are in. Adds the grant-union cluster test that found it and a focused auth test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Session fixtures for the epic's Plan item 15 on lite-07: a client listing one prefix of a relay never hears an origin outside it, a request outside that interest still resolves through the relay, and an origin leaving the interest ends its route behind its floor, End where the relay certifies the request and Offline where its grant knows only part of it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sweep origins, claims per origin (one included), neighbours, and the streams a relay answers, watched or missed, for a repath, a link RTT change, and a stream's close, and bound what same-clock churn leaves remembered. Residual tests pin the axes that still grow: unrelated streams, per-claim re-serves, and closed sessions kept until the doubt timer. A repath now moves a heard route's claims instead of copying them, and a closed hop's report visits only the neighbours sent a route through it. routes/path/repath and routes/path/relink bench the change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cceptance # Conflicts: # rs/moq-net/tests/integration/main.rs
…rence model goes The routing contract's forwarding, export, and qualified-identity fixtures move from the Babel-era reference model to route/tests/forward.rs on the path router, and pool ties to real sessions. The model and its Babel-only fixtures are deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… become quests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou'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 18 minutes. View limit details
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. |
There was a problem hiding this comment.
ℹ️ No critical issues. Two small cleanups are inline.
Reviewed changes
I reviewed the full PR at eec5830. Most of the diff is new acceptance tests plus the deletion of routing_contracts/. The review focused on the four source changes that alter behaviour.
- Wider lite-07 lane as fallback (
model/origin.rs):NodeFilter::Anynow accepts every route-layer lane, androute_orderputs!lane.primaryfirst. A wider covering route serves only while no primary exists. The defaultLane.primaryistrue, so routes from lite-06, IETF and local publishers rank exactly as before. - Reopen handover (
lite/subscriber.rs,routed.rs): at SYNCED, the old request is retired into aRetiredholder before the new request'soutputsrun, and the holder is dropped after them. The node hands the claims over when the old stream drops, and the old origin entries leave only once the new ones are in place. Readers see an update, not Offline then Start. path::Routerclaim moves (route/path.rs):forget_heardreturns theHeardit removes, sorouteandrepathmove the view instead of cloning it.- Visiting fewer streams (
route/path.rs):reportvisits only the peers indexed under the dead hop. Dropping thethrough.is_empty()guard is safe because each peer's pass touches only its owntx_hopsentries.advertiseborrowsansweringinstead of cloning every prefix set, and it andrunnow count astep()for each stream. - New tests and benches: forwarding, cost and residual fixtures on the router; session fixtures for topology, failover, cluster and mount; the
routes/path/repathandroutes/path/relinkbenches onfuzz::PathRouteChange. Thepinnedandresidual_*tests capture known flaws on purpose, and each has a follow-up quest.
claude-opus-5-5 | 𝕏
| // The route layer's narrowest route ahead of a wider one covering the claim. The | ||
| // wider one serves only between a closing session taking the narrowest away and the | ||
| // node promoting the next, so a reader fails over then rather than seeing an end. | ||
| !entry.lane.primary, |
There was a problem hiding this comment.
The route_order doc comment above (lines 860–870) still says the order is "Lower wins: first a route that is neither draining nor unavailable". Primary-lane membership is now the first key, so a wider lite-07 lane ranks below even a draining or unavailable route. Please add a sentence there that names this new first key.
| const FRAMES: u64 = 5; | ||
|
|
||
| /// How long a closed session's far end is doubted. | ||
| const DOUBT: Duration = Duration::from_secs(1); |
There was a problem hiding this comment.
This PR makes path_routes' DOUBT, HOLD and lite07() pub(super) so route_acceptance.rs can share them. route_failover.rs (lines 27, 42 and 45) and route_cluster.rs (lines 26, 29 and 34) still define their own copies. These constants mirror the router's timers, so changing the hold or doubt would mean editing three files that can drift apart. Importing them from crate::path_routes would keep one source.

Works on quest/m2/cluster-routes/acceptance.md: the route layer is proven on the implementation, and the Babel-era reference model is deleted. The fixtures found four flaws. Each one is pinned by a test and becomes a follow-up quest. The quest is rewritten to what remains: retiring the old mitigations once those follow-ups land.
Summary
rs/moq-net/tests/integration/routing_contracts/(5,100 lines) is deleted.route/tests/forward.rs.Changes
Forwarding, on the router (
rs/moq-net/src/route/tests/forward.rs). A lite-07 request names its publisher, so the model's path-only counterexamples become "a named request arrives":local_priorities_never_turn_a_named_request: the model's priority ring, alone and with every relay's subscription joined.a_transit_relay_never_swaps_the_named_publishernested_claims_never_loop_a_named_requestsweep_named_requests_arrive: 150 random meshes. Every request arrives, both alone and joined. After a ring link is cut, no request loops at any step except through a stale route.a_forged_identity_is_contained_by_a_scoped_admissionscoped_delivery_through_two_uplinks_reaches_one_keya_qualified_identity_is_never_qualified_againredundant_cores_fail_over_at_oncea_lost_p2p_session_falls_back_to_the_cdna_dead_uplink_consumes_and_publishes_through_a_lan_peeran_upstream_request_stops_once_the_route_turns_down_onlytransit_selection_does_not_depend_on_arrival_orderTopology and prior art, on sessions (
tests/integration/route_acceptance.rs):a_link_flap_costs_routes_not_broadcasts: 2 announce messages per session going down and 1 coming back, the same for 1 broadcast as for 64.a_stale_neighbour_cannot_revive_an_ended_broadcasta_ring_moves_at_once_to_a_backup_avoiding_the_far_enda_ring_waits_out_the_doubt_for_a_backup_through_the_far_endtwo_relays_routing_through_each_other_both_let_go: both let go one link delay after the cut, not at the 10 s hold deadline.a_vanished_relay_is_noticed_a_keep_alive_aparta_dispute_wheel_settlesa_primary_that_fails_and_returns_takes_every_relay_backpool_ties_agree_on_every_edgelite/subscriber.rs::an_unassigned_or_retired_route_id_closes_the_sessionis the unknown Route ID check. It covers ROUTE_UPDATE, ROUTE_HOLD, ROUTE_END, ANNOUNCE_FLOOR, ANNOUNCE_START and DEAD.Failover (
route_failover.rs):next_hop_moves_keep_a_live_reader: four next-hop moves. The reader lost 0 frames and saw 0 retractions, 0 re-announcements and 4 in-place updates. Exactly one announce message was sent per move.a_narrower_next_hop_fails_over_to_a_wider_routelive_mesh_withdraw_retracts_once_without_latencyandlive_mesh_link_failure_keeps_presence, ported from fix(net): replace the cursor hold with a cluster-link hold-down #4644's scenarios.Cluster (
route_cluster.rs):a_far_edge_reads_a_claim_and_sees_its_withdrawal_oncelosing_a_core_keeps_the_far_edge_readinga_matching_epoch_takes_over_at_the_far_edgea_partitioned_lan_reaches_itself_through_the_cdn_and_healsthe_cdn_never_reaches_itself_through_the_lanoverlapping_wildcards_resolve_to_the_most_specific_claim_everywherea_preferred_down_only_route_hides_the_exportable_alternativean_epochless_replacement_restarts_everywherea_grant_union_crosses_the_scoped_boundary_each_waya_client_watching_one_prefix_holds_only_the_origins_meeting_itan_origin_leaving_the_interest_ends_its_route_by_its_floorMount continuity (
mount.rs):claimed_beneath_the_mount_lite06and_lite07, against the unmounted baselinesclaimed_unmounted_lite06and_lite07.Cost (
route/tests/cost.rs,route/node/tests.rs, and the benchesroutes/path/repathandroutes/path/relink):a_repath_costs_the_streams_it_reaches_and_nothing_per_claima_link_update_costs_the_routes_through_it_and_nothing_per_claimresidual_*tests listed under Follow-ups.Bugs fixed:
model/origin.rs: a reader followed only the narrowest lite-07 route to a broadcast.lite/subscriber.rs: a reopened announce request let go of the old request's claims before the new one served them.**token) showed every claim inside the old scope as Offline, then Start.auth::lite_07_a_scope_widened_to_the_root_reopens_without_letting_go.route/path.rs: moving a heard route to a new path copied every claim behind it.work()now counts each stream it visits, so the regressions see that cost.The epic README and
quest/m3/cluster-routing/federation.mdnow name the ported tests.Caused by
Decisions
The agent took each of these under /quest-afk, for the maintainer's review.
verify-routemodel check, and three of them touchpath.rsor doubt, which moq-dev/moq#8734 is changing right now.route/tests/handoff.rs.Follow-ups
Public API and wire impact
fuzz::PathRouteChangeis new, behind thefuzzfeature, for the benches.Validation
quest gate just check: all 12,803 tests pass, and every check module is clean.cargo nextest run -p moq-net --features fuzz,async: 3,983 tests pass.cargo clippy -p moq-net --all-targets --features fuzz,async -D warnings: clean.assert_loop_freeat every step after a cut.just test interop --all. Nothing on the wire, inmoq-ffi, or in a gateway changed.Models
Size: L
Implementer: Claude, claude-opus-5-5, unknown effort
🤖 Generated with Claude Code
(Written by Claude Opus 5.5)
Review
Rewritten by
quest reviewafter each round.Head: eec5830
Base: origin/main at f8c7df9
Risk: medium,
the base has no RISK.md to name what is always high or customer-facing, so every change is mediumClassified: medium by default
Reviewer: Codex, gpt-6.1-sol, xhigh effort
Session:
01a1dfdd-da5a-7d81-afad-1c7c2f11fb6b, round 1Score: 9/10,
No actionable regressions were found in the handoff fixes or routing optimizations during source review; builds and tests were not run, as instructed.Rounds: 1; first round 0; findings 0: fixed 0, refuted 0, open 0
Findings: none