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
This commit is contained in:
2026-07-02 10:35:45 +02:00
parent 88e9c9a539
commit f029c35374
@@ -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, :672906): the historical record stays. Only live
CLI-surface lines move (:931, :943, :740, :958, :18981959 symbol names).
- **Glossary "Stage 1 / Stage 2" entry** (docs/glossary.md:250252): 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 <sma|macd|stage1-r>] [--real <SYMBOL> ...] ...
```
after:
```text
Usage: aura run [--harness <sma|macd|r-sma>] [--real <SYMBOL> ...] ...
```
`aura sweep --list-axes` output (golden, cli_run.rs:3848), before →
after: every `stage1_signal.<knob>` line becomes `sma_signal.<knob>`; 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, :18981959) |
| `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`).