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

4.0 KiB
Raw Blame History

PR #2340 Review — Practical Guide

DOs

  • Use MutexExt::lock_unchecked: Replace .lock().unwrap() when poisoning is unrecoverable; centralize the panic message.
use std::sync::{Mutex, MutexGuard};

trait MutexExt<T> {
    fn lock_unchecked(&self) -> MutexGuard<'_, T>;
}

impl<T> MutexExt<T> for Mutex<T> {
    fn lock_unchecked(&self) -> MutexGuard<'_, T> {
        #[expect(clippy::expect_used)]
        self.lock().expect("poisoned lock")
    }
}

// Usage
let mut state = self.state.lock_unchecked();
  • Scope the extension locally: Define the trait privately in the module that needs it; add elsewhere only as needed.
// No `pub` on the trait or impl; file-local by default.
trait MutexExt<T> { /* ... */ }
  • Prefer let-chains over unwrap on Option: Keep branches safe and clear.
if sess.show_raw_agent_reasoning && let Some(content) = content {
    for item in content {
        // ...
    }
}
  • Drive patch safety from SandboxPolicy: Pass the policy (not adhoc roots) to safety checks.
use crate::safety::{assess_patch_safety, SafetyCheck};

match assess_patch_safety(
    &action,
    sess.get_approval_policy(),
    sess.get_sandbox_policy(),
    sess.get_cwd(),
) {
    SafetyCheck::AutoApprove { .. } => { /* run apply_patch in sandbox */ }
    SafetyCheck::NeedsApproval { .. } => { /* request approval */ }
}
  • Use WritableRoot::is_path_writable to respect readonly subpaths.
use crate::protocol::WritableRoot;

let root = WritableRoot {
    root: cwd.clone(),
    read_only_subpaths: vec![cwd.join(".git")],
};

assert!(root.is_path_writable(&cwd.join("src/lib.rs")));
assert!(!root.is_path_writable(&cwd.join(".git/HEAD")));
  • Write robust tests with TempDir and explicit policy that excludes temp dirs by default.
use tempfile::TempDir;
use crate::protocol::SandboxPolicy;

let tmp = TempDir::new().unwrap();
let cwd = tmp.path().to_path_buf();

let policy = SandboxPolicy::WorkspaceWrite {
    writable_roots: vec![],
    network_access: false,
    exclude_tmpdir_env_var: true,
    exclude_slash_tmp: true,
};

// Inside workspace → allowed; outside → denied unless added explicitly.
  • Localize lint allowances: Remove cratewide unwrap allowances; annotate narrowly where justified.
#[expect(clippy::expect_used)]
self.lock().expect("poisoned lock");
  • Consider RwLock for readheavy paths: Audit access patterns; use Mutex only when appropriate.
use std::sync::RwLock;
// If mostly reads:
let cache = RwLock::new(MyCache::default());

DONTs

  • Dont call .lock().unwrap() on Mutex.
// Bad
let mut st = self.state.lock().unwrap();
// Good
let mut st = self.state.lock_unchecked();
  • Dont reintroduce cratewide #![expect(clippy::unwrap_used)].
// Bad (crate root)
#![expect(clippy::unwrap_used)]
  • Dont pass Vec<PathBuf> “writable roots” to safety checks anymore.
// Bad
assess_patch_safety(&action, policy, &writable_roots, &cwd);
// Good
assess_patch_safety(&action, policy, sess.get_sandbox_policy(), &cwd);
  • Dont assume system temp dirs are writable in tests under WorkspaceWrite.
// Bad: leaves temp dirs implicitly writable
let policy = SandboxPolicy::WorkspaceWrite {
    writable_roots: vec![],
    network_access: false,
    exclude_tmpdir_env_var: false,
    exclude_slash_tmp: false,
};
  • Dont unwrap() Option inside conditionals; patternmatch instead.
// Bad
if flag && content.is_some() { for x in content.unwrap() { /* ... */ } }
// Good
if flag && let Some(content) = content { /* ... */ }
  • Dont globalize the lock extension trait unless multiple modules need it.
// Bad
pub trait MutexExt<T> { /* ... */ }  // exported cratewide without need
  • Dont expect writes to be allowed under ReadOnly policy; treat DangerFullAccess as unconstrained and WorkspaceWrite as scoped.
// ReadOnly → no writes; DangerFullAccess → unconstrained; WorkspaceWrite → configured roots + cwd