From ab7f0b06500d6633ff9b1a8ee782fcfb1803c9d3 Mon Sep 17 00:00:00 2001 From: Brummel Date: Thu, 2 Jul 2026 12:39:29 +0200 Subject: [PATCH] plan: 0101 normalize CLI usage-message casing One lockstep task: 10 byte-exact literal edits (6 lowercase usage: flips, 4 bare closures gain the 'Usage: aura ' prefix, mc built-in gets the program name in both alternatives) + the single casing-sensitive pin flip in cli_run.rs, then build / targeted test / full suite / clippy / grep gates / diff-shape gate / sweep smoke. refs #179 --- docs/plans/0101-normalize-cli-usage-casing.md | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 docs/plans/0101-normalize-cli-usage-casing.md diff --git a/docs/plans/0101-normalize-cli-usage-casing.md b/docs/plans/0101-normalize-cli-usage-casing.md new file mode 100644 index 0000000..805305b --- /dev/null +++ b/docs/plans/0101-normalize-cli-usage-casing.md @@ -0,0 +1,223 @@ +# 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`.