From ce9395351ffc9be3032625e79bd0634e4e87cd83 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sat, 26 Sep 2026 17:38:10 -0700 Subject: [PATCH 1/2] docs: fix stale agent rules, the moq-net hop range, and the ffi unannounce doc - rs/AGENTS.md: internal dev-dependencies are path-only (#4015), and tests crossing real networking run on the wall clock (#4244, #4291). - rs/moq-net/AGENTS.md: point at fuzz/fuzz_targets/ instead of a stale list. - moq-net CHANGELOG: random hops stay below 2^53 (#3933), not 62-bit. - moq-ffi: unannounce on a standalone broadcast is a no-op. Co-Authored-By: Claude Opus 5.5 --- rs/AGENTS.md | 4 ++-- rs/moq-ffi/src/producer.rs | 4 ++-- rs/moq-net/AGENTS.md | 2 +- rs/moq-net/CHANGELOG.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rs/AGENTS.md b/rs/AGENTS.md index d2ba893ae8..4d1356c455 100644 --- a/rs/AGENTS.md +++ b/rs/AGENTS.md @@ -38,7 +38,7 @@ Prefer poll. New logic is a `poll_*` with an `async` helper, not the other way a - `if let` / `let else` over a `match` whose only job is to bind. Keep `match` when both arms do work. - Derive `Serialize`/`Deserialize`; a hand-written impl is a second copy of the wire shape. Reach for `serde_with` for what the derive can't express. - Public modules with short names: `broadcast::Consumer`, not `BroadcastConsumer`. Keep `mod encoder` private and re-export flat as `encode::Encoder`. -- Workspace members and shared dependency versions live in the root `Cargo.toml`; crates reference deps via `{ workspace = true }`. +- Workspace members and shared dependency versions live in the root `Cargo.toml`; crates reference deps via `{ workspace = true }`, except internal dev-dependencies, which are path-only so releases publish (`_publish-test` enforces it). - Use newtypes and enums instead of untyped strings. - Have the language make misuse impossible: terminal operations consume `self`, cleanup in `Drop`, etc. @@ -50,7 +50,7 @@ Prefer poll. New logic is a `poll_*` with an `async` helper, not the other way a # Testing -- Tests are inline `#[cfg(test)] mod tests`. Time-dependent async tests call `tokio::time::pause()` first. +- Tests are inline `#[cfg(test)] mod tests`. Time-dependent async tests call `tokio::time::pause()` first, unless they cross real networking that can't be mocked (sockets, smoke tests); those run on the wall clock and assert lower bounds. - Run tests through `just` (nextest), not `cargo test`: nextest kills a wedged test as TIMEOUT, cargo hangs forever. A test flagged SLOW is a bug to fix, not a threshold to raise. - `just check` compiles default features only, like CI. `just rs features` (nightly) covers `--all-features` / `--no-default-features`. Keep a feature gate around the dependency, not the logic, so the logic's tests stay in the merge gate. - Local checks compile only the host platform; `just rs windows` / `macos` must run on that OS and `just rs wasm` covers `moq-wasm`. Say plainly in the PR when platform code is uncompiled. diff --git a/rs/moq-ffi/src/producer.rs b/rs/moq-ffi/src/producer.rs index 68261bf203..377ec3c7a4 100644 --- a/rs/moq-ffi/src/producer.rs +++ b/rs/moq-ffi/src/producer.rs @@ -253,8 +253,8 @@ impl MoqBroadcastProducer { /// Retract this broadcast's exact-path advertisement, if any. /// /// Local consumers and peers alike stop discovering and requesting it; - /// tracks already in flight carry on. Announcing again brings it back. Errors - /// with `Closed` on a standalone broadcast (no origin to announce on). + /// tracks already in flight carry on. Announcing again brings it back. A no-op + /// on a standalone broadcast. pub fn unannounce(&self) -> Result<(), MoqError> { let _guard = crate::ffi::enter(); self.with_state(|state| { diff --git a/rs/moq-net/AGENTS.md b/rs/moq-net/AGENTS.md index ed248fc94c..1fbbd48ffa 100644 --- a/rs/moq-net/AGENTS.md +++ b/rs/moq-net/AGENTS.md @@ -11,6 +11,6 @@ The wire layer. Generic over the transport and media-agnostic: the relay never i # Testing -- `just rs fuzz ` (`lite`, `ietf`, `varint`, `path`) needs nightly. The target bodies live in `src/fuzz.rs`; `fuzz/regressions//` replays under `just check`, so commit every crash input there. +- `just rs fuzz ` (one per file in `fuzz/fuzz_targets/`) needs nightly. The target bodies live in `src/fuzz.rs`; `fuzz/regressions//` replays under `just check`, so commit every crash input there. - `just rs loom` model-checks the concurrent handoffs. A hang is a lost wakeup, not a flake. - `just test interop --all` runs the cross-language interop matrix after a wire change. diff --git a/rs/moq-net/CHANGELOG.md b/rs/moq-net/CHANGELOG.md index 3bd5b21584..89eaa3be34 100644 --- a/rs/moq-net/CHANGELOG.md +++ b/rs/moq-net/CHANGELOG.md @@ -131,7 +131,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [**breaking**] `create_track`, `reserve_track`, `unique_track`, `finish`, `create_group`, and `append_group` take `&self`. `track::Consumer::info()` is `query()`. `track::Demand` gains `is_used` / `poll_used` / `poll_unused`. `track::Producer::poll_unused` returns `Poll>`. `bandwidth::Producer::closed()` returns the cause. - [**breaking**] `stats::Presence` and `stats::Traffic` name both edges of each cumulative pair `*_started` / `*_ended` (`sessions_started` / `sessions_ended`, `announces_started` / `announces_ended`, `broadcasts_*`, `subscriptions_*`). Serialize still writes the previous `announced` / `*_closed` names beside the new ones; deserialize accepts either spelling, with the canonical name winning. - [**breaking**] `origin::Info` is `origin::Config` with public fields and no `with_*` builders. `Producer::info()` is `config()`. -- [**breaking**] `origin::Config::default()` mints a random hop, `Config::id` is `hop`, and origin handles expose `hop()` instead of dereferencing to `Hop`. Random hops now use the full 62-bit wire range; current `@moq/net` clients decode them as `bigint`, while legacy `@moq/lite` clients limited to `Number.MAX_SAFE_INTEGER` can reject larger values and must upgrade. +- [**breaking**] `origin::Config::default()` mints a random hop, `Config::id` is `hop`, and origin handles expose `hop()` instead of dereferencing to `Hop`. Random hops stay below 2^53, so legacy `@moq/lite` clients limited to `Number.MAX_SAFE_INTEGER` still decode them; current `@moq/net` clients decode the full 62-bit wire range as `bigint`. - [**breaking**] `origin::Producer::scope(root, patterns)` and `origin::Consumer::scope(root, patterns)` replace the separate `with_root` / `scope` calls and return `Result` with `Unauthorized` for an empty grant. - [**breaking**] `origin::Pending` is `origin::Requesting`, the consumer-side wait for a request to resolve. - `origin::Producer::publish(path, route)` creates and advertises a broadcast together. From f7c82041ea87256693ffb8f489abb5854513e140 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sat, 26 Sep 2026 17:50:16 -0700 Subject: [PATCH 2/2] dart: regenerate for the unannounce doc Co-Authored-By: Claude Opus 5.5 --- dart/moq_ffi/lib/src/moq.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dart/moq_ffi/lib/src/moq.dart b/dart/moq_ffi/lib/src/moq.dart index 12e167a28a..a79ae74b9a 100644 --- a/dart/moq_ffi/lib/src/moq.dart +++ b/dart/moq_ffi/lib/src/moq.dart @@ -12896,7 +12896,7 @@ void _checkApiChecksums() { throw UniffiInternalError.panicked("UniFFI API checksum mismatch"); } if (uniffi_moq_ffi_checksum_method_moqbroadcastproducer_unannounce() != - 63513) { + 49647) { throw UniffiInternalError.panicked("UniFFI API checksum mismatch"); } if (uniffi_moq_ffi_checksum_method_moqcontainerproducer_cut() != 17534) {