Files
codex/prs/bolinfest/PR-2328.md
2025-09-02 15:17:45 -07:00

45 KiB
Raw Blame History

PR #2328: Added allow-expect-in-tests / allow-unwrap-in-tests

Description

This PR:

  • Added the clippy.toml to configure allowable expect / unwrap usage in tests
  • Removed as many expect/allow lines as possible from tests
  • moved a bunch of allows to expects where possible

Note: in integration tests, non #[test] helper functions are not covered by this so we had to leave a few lingering expect(expect_used checks around

Full Diff

diff --git a/codex-rs/apply-patch/src/lib.rs b/codex-rs/apply-patch/src/lib.rs
index 262d219d6d..87df66dd23 100644
--- a/codex-rs/apply-patch/src/lib.rs
+++ b/codex-rs/apply-patch/src/lib.rs
@@ -166,7 +166,7 @@ impl ApplyPatchAction {
             panic!("path must be absolute");
         }
 
-        #[allow(clippy::expect_used)]
+        #[expect(clippy::expect_used)]
         let filename = path
             .file_name()
             .expect("path should not be empty")
@@ -179,7 +179,7 @@ impl ApplyPatchAction {
 *** End Patch"#,
         );
         let changes = HashMap::from([(path.to_path_buf(), ApplyPatchFileChange::Add { content })]);
-        #[allow(clippy::expect_used)]
+        #[expect(clippy::expect_used)]
         Self {
             changes,
             cwd: path
@@ -682,8 +682,6 @@ pub fn print_summary(
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
-
     use super::*;
     use pretty_assertions::assert_eq;
     use std::fs;
diff --git a/codex-rs/apply-patch/src/parser.rs b/codex-rs/apply-patch/src/parser.rs
index 44c5b14619..ff9dfd6f8f 100644
--- a/codex-rs/apply-patch/src/parser.rs
+++ b/codex-rs/apply-patch/src/parser.rs
@@ -427,7 +427,6 @@ fn parse_update_file_chunk(
 }
 
 #[test]
-#[allow(clippy::unwrap_used)]
 fn test_parse_patch() {
     assert_eq!(
         parse_patch_text("bad", ParseMode::Strict),
diff --git a/codex-rs/chatgpt/tests/apply_command_e2e.rs b/codex-rs/chatgpt/tests/apply_command_e2e.rs
index f1a35e1521..2aa8b809bb 100644
--- a/codex-rs/chatgpt/tests/apply_command_e2e.rs
+++ b/codex-rs/chatgpt/tests/apply_command_e2e.rs
@@ -1,5 +1,3 @@
-#![expect(clippy::expect_used)]
-
 use codex_chatgpt::apply_command::apply_diff_from_task;
 use codex_chatgpt::get_task::GetTaskResponse;
 use std::path::Path;
diff --git a/codex-rs/clippy.toml b/codex-rs/clippy.toml
new file mode 100644
index 0000000000..9e614bec42
--- /dev/null
+++ b/codex-rs/clippy.toml
@@ -0,0 +1,2 @@
+allow-expect-in-tests = true
+allow-unwrap-in-tests = true
\ No newline at end of file
diff --git a/codex-rs/common/src/config_override.rs b/codex-rs/common/src/config_override.rs
index c9b18edc7c..6b77099524 100644
--- a/codex-rs/common/src/config_override.rs
+++ b/codex-rs/common/src/config_override.rs
@@ -142,7 +142,6 @@ fn parse_toml_value(raw: &str) -> Result<Value, toml::de::Error> {
 }
 
 #[cfg(all(test, feature = "cli"))]
-#[allow(clippy::expect_used, clippy::unwrap_used)]
 mod tests {
     use super::*;
 
diff --git a/codex-rs/core/src/bash.rs b/codex-rs/core/src/bash.rs
index b9cd444356..5b94daf252 100644
--- a/codex-rs/core/src/bash.rs
+++ b/codex-rs/core/src/bash.rs
@@ -132,7 +132,6 @@ fn parse_plain_command_from_node(cmd: tree_sitter::Node, src: &str) -> Option<Ve
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
 
     fn parse_seq(src: &str) -> Option<Vec<Vec<String>>> {
diff --git a/codex-rs/core/src/client.rs b/codex-rs/core/src/client.rs
index 135782bc31..3d26bd0880 100644
--- a/codex-rs/core/src/client.rs
+++ b/codex-rs/core/src/client.rs
@@ -609,8 +609,6 @@ fn try_parse_retry_after(err: &Error) -> Option<Duration> {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::expect_used, clippy::unwrap_used)]
-
     use super::*;
     use serde_json::json;
     use tokio::sync::mpsc;
diff --git a/codex-rs/core/src/client_common.rs b/codex-rs/core/src/client_common.rs
index d8684648f8..c3489200c9 100644
--- a/codex-rs/core/src/client_common.rs
+++ b/codex-rs/core/src/client_common.rs
@@ -187,7 +187,6 @@ impl Stream for ResponseStream {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::expect_used)]
     use crate::model_family::find_family_for_model;
 
     use super::*;
diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs
index 098ff115fa..482ac2f1ab 100644
--- a/codex-rs/core/src/codex.rs
+++ b/codex-rs/core/src/codex.rs
@@ -1,5 +1,5 @@
 // Poisoned mutex should fail the program
-#![allow(clippy::unwrap_used)]
+#![expect(clippy::unwrap_used)]
 
 use std::borrow::Cow;
 use std::collections::HashMap;
diff --git a/codex-rs/core/src/config.rs b/codex-rs/core/src/config.rs
index f9c15b9eed..b17bb80815 100644
--- a/codex-rs/core/src/config.rs
+++ b/codex-rs/core/src/config.rs
@@ -765,7 +765,6 @@ pub fn log_dir(cfg: &Config) -> std::io::Result<PathBuf> {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::expect_used, clippy::unwrap_used)]
     use crate::config_types::HistoryPersistence;
 
     use super::*;
diff --git a/codex-rs/core/src/exec_env.rs b/codex-rs/core/src/exec_env.rs
index 2957f3da15..88246b063c 100644
--- a/codex-rs/core/src/exec_env.rs
+++ b/codex-rs/core/src/exec_env.rs
@@ -70,8 +70,6 @@ where
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used, clippy::expect_used)]
-
     use super::*;
     use crate::config_types::ShellEnvironmentPolicyInherit;
     use maplit::hashmap;
diff --git a/codex-rs/core/src/git_info.rs b/codex-rs/core/src/git_info.rs
index 52d029f669..09a59b7b8c 100644
--- a/codex-rs/core/src/git_info.rs
+++ b/codex-rs/core/src/git_info.rs
@@ -99,9 +99,6 @@ async fn run_git_command_with_timeout(args: &[&str], cwd: &Path) -> Option<std::
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::expect_used)]
-    #![allow(clippy::unwrap_used)]
-
     use super::*;
 
     use std::fs;
diff --git a/codex-rs/core/src/is_safe_command.rs b/codex-rs/core/src/is_safe_command.rs
index f5f453f8d8..38dd9562f8 100644
--- a/codex-rs/core/src/is_safe_command.rs
+++ b/codex-rs/core/src/is_safe_command.rs
@@ -162,7 +162,6 @@ fn is_valid_sed_n_arg(arg: Option<&str>) -> bool {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
 
     fn vec_str(args: &[&str]) -> Vec<String> {
diff --git a/codex-rs/core/src/mcp_connection_manager.rs b/codex-rs/core/src/mcp_connection_manager.rs
index 2e33c8754b..b5813a0462 100644
--- a/codex-rs/core/src/mcp_connection_manager.rs
+++ b/codex-rs/core/src/mcp_connection_manager.rs
@@ -281,7 +281,6 @@ fn is_valid_mcp_server_name(server_name: &str) -> bool {
 }
 
 #[cfg(test)]
-#[allow(clippy::unwrap_used)]
 mod tests {
     use super::*;
     use mcp_types::ToolInputSchema;
diff --git a/codex-rs/core/src/model_provider_info.rs b/codex-rs/core/src/model_provider_info.rs
index 98f07deb1e..00eabc539c 100644
--- a/codex-rs/core/src/model_provider_info.rs
+++ b/codex-rs/core/src/model_provider_info.rs
@@ -322,7 +322,6 @@ pub fn create_oss_provider_with_base_url(base_url: &str) -> ModelProviderInfo {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
     use pretty_assertions::assert_eq;
 
diff --git a/codex-rs/core/src/models.rs b/codex-rs/core/src/models.rs
index da1e31b706..5e67fc381a 100644
--- a/codex-rs/core/src/models.rs
+++ b/codex-rs/core/src/models.rs
@@ -266,7 +266,6 @@ impl std::ops::Deref for FunctionCallOutputPayload {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
 
     #[test]
diff --git a/codex-rs/core/src/openai_tools.rs b/codex-rs/core/src/openai_tools.rs
index ad794c38f1..7c65880433 100644
--- a/codex-rs/core/src/openai_tools.rs
+++ b/codex-rs/core/src/openai_tools.rs
@@ -470,7 +470,6 @@ pub(crate) fn get_openai_tools(
 }
 
 #[cfg(test)]
-#[allow(clippy::expect_used)]
 mod tests {
     use crate::model_family::find_family_for_model;
     use mcp_types::ToolInputSchema;
diff --git a/codex-rs/core/src/project_doc.rs b/codex-rs/core/src/project_doc.rs
index 9f46159d1d..3591b5b1d8 100644
--- a/codex-rs/core/src/project_doc.rs
+++ b/codex-rs/core/src/project_doc.rs
@@ -134,8 +134,6 @@ async fn load_first_candidate(
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::expect_used, clippy::unwrap_used)]
-
     use super::*;
     use crate::config::ConfigOverrides;
     use crate::config::ConfigToml;
diff --git a/codex-rs/core/src/protocol.rs b/codex-rs/core/src/protocol.rs
index f32d9ccf53..ac95b6a20a 100644
--- a/codex-rs/core/src/protocol.rs
+++ b/codex-rs/core/src/protocol.rs
@@ -697,7 +697,6 @@ pub struct Chunk {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
 
     /// Serialize Event to verify that its JSON representation has the expected
diff --git a/codex-rs/core/src/safety.rs b/codex-rs/core/src/safety.rs
index 860a728def..74872ddc4f 100644
--- a/codex-rs/core/src/safety.rs
+++ b/codex-rs/core/src/safety.rs
@@ -245,7 +245,6 @@ fn is_write_patch_constrained_to_writable_paths(
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
 
     #[test]
diff --git a/codex-rs/core/src/seatbelt.rs b/codex-rs/core/src/seatbelt.rs
index ff9dbaa7f9..31aa770d2e 100644
--- a/codex-rs/core/src/seatbelt.rs
+++ b/codex-rs/core/src/seatbelt.rs
@@ -122,7 +122,6 @@ fn create_seatbelt_command_args(
 
 #[cfg(test)]
 mod tests {
-    #![expect(clippy::expect_used)]
     use super::MACOS_SEATBELT_BASE_POLICY;
     use super::create_seatbelt_command_args;
     use crate::protocol::SandboxPolicy;
diff --git a/codex-rs/core/src/shell.rs b/codex-rs/core/src/shell.rs
index 4a4e0146da..0cde3b4a78 100644
--- a/codex-rs/core/src/shell.rs
+++ b/codex-rs/core/src/shell.rs
@@ -98,7 +98,6 @@ mod tests {
     use std::process::Command;
 
     #[tokio::test]
-    #[expect(clippy::unwrap_used)]
     async fn test_current_shell_detects_zsh() {
         let shell = Command::new("sh")
             .arg("-c")
@@ -129,7 +128,6 @@ mod tests {
         assert_eq!(actual_cmd, None);
     }
 
-    #[expect(clippy::unwrap_used)]
     #[tokio::test]
     async fn test_run_with_profile_escaping_and_execution() {
         let shell_path = "/bin/zsh";
diff --git a/codex-rs/core/src/turn_diff_tracker.rs b/codex-rs/core/src/turn_diff_tracker.rs
index 7026d7bb32..5e73fa0650 100644
--- a/codex-rs/core/src/turn_diff_tracker.rs
+++ b/codex-rs/core/src/turn_diff_tracker.rs
@@ -466,7 +466,6 @@ fn is_windows_drive_or_unc_root(p: &std::path::Path) -> bool {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
     use pretty_assertions::assert_eq;
     use tempfile::tempdir;
diff --git a/codex-rs/core/src/user_agent.rs b/codex-rs/core/src/user_agent.rs
index a0cf387069..ddcfd4b7f1 100644
--- a/codex-rs/core/src/user_agent.rs
+++ b/codex-rs/core/src/user_agent.rs
@@ -13,7 +13,6 @@ pub fn get_codex_user_agent(originator: Option<&str>) -> String {
 }
 
 #[cfg(test)]
-#[allow(clippy::unwrap_used)]
 mod tests {
     use super::*;
 
diff --git a/codex-rs/core/src/user_notification.rs b/codex-rs/core/src/user_notification.rs
index e7479f89cd..0a3cb49e78 100644
--- a/codex-rs/core/src/user_notification.rs
+++ b/codex-rs/core/src/user_notification.rs
@@ -20,7 +20,6 @@ pub(crate) enum UserNotification {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
 
     #[test]
diff --git a/codex-rs/core/tests/cli_stream.rs b/codex-rs/core/tests/cli_stream.rs
index c8570577ce..219e99787d 100644
--- a/codex-rs/core/tests/cli_stream.rs
+++ b/codex-rs/core/tests/cli_stream.rs
@@ -1,5 +1,3 @@
-#![expect(clippy::unwrap_used)]
-
 use assert_cmd::Command as AssertCommand;
 use codex_core::spawn::CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR;
 use std::time::Duration;
diff --git a/codex-rs/core/tests/client.rs b/codex-rs/core/tests/client.rs
index 10c6c66fb5..2f7977eeb6 100644
--- a/codex-rs/core/tests/client.rs
+++ b/codex-rs/core/tests/client.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::expect_used, clippy::unwrap_used)]
-
 use codex_core::ConversationManager;
 use codex_core::ModelProviderInfo;
 use codex_core::NewConversation;
@@ -27,10 +25,12 @@ fn sse_completed(id: &str) -> String {
     load_sse_fixture_with_id("tests/fixtures/completed_template.json", id)
 }
 
+#[expect(clippy::unwrap_used)]
 fn assert_message_role(request_body: &serde_json::Value, role: &str) {
     assert_eq!(request_body["role"].as_str().unwrap(), role);
 }
 
+#[expect(clippy::expect_used)]
 fn assert_message_starts_with(request_body: &serde_json::Value, text: &str) {
     let content = request_body["content"][0]["text"]
         .as_str()
@@ -42,6 +42,7 @@ fn assert_message_starts_with(request_body: &serde_json::Value, text: &str) {
     );
 }
 
+#[expect(clippy::expect_used)]
 fn assert_message_ends_with(request_body: &serde_json::Value, text: &str) {
     let content = request_body["content"][0]["text"]
         .as_str()
@@ -55,8 +56,6 @@ fn assert_message_ends_with(request_body: &serde_json::Value, text: &str) {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn includes_session_id_and_model_headers_in_request() {
-    #![allow(clippy::unwrap_used)]
-
     if std::env::var(CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR).is_ok() {
         println!(
             "Skipping test because it cannot execute when network is disabled in a Codex sandbox."
@@ -129,8 +128,6 @@ async fn includes_session_id_and_model_headers_in_request() {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn includes_base_instructions_override_in_request() {
-    #![allow(clippy::unwrap_used)]
-
     // Mock server
     let server = MockServer::start().await;
 
@@ -187,8 +184,6 @@ async fn includes_base_instructions_override_in_request() {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn originator_config_override_is_used() {
-    #![allow(clippy::unwrap_used)]
-
     // Mock server
     let server = MockServer::start().await;
 
@@ -238,8 +233,6 @@ async fn originator_config_override_is_used() {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn chatgpt_auth_sends_correct_request() {
-    #![allow(clippy::unwrap_used)]
-
     if std::env::var(CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR).is_ok() {
         println!(
             "Skipping test because it cannot execute when network is disabled in a Codex sandbox."
@@ -320,8 +313,6 @@ async fn chatgpt_auth_sends_correct_request() {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn includes_user_instructions_message_in_request() {
-    #![allow(clippy::unwrap_used)]
-
     let server = MockServer::start().await;
 
     let first = ResponseTemplate::new(200)
@@ -382,8 +373,6 @@ async fn includes_user_instructions_message_in_request() {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn azure_overrides_assign_properties_used_for_responses_url() {
-    #![allow(clippy::unwrap_used)]
-
     let existing_env_var_with_random_value = if cfg!(windows) { "USERNAME" } else { "USER" };
 
     // Mock server
@@ -460,8 +449,6 @@ async fn azure_overrides_assign_properties_used_for_responses_url() {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn env_var_overrides_loaded_auth() {
-    #![allow(clippy::unwrap_used)]
-
     let existing_env_var_with_random_value = if cfg!(windows) { "USERNAME" } else { "USER" };
 
     // Mock server
diff --git a/codex-rs/core/tests/common/lib.rs b/codex-rs/core/tests/common/lib.rs
index 04b6dc4b62..0a9c8d5aa8 100644
--- a/codex-rs/core/tests/common/lib.rs
+++ b/codex-rs/core/tests/common/lib.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::expect_used)]
+#![expect(clippy::expect_used)]
 
 use tempfile::TempDir;
 
diff --git a/codex-rs/core/tests/exec.rs b/codex-rs/core/tests/exec.rs
index ff5d2b7d54..f011aa7a0a 100644
--- a/codex-rs/core/tests/exec.rs
+++ b/codex-rs/core/tests/exec.rs
@@ -1,5 +1,4 @@
 #![cfg(target_os = "macos")]
-#![expect(clippy::unwrap_used, clippy::expect_used)]
 
 use std::collections::HashMap;
 
@@ -24,6 +23,7 @@ fn skip_test() -> bool {
     false
 }
 
+#[expect(clippy::expect_used)]
 async fn run_test_cmd(tmp: TempDir, cmd: Vec<&str>) -> Result<ExecToolCallOutput> {
     let sandbox_type = get_platform_sandbox().expect("should be able to get sandbox type");
     assert_eq!(sandbox_type, SandboxType::MacosSeatbelt);
@@ -68,7 +68,6 @@ async fn truncates_output_lines() {
     let tmp = TempDir::new().expect("should be able to create temp dir");
     let cmd = vec!["seq", "300"];
 
-    #[expect(clippy::unwrap_used)]
     let output = run_test_cmd(tmp, cmd).await.unwrap();
 
     let expected_output = (1..=256)
diff --git a/codex-rs/core/tests/live_cli.rs b/codex-rs/core/tests/live_cli.rs
index d79e242c4d..e77fe6998e 100644
--- a/codex-rs/core/tests/live_cli.rs
+++ b/codex-rs/core/tests/live_cli.rs
@@ -17,7 +17,7 @@ fn require_api_key() -> String {
 
 /// Helper that spawns the binary inside a TempDir with minimal flags. Returns (Assert, TempDir).
 fn run_live(prompt: &str) -> (assert_cmd::assert::Assert, TempDir) {
-    #![allow(clippy::unwrap_used)]
+    #![expect(clippy::unwrap_used)]
     use std::io::Read;
     use std::io::Write;
     use std::thread;
@@ -113,7 +113,6 @@ fn run_live(prompt: &str) -> (assert_cmd::assert::Assert, TempDir) {
 #[ignore]
 #[test]
 fn live_create_file_hello_txt() {
-    #![allow(clippy::unwrap_used)]
     if std::env::var("OPENAI_API_KEY").is_err() {
         eprintln!("skipping live_create_file_hello_txt  OPENAI_API_KEY not set");
         return;
diff --git a/codex-rs/core/tests/prompt_caching.rs b/codex-rs/core/tests/prompt_caching.rs
index 0c2552ee05..d637eb674e 100644
--- a/codex-rs/core/tests/prompt_caching.rs
+++ b/codex-rs/core/tests/prompt_caching.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::expect_used, clippy::unwrap_used)]
-
 use codex_core::ConversationManager;
 use codex_core::ModelProviderInfo;
 use codex_core::built_in_model_providers;
@@ -24,7 +22,6 @@ fn sse_completed(id: &str) -> String {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn prefixes_context_and_instructions_once_and_consistently_across_requests() {
-    #![allow(clippy::unwrap_used)]
     use pretty_assertions::assert_eq;
 
     let server = MockServer::start().await;
diff --git a/codex-rs/core/tests/seatbelt.rs b/codex-rs/core/tests/seatbelt.rs
index fb2e7452f1..638ac48bb8 100644
--- a/codex-rs/core/tests/seatbelt.rs
+++ b/codex-rs/core/tests/seatbelt.rs
@@ -1,5 +1,4 @@
 #![cfg(target_os = "macos")]
-#![expect(clippy::expect_used)]
 
 //! Tests for the macOS sandboxing that are specific to Seatbelt.
 //! Tests that apply to both Mac and Linux sandboxing should go in sandbox.rs.
@@ -160,6 +159,7 @@ async fn read_only_forbids_all_writes() {
         .await;
 }
 
+#[expect(clippy::expect_used)]
 fn create_test_scenario(tmp: &TempDir) -> TestScenario {
     let repo_parent = tmp.path().to_path_buf();
     let repo_root = repo_parent.join("repo");
@@ -177,6 +177,7 @@ fn create_test_scenario(tmp: &TempDir) -> TestScenario {
     }
 }
 
+#[expect(clippy::expect_used)]
 /// Note that `path` must be absolute.
 async fn touch(path: &Path, policy: &SandboxPolicy) -> bool {
     assert!(path.is_absolute(), "Path must be absolute: {path:?}");
diff --git a/codex-rs/core/tests/stream_error_allows_next_turn.rs b/codex-rs/core/tests/stream_error_allows_next_turn.rs
index d590c43312..415e75a426 100644
--- a/codex-rs/core/tests/stream_error_allows_next_turn.rs
+++ b/codex-rs/core/tests/stream_error_allows_next_turn.rs
@@ -25,7 +25,6 @@ fn sse_completed(id: &str) -> String {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn continue_after_stream_error() {
-    #![allow(clippy::unwrap_used)]
     if std::env::var(CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR).is_ok() {
         println!(
             "Skipping test because it cannot execute when network is disabled in a Codex sandbox."
diff --git a/codex-rs/core/tests/stream_no_completed.rs b/codex-rs/core/tests/stream_no_completed.rs
index 5fa8ab8ba1..3fb3f642d7 100644
--- a/codex-rs/core/tests/stream_no_completed.rs
+++ b/codex-rs/core/tests/stream_no_completed.rs
@@ -33,8 +33,6 @@ fn sse_completed(id: &str) -> String {
 
 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
 async fn retries_on_early_close() {
-    #![allow(clippy::unwrap_used)]
-
     if std::env::var(CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR).is_ok() {
         println!(
             "Skipping test because it cannot execute when network is disabled in a Codex sandbox."
diff --git a/codex-rs/exec/src/event_processor_with_human_output.rs b/codex-rs/exec/src/event_processor_with_human_output.rs
index 22cf130462..5d64fe620b 100644
--- a/codex-rs/exec/src/event_processor_with_human_output.rs
+++ b/codex-rs/exec/src/event_processor_with_human_output.rs
@@ -191,7 +191,7 @@ impl EventProcessor for EventProcessorWithHumanOutput {
                     self.answer_started = true;
                 }
                 print!("{delta}");
-                #[allow(clippy::expect_used)]
+                #[expect(clippy::expect_used)]
                 std::io::stdout().flush().expect("could not flush stdout");
             }
             EventMsg::AgentReasoningDelta(AgentReasoningDeltaEvent { delta }) => {
@@ -207,7 +207,7 @@ impl EventProcessor for EventProcessorWithHumanOutput {
                     self.reasoning_started = true;
                 }
                 print!("{delta}");
-                #[allow(clippy::expect_used)]
+                #[expect(clippy::expect_used)]
                 std::io::stdout().flush().expect("could not flush stdout");
             }
             EventMsg::AgentReasoningSectionBreak(_) => {
@@ -215,7 +215,7 @@ impl EventProcessor for EventProcessorWithHumanOutput {
                     return CodexStatus::Running;
                 }
                 println!();
-                #[allow(clippy::expect_used)]
+                #[expect(clippy::expect_used)]
                 std::io::stdout().flush().expect("could not flush stdout");
             }
             EventMsg::AgentReasoningRawContent(AgentReasoningRawContentEvent { text }) => {
@@ -224,7 +224,7 @@ impl EventProcessor for EventProcessorWithHumanOutput {
                 }
                 if !self.raw_reasoning_started {
                     print!("{text}");
-                    #[allow(clippy::expect_used)]
+                    #[expect(clippy::expect_used)]
                     std::io::stdout().flush().expect("could not flush stdout");
                 } else {
                     println!();
@@ -241,7 +241,7 @@ impl EventProcessor for EventProcessorWithHumanOutput {
                     self.raw_reasoning_started = true;
                 }
                 print!("{delta}");
-                #[allow(clippy::expect_used)]
+                #[expect(clippy::expect_used)]
                 std::io::stdout().flush().expect("could not flush stdout");
             }
             EventMsg::AgentMessage(AgentMessageEvent { message }) => {
diff --git a/codex-rs/exec/src/event_processor_with_json_output.rs b/codex-rs/exec/src/event_processor_with_json_output.rs
index 76985518e6..11e9732e99 100644
--- a/codex-rs/exec/src/event_processor_with_json_output.rs
+++ b/codex-rs/exec/src/event_processor_with_json_output.rs
@@ -28,7 +28,7 @@ impl EventProcessor for EventProcessorWithJsonOutput {
             .into_iter()
             .map(|(key, value)| (key.to_string(), value))
             .collect::<HashMap<String, String>>();
-        #[allow(clippy::expect_used)]
+        #[expect(clippy::expect_used)]
         let config_json =
             serde_json::to_string(&entries).expect("Failed to serialize config summary to JSON");
         println!("{config_json}");
diff --git a/codex-rs/exec/tests/sandbox.rs b/codex-rs/exec/tests/sandbox.rs
index 22caf8abc6..a98e0a9760 100644
--- a/codex-rs/exec/tests/sandbox.rs
+++ b/codex-rs/exec/tests/sandbox.rs
@@ -1,6 +1,4 @@
 #![cfg(unix)]
-#![expect(clippy::expect_used)]
-
 use codex_core::protocol::SandboxPolicy;
 use codex_core::spawn::StdioPolicy;
 use std::collections::HashMap;
@@ -180,6 +178,7 @@ async fn allow_unix_socketpair_recvfrom() {
 
 const IN_SANDBOX_ENV_VAR: &str = "IN_SANDBOX";
 
+#[expect(clippy::expect_used)]
 pub async fn run_code_under_sandbox<F, Fut>(
     test_selector: &str,
     policy: &SandboxPolicy,
diff --git a/codex-rs/execpolicy/src/execv_checker.rs b/codex-rs/execpolicy/src/execv_checker.rs
index 3c9084e825..242ea6d177 100644
--- a/codex-rs/execpolicy/src/execv_checker.rs
+++ b/codex-rs/execpolicy/src/execv_checker.rs
@@ -140,7 +140,6 @@ fn is_executable_file(path: &str) -> bool {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use tempfile::TempDir;
 
     use super::*;
diff --git a/codex-rs/execpolicy/tests/bad.rs b/codex-rs/execpolicy/tests/bad.rs
index 5c2999a0cb..8b6e195fb0 100644
--- a/codex-rs/execpolicy/tests/bad.rs
+++ b/codex-rs/execpolicy/tests/bad.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 use codex_execpolicy::NegativeExamplePassedCheck;
 use codex_execpolicy::get_default_policy;
 
diff --git a/codex-rs/execpolicy/tests/cp.rs b/codex-rs/execpolicy/tests/cp.rs
index 14fd24410f..aa19f0b5d5 100644
--- a/codex-rs/execpolicy/tests/cp.rs
+++ b/codex-rs/execpolicy/tests/cp.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 extern crate codex_execpolicy;
 
 use codex_execpolicy::ArgMatcher;
@@ -12,6 +11,7 @@ use codex_execpolicy::Result;
 use codex_execpolicy::ValidExec;
 use codex_execpolicy::get_default_policy;
 
+#[expect(clippy::expect_used)]
 fn setup() -> Policy {
     get_default_policy().expect("failed to load default policy")
 }
diff --git a/codex-rs/execpolicy/tests/good.rs b/codex-rs/execpolicy/tests/good.rs
index 645728afbd..3b7313a335 100644
--- a/codex-rs/execpolicy/tests/good.rs
+++ b/codex-rs/execpolicy/tests/good.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 use codex_execpolicy::PositiveExampleFailedCheck;
 use codex_execpolicy::get_default_policy;
 
diff --git a/codex-rs/execpolicy/tests/head.rs b/codex-rs/execpolicy/tests/head.rs
index 8d7a165cca..3c32ccfbfe 100644
--- a/codex-rs/execpolicy/tests/head.rs
+++ b/codex-rs/execpolicy/tests/head.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 use codex_execpolicy::ArgMatcher;
 use codex_execpolicy::ArgType;
 use codex_execpolicy::Error;
@@ -13,6 +12,7 @@ use codex_execpolicy::get_default_policy;
 
 extern crate codex_execpolicy;
 
+#[expect(clippy::expect_used)]
 fn setup() -> Policy {
     get_default_policy().expect("failed to load default policy")
 }
diff --git a/codex-rs/execpolicy/tests/literal.rs b/codex-rs/execpolicy/tests/literal.rs
index 629aeb9cfe..d849371e3b 100644
--- a/codex-rs/execpolicy/tests/literal.rs
+++ b/codex-rs/execpolicy/tests/literal.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 use codex_execpolicy::ArgType;
 use codex_execpolicy::Error;
 use codex_execpolicy::ExecCall;
diff --git a/codex-rs/execpolicy/tests/ls.rs b/codex-rs/execpolicy/tests/ls.rs
index 854ec3bf58..e52316c06e 100644
--- a/codex-rs/execpolicy/tests/ls.rs
+++ b/codex-rs/execpolicy/tests/ls.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 extern crate codex_execpolicy;
 
 use codex_execpolicy::ArgType;
@@ -12,6 +11,7 @@ use codex_execpolicy::Result;
 use codex_execpolicy::ValidExec;
 use codex_execpolicy::get_default_policy;
 
+#[expect(clippy::expect_used)]
 fn setup() -> Policy {
     get_default_policy().expect("failed to load default policy")
 }
diff --git a/codex-rs/execpolicy/tests/pwd.rs b/codex-rs/execpolicy/tests/pwd.rs
index 339908e928..fdf5a4f1a5 100644
--- a/codex-rs/execpolicy/tests/pwd.rs
+++ b/codex-rs/execpolicy/tests/pwd.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 extern crate codex_execpolicy;
 
 use std::vec;
@@ -12,6 +11,7 @@ use codex_execpolicy::PositionalArg;
 use codex_execpolicy::ValidExec;
 use codex_execpolicy::get_default_policy;
 
+#[expect(clippy::expect_used)]
 fn setup() -> Policy {
     get_default_policy().expect("failed to load default policy")
 }
diff --git a/codex-rs/execpolicy/tests/sed.rs b/codex-rs/execpolicy/tests/sed.rs
index 064e539305..bf35bf6d46 100644
--- a/codex-rs/execpolicy/tests/sed.rs
+++ b/codex-rs/execpolicy/tests/sed.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 extern crate codex_execpolicy;
 
 use codex_execpolicy::ArgType;
@@ -13,6 +12,7 @@ use codex_execpolicy::Result;
 use codex_execpolicy::ValidExec;
 use codex_execpolicy::get_default_policy;
 
+#[expect(clippy::expect_used)]
 fn setup() -> Policy {
     get_default_policy().expect("failed to load default policy")
 }
diff --git a/codex-rs/linux-sandbox/tests/landlock.rs b/codex-rs/linux-sandbox/tests/landlock.rs
index 76de2547a6..8faa02d158 100644
--- a/codex-rs/linux-sandbox/tests/landlock.rs
+++ b/codex-rs/linux-sandbox/tests/landlock.rs
@@ -1,6 +1,4 @@
 #![cfg(target_os = "linux")]
-#![expect(clippy::unwrap_used, clippy::expect_used)]
-
 use codex_core::config_types::ShellEnvironmentPolicy;
 use codex_core::error::CodexErr;
 use codex_core::error::SandboxErr;
@@ -35,7 +33,7 @@ fn create_env_from_core_vars() -> HashMap<String, String> {
     create_env(&policy)
 }
 
-#[allow(clippy::print_stdout)]
+#[expect(clippy::print_stdout, clippy::expect_used, clippy::unwrap_used)]
 async fn run_cmd(cmd: &[&str], writable_roots: &[PathBuf], timeout_ms: u64) {
     let params = ExecParams {
         command: cmd.iter().map(|elm| elm.to_string()).collect(),
@@ -132,6 +130,7 @@ async fn test_timeout() {
 /// does NOT succeed (i.e. returns a nonzero exit code) **unless** the binary
 /// is missing in which case we silently treat it as an accepted skip so the
 /// suite remains green on leaner CI images.
+#[expect(clippy::expect_used)]
 async fn assert_network_blocked(cmd: &[&str]) {
     let cwd = std::env::current_dir().expect("cwd should exist");
     let params = ExecParams {
diff --git a/codex-rs/login/src/lib.rs b/codex-rs/login/src/lib.rs
index d4358d2735..c40c1e6b52 100644
--- a/codex-rs/login/src/lib.rs
+++ b/codex-rs/login/src/lib.rs
@@ -427,7 +427,6 @@ pub struct AuthDotJson {
 
 #[cfg(test)]
 mod tests {
-    #![expect(clippy::expect_used, clippy::unwrap_used)]
     use super::*;
     use crate::token_data::IdTokenInfo;
     use crate::token_data::KnownPlan;
diff --git a/codex-rs/login/src/token_data.rs b/codex-rs/login/src/token_data.rs
index 1cb537fa24..2ac549fda2 100644
--- a/codex-rs/login/src/token_data.rs
+++ b/codex-rs/login/src/token_data.rs
@@ -155,7 +155,6 @@ mod tests {
     use serde::Serialize;
 
     #[test]
-    #[expect(clippy::expect_used, clippy::unwrap_used)]
     fn id_token_info_parses_email_and_plan() {
         #[derive(Serialize)]
         struct Header {
diff --git a/codex-rs/login/tests/login_server_e2e.rs b/codex-rs/login/tests/login_server_e2e.rs
index 3fe0e32041..3d00480051 100644
--- a/codex-rs/login/tests/login_server_e2e.rs
+++ b/codex-rs/login/tests/login_server_e2e.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::unwrap_used)]
+#![expect(clippy::unwrap_used)]
 use std::net::SocketAddr;
 use std::net::TcpListener;
 use std::thread;
diff --git a/codex-rs/mcp-server/src/codex_tool_config.rs b/codex-rs/mcp-server/src/codex_tool_config.rs
index 1d77eb4b82..548f29334f 100644
--- a/codex-rs/mcp-server/src/codex_tool_config.rs
+++ b/codex-rs/mcp-server/src/codex_tool_config.rs
@@ -236,7 +236,6 @@ mod tests {
     #[test]
     fn verify_codex_tool_json_schema() {
         let tool = create_tool_for_codex_tool_call_param();
-        #[expect(clippy::expect_used)]
         let tool_json = serde_json::to_value(&tool).expect("tool serializes");
         let expected_tool_json = serde_json::json!({
           "name": "codex",
@@ -305,7 +304,6 @@ mod tests {
     #[test]
     fn verify_codex_tool_reply_json_schema() {
         let tool = create_tool_for_codex_tool_call_reply_param();
-        #[expect(clippy::expect_used)]
         let tool_json = serde_json::to_value(&tool).expect("tool serializes");
         let expected_tool_json = serde_json::json!({
           "description": "Continue a Codex session by providing the session id and prompt.",
diff --git a/codex-rs/mcp-server/src/json_to_toml.rs b/codex-rs/mcp-server/src/json_to_toml.rs
index ae33382a1d..04f1f30615 100644
--- a/codex-rs/mcp-server/src/json_to_toml.rs
+++ b/codex-rs/mcp-server/src/json_to_toml.rs
@@ -28,7 +28,6 @@ pub(crate) fn json_to_toml(v: JsonValue) -> TomlValue {
 }
 
 #[cfg(test)]
-#[allow(clippy::unwrap_used)]
 mod tests {
     use super::*;
     use pretty_assertions::assert_eq;
diff --git a/codex-rs/mcp-server/src/mcp_protocol.rs b/codex-rs/mcp-server/src/mcp_protocol.rs
index 0528e18a39..26c6655f3b 100644
--- a/codex-rs/mcp-server/src/mcp_protocol.rs
+++ b/codex-rs/mcp-server/src/mcp_protocol.rs
@@ -293,8 +293,6 @@ pub enum ClientNotification {
 }
 
 #[cfg(test)]
-#[allow(clippy::expect_used)]
-#[allow(clippy::unwrap_used)]
 mod tests {
     use std::path::PathBuf;
 
diff --git a/codex-rs/mcp-server/src/outgoing_message.rs b/codex-rs/mcp-server/src/outgoing_message.rs
index f13b8b324f..f408ca0a45 100644
--- a/codex-rs/mcp-server/src/outgoing_message.rs
+++ b/codex-rs/mcp-server/src/outgoing_message.rs
@@ -101,7 +101,7 @@ impl OutgoingMessageSender {
         event: &Event,
         meta: Option<OutgoingNotificationMeta>,
     ) {
-        #[allow(clippy::expect_used)]
+        #[expect(clippy::expect_used)]
         let event_json = serde_json::to_value(event).expect("Event must serialize");
 
         let params = if let Ok(params) = serde_json::to_value(OutgoingNotificationParams {
@@ -244,8 +244,6 @@ pub(crate) struct OutgoingError {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
-
     use codex_core::protocol::EventMsg;
     use codex_core::protocol::SessionConfiguredEvent;
     use pretty_assertions::assert_eq;
diff --git a/codex-rs/mcp-server/src/wire_format.rs b/codex-rs/mcp-server/src/wire_format.rs
index 95d55e8bf5..034c72a1c2 100644
--- a/codex-rs/mcp-server/src/wire_format.rs
+++ b/codex-rs/mcp-server/src/wire_format.rs
@@ -222,7 +222,6 @@ pub struct ApplyPatchApprovalResponse {
     pub decision: ReviewDecision,
 }
 
-#[allow(clippy::unwrap_used)]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/codex-rs/mcp-server/tests/codex_message_processor_flow.rs b/codex-rs/mcp-server/tests/codex_message_processor_flow.rs
index 7b7845609e..2cc55c6d62 100644
--- a/codex-rs/mcp-server/tests/codex_message_processor_flow.rs
+++ b/codex-rs/mcp-server/tests/codex_message_processor_flow.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::expect_used, clippy::unwrap_used)]
-
 use std::path::Path;
 
 use codex_core::spawn::CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR;
diff --git a/codex-rs/mcp-server/tests/codex_tool.rs b/codex-rs/mcp-server/tests/codex_tool.rs
index fc992a8cd1..92f11eaa4f 100644
--- a/codex-rs/mcp-server/tests/codex_tool.rs
+++ b/codex-rs/mcp-server/tests/codex_tool.rs
@@ -304,7 +304,7 @@ async fn test_codex_tool_passes_base_instructions() {
 }
 
 async fn codex_tool_passes_base_instructions() -> anyhow::Result<()> {
-    #![allow(clippy::unwrap_used)]
+    #![expect(clippy::unwrap_used)]
 
     let server =
         create_mock_chat_completions_server(vec![create_final_assistant_message_sse_response(
diff --git a/codex-rs/mcp-server/tests/create_conversation.rs b/codex-rs/mcp-server/tests/create_conversation.rs
index 41052ea7b3..2349b0b9e4 100644
--- a/codex-rs/mcp-server/tests/create_conversation.rs
+++ b/codex-rs/mcp-server/tests/create_conversation.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::expect_used, clippy::unwrap_used)]
-
 use std::path::Path;
 
 use mcp_test_support::McpProcess;
diff --git a/codex-rs/mcp-server/tests/send_message.rs b/codex-rs/mcp-server/tests/send_message.rs
index f06c1587e3..bf2966ef05 100644
--- a/codex-rs/mcp-server/tests/send_message.rs
+++ b/codex-rs/mcp-server/tests/send_message.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::expect_used)]
-
 use std::path::Path;
 use std::thread::sleep;
 use std::time::Duration;
diff --git a/codex-rs/mcp-types/tests/initialize.rs b/codex-rs/mcp-types/tests/initialize.rs
index c69586f030..04778f2a90 100644
--- a/codex-rs/mcp-types/tests/initialize.rs
+++ b/codex-rs/mcp-types/tests/initialize.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 use mcp_types::ClientCapabilities;
 use mcp_types::ClientRequest;
 use mcp_types::Implementation;
diff --git a/codex-rs/mcp-types/tests/progress_notification.rs b/codex-rs/mcp-types/tests/progress_notification.rs
index b518e4a91c..396efca2bd 100644
--- a/codex-rs/mcp-types/tests/progress_notification.rs
+++ b/codex-rs/mcp-types/tests/progress_notification.rs
@@ -1,4 +1,3 @@
-#![expect(clippy::expect_used)]
 use mcp_types::JSONRPCMessage;
 use mcp_types::ProgressNotificationParams;
 use mcp_types::ProgressToken;
diff --git a/codex-rs/ollama/src/client.rs b/codex-rs/ollama/src/client.rs
index 6f4621135c..55c86e31f8 100644
--- a/codex-rs/ollama/src/client.rs
+++ b/codex-rs/ollama/src/client.rs
@@ -53,7 +53,7 @@ impl OllamaClient {
 
     /// Build a client from a provider definition and verify the server is reachable.
     async fn try_from_provider(provider: &ModelProviderInfo) -> io::Result<Self> {
-        #![allow(clippy::expect_used)]
+        #![expect(clippy::expect_used)]
         let base_url = provider
             .base_url
             .as_ref()
@@ -235,7 +235,6 @@ impl OllamaClient {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::expect_used, clippy::unwrap_used)]
     use super::*;
 
     // Happy-path tests using a mock HTTP server; skip if sandbox network is disabled.
diff --git a/codex-rs/tui/src/app.rs b/codex-rs/tui/src/app.rs
index 256289b21f..ee054e037a 100644
--- a/codex-rs/tui/src/app.rs
+++ b/codex-rs/tui/src/app.rs
@@ -188,7 +188,7 @@ impl App<'_> {
                         }
                     }
 
-                    #[allow(clippy::expect_used)]
+                    #[expect(clippy::expect_used)]
                     let deadline = next_deadline.expect("deadline set");
                     let now = Instant::now();
                     let timeout = if deadline > now {
diff --git a/codex-rs/tui/src/bottom_pane/chat_composer_history.rs b/codex-rs/tui/src/bottom_pane/chat_composer_history.rs
index a744a409f3..93accfcd1a 100644
--- a/codex-rs/tui/src/bottom_pane/chat_composer_history.rs
+++ b/codex-rs/tui/src/bottom_pane/chat_composer_history.rs
@@ -182,7 +182,6 @@ impl ChatComposerHistory {
 
 #[cfg(test)]
 mod tests {
-    #![expect(clippy::expect_used)]
     use super::*;
     use crate::app_event::AppEvent;
     use codex_core::protocol::Op;
diff --git a/codex-rs/tui/src/bottom_pane/textarea.rs b/codex-rs/tui/src/bottom_pane/textarea.rs
index f0cfa614f9..d29698d7df 100644
--- a/codex-rs/tui/src/bottom_pane/textarea.rs
+++ b/codex-rs/tui/src/bottom_pane/textarea.rs
@@ -801,7 +801,7 @@ impl TextArea {
         }
     }
 
-    #[allow(clippy::unwrap_used)]
+    #[expect(clippy::unwrap_used)]
     fn wrapped_lines(&self, width: u16) -> Ref<'_, Vec<Range<usize>>> {
         // Ensure cache is ready (potentially mutably borrow, then drop)
         {
@@ -926,7 +926,6 @@ impl TextArea {
 }
 
 #[cfg(test)]
-#[allow(clippy::unwrap_used)]
 mod tests {
     use super::*;
     // crossterm types are intentionally not imported here to avoid unused warnings
@@ -1432,7 +1431,6 @@ mod tests {
         // Seed the RNG based on the current day in Pacific Time (PST/PDT). This
         // keeps the fuzz test deterministic within a day while still varying
         // day-to-day to improve coverage.
-        #[allow(clippy::unwrap_used)]
         let pst_today_seed: u64 = (chrono::Utc::now() - chrono::Duration::hours(8))
             .date_naive()
             .and_hms_opt(0, 0, 0)
diff --git a/codex-rs/tui/src/chatwidget/tests.rs b/codex-rs/tui/src/chatwidget/tests.rs
index 3336024272..95542c06fb 100644
--- a/codex-rs/tui/src/chatwidget/tests.rs
+++ b/codex-rs/tui/src/chatwidget/tests.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::unwrap_used, clippy::expect_used, unnameable_test_items)]
-
 use super::*;
 use crate::app_event::AppEvent;
 use crate::app_event_sender::AppEventSender;
diff --git a/codex-rs/tui/src/citation_regex.rs b/codex-rs/tui/src/citation_regex.rs
index e5355ec2b8..ff5147ca83 100644
--- a/codex-rs/tui/src/citation_regex.rs
+++ b/codex-rs/tui/src/citation_regex.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::expect_used)]
+#![expect(clippy::expect_used)]
 
 use regex_lite::Regex;
 
diff --git a/codex-rs/tui/src/diff_render.rs b/codex-rs/tui/src/diff_render.rs
index 5a3199c04b..152a8e2862 100644
--- a/codex-rs/tui/src/diff_render.rs
+++ b/codex-rs/tui/src/diff_render.rs
@@ -357,7 +357,6 @@ fn style_del() -> Style {
     Style::default().fg(Color::Red)
 }
 
-#[allow(clippy::expect_used)]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/codex-rs/tui/src/file_search.rs b/codex-rs/tui/src/file_search.rs
index 9fb010a095..8a05b2c165 100644
--- a/codex-rs/tui/src/file_search.rs
+++ b/codex-rs/tui/src/file_search.rs
@@ -31,10 +31,7 @@ use std::time::Duration;
 use crate::app_event::AppEvent;
 use crate::app_event_sender::AppEventSender;
 
-#[allow(clippy::unwrap_used)]
 const MAX_FILE_SEARCH_RESULTS: NonZeroUsize = NonZeroUsize::new(8).unwrap();
-
-#[allow(clippy::unwrap_used)]
 const NUM_FILE_SEARCH_THREADS: NonZeroUsize = NonZeroUsize::new(2).unwrap();
 
 /// How long to wait after a keystroke before firing the first search when none
@@ -84,7 +81,7 @@ impl FileSearchManager {
     /// Call whenever the user edits the `@` token.
     pub fn on_user_query(&self, query: String) {
         {
-            #[allow(clippy::unwrap_used)]
+            #[expect(clippy::unwrap_used)]
             let mut st = self.state.lock().unwrap();
             if query == st.latest_query {
                 // No change, nothing to do.
@@ -125,7 +122,7 @@ impl FileSearchManager {
             // `active_search` is cleared.
             thread::sleep(FILE_SEARCH_DEBOUNCE);
             loop {
-                #[allow(clippy::unwrap_used)]
+                #[expect(clippy::unwrap_used)]
                 if state.lock().unwrap().active_search.is_none() {
                     break;
                 }
@@ -137,7 +134,7 @@ impl FileSearchManager {
             let cancellation_token = Arc::new(AtomicBool::new(false));
             let token = cancellation_token.clone();
             let query = {
-                #[allow(clippy::unwrap_used)]
+                #[expect(clippy::unwrap_used)]
                 let mut st = state.lock().unwrap();
                 let query = st.latest_query.clone();
                 st.is_search_scheduled = false;
@@ -188,7 +185,7 @@ impl FileSearchManager {
             // that we are clearing the ActiveSearch that corresponds to the
             // cancellation token we were given.
             {
-                #[allow(clippy::unwrap_used)]
+                #[expect(clippy::unwrap_used)]
                 let mut st = search_state.lock().unwrap();
                 if let Some(active_search) = &st.active_search {
                     if Arc::ptr_eq(&active_search.cancellation_token, &cancellation_token) {
diff --git a/codex-rs/tui/src/insert_history.rs b/codex-rs/tui/src/insert_history.rs
index 971c376234..ced667af8d 100644
--- a/codex-rs/tui/src/insert_history.rs
+++ b/codex-rs/tui/src/insert_history.rs
@@ -379,7 +379,6 @@ fn slice_line_spans(
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
 
     #[test]
diff --git a/codex-rs/tui/src/lib.rs b/codex-rs/tui/src/lib.rs
index a661242d3e..f1a7d99b79 100644
--- a/codex-rs/tui/src/lib.rs
+++ b/codex-rs/tui/src/lib.rs
@@ -295,7 +295,6 @@ fn restore() {
     }
 }
 
-#[allow(clippy::unwrap_used)]
 fn should_show_login_screen(config: &Config) -> bool {
     if config.model_provider.requires_openai_auth {
         // Reading the OpenAI API key is an async operation because it may need
diff --git a/codex-rs/tui/src/text_formatting.rs b/codex-rs/tui/src/text_formatting.rs
index 208dc700a8..b77c6e5baa 100644
--- a/codex-rs/tui/src/text_formatting.rs
+++ b/codex-rs/tui/src/text_formatting.rs
@@ -102,7 +102,6 @@ pub(crate) fn truncate_text(text: &str, max_graphemes: usize) -> String {
 
 #[cfg(test)]
 mod tests {
-    #![allow(clippy::unwrap_used)]
     use super::*;
     use pretty_assertions::assert_eq;

Review Comments

codex-rs/core/src/codex.rs

@@ -1,5 +1,5 @@
 // Poisoned mutex should fail the program
-#![allow(clippy::unwrap_used)]
+#![expect(clippy::unwrap_used)]

Hopefully I can ultimately eliminate this one...

codex-rs/core/tests/seatbelt.rs

@@ -1,5 +1,4 @@
 #![cfg(target_os = "macos")]
-#![expect(clippy::expect_used)]

This could maybe stay?

codex-rs/linux-sandbox/tests/landlock.rs

@@ -35,7 +33,7 @@ fn create_env_from_core_vars() -> HashMap<String, String> {
     create_env(&policy)
 }
 
-#[allow(clippy::print_stdout)]
+#[expect(clippy::print_stdout, clippy::expect_used, clippy::unwrap_used)]

🤔

codex-rs/tui/src/file_search.rs

@@ -31,10 +31,7 @@ use std::time::Duration;
 use crate::app_event::AppEvent;
 use crate::app_event_sender::AppEventSender;
 
-#[allow(clippy::unwrap_used)]
 const MAX_FILE_SEARCH_RESULTS: NonZeroUsize = NonZeroUsize::new(8).unwrap();
-
-#[allow(clippy::unwrap_used)]

Interesting this goes away?