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
This commit is contained in:
@@ -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 <verb> …` (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 <T> | --unwired | --content-id"
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
"aura: Usage: aura graph introspect --vocabulary | --node <T> | --unwired | --content-id"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Site #2 — `main.rs:3991` (`run_data_from`, let-binding)**
|
||||
|
||||
old:
|
||||
```rust
|
||||
let usage = "usage: aura run <blueprint.json> [--params <json-cell-array>] [--seed <n>] [--real <SYMBOL> [--from <ms>] [--to <ms>]]";
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
let usage = "Usage: aura run <blueprint.json> [--params <json-cell-array>] [--seed <n>] [--real <SYMBOL> [--from <ms>] [--to <ms>]]";
|
||||
```
|
||||
|
||||
- [ ] **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 <blueprint.json> [--params <json-cell-array>] [--seed <n>] [--real <SYMBOL> [--from <ms>] [--to <ms>]]");
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
eprintln!("aura: Usage: aura run <blueprint.json> [--params <json-cell-array>] [--seed <n>] [--real <SYMBOL> [--from <ms>] [--to <ms>]]");
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Site #4 — `main.rs:4272` (`dispatch_runs`)**
|
||||
|
||||
old:
|
||||
```rust
|
||||
eprintln!("aura: usage: aura runs family <id> [rank <metric>]");
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
eprintln!("aura: Usage: aura runs family <id> [rank <metric>]");
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Site #5 — `main.rs:4465` (`dispatch_mc`, blueprint branch; gains the program name)**
|
||||
|
||||
old:
|
||||
```rust
|
||||
let usage = "usage: mc <blueprint.json> --seeds <n> [--name <n>]";
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
let usage = "Usage: aura mc <blueprint.json> --seeds <n> [--name <n>]";
|
||||
```
|
||||
|
||||
- [ ] **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 <n>|--trace <n>] | mc --strategy r-sma [--real <SYMBOL> [--from <ms>] [--to <ms>]] [--fast <csv>] [--slow <csv>] [--stop-length <csv>] [--stop-k <csv>] [--block-len <n>] [--resamples <n>] [--seed <n>]".to_string();
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
let usage = || "Usage: aura mc [--name <n>|--trace <n>] | aura mc --strategy r-sma [--real <SYMBOL> [--from <ms>] [--to <ms>]] [--fast <csv>] [--slow <csv>] [--stop-length <csv>] [--stop-k <csv>] [--block-len <n>] [--resamples <n>] [--seed <n>]".to_string();
|
||||
```
|
||||
|
||||
- [ ] **Step 7: Site #7 — `main.rs:4288` (`dispatch_sweep`, blueprint branch; bare → prefixed; keep the `…` byte)**
|
||||
|
||||
old:
|
||||
```rust
|
||||
let usage = || "sweep <blueprint.json> --axis <name>=<csv> [--axis …] [--name <n> | --trace <n>] [--real <SYM> [--from <ms>] [--to <ms>]]".to_string();
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
let usage = || "Usage: aura sweep <blueprint.json> --axis <name>=<csv> [--axis …] [--name <n> | --trace <n>] [--real <SYM> [--from <ms>] [--to <ms>]]".to_string();
|
||||
```
|
||||
|
||||
- [ ] **Step 8: Site #8 — `main.rs:4346` (`dispatch_sweep`, built-in branch; bare → prefixed)**
|
||||
|
||||
old:
|
||||
```rust
|
||||
let usage = || "sweep [--strategy <sma|momentum|r-sma|r-breakout|r-meanrev>] [--real <SYMBOL> [--from <ms>] [--to <ms>]] [--name <n> | --trace <n>] [--fast <csv>] [--slow <csv>] [--stop-length <csv>] [--stop-k <csv>] [--channel <csv>] [--window <csv>] [--band-k <csv>]".to_string();
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
let usage = || "Usage: aura sweep [--strategy <sma|momentum|r-sma|r-breakout|r-meanrev>] [--real <SYMBOL> [--from <ms>] [--to <ms>]] [--name <n> | --trace <n>] [--fast <csv>] [--slow <csv>] [--stop-length <csv>] [--stop-k <csv>] [--channel <csv>] [--window <csv>] [--band-k <csv>]".to_string();
|
||||
```
|
||||
|
||||
- [ ] **Step 9: Site #9 — `main.rs:4386` (`dispatch_walkforward`, blueprint branch; bare → prefixed; keep the `…` byte)**
|
||||
|
||||
old:
|
||||
```rust
|
||||
let usage = || "walkforward <blueprint.json> --axis <name>=<csv> [--axis …] [--select <argmax|plateau:mean|plateau:worst>] [--name <n>]".to_string();
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
let usage = || "Usage: aura walkforward <blueprint.json> --axis <name>=<csv> [--axis …] [--select <argmax|plateau:mean|plateau:worst>] [--name <n>]".to_string();
|
||||
```
|
||||
|
||||
- [ ] **Step 10: Site #10 — `main.rs:4424` (`dispatch_walkforward`, built-in branch; bare → prefixed)**
|
||||
|
||||
old:
|
||||
```rust
|
||||
let usage = || "walkforward [--strategy <sma|momentum|r-sma|r-breakout|r-meanrev>] [--real <SYMBOL> [--from <ms>] [--to <ms>]] [--name <n> | --trace <n>] [--fast <csv>] [--slow <csv>] [--stop-length <csv>] [--stop-k <csv>] [--select <argmax|plateau:mean|plateau:worst>]".to_string();
|
||||
```
|
||||
new:
|
||||
```rust
|
||||
let usage = || "Usage: aura walkforward [--strategy <sma|momentum|r-sma|r-breakout|r-meanrev>] [--real <SYMBOL> [--from <ms>] [--to <ms>]] [--name <n> | --trace <n>] [--fast <csv>] [--slow <csv>] [--stop-length <csv>] [--stop-k <csv>] [--select <argmax|plateau:mean|plateau:worst>]".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 <sma|momentum|r-sma|r-breakout|r-meanrev>] [--real <SYMBOL> [--from <ms>] [--to <ms>]] [--name <n> | --trace <n>] [--fast <csv>] [--slow <csv>] [--stop-length <csv>] [--stop-k <csv>] [--channel <csv>] [--window <csv>] [--band-k <csv>]`
|
||||
Expected exit code line: `exit=2`.
|
||||
Reference in New Issue
Block a user