Closed set, or open set?
ChefCheffe orders pay by card, SEPA transfer or cash. Every part of the sync must handle all three. Your agent asks: enum or trait? Choose.
Where the error type goes
Two crates: a parser library and the CLI that uses it. Your agent picked an error type for each layer. One choice hurts the first time the CLI wants to retry. Tap it.
Tap the part that will not survive contact with reality — or press 1…3.
The file is always there
Your agent loads the service config at startup and reports how it handled the missing-file case. Judge it.
The config path comes from APP_CONFIG. I unwrap it: the file is always there in every environment we deploy to, and threading a Result through main() would just add noise.
Six of eight states are lies
A Booking record for the hospitality client. Your agent modelled it with fields. Tap the part of the design that lets the data lie.
Tap the part that will not survive contact with reality — or press 1…4.
Three smells in one type
Your agent’s proposed core type for a single-threaded, per-request service. Three smells live in it. Tap the one that forces every caller to restructure their own code.
Tap the part that will not survive contact with reality — or press 1…3.
The first day of a Rust codebase
Several agents will write this codebase. Put the first-day decisions in the order you want them made, then let one agent run through it.
What survives this level
| Lifetimes as an API commitment | A lifetime in a public signature makes every caller keep something alive; buy it only when the copy is measurable. |
| Traits vs enums — open vs closed extension | Closed set you control: enum. Open set others extend: trait. When unsure, enum; you can open it later. |
| The newtype habit | Wrap ids, money and units in their own type so the compiler catches swapped arguments. |
| Making illegal states unrepresentable | If two fields can disagree about the state, replace them with one enum whose variants carry their own data. |
| Option and Result — absence and failure in the type system | Absence is Option, failure is Result; both are handled where the caller can do something about it. |
| Error architecture: thiserror at library edges, anyhow at application edges | Typed errors at crate edges, anyhow only in the binary; decided once, before the first module. |
| unwrap / expect as a load-bearing claim | unwrap is a signed claim that this cannot fail; accept it at startup, never in the request path. |
| Panic vs recoverable, and who decides | Recoverable if the caller has an alternative; a panic is a decision the callee makes on everyone’s behalf. |
| The public API surface is the thing to review | pub is the only thing callers depend on and the only thing you cannot change quietly; review it line by line. |
| Dependency weight, semver and MSRV | Every dependency is a maintenance contract; pin an MSRV and a dependency policy before the first cargo add. |
| What the type system lets you not test | What the types make unrepresentable you do not test; logic, ordering and IO you still do. |
| One error strategy chosen up front | One error strategy for the whole workspace, written in the brief, before any agent writes a module. |
| clippy and rustfmt as enforced conventions | clippy and rustfmt run in CI from day one; conventions are enforced, not relitigated per pull request. |
| You review the public surface; the rest is detail | You personally review pub items and the brief; internals are the agent’s to get wrong and fix. |