# Traits are produced, not just recognised — and the CLI contract finally landed The 0005 drill was completed on the user's own `tasks` crate: `impl fmt::Display for Task` written from the signature up, `unwrap` removed from `main.rs`, `run(args, store) -> Result<(), String>` extracted, `Command::parse(args)?` matching on `Command` values, and `eprintln!` + `process::exit(1)` at the edge. All three shell checks pass (`fly` → exit 1, `done 9` → exit 1, `add "buy milk" 2>/dev/null` → exit 0) and the 17 spec tests still pass. Traits, `Display`, and `?` can be treated as owned from here — lesson 0006 assumes them instead of teaching them. ## Evidence Verified by running the drill's own checks against `~/learn-rust/tasks`, not by reading the diff. The `?`-on-`parse` shape was wrong on first submission (`match Command::parse(&args) { … Err(e) => Err(e) }`) and was corrected after review, so `?` is now produced but was not the first instinct — worth one more forced repetition in 0006, where the error type changes under five call sites at once. ## Implications - The stderr/exit-1 contract has now been missed twice before landing (0003 spec, 0005 step 3). The pattern is clear: a step whose check the user does not actually paste into a shell does not get done. Every future drill step needs a one-line runnable check, and the lesson should say "run it, do not eyeball it". - The recall quiz scored Enums 0/1 while the same session produced three working enums. Recall of *why* a construct exists lags the ability to use it. Fix by making the compiler state the reason (0006 shows real `E0004` output for a newly added variant) rather than asserting it in prose. - Their own duplicated `"id not found"` string across `command.rs` and `store.rs` is the concrete motivation for `TaskError`; using the user's own defect beats an invented example.