Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Build Your Own Guardrails

You’re going to spend two days reviewing code you didn’t write. The reviewing is manual. Enforcing what you find doesn’t have to be. Rust’s tooling can turn a review finding into a check that runs on every build. And the agent that wrote the code is good at writing that configuration too.

The pattern:

  1. A review catches a problem: an unwrap() on input, a dependency nobody vetted, a test that asserts nothing.
  2. You fix the instance.
  3. You ask the agent to add a check that rejects the whole class from now on.

A prompt for step 3 looks like this:

Add a Clippy configuration that rejects this class of code. Show me the lint names, set the levels in the crate root, and add a clippy.toml with disallowed-methods for the calls we banned in review.

The agent knows the lint tables better than most of us do. You decide what must never happen. The tooling checks it on every change after that, including the agent’s own.

Tools we’ll use or mention

  • Clippy with a project configuration. Running default Clippy is a start. A per-project policy does more: lint levels in the crate root (#![warn(clippy::unwrap_used)] and similar), a clippy.toml with disallowed-methods and disallowed-types for calls your review banned, and --deny warnings in CI. Project A sets one up for the parser this afternoon.
  • Miri interprets your code and detects undefined behavior and memory errors that tests can miss. Run it whenever unsafe appears. It’s also cheap to run when none does. cargo +nightly miri test on Project B takes about two minutes.
  • mutest-rs mutates your code and reruns your tests. A mutant that survives marks a spot where the suite asserts nothing. This is how you check whether the agent’s green tests verify anything. Project C’s metrics tests are a good target.
  • Loom checks concurrent code by exploring thread interleavings. Nothing in this course is concurrent, so we only mention it: know that it exists, and reach for it when threads arrive.
  • Kani proves properties by bounded model checking. A passing test says “we found no failing input”. A Kani proof says “no input up to this size can fail”. Writing one proof for the Project C arbiter is a stretch goal.
  • Verus extends Rust with machine-checked specifications. We’ll not use it in this course. It’s worth knowing about for contracts that matter enough to verify fully.

Why this works in Rust

Every tool on that list leans on the same property: in Rust the contracts live in the types, and the toolchain can be programmed against them. A lint you configure today enforces a review decision on every line written after it, including the ones the agent writes next week. So when you ask the agent for code, ask for the guardrail in the same prompt.