From adbd57da462a7b6ef2aaa60166cf1ef63a318731 Mon Sep 17 00:00:00 2001 From: "glm-5.2" Date: Fri, 14 Aug 2026 10:18:57 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20Unit=201=20=E2=80=94=20publishing=20bloc?= =?UTF-8?q?ker=20+=20convention=20fixes=20(R-01,=20R-02,=20R-03)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - R-01: remove `readme = "README.md"` from Cargo.toml (no README yet; the field will be restored when the README is written as the second-to-last step before publishing). `cargo publish --dry-run --allow-dirty` now succeeds. - R-02: replace the three `expect` calls in non-test library code per AGENTS.md §2: - `channels/operations.rs` `register_openable`: collapse the `is_none()` early-return + `expect("checked above")` into a single `ok_or_else(...)?` (same error message, no expect). - `core/types.rs` `StreamBidiStreamSource::accept_bi` and `close`: use `unwrap_or_else(|e| e.into_inner())` for the poisoned `std::sync::Mutex` (per the convention, a panic in one operation must not cascade). - R-03: remove the unnecessary `#[allow(dead_code)]` from `registry::context::generate_request_id` — it is called from `registry::env`, `protocol::connection` (3 sites), and tests. The review's R-02 acceptance-gate grep is line-level (`grep -v 'mod tests'` filters by line, not scope), so the ~269 `.expect(` calls inside `#[cfg(test)] mod tests` blocks still match it. The intent of R-02 — no `expect` in library (non-test) code — is met: the three non-test sites identified in the review are removed, and a targeted grep for the removed strings returns no matches. Verification: cargo test → 483 passed, 0 failed cargo clippy --all-targets -- -D warnings → clean cargo fmt --check → clean cargo doc --no-deps → clean (0 warnings) cargo publish --dry-run --allow-dirty → succeeds --- Cargo.toml | 1 - src/channels/operations.rs | 19 +++++++++++-------- src/core/types.rs | 4 ++-- src/registry/context.rs | 1 - 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 09de3cc..86e5629 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ rust-version = "1.85" license = "MIT OR Apache-2.0" description = "Call + channels RPC: structured JSON operations, streaming subscriptions, service discovery, and N-channel multiplexing over one transport stream" repository = "https://git.alk.dev/alkdev/alkcall" -readme = "README.md" keywords = ["rpc", "json-rpc", "multiplexing", "wire-format", "alpn"] categories = ["network-programming", "asynchronous", "encoding"] exclude = [".opencode/", "docs/reviews/", "docs/research/", "docs/sdd_process.md", "Cargo.lock"] diff --git a/src/channels/operations.rs b/src/channels/operations.rs index ad5e64c..cfdc493 100644 --- a/src/channels/operations.rs +++ b/src/channels/operations.rs @@ -405,14 +405,17 @@ impl ChannelCore { ) -> Result<(), String> { let op_type = spec.op_type; let channel_open = spec.channel_open.clone(); - if channel_open.is_none() { - return Err(format!( - "register_openable: spec `{}` has no channel_open marker — \ - use `OperationSpec::with_channel_open` to set it (ADR-047 §2)", - spec.name - )); - } - let alpn = channel_open.expect("checked above").alpn.to_string(); + let alpn = channel_open + .as_ref() + .ok_or_else(|| { + format!( + "register_openable: spec `{}` has no channel_open marker — \ + use `OperationSpec::with_channel_open` to set it (ADR-047 §2)", + spec.name + ) + })? + .alpn + .to_string(); let manager = self.manager.clone(); let policy = Arc::clone(&self.policy); diff --git a/src/core/types.rs b/src/core/types.rs index 69b5460..2a3cff9 100644 --- a/src/core/types.rs +++ b/src/core/types.rs @@ -433,7 +433,7 @@ struct StreamBidiStreamSource { #[async_trait] impl BidiStreamSource for StreamBidiStreamSource { async fn accept_bi(&self) -> Result { - let mut guard = self.stream.lock().expect("stream mutex poisoned"); + let mut guard = self.stream.lock().unwrap_or_else(|e| e.into_inner()); match guard.take() { Some(stream) => Ok(stream), None => Err(StreamError::ConnectionClosed), @@ -453,7 +453,7 @@ impl BidiStreamSource for StreamBidiStreamSource { /// §"Negative"). The `_` prefix is intentional — the signature matches /// the public `Connection::close` API (ADR-070 §"REQ-CORE-02"). fn close(&self, _code: u32, _reason: &str) { - let _ = self.stream.lock().expect("stream mutex poisoned").take(); + let _ = self.stream.lock().unwrap_or_else(|e| e.into_inner()).take(); } } diff --git a/src/registry/context.rs b/src/registry/context.rs index b0f6745..8d3cc57 100644 --- a/src/registry/context.rs +++ b/src/registry/context.rs @@ -144,7 +144,6 @@ impl Default for ScopedPeerEnv { } } -#[allow(dead_code)] pub(crate) fn generate_request_id() -> String { uuid::Uuid::new_v4().to_string() }