diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index 5450b7e6..04267a6c 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -438,6 +438,9 @@
- [Parse, Don't Validate](idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md)
- [Is It Encapsulated?](idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md)
- [RAII](idiomatic/leveraging-the-type-system/raii.md)
+ - [Mutex](idiomatic/leveraging-the-type-system/raii/mutex.md)
+ - [Drop Bomb](idiomatic/leveraging-the-type-system/raii/drop_bomb.md)
+ - [Scope Guard](idiomatic/leveraging-the-type-system/raii/scope_guard.md)
---
diff --git a/src/idiomatic/leveraging-the-type-system/_old/raii/scope_guards.md b/src/idiomatic/leveraging-the-type-system/_old/raii/scope_guards.md
index 273b8ac9..829c85b0 100644
--- a/src/idiomatic/leveraging-the-type-system/_old/raii/scope_guards.md
+++ b/src/idiomatic/leveraging-the-type-system/_old/raii/scope_guards.md
@@ -146,21 +146,11 @@ fn main() {
that's in the slide? I can slap together a sketch in the playground if
it's not clear what I'm suggesting.
```
-
- - The `ScopeGuard` type in the `scopeguard` crate also includes a `Debug`
- implementation and a third parameter: a
+ - `scopeguard` also supports selecting a
[`Strategy`](https://docs.rs/scopeguard/latest/scopeguard/trait.Strategy.html)
- that determines when the `drop_fn` should run.
-
- - By default, the strategy runs the drop function unconditionally. However,
- the crate also provides built-in strategies to run the drop function only
- during unwinding (due to a panic), or only on successful scope exit.
-
- You can also implement your own `Strategy` trait to define custom
- conditions for when the cleanup should occur.
-
- TODO: again... more concise, e.g. reduce the above to:
-
+ to determine when the cleanup logic should run, i.e. always, only on
+ successful exit, or only on unwind. The crate also supports defining custom
+ strategies.
```
- `scopeguard` also supports selecting a
[`Strategy`](https://docs.rs/scopeguard/latest/scopeguard/trait.Strategy.html)
diff --git a/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md b/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md
new file mode 100644
index 00000000..3cea9057
--- /dev/null
+++ b/src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md
@@ -0,0 +1,110 @@
+# Drop Bombs: Enforcing API Correctness
+
+Use `Drop` to enforce invariants and detect incorrect API usage. A "drop bomb"
+panics if a value is dropped without being explicitly finalized.
+
+This pattern is often used when the finalizing operation (like `commit()` or
+`rollback()`) needs to return a `Result`, which cannot be done from `Drop`.
+
+```rust,editable
+struct Transaction {
+ active: bool,
+}
+
+impl Transaction {
+ /// Begin a [`Transaction`].
+ ///
+ /// ## Panics
+ ///
+ /// Panics if the transaction is dropped without
+ /// calling [`Self::commit`] or [`Self::rollback`].
+ fn start() -> Self {
+ Self { active: true }
+ }
+
+ fn commit(mut self) {
+ self.active = false;
+ // Dropped after this point — no panic
+ }
+
+ fn rollback(mut self) {
+ self.active = false;
+ // Dropped after this point — no panic
+ }
+}
+
+impl Drop for Transaction {
+ fn drop(&mut self) {
+ if self.active {
+ panic!("Transaction dropped without commit or rollback!");
+ }
+ }
+}
+
+fn main() {
+ // OK: commit defuses the bomb
+ let tx1 = Transaction::start();
+ tx1.commit();
+
+ // Uncomment to see the panic:
+ // let tx2 = Transaction::start();
+ // dropped without commit or rollback → panic
+}
+```
+
+
+
+- This pattern ensures that a value like `Transaction` cannot be silently
+ dropped in an unfinished state. The destructor panics if neither `commit()`
+ nor `rollback()` has been called.
+
+- A common reason to use this pattern is when cleanup cannot be done in `Drop`,
+ either because it is fallible or asynchronous. For example, most databases do
+ not allow rollback to be safely handled inside `drop()` alone.
+
+- This pattern is appropriate even in public APIs. It can help users catch bugs
+ early when they forget to explicitly finalize a transactional object.
+
+- If a value can be safely cleaned up in `Drop`, consider falling back to that
+ behavior in Release mode and panicking only in Debug. This decision should be
+ made based on the guarantees your API provides.
+
+- Panicking in Release builds is a valid choice if silent misuse could lead to
+ serious correctness issues or security concerns.
+
+## Additional Patterns
+
+- [`Option` with `.take()`](https://doc.rust-lang.org/std/option/enum.Option.html#method.take):
+ A common pattern inside `Drop` to move out internal values and prevent double
+ drops.
+
+ ```rust,compile_fail
+ impl Drop for MyResource {
+ fn drop(&mut self) {
+ if let Some(handle) = self.handle.take() {
+ // do cleanup with handle
+ }
+ }
+ }
+ ```
+
+- [`ManuallyDrop`](https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html):
+ Prevents automatic destruction and gives full manual control. Requires
+ `unsafe`, so only use when strictly necessary.
+
+- [`drop_bomb` crate](https://docs.rs/drop_bomb/latest/drop_bomb/): A small
+ utility that panics if dropped unless explicitly defused with `.defuse()`.
+ Comes with a `DebugDropBomb` variant that only activates in debug builds.
+
+- In some systems, a value must be finalized by a specific API before it is
+ dropped.
+
+ For example, an `SshConnection` might need to be deregistered from an
+ `SshServer` before being dropped, or the program panics. This helps catch
+ programming mistakes during development and enforces correct teardown at
+ runtime.
+
+ See a working example in the Rust playground:
+
+
+
diff --git a/src/idiomatic/leveraging-the-type-system/raii/mutex.md b/src/idiomatic/leveraging-the-type-system/raii/mutex.md
new file mode 100644
index 00000000..f883abdb
--- /dev/null
+++ b/src/idiomatic/leveraging-the-type-system/raii/mutex.md
@@ -0,0 +1,127 @@
+# Mutex
+
+In earlier examples, RAII was used to manage concrete resources like file
+descriptors. With a `Mutex`, the resource is more abstract: exclusive access to
+a value.
+
+Rust models this using a `MutexGuard`, which ties access to a critical section
+to the lifetime of a value on the stack.
+
+```rust
+#[derive(Debug)]
+struct Mutex {
+ value: std::cell::UnsafeCell,
+ // [...]
+}
+
+#[derive(Debug)]
+struct MutexGuard<'a, T> {
+ value: &'a mut T,
+ // [...]
+}
+
+impl Mutex {
+ fn new(value: T) -> Self {
+ Self {
+ value: std::cell::UnsafeCell::new(value),
+ // [...]
+ }
+ }
+
+ fn lock(&self) -> MutexGuard {
+ // [...]
+ let value = unsafe { &mut *self.value.get() };
+ MutexGuard { value }
+ }
+}
+
+impl<'a, T> std::ops::Deref for MutexGuard<'a, T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ self.value
+ }
+}
+
+impl<'a, T> std::ops::DerefMut for MutexGuard<'a, T> {
+ fn deref_mut(&mut self) -> &mut T {
+ self.value
+ }
+}
+
+impl<'a, T> Drop for MutexGuard<'a, T> {
+ fn drop(&mut self) {
+ // [...]
+ println!("drop MutexGuard");
+ }
+}
+
+fn main() {
+ let m = Mutex::new(vec![1, 2, 3]);
+
+ let mut guard = m.lock();
+ guard.push(4);
+ guard.push(5);
+ println!("{guard:?}");
+}
+```
+
+
+
+- A `Mutex` controls exclusive access to a value. Unlike earlier RAII examples,
+ the resource here is not external but logical: the right to mutate shared
+ data.
+
+- This right is represented by a `MutexGuard`. Only one can exist at a time.
+ While it lives, it provides `&mut T` access — enforced using `UnsafeCell`.
+
+- Although `lock()` takes `&self`, it returns a `MutexGuard` with mutable
+ access. This is possible through interior mutability: a common pattern for
+ safe shared-state mutation.
+
+- `MutexGuard` implements `Deref` and `DerefMut`, making access ergonomic. You
+ lock the mutex, use the guard like a `&mut T`, and the lock is released
+ automatically when the guard goes out of scope.
+
+- The release is handled by `Drop`. There is no need to call a separate unlock
+ function — this is RAII in action.
+
+## Poisoning
+
+- If a thread panics while holding the lock, the value may be in a corrupt
+ state.
+
+- To signal this, the standard library uses poisoning. When `Drop` runs during a
+ panic, the mutex marks itself as poisoned.
+
+- On the next `lock()`, this shows up as an error. The caller must decide
+ whether to proceed or handle the error differently.
+
+- See this example showing the standard library API with poisoning:
+
+
+### Mutex Lock Lifecycle
+
+```bob
++---------------+ +----------------------+
+| Mutex | lock | MutexGuard |
+| ( Unlocked ) +-------->| ( Exclusive Access ) |
++---------------+ +-------+--------------+
+ |
+ | drop
+ v
++---------------+ yes +-------------------+
+| Mutex |<------+ Thread panicking? |
+| ( Poisoned ) | +-------+-----------+
++------+--------+ | no
+ | v
+ | +---------------+
+ | lock | Mutex |
+ | | ( Unlocked ) |
+ | +---------------+
+ v
++------------------+
+| Err ( Poisoned ) |
++------------------+
+```
+
+
diff --git a/src/idiomatic/leveraging-the-type-system/raii/scope_guard.md b/src/idiomatic/leveraging-the-type-system/raii/scope_guard.md
new file mode 100644
index 00000000..fb45e7a3
--- /dev/null
+++ b/src/idiomatic/leveraging-the-type-system/raii/scope_guard.md
@@ -0,0 +1,77 @@
+# Scope Guards
+
+A scope guard uses the `Drop` trait to ensure cleanup code runs automatically
+when a scope exits — even if due to an error.
+
+```rust,editable,compile_fail
+use scopeguard::{ScopeGuard, guard};
+use std::{
+ fs::{self, File},
+ io::Write,
+};
+
+fn download_successful() -> bool {
+ true // change to false to simulate failure
+}
+
+fn main() {
+ let path = "download.tmp";
+ let mut file = File::create(path).expect("cannot create temporary file");
+
+ // Set up cleanup immediately after file creation
+ let cleanup = guard(path, |path| {
+ println!("download failed, deleting: {:?}", path);
+ let _ = fs::remove_file(path);
+ });
+
+ writeln!(file, "partial data...").unwrap();
+
+ if download_successful() {
+ // Download succeeded, keep the file
+ let _path = ScopeGuard::into_inner(cleanup);
+ println!("Download complete!");
+ }
+ // Otherwise, the guard runs and deletes the file
+}
+```
+
+
+
+- This example simulates an HTTP download. We create a temporary file first,
+ then use a scope guard to ensure that the file is deleted if the download
+ fails.
+
+- The guard is placed directly after creating the file, so even if `writeln!()`
+ fails, the file will still be cleaned up. This ordering is essential for
+ correctness.
+
+- The guard's closure runs on scope exit unless defused with
+ `ScopeGuard::into_inner`. In the success path, we defuse it to preserve the
+ file.
+
+- This pattern is useful when you want fallbacks or cleanup code to run
+ automatically but only if success is not explicitly signaled.
+
+- The `scopeguard` crate also supports cleanup strategies via the
+ [`Strategy`](https://docs.rs/scopeguard/latest/scopeguard/trait.Strategy.html)
+ trait. You can choose to run the guard on unwind only, or on success only, not
+ just always.
+
+## Manual Implementation Example
+
+If you need a custom scope guard for a very specific task, you can implement one
+manually. Here's a standalone example that mirrors the file deletion scenario
+shown above:
+
+## Related Patterns
+
+- Recall from the [Drop Bombs](./drop_bomb.md) chapter: drop bombs enforce that
+ a resource is finalized. Scope guards take that further — they let you define
+ automatic fallback behavior for cleanup when a resource is _not_ explicitly
+ finalized.
+
+- This pattern works well in combination with `Drop`, especially in fallible or
+ multi-step operations where cleanup needs to be predictable, regardless of
+ which step failed.
+
+