From f029c3537475555336cb23d97875c12ccf7cba0f Mon Sep 17 00:00:00 2001 From: Brummel Date: Thu, 2 Jul 2026 10:35:45 +0200 Subject: [PATCH] spec: 0100 rename the stage1-* family to the r-family (boss-signed) The stage1 ordinal is dead vocabulary since the C10 reframe; the spec renames the selector/identifier family to r-sma / r-breakout / r-meanrev (signal-named members under the R-yardstick marker), reworders dead Stage-1/Stage-2 doc prose, and pins the survivors (history, fieldtests). Signed autonomously under /boss on the grounding-check PASS; fork decisions recorded on the reference issue. refs #174 --- .../0100-rename-stage1-family-to-r-family.md | 263 ++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 docs/specs/0100-rename-stage1-family-to-r-family.md diff --git a/docs/specs/0100-rename-stage1-family-to-r-family.md b/docs/specs/0100-rename-stage1-family-to-r-family.md new file mode 100644 index 0000000..55310b6 --- /dev/null +++ b/docs/specs/0100-rename-stage1-family-to-r-family.md @@ -0,0 +1,263 @@ +# Rename the stage1-* family to the r-family — Design Spec + +**Date:** 2026-07-02 +**Status:** Draft — awaiting sign-off (grounding-check gate; /boss auto-sign) +**Authors:** orchestrator + Claude + +## Goal + +Eliminate the dead `stage1` / `stage2` ordinal from every live identifier and +user-facing string (issue #174). The two-stage research model was retired by the +C10 reframe (ledger `29cdc8c`); the ordinal now provokes exactly the wrong +question ("where is stage 2?"). This is a vocabulary-only cycle: no behaviour +changes except the vocabulary itself — selector tokens, Rust identifiers, one +persisted composite name, and dead-ordinal doc prose. + +The replacement vocabulary is the **r-family**: members named by their signal +under the `r-` marker, because the R yardstick is the family's live +discriminator against the pip-legacy selectors (the CLI itself refuses +`--harness sma/macd` with "produces no R") and the codebase's R token ecology +(`r_equity`, `RMetrics`, `mean_r`) already uses exactly this marker. Decision +log with rejected candidates: issue #174, comment "Design reconciliation +(specify)". + +## Architecture + +### Token mapping (normative) + +User-facing selector strings: + +| before | after | +|---|---| +| `stage1-r` | `r-sma` | +| `stage1-breakout` | `r-breakout` | +| `stage1-meanrev` | `r-meanrev` | + +`sma`, `macd`, `momentum` selectors are untouched. The resulting vocabulary is +uniformly signal-named: `sma`, `macd`, `momentum`, `r-sma`, `r-breakout`, +`r-meanrev`. + +Rust identifiers (all in `crates/aura-cli/src/main.rs` unless noted): + +| before | after | +|---|---| +| `Strategy::Stage1R / Stage1Breakout / Stage1MeanRev` | `Strategy::RSma / RBreakout / RMeanRev` | +| `HarnessKind::Stage1R` | `HarnessKind::RSma` | +| `Stage1RGrid` | `RGrid` (the family-shared knob grid) | +| `stage1_r_sweep_family / _space / _sweep_over / _graph / _prices / _friendly_name / _broker_label` | `r_sma_*` | +| `stage1_breakout_sweep_family / stage1_breakout_graph` | `r_breakout_*` | +| `stage1_meanrev_sweep_family / stage1_meanrev_graph` | `r_meanrev_*` | +| `run_stage1_r` | `run_r_sma` | +| `wrap_stage1r` (shared downstream scaffolding) | `wrap_r` | +| `run_signal_stage1r` | `run_signal_r` | +| `STAGE1_R_SMA_FAST / _SMA_SLOW / _STOP_LENGTH / _STOP_K / _BIAS_SCALE` | `R_SMA_FAST / R_SMA_SLOW / R_SMA_STOP_LENGTH / R_SMA_STOP_K / R_SMA_BIAS_SCALE` | +| composite `stage1_signal` (`GraphBuilder::new("stage1_signal")`) | `sma_signal` | +| top-level graph debug names `"stage1_r"` / `"stage1_breakout"` / `"stage1_meanrev"` | `"r_sma"` / `"r_breakout"` / `"r_meanrev"` | + +Test-internal names follow the same mapping mechanically: test fn names +(`stage1_r_single_run_output_golden` → `r_sma_single_run_output_golden`, …), +temp-cwd literals (`"wf-stage1r"` → `"wf-r-sma"`, `"mc_stage1r_boot"` → +`"mc_r_sma_boot"`, …), file names (§Components). + +None of the target tokens exist in the tree today (collision-checked: +`sma_signal`, `r-sma`, `RSma`, `r_sma_`, `wrap_r`, `run_signal_r`, `R_SMA_`, +`RGrid` — zero hits). + +### Persisted identity + +The only stage1 token that reaches disk is the composite name `stage1_signal`: +it is the param-space prefix (`stage1_signal.fast.length` / +`stage1_signal.slow.length`) surfaced by `list-axes`, accepted by `--axis`, +serialized in three test fixtures, and an input to `topology_hash` / +content-id. Renaming it to `sma_signal` therefore shifts content-ids and +fixture bytes. This is accepted: no test pins a literal hash and the registry +never parses record names (both recon-verified). `stage1_r_friendly_name` — +despite the issue body's wording — maps param names *away* from stage1 and +writes no on-disk bytes; its rename is source-only. No migration of user +`runs/` artifacts (runtime data outside the repo contract). + +### Explicitly out of scope (survivors) + +- **Ledger history** (`docs/design/INDEX.md` Stage-1/Stage-2 reframe sections, + e.g. :297, :617, :672–906): the historical record stays. Only live + CLI-surface lines move (:931, :943, :740, :958, :1898–1959 symbol names). +- **Glossary "Stage 1 / Stage 2" entry** (docs/glossary.md:250–252): stays as + history; only its tail clause ("survives … as identifier name") is updated to + record the rename (record-reality glossary write). +- **fieldtests/ corpus**: committed historical evidence of past cycles; renaming + inside it would falsify the record. Untouched. +- **docs/specs/fieldtest-milestone-world-c21-blueprint-data-families.md**: + ephemeral prior-cycle artifact, removed at cycle close anyway. Untouched. +- **`crates/aura-engine/src/harness.rs:1898`**: "stage1/stage2/stage3" there are + resampling stages of a reduction test — a false positive. Untouched. + +## Concrete code shapes + +### User-facing invocation (before → after) + +```console +# before +aura run --harness stage1-r --real EURUSD --cost-per-trade 0.5 +aura sweep --strategy stage1-r --name s1 --axis stage1_signal.fast.length=2,4 +aura generalize --real EURUSD,GBPUSD --fast 2 --slow 4 --stop-length 3 --stop-k 1.5 + +# after +aura run --harness r-sma --real EURUSD --cost-per-trade 0.5 +aura sweep --strategy r-sma --name s1 --axis sma_signal.fast.length=2,4 +aura generalize --real EURUSD,GBPUSD --fast 2 --slow 4 --stop-length 3 --stop-k 1.5 +``` + +Usage line (main.rs:4012), before: + +```text +Usage: aura run [--harness ] [--real ...] ... +``` + +after: + +```text +Usage: aura run [--harness ] [--real ...] ... +``` + +`aura sweep --list-axes` output (golden, cli_run.rs:3848), before → +after: every `stage1_signal.` line becomes `sma_signal.`; kinds and +ordering byte-identical otherwise. + +### Selector enum and parse arms (main.rs:1520, :1556, :4126) + +```rust +// before // after +enum Strategy { enum Strategy { + SmaCross, SmaCross, + Momentum, Momentum, + Stage1R, RSma, + Stage1Breakout, RBreakout, + Stage1MeanRev, RMeanRev, +} } + +Strategy::Stage1R => "stage1-r", Strategy::RSma => "r-sma", +Some("stage1-r") => Strategy::Stage1R, Some("r-sma") => Strategy::RSma, +``` + +`HarnessKind::Stage1R` (main.rs:3601, parse :4021) follows identically to +`HarnessKind::RSma` / token `r-sma`. + +### Composite and fixtures (main.rs:2518; tests/fixtures/) + +```rust +// before +let mut g = GraphBuilder::new("stage1_signal"); +// after +let mut g = GraphBuilder::new("sma_signal"); +``` + +- `crates/aura-cli/tests/fixtures/stage1_signal.json` → `sma_signal.json`, + regenerated by the `#[ignore]` regenerator (main.rs:5785, path updated). +- `.../stage1_signal_open.json` → `sma_signal_open.json`, regenerated + (main.rs:5795, path updated). +- `.../unknown_node.json` (`"name":"stage1_signal"`, hand-authored, no + regenerator): hand-edit the name to `sma_signal`. + +### Dead-ordinal prose (the pattern, applied at every listed site) + +`crates/aura-std/src/sizer.rs:1-8`, before (excerpt): + +```rust +//! `Sizer` — the flat-1R sizing seam (C10 Stage-1). ... and is the Stage-2 seam: +//! fixed-fractional sizing swaps `risk_budget` for `risk_fraction · equity` ... +//! ... it only scales the (Stage-2) currency exposure. +``` + +after: + +```rust +//! `Sizer` — the flat-1R sizing seam (C10). ... and is the live/deploy-edge seam: +//! fixed-fractional sizing swaps `risk_budget` for `risk_fraction · equity` ... +//! ... it only scales the (deploy-edge) currency exposure. +``` + +Same substitution — "Stage-1" → the feed-forward research loop, "Stage-2" → the +live/deploy edge, per the C10-reframe vocabulary already in the ledger and +glossary — at: `crates/aura-analysis/src/lib.rs` (6 hits), +`crates/aura-composites/src/lib.rs` (2), `crates/aura-std/src/position_management.rs` +(4), `crates/aura-composites/tests/risk_executor.rs` prose (7), +`crates/aura-cli/Cargo.toml:15-16`, `crates/aura-engine/Cargo.toml:25`, project +`CLAUDE.md` invariant 7 (:98-99, :106). The CLAUDE.md edit records the +already-ratified C10 reframe — a wording alignment, not a design change. + +### Error messages (main.rs:4041, :4067), before → after + +```text +cost flags require an R-evaluator harness (stage1-r); --harness sma/macd produces no R to charge against +→ cost flags require an R-evaluator harness (r-sma); --harness sma/macd produces no R to charge against + +generalize requires --strategy stage1-r (the candidate must produce R) +→ generalize requires --strategy r-sma (the candidate must produce R) +``` + +## Components + +| Surface | Work | +|---|---| +| `crates/aura-cli/src/main.rs` (276 hits) | identifier renames per mapping; selector/usage/help/error strings; `#[cfg(test)]` block (~150 hits) incl. regenerator paths | +| `crates/aura-cli/tests/cli_run.rs` (227 hits) | selector literals (49), test fn names (~40), `--axis sma_signal.*` keys (~30), temp-cwd literals, golden expectations | +| `crates/aura-engine/tests/stage1_{r,breakout,meanrev}_e2e.rs` | `git mv` → `r_{sma,breakout,meanrev}_e2e.rs` (content: stage1_r_e2e.rs 3 hits; stage1_meanrev_e2e.rs:6 doc ref "mirrors stage1_breakout_e2e" → "mirrors r_breakout_e2e"; stage1_breakout_e2e.rs token-free) | +| `crates/aura-engine/tests/streaming_reduction_equivalence.rs:2`, `crates/aura-cli/tests/graph_construct.rs:237`, `crates/aura-engine/tests/stage1_meanrev_e2e.rs:6` | doc-reference updates | +| fixtures (3 JSONs) | 2 regenerate + rename, 1 hand-edit (§Concrete code shapes) | +| `docs/design/INDEX.md` | live CLI-surface lines only (:740, :931, :943, :958, :1898–1959) | +| `docs/glossary.md:252` | tail-clause update recording the rename | +| `CLAUDE.md` (:98-99, :106) | dead-ordinal rewording per C10 vocabulary | +| rustdoc/comment prose (aura-analysis, aura-composites, aura-std, risk_executor, Cargo.tomls) | dead-ordinal rewording | + +## Data flow + +Unchanged. The single observable data-shape change is the param-space prefix +`stage1_signal.*` → `sma_signal.*` (axis names in `list-axes` output, `--axis` +arguments, blueprint JSON) and the consequent content-id/topology-hash shift. +Graph topology, node semantics, R evaluation, registry record structure: all +byte-identical in behaviour. + +## Error handling + +The exit-code contract is untouched (usage errors = 2, runtime = 1, per the +clap cycle). Unknown-selector handling is structurally unchanged; only the +vocabulary inside the usage/error strings moves (§Concrete code shapes). No new +error paths. + +## Testing strategy + +- **Suite green, goldens moved deliberately.** This is a user-facing vocabulary + change, so byte-pinned goldens *move with it* — but only in the renamed + tokens. Numeric content of every golden expectation stays byte-identical + (the float expressions are not touched; only name/prefix substrings change). +- **Fixture regeneration** via the two `#[ignore]` regenerator tests after the + composite rename; `unknown_node.json` hand-edited; the graph-construct suite + then passes against the renamed fixtures. +- **Grep gate (the acceptance test for box 1):** + `git grep -inE '(stage[- ]?1|stage[- ]?2)' -- crates/ CLAUDE.md README.md` + returns only the named survivors: `crates/aura-engine/src/harness.rs` + resampling-stage comment. Ledger/glossary checked separately: hits only + inside history sections and the glossary's historical entry. +- **Behavioural smoke:** `aura run --harness r-sma` and + `aura sweep --strategy r-sma --list-axes` produce output identical to the + pre-rename baselines modulo the renamed tokens (covered by the updated + goldens). +- `cargo build --workspace`, `cargo test --workspace`, + `cargo clippy --workspace --all-targets -- -D warnings` all green. + +## Acceptance criteria + +1. No `stage1` / `stage2` ordinal survives in a live identifier or user-facing + string. Survivors (exhaustive): ledger history sections, the glossary's + historical "Stage 1 / Stage 2" entry (tail updated), fieldtests/ corpus, the + prior-cycle fieldtest spec, the harness.rs resampling false positive. +2. Selectors, both enums, graph/runner/grid builders, friendly-name/broker-label + fns, shared scaffolding (`wrap_r`, `run_signal_r`), consts, composite name, + fixtures, test fn names, and test file names renamed per the normative + mapping — consistently, no partial states. +3. `crates/aura-std/src/sizer.rs` note (and the other listed prose sites, + including CLAUDE.md invariant 7) reworded to drop the dead ordinal, using the + C10-reframe vocabulary. +4. The grep gate passes as specified in §Testing strategy. +5. `cargo build --workspace` and `cargo test --workspace` green (clippy too). +6. Issue #174 closed by the landing commit (`closes #174`).