# Normalize CLI usage-message casing — Implementation Plan > **Parent spec:** `docs/specs/0101-normalize-cli-usage-casing.md` > > **For agentic workers:** REQUIRED SUB-SKILL: use the > `implement` skill to run this plan. Steps use `- [ ]` > checkboxes for tracking. **Goal:** Normalize every hand-rolled CLI usage line to the single house style `Usage: aura …` (10 literal edits) and flip the one casing-sensitive test pin in lockstep — cosmetic only, no behaviour change (issue #179). **Architecture:** All edits are byte-substitutions inside existing string literals on existing exit-2 usage paths; emission channels (stderr via the `aura: ` convention), exit codes, and control flow stay byte-identical. The lockstep unit is indivisible: the mc built-in literal (site #6) and the `cli_run.rs` pin must move together or the suite goes red, so this plan is one task. **Tech Stack:** `crates/aura-cli` (clap v4 derive CLI), Rust string literals, `cargo test` integration suite `cli_run.rs`. --- **Files this plan creates or modifies:** - Modify: `crates/aura-cli/src/graph_construct.rs:191` — site #1 casing flip - Modify: `crates/aura-cli/src/main.rs:3991,4187,4272,4288,4346,4386,4424,4465,4503` — sites #2–#10 - Test: `crates/aura-cli/tests/cli_run.rs:1409` — the single casing-sensitive pin flips lowercase `"usage"` → `"Usage"` **Off-limits (do not touch):** every other string in `crates/aura-cli` (refusal diagnostics, the already-conforming `run_args_from` literal at `main.rs:4012`), all other test bytes, and the `fieldtests/` corpus (its old exact-equality usage pins are out-of-workspace by design and stay byte-identical). --- ### Task 1: House-style normalization + lockstep pin flip **Files:** - Modify: `crates/aura-cli/src/graph_construct.rs:191` - Modify: `crates/aura-cli/src/main.rs:3991,4187,4272,4288,4346,4386,4424,4465,4503` - Test: `crates/aura-cli/tests/cli_run.rs:1409` Each edit below is exact: `old` is the complete current line (verified unique in its file), `new` is the complete replacement line. Only the shown bytes change. Note sites #7 and #9 contain a Unicode ellipsis (`…`) inside `[--axis …]` — preserve it verbatim. - [ ] **Step 1: Site #1 — `graph_construct.rs:191` (`introspect_cmd`)** old: ```rust "aura: usage: aura graph introspect --vocabulary | --node | --unwired | --content-id" ``` new: ```rust "aura: Usage: aura graph introspect --vocabulary | --node | --unwired | --content-id" ``` - [ ] **Step 2: Site #2 — `main.rs:3991` (`run_data_from`, let-binding)** old: ```rust let usage = "usage: aura run [--params ] [--seed ] [--real [--from ] [--to ]]"; ``` new: ```rust let usage = "Usage: aura run [--params ] [--seed ] [--real [--from ] [--to ]]"; ``` - [ ] **Step 3: Site #3 — `main.rs:4187` (`dispatch_run`, inline eprintln, verbatim twin of #2 with baked `aura: `)** old: ```rust eprintln!("aura: usage: aura run [--params ] [--seed ] [--real [--from ] [--to ]]"); ``` new: ```rust eprintln!("aura: Usage: aura run [--params ] [--seed ] [--real [--from ] [--to ]]"); ``` - [ ] **Step 4: Site #4 — `main.rs:4272` (`dispatch_runs`)** old: ```rust eprintln!("aura: usage: aura runs family [rank ]"); ``` new: ```rust eprintln!("aura: Usage: aura runs family [rank ]"); ``` - [ ] **Step 5: Site #5 — `main.rs:4465` (`dispatch_mc`, blueprint branch; gains the program name)** old: ```rust let usage = "usage: mc --seeds [--name ]"; ``` new: ```rust let usage = "Usage: aura mc --seeds [--name ]"; ``` - [ ] **Step 6: Site #6 — `main.rs:4503` (`dispatch_mc`, built-in branch; BOTH ` | `-separated alternatives gain the program name)** old: ```rust let usage = || "usage: mc [--name |--trace ] | mc --strategy r-sma [--real [--from ] [--to ]] [--fast ] [--slow ] [--stop-length ] [--stop-k ] [--block-len ] [--resamples ] [--seed ]".to_string(); ``` new: ```rust let usage = || "Usage: aura mc [--name |--trace ] | aura mc --strategy r-sma [--real [--from ] [--to ]] [--fast ] [--slow ] [--stop-length ] [--stop-k ] [--block-len ] [--resamples ] [--seed ]".to_string(); ``` - [ ] **Step 7: Site #7 — `main.rs:4288` (`dispatch_sweep`, blueprint branch; bare → prefixed; keep the `…` byte)** old: ```rust let usage = || "sweep --axis = [--axis …] [--name | --trace ] [--real [--from ] [--to ]]".to_string(); ``` new: ```rust let usage = || "Usage: aura sweep --axis = [--axis …] [--name | --trace ] [--real [--from ] [--to ]]".to_string(); ``` - [ ] **Step 8: Site #8 — `main.rs:4346` (`dispatch_sweep`, built-in branch; bare → prefixed)** old: ```rust let usage = || "sweep [--strategy ] [--real [--from ] [--to ]] [--name | --trace ] [--fast ] [--slow ] [--stop-length ] [--stop-k ] [--channel ] [--window ] [--band-k ]".to_string(); ``` new: ```rust let usage = || "Usage: aura sweep [--strategy ] [--real [--from ] [--to ]] [--name | --trace ] [--fast ] [--slow ] [--stop-length ] [--stop-k ] [--channel ] [--window ] [--band-k ]".to_string(); ``` - [ ] **Step 9: Site #9 — `main.rs:4386` (`dispatch_walkforward`, blueprint branch; bare → prefixed; keep the `…` byte)** old: ```rust let usage = || "walkforward --axis = [--axis …] [--select ] [--name ]".to_string(); ``` new: ```rust let usage = || "Usage: aura walkforward --axis = [--axis …] [--select ] [--name ]".to_string(); ``` - [ ] **Step 10: Site #10 — `main.rs:4424` (`dispatch_walkforward`, built-in branch; bare → prefixed)** old: ```rust let usage = || "walkforward [--strategy ] [--real [--from ] [--to ]] [--name | --trace ] [--fast ] [--slow ] [--stop-length ] [--stop-k ] [--select ]".to_string(); ``` new: ```rust let usage = || "Usage: aura walkforward [--strategy ] [--real [--from ] [--to ]] [--name | --trace ] [--fast ] [--slow ] [--stop-length ] [--stop-k ] [--select ]".to_string(); ``` - [ ] **Step 11: Lockstep pin flip — `cli_run.rs:1409` (test `mc_rejects_real_flag_with_usage_exit_2`)** Only the predicate substring flips; the panic-message argument keeps its lowercase "usage" verbatim. old: ```rust assert!(stderr.contains("usage"), "mc --real stderr must carry usage: {stderr:?}"); ``` new: ```rust assert!(stderr.contains("Usage"), "mc --real stderr must carry usage: {stderr:?}"); ``` - [ ] **Step 12: Build gate** Run: `cargo build --workspace` Expected: clean compile, 0 errors, 0 warnings introduced. - [ ] **Step 13: Targeted pin test** Run: `cargo test -p aura-cli --test cli_run mc_rejects_real_flag_with_usage_exit_2` Expected: `1 passed; 0 failed` (exactly one test matches the filter). - [ ] **Step 14: Full-suite gate** Run: `cargo test --workspace` Expected: green, 0 failures across all targets. Any failure other than a test this plan did not touch going red means an edit strayed outside the normative table — fix the edit, never a pin. - [ ] **Step 15: Lint gate** Run: `cargo clippy --workspace --all-targets -- -D warnings` Expected: clean, 0 warnings. - [ ] **Step 16: Literal grep gates** Run: `grep -rn '"usage:' crates/aura-cli/src/` Expected: no output (exit 1 — zero hits). Run: `grep -rn 'aura: usage:' crates/aura-cli/src/` Expected: no output (exit 1 — zero hits). Run: `grep -rn 'Usage: aura' crates/aura-cli/src/ | wc -l` Expected: `11` (the 10 edited sites + the untouched conforming `run_args_from` literal at `main.rs:4012`). - [ ] **Step 17: Diff-shape gate** Run: `git diff --stat` Expected: exactly 3 files changed — `crates/aura-cli/src/main.rs`, `crates/aura-cli/src/graph_construct.rs`, `crates/aura-cli/tests/cli_run.rs` (plus this plan/spec under `docs/` if listed); no `fieldtests/` path, no other test file. - [ ] **Step 18: Smoke (worked example from the spec)** Run: `cargo run -q -p aura-cli -- sweep --strategy bogus; echo "exit=$?"` Expected stderr line: `aura: Usage: aura sweep [--strategy ] [--real [--from ] [--to ]] [--name | --trace ] [--fast ] [--slow ] [--stop-length ] [--stop-k ] [--channel ] [--window ] [--band-k ]` Expected exit code line: `exit=2`.