Skip to main content

max / makenotwork

kberg: adopt universal clippy/lint baseline; warnings to zero Add the shared pedantic + unreachable_pub baseline. Fixes: #[must_use] on the 11 builder setters (return_self_not_must_use); named the ToolKind::Read arms instead of `_` (match_wildcard_for_single_variants); by-value self on the Copy SurfaceProjection method; dropped a redundant `continue`. Three consume-by-value params carry a documented #[allow(needless_pass_by_value)]. clippy --all-targets clean, cargo fmt clean, 31 tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-23 13:08 UTC
Commit: 14ccb0cd7d0eefb984f8e9ee0fdd4136f9f218b2
Parent: 829ed17
9 files changed, +87 insertions, -39 deletions
@@ -34,3 +34,35 @@ tokio-stream = { version = "0.1", optional = true, features = ["sync"] }
34 34 tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "sync", "time"] }
35 35 tracing-subscriber = { version = "0.3", features = ["env-filter"] }
36 36 reqwest = { version = "0.13", features = ["json"] }
37 +
38 + [lints.rust]
39 + unused = "warn"
40 + unreachable_pub = "warn"
41 +
42 + [lints.clippy]
43 + pedantic = { level = "warn", priority = -1 }
44 + # Allow-list tuned from a measured breakdown across server/multithreaded/pter
45 + # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything
46 + # else in `pedantic` stays a warning. Keep this block identical across repos.
47 + module_name_repetitions = "allow"
48 + # Doc lints — no docs-completeness push underway.
49 + missing_errors_doc = "allow"
50 + missing_panics_doc = "allow"
51 + doc_markdown = "allow"
52 + # Numeric casts — endemic and mostly intentional in size/byte math.
53 + cast_possible_truncation = "allow"
54 + cast_sign_loss = "allow"
55 + cast_precision_loss = "allow"
56 + cast_possible_wrap = "allow"
57 + cast_lossless = "allow"
58 + # Subjective structure/style nags — high churn, low signal.
59 + must_use_candidate = "allow"
60 + too_many_lines = "allow"
61 + struct_excessive_bools = "allow"
62 + similar_names = "allow"
63 + items_after_statements = "allow"
64 + single_match_else = "allow"
65 + # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown.
66 + match_same_arms = "allow"
67 + unnecessary_wraps = "allow"
68 + type_complexity = "allow"
@@ -29,10 +29,10 @@ struct Add;
29 29
30 30 #[async_trait]
31 31 impl Tool for Add {
32 - fn name(&self) -> &str {
32 + fn name(&self) -> &'static str {
33 33 "add"
34 34 }
35 - fn description(&self) -> &str {
35 + fn description(&self) -> &'static str {
36 36 "Add two integers and return the sum."
37 37 }
38 38 fn kind(&self) -> ToolKind {
@@ -74,10 +74,10 @@ struct RememberProject;
74 74
75 75 #[async_trait]
76 76 impl Tool for RememberProject {
77 - fn name(&self) -> &str {
77 + fn name(&self) -> &'static str {
78 78 "remember_project"
79 79 }
80 - fn description(&self) -> &str {
80 + fn description(&self) -> &'static str {
81 81 "Record a new project the user is working on."
82 82 }
83 83 fn kind(&self) -> ToolKind {
@@ -118,22 +118,26 @@ impl<P: InferenceProvider> Agent<P> {
118 118 }
119 119 }
120 120
121 + #[must_use]
121 122 pub fn with_max_steps(mut self, n: usize) -> Self {
122 123 self.config.max_steps = n;
123 124 self
124 125 }
125 126
127 + #[must_use]
126 128 pub fn with_projection(mut self, projection: SurfaceProjection) -> Self {
127 129 self.config.projection = projection;
128 130 self
129 131 }
130 132
133 + #[must_use]
131 134 pub fn with_grants(mut self, grants: HashSet<String>) -> Self {
132 135 self.config.grants = Some(grants);
133 136 self
134 137 }
135 138
136 139 /// Bypass capability checks. Only appropriate for fully-trusted callers.
140 + #[must_use]
137 141 pub fn without_grant_checks(mut self) -> Self {
138 142 self.config.grants = None;
139 143 self
@@ -29,6 +29,7 @@ impl OllamaProvider {
29 29 }
30 30 }
31 31
32 + #[must_use]
32 33 pub fn with_base_url(mut self, url: impl Into<String>) -> Self {
33 34 self.base_url = url.into();
34 35 self
@@ -52,11 +52,13 @@ impl ResourceDescriptor {
52 52 }
53 53 }
54 54
55 + #[must_use]
55 56 pub fn with_description(mut self, description: impl Into<String>) -> Self {
56 57 self.description = Some(description.into());
57 58 self
58 59 }
59 60
61 + #[must_use]
60 62 pub fn with_mime_type(mut self, mime_type: impl Into<String>) -> Self {
61 63 self.mime_type = Some(mime_type.into());
62 64 self
@@ -100,6 +102,7 @@ impl ResourceContents {
100 102 }
101 103 }
102 104
105 + #[must_use]
103 106 pub fn with_mime_type(mut self, mime_type: impl Into<String>) -> Self {
104 107 self.mime_type = Some(mime_type.into());
105 108 self
@@ -231,6 +234,8 @@ pub(crate) struct ReadResourceParams {
231 234 /// Wrap a single [`ResourceContents`] into the `resources/read` result shape
232 235 /// (`{ "contents": [ ... ] }`).
233 236 #[cfg(feature = "server")]
237 + // contents is consumed into the returned JSON value.
238 + #[allow(clippy::needless_pass_by_value)]
234 239 pub(crate) fn read_result(contents: ResourceContents) -> serde_json::Value {
235 240 serde_json::json!({ "contents": [contents] })
236 241 }
@@ -86,6 +86,7 @@ impl ServeConfig {
86 86 }
87 87 }
88 88
89 + #[must_use]
89 90 pub fn with_projection(mut self, projection: SurfaceProjection) -> Self {
90 91 self.projection = projection;
91 92 self
@@ -93,6 +94,7 @@ impl ServeConfig {
93 94
94 95 /// Attach a resource registry, enabling `resources/list` and
95 96 /// `resources/read` and advertising the `resources` capability.
97 + #[must_use]
96 98 pub fn with_resources(mut self, resources: ResourceRegistry) -> Self {
97 99 self.resources = Some(resources);
98 100 self
@@ -130,8 +132,7 @@ impl BoundServer {
130 132 pub fn cancel_session(&self, session_id: &str, reason: &str) -> usize {
131 133 self.sessions
132 134 .get(session_id)
133 - .map(|s| s.cancel_all(reason))
134 - .unwrap_or(0)
135 + .map_or(0, |s| s.cancel_all(reason))
135 136 }
136 137
137 138 /// Ids of the currently-connected sessions.
@@ -283,7 +284,7 @@ async fn handle_sse(State(state): State<AppState>, headers: HeaderMap) -> axum::
283 284 }
284 285 // A slow session that lagged past the buffer drops those
285 286 // updates and keeps streaming; it re-reads on next use.
286 - Err(tokio::sync::broadcast::error::RecvError::Lagged(_)) => continue,
287 + Err(tokio::sync::broadcast::error::RecvError::Lagged(_)) => {}
287 288 Err(tokio::sync::broadcast::error::RecvError::Closed) => break,
288 289 }
289 290 }
@@ -429,6 +430,8 @@ fn resources_unsupported(id: Value) -> JsonRpcResponse {
429 430 JsonRpcResponse::err(id, codes::METHOD_NOT_FOUND, "server exposes no resources")
430 431 }
431 432
433 + // id/e are consumed into the returned response.
434 + #[allow(clippy::needless_pass_by_value)]
432 435 fn rpc_err_from(id: Value, e: Error) -> JsonRpcResponse {
433 436 let (code, message) = match &e {
434 437 Error::ToolNotFound(_) => (codes::METHOD_NOT_FOUND, e.to_string()),
@@ -474,10 +477,10 @@ mod tests {
474 477 struct Echo;
475 478 #[async_trait]
476 479 impl Tool for Echo {
477 - fn name(&self) -> &str {
480 + fn name(&self) -> &'static str {
478 481 "echo"
479 482 }
480 - fn description(&self) -> &str {
483 + fn description(&self) -> &'static str {
481 484 "read echo"
482 485 }
483 486 fn kind(&self) -> ToolKind {
@@ -497,6 +500,8 @@ mod tests {
497 500 r
498 501 }
499 502
503 + // id/params are consumed into the returned request (test helper).
504 + #[allow(clippy::needless_pass_by_value)]
500 505 fn request(id: Option<Value>, method: &str, params: Value) -> JsonRpcRequest {
501 506 serde_json::from_value(json!({
502 507 "jsonrpc": "2.0",
@@ -52,27 +52,27 @@ impl Session {
52 52 }
53 53 }
54 54
55 - pub fn subscribe(&self, uri: impl Into<String>) {
55 + pub(crate) fn subscribe(&self, uri: impl Into<String>) {
56 56 self.subscriptions.lock().unwrap().insert(uri.into());
57 57 }
58 58
59 59 /// Remove a subscription. Returns whether it was present.
60 - pub fn unsubscribe(&self, uri: &str) -> bool {
60 + pub(crate) fn unsubscribe(&self, uri: &str) -> bool {
61 61 self.subscriptions.lock().unwrap().remove(uri)
62 62 }
63 63
64 - pub fn is_subscribed(&self, uri: &str) -> bool {
64 + pub(crate) fn is_subscribed(&self, uri: &str) -> bool {
65 65 self.subscriptions.lock().unwrap().contains(uri)
66 66 }
67 67
68 68 /// Attach the SSE out channel (called when the client opens GET `/mcp`).
69 69 /// Replaces any prior channel — a reconnect supersedes the stale stream.
70 - pub fn attach_out(&self, tx: OutSender) {
70 + pub(crate) fn attach_out(&self, tx: OutSender) {
71 71 *self.out.lock().unwrap() = Some(tx);
72 72 }
73 73
74 74 /// Push a notification to the SSE stream if one is connected.
75 - pub fn push(&self, notification: Value) {
75 + pub(crate) fn push(&self, notification: Value) {
76 76 if let Some(tx) = self.out.lock().unwrap().as_ref() {
77 77 let _ = tx.send(notification);
78 78 }
@@ -82,7 +82,7 @@ impl Session {
82 82 /// call is registered under `id` until it completes; a concurrent
83 83 /// [`cancel_request`](Self::cancel_request) or [`cancel_all`](Self::cancel_all)
84 84 /// aborts it with [`Error::Cancelled`].
85 - pub async fn run_cancellable<F>(&self, id: &Value, fut: F) -> Result<ToolCallResult>
85 + pub(crate) async fn run_cancellable<F>(&self, id: &Value, fut: F) -> Result<ToolCallResult>
86 86 where
87 87 F: Future<Output = Result<ToolCallResult>>,
88 88 {
@@ -109,7 +109,7 @@ impl Session {
109 109 /// Cancel one in-flight request by its (stringified) id. Triggers the
110 110 /// select in [`run_cancellable`](Self::run_cancellable). No-op if the id is
111 111 /// not in flight (already finished or never existed).
112 - pub fn cancel_request(&self, id_key: &str) {
112 + pub(crate) fn cancel_request(&self, id_key: &str) {
113 113 if let Some(entry) = self.inflight.lock().unwrap().remove(id_key) {
114 114 let _ = entry.cancel.send(());
115 115 }
@@ -118,7 +118,7 @@ impl Session {
118 118 /// Cancel every in-flight request for this session and tell the client,
119 119 /// pushing a `notifications/cancelled` for each. This is the app-initiated
120 120 /// path — a human taking a buffer back. Returns the count cancelled.
121 - pub fn cancel_all(&self, reason: &str) -> usize {
121 + pub(crate) fn cancel_all(&self, reason: &str) -> usize {
122 122 let drained: Vec<Inflight> = {
123 123 let mut map = self.inflight.lock().unwrap();
124 124 map.drain().map(|(_, v)| v).collect()
@@ -141,28 +141,28 @@ pub(crate) struct Sessions {
141 141
142 142 impl Sessions {
143 143 /// Create a fresh session with a random id and return it.
144 - pub fn create(&self) -> Arc<Session> {
144 + pub(super) fn create(&self) -> Arc<Session> {
145 145 let id = uuid::Uuid::new_v4().to_string();
146 146 let session = Arc::new(Session::new(id.clone()));
147 147 self.map.lock().unwrap().insert(id, session.clone());
148 148 session
149 149 }
150 150
151 - pub fn get(&self, id: &str) -> Option<Arc<Session>> {
151 + pub(super) fn get(&self, id: &str) -> Option<Arc<Session>> {
152 152 self.map.lock().unwrap().get(id).cloned()
153 153 }
154 154
155 155 /// Remove a session (client sent DELETE `/mcp`). Returns whether present.
156 - pub fn remove(&self, id: &str) -> bool {
156 + pub(super) fn remove(&self, id: &str) -> bool {
157 157 self.map.lock().unwrap().remove(id).is_some()
158 158 }
159 159
160 - pub fn ids(&self) -> Vec<String> {
160 + pub(super) fn ids(&self) -> Vec<String> {
161 161 self.map.lock().unwrap().keys().cloned().collect()
162 162 }
163 163
164 164 /// Cancel in-flight ops across every session. Returns the total cancelled.
165 - pub fn cancel_all(&self, reason: &str) -> usize {
165 + pub(super) fn cancel_all(&self, reason: &str) -> usize {
166 166 let sessions: Vec<Arc<Session>> = self.map.lock().unwrap().values().cloned().collect();
167 167 sessions.iter().map(|s| s.cancel_all(reason)).sum()
168 168 }
@@ -58,7 +58,7 @@ impl ToolKind {
58 58 pub fn capability_id(&self) -> Option<&str> {
59 59 match self {
60 60 ToolKind::Write(cap) => Some(&cap.id),
61 - _ => None,
61 + ToolKind::Read => None,
62 62 }
63 63 }
64 64 }
@@ -150,7 +150,7 @@ pub enum SurfaceProjection {
150 150 }
151 151
152 152 impl SurfaceProjection {
153 - fn includes(&self, small_model_safe: bool) -> bool {
153 + fn includes(self, small_model_safe: bool) -> bool {
154 154 match self {
155 155 SurfaceProjection::Full => true,
156 156 SurfaceProjection::Compact => small_model_safe,
@@ -226,9 +226,10 @@ impl ToolRegistry {
226 226 let map = Arc::get_mut(&mut self.tools).expect(
227 227 "ToolRegistry::register called after cloning; register all tools before serving",
228 228 );
229 - if map.contains_key(&name) {
230 - panic!("duplicate tool registration: {name}");
231 - }
229 + assert!(
230 + !map.contains_key(&name),
231 + "duplicate tool registration: {name}"
232 + );
232 233 map.insert(name, Arc::new(tool));
233 234 }
234 235
@@ -255,7 +256,7 @@ impl ToolRegistry {
255 256 },
256 257 capability: match t.kind() {
257 258 ToolKind::Write(cap) => Some(cap),
258 - _ => None,
259 + ToolKind::Read => None,
259 260 },
260 261 refusal_reason: t.refusal_reason().map(str::to_string),
261 262 })
@@ -310,10 +311,10 @@ mod tests {
310 311 struct Echo;
311 312 #[async_trait]
312 313 impl Tool for Echo {
313 - fn name(&self) -> &str {
314 + fn name(&self) -> &'static str {
314 315 "echo"
315 316 }
316 - fn description(&self) -> &str {
317 + fn description(&self) -> &'static str {
317 318 "read-only echo"
318 319 }
319 320 fn kind(&self) -> ToolKind {
@@ -333,10 +334,10 @@ mod tests {
333 334 struct Mutate;
334 335 #[async_trait]
335 336 impl Tool for Mutate {
336 - fn name(&self) -> &str {
337 + fn name(&self) -> &'static str {
337 338 "mutate"
338 339 }
339 - fn description(&self) -> &str {
340 + fn description(&self) -> &'static str {
340 341 "write, gated on `test.write`"
341 342 }
342 343 fn kind(&self) -> ToolKind {
@@ -363,7 +364,7 @@ mod tests {
363 364 }
364 365
365 366 fn grants(ids: &[&str]) -> HashSet<String> {
366 - ids.iter().map(|s| s.to_string()).collect()
367 + ids.iter().map(std::string::ToString::to_string).collect()
367 368 }
368 369
369 370 #[tokio::test]
@@ -19,10 +19,10 @@ use serde_json::{Value, json};
19 19 struct Ping;
20 20 #[async_trait]
21 21 impl Tool for Ping {
22 - fn name(&self) -> &str {
22 + fn name(&self) -> &'static str {
23 23 "ping"
24 24 }
25 - fn description(&self) -> &str {
25 + fn description(&self) -> &'static str {
26 26 "read-only ping"
27 27 }
28 28 fn kind(&self) -> ToolKind {
@@ -42,10 +42,10 @@ impl Tool for Ping {
42 42 struct Save;
43 43 #[async_trait]
44 44 impl Tool for Save {
45 - fn name(&self) -> &str {
45 + fn name(&self) -> &'static str {
46 46 "save"
47 47 }
48 - fn description(&self) -> &str {
48 + fn description(&self) -> &'static str {
49 49 "write, gated on `demo.save`"
50 50 }
51 51 fn kind(&self) -> ToolKind {
@@ -72,10 +72,10 @@ fn registry() -> ToolRegistry {
72 72 struct Hang;
73 73 #[async_trait]
74 74 impl Tool for Hang {
75 - fn name(&self) -> &str {
75 + fn name(&self) -> &'static str {
76 76 "hang"
77 77 }
78 - fn description(&self) -> &str {
78 + fn description(&self) -> &'static str {
79 79 "read-only; blocks until cancelled"
80 80 }
81 81 fn kind(&self) -> ToolKind {