audit: cycle 0100 tidy (drift-clean after one ledger alignment)
Architect review of 88e9c9a..HEAD. What holds: token purity of the rename (removed + mapping == added, 33 sanctioned prose rewordings, numeric golden bytes untouched); CLAUDE.md invariant 7 now matches the ledger C10 section clause-by-clause; no silent alias for the old selectors (unknown-selector exit-2 path is tested). Regression: cargo build / clippy -D warnings / doc build clean; cargo test --workspace rc=0, 51 targets, 0 failures. No baselines exist to move, so nothing to ratify. Drift resolved in this commit: the C10 terminology note (INDEX.md) still called Stage-1 a surviving identifier name after the glossary recorded the rename - aligned to name the r-family rename (#174). Remaining low items: the spec's own survivor-list contradiction was ratified and recorded on the issue; the RGrid const-seeding debt is recorded on the harness-retirement issue (refs #159). Ephemeral cycle artifacts removed per convention: spec 0100, plan 0100, and the spent prior-milestone fieldtest spec. refs #174
This commit is contained in:
@@ -723,8 +723,10 @@ explicit: the net-R curve is a research / ranking hypothesis; the forward / live
|
||||
run is ground truth. `SimBroker` is downgraded to a legacy / optional pip
|
||||
yardstick, not to be expanded. (Terminology note: with Stage 2 gone, the
|
||||
**"Stage-1"** label below is no longer one half of a two-stage gate — it survives
|
||||
only as a historical cycle / identifier name, like the `exposure` → `bias` on-disk
|
||||
alias, denoting the shipped feed-forward R chain.)
|
||||
only as a historical cycle name, like the `exposure` → `bias` on-disk alias,
|
||||
denoting the shipped feed-forward R chain; the identifier family that carried it
|
||||
was renamed to the r-family — `r-sma` / `r-breakout` / `r-meanrev` — in cycle
|
||||
0100, #174.)
|
||||
|
||||
**Realization (cycle 0081 — cost-model graph, cycle 1, #148).** The first concrete
|
||||
cost node + the net-R seam shipped. `ConstantCost` (`aura-std`) is an ordinary
|
||||
|
||||
@@ -1,411 +0,0 @@
|
||||
# Rename the stage1-* family to the r-family — Implementation Plan
|
||||
|
||||
> **Parent spec:** `docs/specs/0100-rename-stage1-family-to-r-family.md`
|
||||
>
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: use the
|
||||
> `implement` skill to run this plan. Steps use `- [ ]`
|
||||
> checkboxes for tracking.
|
||||
|
||||
**Goal:** Eliminate the dead `stage1`/`stage2` ordinal from every live
|
||||
identifier and user-facing string, renaming the family to `r-sma` /
|
||||
`r-breakout` / `r-meanrev` per the spec's normative token mapping.
|
||||
|
||||
**Architecture:** A vocabulary-only rename in five ordered surfaces: (1) the
|
||||
aura-cli binary + its persisted-identity fixtures (one compilation unit — the
|
||||
test block `include_str!`s the fixtures, so file renames and source renames
|
||||
are inseparable), (2) the cli_run integration suite, (3) the engine e2e files
|
||||
+ doc-references, (4) dead-ordinal prose across docs and rustdoc, (5) a
|
||||
workspace-wide verification with a grep gate. Substitutions are ORDERED —
|
||||
longest/most-specific token first — because several old tokens are substrings
|
||||
of each other (`Stage1RGrid` ⊃ `Stage1R`; `STAGE1_R_SMA_FAST` ⊃ `STAGE1_R_`;
|
||||
`wrap_stage1r` ⊃ `stage1r`).
|
||||
|
||||
**Tech Stack:** Rust workspace (cargo), sed for mechanical substitution, git mv
|
||||
for file renames, two `#[ignore]` fixture-regenerator tests.
|
||||
|
||||
---
|
||||
|
||||
**Files this plan creates or modifies:**
|
||||
|
||||
- Modify: `crates/aura-cli/src/main.rs` (276 hits: enums :1523-1525/:3601,
|
||||
Display :1556-1558, parse :4021/:4126-4128, `Stage1RGrid` :1069, fns
|
||||
:1049/:1117/:1131/:1241/:1254/:1359/:1425/:2494/:2517/:2583/:2613/:2794/:3268/:3368/:3480,
|
||||
consts :2447-2464, usage/help strings
|
||||
:1604/:3805/:3830-3834/:3842/:3893/:3935/:3938/:4012/:4040-4041/:4067/:4346/:4424/:4503,
|
||||
test block :5390-5912 incl. regenerators :5783/:5793 and `include_str!`
|
||||
:5487/:5494/:5501, prose banners :2046/:2445/:2512/:2561/:2606/:2789/:3358)
|
||||
- Rename: `crates/aura-cli/tests/fixtures/stage1_signal.json` → `sma_signal.json` (then regenerated)
|
||||
- Rename: `crates/aura-cli/tests/fixtures/stage1_signal_open.json` → `sma_signal_open.json` (then regenerated)
|
||||
- Modify: `crates/aura-cli/tests/fixtures/unknown_node.json` (hand-edit `"name"`)
|
||||
- Modify: `crates/aura-cli/tests/cli_run.rs` (227 hits: selector literals, axis
|
||||
keys, test fn names, goldens incl. list-axes :3848, temp-cwd literals, prose :3001)
|
||||
- Rename: `crates/aura-engine/tests/stage1_r_e2e.rs` → `r_sma_e2e.rs` (content hits :1/:97/:127)
|
||||
- Rename: `crates/aura-engine/tests/stage1_breakout_e2e.rs` → `r_breakout_e2e.rs` (body token-free)
|
||||
- Rename: `crates/aura-engine/tests/stage1_meanrev_e2e.rs` → `r_meanrev_e2e.rs` (doc-ref :6)
|
||||
- Modify: `crates/aura-engine/tests/streaming_reduction_equivalence.rs:2` (doc-ref)
|
||||
- Modify: `crates/aura-cli/tests/graph_construct.rs:237` (doc-ref)
|
||||
- Modify: `crates/aura-std/src/sizer.rs:1-8`, `crates/aura-std/src/position_management.rs:1,:149,:160,:278`
|
||||
- Modify: `crates/aura-analysis/src/lib.rs:74,:82,:132,:327,:378,:1111`
|
||||
- Modify: `crates/aura-composites/src/lib.rs:1,:38`, `crates/aura-composites/tests/risk_executor.rs:1,:5,:17,:103,:130,:151,:249`
|
||||
- Modify: `crates/aura-cli/Cargo.toml:15-16`, `crates/aura-engine/Cargo.toml:25`
|
||||
- Modify: `CLAUDE.md:98-99,:106`
|
||||
- Modify: `docs/glossary.md:96,:252`
|
||||
- Modify: `docs/design/INDEX.md` live lines only (:740, :931, :932, :940, :943,
|
||||
:957, :958, :1330, :1890, :1898-1959); history sections (:297, :617, :672-906) untouched
|
||||
- NOT touched (survivors): `crates/aura-engine/src/harness.rs:1898`,
|
||||
`fieldtests/**`, `docs/specs/fieldtest-milestone-world-c21-blueprint-data-families.md`,
|
||||
ledger history sections, the glossary "Stage 1 / Stage 2" entry heading/body
|
||||
(only its :252 tail clause and the :96 forward-reference are edited)
|
||||
|
||||
---
|
||||
|
||||
### Task 1: aura-cli source + persisted-identity fixtures
|
||||
|
||||
The binary source and the fixture files are one unit: the test block
|
||||
`include_str!`s the fixtures (main.rs :5487/:5494/:5501), so the path rename
|
||||
and the file rename must land together or the crate does not compile.
|
||||
|
||||
**Files:**
|
||||
- Modify: `crates/aura-cli/src/main.rs`
|
||||
- Rename + regenerate: `crates/aura-cli/tests/fixtures/stage1_signal.json`, `stage1_signal_open.json`
|
||||
- Modify: `crates/aura-cli/tests/fixtures/unknown_node.json`
|
||||
|
||||
- [ ] **Step 1: Ordered identifier/const/type substitutions in main.rs**
|
||||
|
||||
Run (exactly this order — earlier patterns are supersets of later ones):
|
||||
|
||||
```bash
|
||||
cd /home/brummel/dev/aura
|
||||
sed -i 's/STAGE1_R_SMA_FAST/R_SMA_FAST/g;
|
||||
s/STAGE1_R_SMA_SLOW/R_SMA_SLOW/g' crates/aura-cli/src/main.rs
|
||||
sed -i 's/STAGE1_R_/R_SMA_/g' crates/aura-cli/src/main.rs
|
||||
sed -i 's/Stage1RGrid/RGrid/g' crates/aura-cli/src/main.rs
|
||||
sed -i 's/Stage1R/RSma/g;
|
||||
s/Stage1Breakout/RBreakout/g;
|
||||
s/Stage1MeanRev/RMeanRev/g' crates/aura-cli/src/main.rs
|
||||
sed -i 's/wrap_stage1r/wrap_r/g;
|
||||
s/run_signal_stage1r/run_signal_r/g' crates/aura-cli/src/main.rs
|
||||
sed -i 's/stage1_signal/sma_signal/g' crates/aura-cli/src/main.rs
|
||||
sed -i 's/stage1_r/r_sma/g;
|
||||
s/stage1_breakout/r_breakout/g;
|
||||
s/stage1_meanrev/r_meanrev/g' crates/aura-cli/src/main.rs
|
||||
sed -i 's/stage1-r/r-sma/g;
|
||||
s/stage1-breakout/r-breakout/g;
|
||||
s/stage1-meanrev/r-meanrev/g' crates/aura-cli/src/main.rs
|
||||
```
|
||||
|
||||
(`s/stage1_r/r_sma/g` intentionally also converts `run_stage1_r` →
|
||||
`run_r_sma` and doc-mentions of `stage1_r_e2e.rs` → `r_sma_e2e.rs`.)
|
||||
|
||||
- [ ] **Step 2: Prose-form ordinal substitutions in main.rs**
|
||||
|
||||
The 7 prose lines the token rules miss (verified exhaustive by
|
||||
`git grep -inE 'stage[- ]1|stage[- ]2' crates/aura-cli/src/main.rs | grep -ivE 'stage1[-_r]|stage1r'`):
|
||||
|
||||
```bash
|
||||
sed -i 's/Stage-1 R harness/r-sma harness/g;
|
||||
s/The Stage-1 signal leg/The r-sma signal leg/;
|
||||
s/Wrap a Stage-1 `signal` composite/Wrap a `signal` composite/;
|
||||
s/in the Stage-1 R run/in the R run/;
|
||||
s/Stage-1-R scaffolding/R scaffolding/;
|
||||
s/The Stage-1 EWMA/The EWMA/;
|
||||
s/Stage-1 (no costs)/gross R (no costs)/' crates/aura-cli/src/main.rs
|
||||
```
|
||||
|
||||
(`Stage-1 R harness` covers both :2445 and :2561.)
|
||||
|
||||
- [ ] **Step 3: Verify main.rs is ordinal-free**
|
||||
|
||||
Run: `git grep -icE 'stage[- ]?1|stage[- ]?2' -- crates/aura-cli/src/main.rs || echo CLEAN`
|
||||
Expected: `CLEAN` (zero matching lines; non-zero output = a missed site, fix
|
||||
it with the mapping table in the spec before proceeding)
|
||||
|
||||
- [ ] **Step 4: git mv the two regenerable fixtures**
|
||||
|
||||
```bash
|
||||
git mv crates/aura-cli/tests/fixtures/stage1_signal.json crates/aura-cli/tests/fixtures/sma_signal.json
|
||||
git mv crates/aura-cli/tests/fixtures/stage1_signal_open.json crates/aura-cli/tests/fixtures/sma_signal_open.json
|
||||
```
|
||||
|
||||
(Contents are stale — still naming `stage1_signal` inside — until Step 6
|
||||
regenerates them; the mv keeps the renamed `include_str!` paths resolving.)
|
||||
|
||||
- [ ] **Step 5: Build gate**
|
||||
|
||||
Run: `cargo build -p aura-cli`
|
||||
Expected: 0 errors (warnings about nothing; a compile error here means an
|
||||
`include_str!` path and a fixture name diverged — recheck Steps 1+4)
|
||||
|
||||
- [ ] **Step 6: Regenerate the two fixtures with the renamed composite**
|
||||
|
||||
Run: `cargo test -p aura-cli --bin aura -- --ignored emit_demo_signal`
|
||||
Expected: `test result: ok. 2 passed` (fns `emit_demo_signal_fixture` :5783,
|
||||
`emit_demo_signal_open_fixture` :5793 — they rewrite both JSONs, which now
|
||||
serialize `"sma_signal"`)
|
||||
|
||||
- [ ] **Step 7: Hand-edit the regenerator-less fixture**
|
||||
|
||||
Run: `sed -i 's/stage1_signal/sma_signal/g' crates/aura-cli/tests/fixtures/unknown_node.json`
|
||||
(unknown_node.json is hand-authored — no regenerator exists; it pins the
|
||||
unknown-node rejection, the name is incidental identity.)
|
||||
|
||||
- [ ] **Step 8: Verify fixtures are ordinal-free and regenerated**
|
||||
|
||||
Run: `grep -rc 'stage1' crates/aura-cli/tests/fixtures/ || echo CLEAN`
|
||||
Expected: `CLEAN`
|
||||
Run: `grep -l 'sma_signal' crates/aura-cli/tests/fixtures/*.json`
|
||||
Expected: all three JSONs listed
|
||||
|
||||
- [ ] **Step 9: Unit-test gate (bin target only — cli_run is Task 2's gate)**
|
||||
|
||||
Run: `cargo test -p aura-cli --bin aura`
|
||||
Expected: PASS, 0 failed (the fixture-roundtrip unit tests recompile against
|
||||
the regenerated bytes)
|
||||
|
||||
### Task 2: cli_run integration suite
|
||||
|
||||
**Files:**
|
||||
- Modify: `crates/aura-cli/tests/cli_run.rs`
|
||||
|
||||
- [ ] **Step 1: Ordered substitutions in cli_run.rs**
|
||||
|
||||
```bash
|
||||
sed -i 's/stage1_signal/sma_signal/g' crates/aura-cli/tests/cli_run.rs
|
||||
sed -i 's/stage1_r/r_sma/g;
|
||||
s/stage1_breakout/r_breakout/g;
|
||||
s/stage1_meanrev/r_meanrev/g' crates/aura-cli/tests/cli_run.rs
|
||||
sed -i 's/stage1-r/r-sma/g;
|
||||
s/stage1-breakout/r-breakout/g;
|
||||
s/stage1-meanrev/r-meanrev/g' crates/aura-cli/tests/cli_run.rs
|
||||
sed -i 's/wf-stage1r/wf-r-sma/g;
|
||||
s/mc_stage1r_boot/mc_r_sma_boot/g;
|
||||
s/mc_stage1r_block/mc_r_sma_block/g;
|
||||
s/mc_stage1r_clamp/mc_r_sma_clamp/g' crates/aura-cli/tests/cli_run.rs
|
||||
sed -i 's/stage1r/r_sma/g' crates/aura-cli/tests/cli_run.rs
|
||||
sed -i 's/Frictionless Stage-1/Frictionless gross R/' crates/aura-cli/tests/cli_run.rs
|
||||
```
|
||||
|
||||
(The 5th command converts the remaining `stage1r` in fn names — e.g.
|
||||
`generalize_refuses_a_non_stage1r_strategy` → `..._non_r_sma_strategy` — and
|
||||
must run AFTER the temp-cwd literal command. Fixture paths `stage1_signal.json`
|
||||
etc. are covered by the first command. The goldens' numeric bytes are NOT
|
||||
touched — only rename substrings inside expectation strings change, per the
|
||||
spec's byte-discipline.)
|
||||
|
||||
- [ ] **Step 2: Verify cli_run.rs is ordinal-free**
|
||||
|
||||
Run: `git grep -icE 'stage[- ]?1|stage[- ]?2' -- crates/aura-cli/tests/cli_run.rs || echo CLEAN`
|
||||
Expected: `CLEAN`
|
||||
|
||||
- [ ] **Step 3: Integration gate**
|
||||
|
||||
Run: `cargo test -p aura-cli --test cli_run`
|
||||
Expected: PASS, 0 failed. This is the load-bearing gate of the whole rename:
|
||||
selector goldens (`single_run_output_golden`), net-R cost goldens
|
||||
(`flat_cost_net_expectancy_r_golden`), dual-yardstick
|
||||
(`carries_both_pip_and_r_yardsticks`), the list-axes byte-golden (now
|
||||
`sma_signal.fast.length:I64\nsma_signal.slow.length:I64`), sweep/mc/
|
||||
walkforward/generalize families, and the fixture-loading blueprint tests all
|
||||
run the real binary end-to-end. A failure whose diff shows anything but a
|
||||
renamed token is a STOP: report, do not improvise.
|
||||
|
||||
- [ ] **Step 4: graph_construct gate (fixture consumers outside cli_run)**
|
||||
|
||||
Run: `cargo test -p aura-cli --test graph_construct`
|
||||
Expected: PASS, 0 failed (op-script vs builder content-id comparisons shift on
|
||||
BOTH sides with the composite rename, so equality assertions hold)
|
||||
|
||||
### Task 3: engine e2e files + doc-references
|
||||
|
||||
**Files:**
|
||||
- Rename: `crates/aura-engine/tests/stage1_r_e2e.rs` → `r_sma_e2e.rs`
|
||||
- Rename: `crates/aura-engine/tests/stage1_breakout_e2e.rs` → `r_breakout_e2e.rs`
|
||||
- Rename: `crates/aura-engine/tests/stage1_meanrev_e2e.rs` → `r_meanrev_e2e.rs`
|
||||
- Modify: `crates/aura-engine/tests/streaming_reduction_equivalence.rs:2`
|
||||
- Modify: `crates/aura-cli/tests/graph_construct.rs:237`
|
||||
|
||||
- [ ] **Step 1: git mv + content substitutions**
|
||||
|
||||
```bash
|
||||
git mv crates/aura-engine/tests/stage1_r_e2e.rs crates/aura-engine/tests/r_sma_e2e.rs
|
||||
git mv crates/aura-engine/tests/stage1_breakout_e2e.rs crates/aura-engine/tests/r_breakout_e2e.rs
|
||||
git mv crates/aura-engine/tests/stage1_meanrev_e2e.rs crates/aura-engine/tests/r_meanrev_e2e.rs
|
||||
sed -i 's/stage1_r/r_sma/g; s/stage1-r/r-sma/g' crates/aura-engine/tests/r_sma_e2e.rs
|
||||
sed -i 's/stage1_breakout_e2e/r_breakout_e2e/' crates/aura-engine/tests/r_meanrev_e2e.rs
|
||||
sed -i 's/stage1_r_e2e/r_sma_e2e/' crates/aura-engine/tests/streaming_reduction_equivalence.rs
|
||||
sed -i 's/stage1_signal/sma_signal/' crates/aura-cli/tests/graph_construct.rs
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Verify the five files are ordinal-free**
|
||||
|
||||
Run: `git grep -icE 'stage[- ]?1|stage[- ]?2' -- crates/aura-engine/tests/ crates/aura-cli/tests/graph_construct.rs || echo CLEAN`
|
||||
Expected: `CLEAN`
|
||||
|
||||
- [ ] **Step 3: e2e gates (one target per invocation)**
|
||||
|
||||
Run: `cargo test -p aura-engine --test r_sma_e2e`
|
||||
Expected: PASS (e.g. `clean_stop_folds_to_exactly_minus_one_r`,
|
||||
`net_r_equity_final_sample_agrees`)
|
||||
Run: `cargo test -p aura-engine --test r_breakout_e2e`
|
||||
Expected: PASS (e.g. `breakout_is_causal_and_holds_pm1_direction`)
|
||||
Run: `cargo test -p aura-engine --test r_meanrev_e2e`
|
||||
Expected: PASS (e.g. `meanrev_fades_against_the_move_and_holds_the_latch`)
|
||||
Run: `cargo test -p aura-engine --test streaming_reduction_equivalence`
|
||||
Expected: PASS
|
||||
|
||||
### Task 4: dead-ordinal prose across rustdoc, Cargo.tomls, CLAUDE.md, glossary, ledger
|
||||
|
||||
**Files:**
|
||||
- Modify: `crates/aura-std/src/sizer.rs`, `crates/aura-std/src/position_management.rs`,
|
||||
`crates/aura-analysis/src/lib.rs`, `crates/aura-composites/src/lib.rs`,
|
||||
`crates/aura-composites/tests/risk_executor.rs`, `crates/aura-cli/Cargo.toml`,
|
||||
`crates/aura-engine/Cargo.toml`, `CLAUDE.md`, `docs/glossary.md`, `docs/design/INDEX.md`
|
||||
|
||||
- [ ] **Step 1: sizer.rs — replace the module note (lines 1-8) verbatim**
|
||||
|
||||
Old (exact current bytes, lines 1-8):
|
||||
|
||||
```rust
|
||||
//! `Sizer` — the flat-1R sizing seam (C10 Stage-1). Turns a protective-stop distance
|
||||
//! into a position `size = risk_budget / stop_distance`: with `risk_budget = 1.0` this is
|
||||
//! true flat-1R (one risk unit per trade) and `size` is inversely proportional to the
|
||||
//! stop — NOT a constant. The `bias` input gates firing (a size is only meaningful when a
|
||||
//! strategy is taking a position) and is the Stage-2 seam: fixed-fractional sizing swaps
|
||||
//! `risk_budget` for `risk_fraction · equity` (an added equity input), same node shape.
|
||||
//! R is computed SIZE-INVARIANTLY downstream, so the Sizer never contaminates signal
|
||||
//! quality — it only scales the (Stage-2) currency exposure.
|
||||
```
|
||||
|
||||
New:
|
||||
|
||||
```rust
|
||||
//! `Sizer` — the flat-1R sizing seam (C10). Turns a protective-stop distance
|
||||
//! into a position `size = risk_budget / stop_distance`: with `risk_budget = 1.0` this is
|
||||
//! true flat-1R (one risk unit per trade) and `size` is inversely proportional to the
|
||||
//! stop — NOT a constant. The `bias` input gates firing (a size is only meaningful when a
|
||||
//! strategy is taking a position) and is the live/deploy-edge seam: fixed-fractional
|
||||
//! sizing swaps `risk_budget` for `risk_fraction · equity` (an added equity input), same
|
||||
//! node shape. R is computed SIZE-INVARIANTLY downstream, so the Sizer never contaminates
|
||||
//! signal quality — it only scales the (deploy-edge) currency exposure.
|
||||
```
|
||||
|
||||
- [ ] **Step 2: remaining rustdoc/comment sites — exact substitutions**
|
||||
|
||||
```bash
|
||||
sed -i 's/Optional Stage-1 R metrics block\./Optional R metrics block./;
|
||||
s/R-based signal-quality metrics (Stage-1), reduced/R-based signal-quality metrics, reduced/;
|
||||
s/stage1_r_e2e\.rs/r_sma_e2e.rs/;
|
||||
s/the Stage-1 cost = 0 invariant/the cost = 0 invariant/;
|
||||
s/(Stage-1 frictionless)/(frictionless)/;
|
||||
s/(frictionless Stage-1)/(frictionless)/' crates/aura-analysis/src/lib.rs
|
||||
sed -i 's/reusable Stage-1 composite-builders/reusable composite-builders for the feed-forward R loop/;
|
||||
s/stage1_r_graph/r_sma_graph/' crates/aura-composites/src/lib.rs
|
||||
sed -i 's/the stateful heart of Stage-1 risk-based execution/the stateful heart of feed-forward risk-based execution/;
|
||||
s/(Stage-1 feed-forward)/(feed-forward)/g;
|
||||
s/the property that keeps Stage 1/the property that keeps the research loop/' crates/aura-std/src/position_management.rs
|
||||
sed -i 's/(Stage-1, #128)/(#128)/;
|
||||
s/(Stage-1 feed-forward)/(feed-forward)/g;
|
||||
s/stage1_r_e2e\.rs/r_sma_e2e.rs/;
|
||||
s/the Stage-1 on-disk back-compat contract/the on-disk back-compat contract/;
|
||||
s/stage1-r/r-sma/g' crates/aura-composites/tests/risk_executor.rs
|
||||
sed -i 's/the Stage-1 RiskExecutor/the RiskExecutor/;
|
||||
s/stage1-r harness/r-sma harness/' crates/aura-cli/Cargo.toml
|
||||
sed -i 's/stage1_r_e2e/r_sma_e2e/' crates/aura-engine/Cargo.toml
|
||||
```
|
||||
|
||||
- [ ] **Step 3: CLAUDE.md invariant 7 — two exact replacements**
|
||||
|
||||
Old (lines 98-99):
|
||||
|
||||
```text
|
||||
instrument-agnostic yardstick — **Stage 1**: flat-1R sizing, feed-forward, no
|
||||
equity feedback, the primary research loop. **Currency P&L is Stage 2** (deploy
|
||||
```
|
||||
|
||||
New:
|
||||
|
||||
```text
|
||||
instrument-agnostic yardstick — the **research loop**: flat-1R sizing,
|
||||
feed-forward, no equity feedback. **Currency P&L is the live/deploy edge** (deploy
|
||||
```
|
||||
|
||||
Old (line 106): `` position_id, instrument_id, volume`) remains the **decoupled, derived** Stage-2 ``
|
||||
New: `` position_id, instrument_id, volume`) remains the **decoupled, derived** deploy-edge ``
|
||||
|
||||
- [ ] **Step 4: glossary — record the rename (record-reality write)**
|
||||
|
||||
Line 96, old clause: `… persist in pre-reframe code until the Stage-1 rename.`
|
||||
New: `… persisted in pre-reframe code until the r-family rename (#174).`
|
||||
|
||||
Line 252, old tail: `**"Stage-1"** now survives only as a historical cycle / identifier name for the shipped feed-forward R chain, not one half of a two-stage gate.`
|
||||
New: `**"Stage-1"** now survives only as a historical cycle name — the shipped feed-forward R chain's identifier family was renamed to the r-family (`r-sma` / `r-breakout` / `r-meanrev`, #174) — not one half of a two-stage gate.`
|
||||
|
||||
(The entry heading `### Stage 1 / Stage 2` and the rest of the entry stay: it
|
||||
IS the historical record the spec's acceptance permits.)
|
||||
|
||||
- [ ] **Step 5: ledger INDEX.md — live lines only**
|
||||
|
||||
Apply to `docs/design/INDEX.md` ONLY on the live lines
|
||||
(:740, :931, :932, :940, :943, :957, :958, :1330, :1890, :1898-1959 — every
|
||||
hit OUTSIDE the history sections :297, :617, :672-906):
|
||||
|
||||
```bash
|
||||
sed -i '907,$ s/stage1_r_sweep_family/r_sma_sweep_family/g;
|
||||
907,$ s/stage1_r_graph/r_sma_graph/g;
|
||||
907,$ s/run_stage1_r/run_r_sma/g;
|
||||
907,$ s/wrap_stage1r/wrap_r/g;
|
||||
907,$ s/stage1-r/r-sma/g;
|
||||
907,$ s/Stage-1-R scaffolding/r-sma scaffolding/;
|
||||
907,$ s/Stage-1-R run/r-sma run/;
|
||||
907,$ s/Stage-1 sweep family/r-sma sweep family/' docs/design/INDEX.md
|
||||
sed -i '700,760 s/stage1_r_graph/r_sma_graph/g' docs/design/INDEX.md
|
||||
```
|
||||
|
||||
Then verify no live hit remains: `git grep -inE '(stage[- ]?1|stage[- ]?2)' -- docs/design/INDEX.md`
|
||||
Expected: hits ONLY at lines within :297, :617, and :672-906 (the history
|
||||
sections). Any hit outside those ranges: apply the same token mapping to it.
|
||||
|
||||
- [ ] **Step 6: Build + residual gates**
|
||||
|
||||
Run: `cargo build --workspace`
|
||||
Expected: 0 errors
|
||||
Run: `git grep -icE 'stage[- ]?1|stage[- ]?2' -- crates/aura-std crates/aura-analysis crates/aura-composites crates/aura-cli/Cargo.toml crates/aura-engine/Cargo.toml CLAUDE.md || echo CLEAN`
|
||||
Expected: `CLEAN`
|
||||
|
||||
### Task 5: workspace verification + grep gate
|
||||
|
||||
**Files:** none (verification only)
|
||||
|
||||
- [ ] **Step 1: full suite**
|
||||
|
||||
Run: `cargo test --workspace`
|
||||
Expected: all targets PASS, 0 failed, 0 new ignored
|
||||
|
||||
- [ ] **Step 2: lint + docs**
|
||||
|
||||
Run: `cargo clippy --workspace --all-targets -- -D warnings`
|
||||
Expected: clean
|
||||
Run: `cargo doc --workspace --no-deps 2>&1 | tail -3`
|
||||
Expected: no warnings/errors
|
||||
|
||||
- [ ] **Step 3: the acceptance grep gate (spec §Testing strategy)**
|
||||
|
||||
Run: `git grep -inE '(stage[- ]?1|stage[- ]?2)' -- crates/ CLAUDE.md README.md`
|
||||
Expected output, exactly one line:
|
||||
`crates/aura-engine/src/harness.rs:1898:...` (the resampling-stage false positive)
|
||||
|
||||
Run: `git grep -ilE '(stage[- ]?1|stage[- ]?2)' -- docs/ ':!docs/specs' ':!docs/plans'`
|
||||
Expected: `docs/design/INDEX.md` and `docs/glossary.md` only — with INDEX.md
|
||||
hits confined to the history sections (verified in Task 4 Step 5) and
|
||||
glossary hits confined to the historical entry (:250-252 region; :96 now
|
||||
references the rename without a bare ordinal — its "r-family rename (#174)"
|
||||
wording carries no stage token).
|
||||
|
||||
- [ ] **Step 4: behavioural smoke (new vocabulary end-to-end)**
|
||||
|
||||
Run: `cargo run -q -p aura-cli -- run --harness r-sma 2>&1 | head -3`
|
||||
Expected: the normal run output (an R block; no usage error)
|
||||
Run: `cargo run -q -p aura-cli -- run --harness stage1-r; echo "exit=$?"`
|
||||
Expected: the usage line naming `<sma|macd|r-sma>` on stderr, then `exit=2`
|
||||
(old token is a usage error — no silent alias survives, per acceptance box 1;
|
||||
no pipe before the `echo`, so `$?` is the CLI's exit status, not a filter's)
|
||||
@@ -1,263 +0,0 @@
|
||||
# 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 <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, :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`).
|
||||
@@ -1,204 +0,0 @@
|
||||
# Fieldtest — milestone World/C21 (run + orchestrate harness families from blueprint-data) — 2026-07-01
|
||||
|
||||
**Status:** Draft — awaiting orchestrator triage
|
||||
**Author:** fieldtester (dispatched by fieldtest skill)
|
||||
**Binary exercised:** `target/debug/aura`, built from HEAD `4710fcc` via
|
||||
`cargo build --workspace` (build clean). All invocations are the debug binary of
|
||||
the current working tree.
|
||||
|
||||
## Scope
|
||||
|
||||
The milestone promises that the **World** constructs and orchestrates *families*
|
||||
of harnesses from serialized **blueprint-data** — not just one backtest. A
|
||||
downstream researcher takes a loaded blueprint (a serialized signal graph) and
|
||||
drives a coherent verb family over it: `graph build` (author a blueprint from a
|
||||
JSON op-script), `sweep --list-axes` (discover sweepable knobs), `sweep --axis …`
|
||||
(grid families), `mc --seeds N` (Monte-Carlo families), `walkforward --axis …`
|
||||
(IS-refit walk-forward families, the capstone #173 / cycle 0097), `runs families`
|
||||
+ `runs family <id> rank <metric>` (list + rank), and `reproduce <id>`
|
||||
(content-addressed, bit-identical re-derivation across all three family kinds
|
||||
through one shared store, C18). This fieldtest drove all of it **from the public
|
||||
surface only** — the design ledger (C24/C18/C21/C9), the glossary, the documented
|
||||
op-script grammar, and the two shipped `.json` blueprint fixtures as example data.
|
||||
No implementation source (`crates/**/*.rs`) was read. Blueprints were **authored
|
||||
as a consumer** via `aura graph build` from op-scripts, not copied from fixtures.
|
||||
|
||||
## Examples
|
||||
|
||||
### fieldtests/world-c21-milestone/w1_open_crossover.ops.json — discover → sweep → rank
|
||||
- Op-script → `aura graph build` → an **open** SMA-crossover→Bias blueprint
|
||||
(`w1_open_crossover.bp.json`); then `sweep --list-axes` to discover the axis
|
||||
names, then `sweep --axis …` with exactly those names, then `runs families` /
|
||||
`runs family <id> rank <metric>`.
|
||||
- Fits the milestone's grid-family + discovery + ranking axes; exercises the
|
||||
whole list-axes→sweep→rank composition on a consumer-authored blueprint.
|
||||
- Outcome: **built** (exit 0, canonical, no trailing newline); `--list-axes`
|
||||
named 3 open knobs; a full sweep produced a 4-member `Sweep` family; `rank`
|
||||
ordered best-first by `sqn_normalized` / `expectancy_r`; `reproduce` re-derived
|
||||
4/4 bit-identically. One friction en route (see [spec_gap] mandatory-knobs).
|
||||
|
||||
### fieldtests/world-c21-milestone/w1 (reuse) — walk-forward → reproduce (CAPSTONE)
|
||||
- `aura walkforward w1_open_crossover.bp.json --axis … --select argmax` →
|
||||
`WalkForward` family, then `aura reproduce w2_wf-0`.
|
||||
- The capstone axis (#173): IS-refit walk-forward over a loaded blueprint +
|
||||
content-addressed reproduction of the third family kind.
|
||||
- Outcome: **ran** (exit 0). 3 OOS members + a 4th
|
||||
`{"walkforward":{oos_r, param_stability, stitched_total_pips, windows:3}}`
|
||||
summary line, exactly as promised; `reproduce` re-derived 3/3 bit-identically.
|
||||
|
||||
### fieldtests/world-c21-milestone/w3_closed_crossover.ops.json — Monte-Carlo → reproduce
|
||||
- Op-script → `aura graph build` → a **closed** (fully bound) blueprint; then
|
||||
`aura mc --seeds 5`, then `aura reproduce w3_mc-0`.
|
||||
- Fits the Monte-Carlo-family + reproduce axes; needs the open/closed distinction
|
||||
inverted from sweep (mc requires a closed blueprint).
|
||||
- Outcome: **ran** (exit 0). `--list-axes` empty (fully bound); `mc` produced a
|
||||
5-member `MonteCarlo` family (seeds 1..5, window [1,60], real trades);
|
||||
`reproduce` re-derived 5/5 bit-identically.
|
||||
|
||||
### fieldtests/world-c21-milestone/w4_* — cross-verb coherence & error actionability
|
||||
- Closed→sweep, open→mc, closed→walkforward, unknown-axis, unknown-family-id,
|
||||
subset-of-open-knobs, and `run` on an open blueprint.
|
||||
- Fits the "do the verbs compose / are errors actionable" axis.
|
||||
- Outcome: mostly clean exit-2 diagnostics (see findings), **plus one panic bug**
|
||||
(`aura run` on an open blueprint).
|
||||
|
||||
## Findings
|
||||
|
||||
### [working] Consumer-authored blueprint round-trips through the whole family surface
|
||||
- Examples: w1 (sweep), w2 (walkforward), w3 (mc).
|
||||
- Authoring a blueprint from the **documented op-script grammar** (`aura graph
|
||||
build < ops.json`) was friction-free: exit 0, canonical bytes, no trailing
|
||||
newline (`tail -c` confirmed). The same authored `.bp.json` then fed `run`,
|
||||
`sweep`, `mc`, and `walkforward` unchanged. `graph introspect --vocabulary` /
|
||||
`--node SMA` give a clean author-discovery surface (ports, kinds, bind hint).
|
||||
- This is the milestone's substrate working end-to-end from a real consumer path,
|
||||
not just the shipped fixtures.
|
||||
- Recommended action: carry-on.
|
||||
|
||||
### [working] All three FamilyKinds reproduce bit-identically (the C18 core promise)
|
||||
- Examples: w1 (`Sweep` 4/4), w2 (`WalkForward` 3/3), w3 (`MonteCarlo` 5/5).
|
||||
- `aura reproduce <id>` re-derived every member of every family kind
|
||||
bit-identically (exit 0, `reproduced N/N members bit-identically`). Each member
|
||||
manifest carries the shared `topology_hash`; sweep/wf members echo their params
|
||||
in the reproduce line. This is exactly "every family kind persists AND
|
||||
reproduces through one shared content-addressed store."
|
||||
- Recommended action: carry-on.
|
||||
|
||||
### [working] list-axes → sweep composes and is self-correcting; rank orders best-first
|
||||
- Example: w1.
|
||||
- `--list-axes` printed `<name>:<kind>` per open knob, prefixed by the
|
||||
blueprint's own root name (`graph.fast.length` for my `graph`-named blueprint;
|
||||
`stage1_signal.fast.length` for the fixture). Every printed name was accepted
|
||||
verbatim by `--axis`; a fully-bound knob is absent from the list (fixture's
|
||||
`scale`) and my unbound `scale` is present — the list tracks the actual open
|
||||
set. `runs family … rank sqn_normalized|expectancy_r` ordered members best-first.
|
||||
- Note: the C24 ledger text uses the fixture-specific `stage1_signal.` prefix as
|
||||
its example; `--list-axes` makes the real prefix explicit, so the composition is
|
||||
self-correcting even though the doc example is fixture-bound.
|
||||
- Recommended action: carry-on.
|
||||
|
||||
### [bug] `aura run <open-blueprint.json>` panics instead of erroring cleanly
|
||||
- Example: w4 (`w4_run_open.err` / `.exit`).
|
||||
- Verbatim:
|
||||
```
|
||||
thread 'main' (…) panicked at crates/aura-cli/src/main.rs:3107:10:
|
||||
signal binds + wraps to a valid harness: ParamArity { expected: 3, got: 0 }
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
```
|
||||
Exit 101. The sibling verb `aura mc` on the *same* open blueprint gives a clean,
|
||||
actionable exit-2 error ("mc requires a closed blueprint … 3 free knob(s) — bind
|
||||
them or use `aura sweep --axis`"). `run` should likewise refuse an open
|
||||
(free-knob) blueprint at the dispatch boundary, not `.expect()`-panic — the
|
||||
cycle-0097 audit's own robustness claim is "a malformed blueprint is rejected at
|
||||
the dispatch boundary (exit 2, no panic)". A consumer who authors an open
|
||||
blueprint and runs `aura run` on it (a natural first move) hits a raw panic +
|
||||
backtrace note.
|
||||
- Repro: `aura run <blueprint-with-≥1-free-knob>.json` → panic (exit 101).
|
||||
- Recommended downstream action: debug (RED test: `run` on an open blueprint exits
|
||||
2 with a "requires a closed/bound blueprint" message, no panic).
|
||||
|
||||
### [bug] closed→walkforward with an axis prints the same diagnostic twice
|
||||
- Example: w4 (`w4_4c_closed_to_wf.err`).
|
||||
- `aura walkforward <closed bp> --axis graph.fast.length=2,3` emits
|
||||
`aura: UnknownKnob("graph.fast.length")` **twice** (exit 2). Exit code is
|
||||
correct and there is no panic; the diagnostic is just duplicated. Cosmetic but
|
||||
observable output defect (the sweep / mc paths emit their rejection once).
|
||||
- Repro: `aura walkforward <closed bp> --axis <any>=<v>` → two identical stderr
|
||||
lines.
|
||||
- Recommended downstream action: debug (low severity — dedupe the emit; likely a
|
||||
per-window closure re-raising the same top-level error).
|
||||
|
||||
### [friction] closed→sweep error is terse where the mc-side equivalent is exemplary
|
||||
- Example: w4 (`w4_4a_closed_to_sweep.err` vs `w4_4b_open_to_mc.err`).
|
||||
- `sweep <closed bp> --axis graph.fast.length=…` → `UnknownKnob("graph.fast.length")`.
|
||||
The knob *exists* in the blueprint but is bound out, so "UnknownKnob" is
|
||||
technically-true-but-misleading. The inverse case (`mc <open bp>`) instead says
|
||||
"mc requires a closed blueprint (no free parameters); 3 free knob(s) — bind them
|
||||
or use `aura sweep --axis`" — which names the count and the fix. The sweep side
|
||||
deserves the symmetric "this blueprint is fully bound; nothing to sweep (use
|
||||
`--list-axes`)" message.
|
||||
- Why friction (not bug): task completes with the right exit code; the surface
|
||||
just under-explains a coherent rejection.
|
||||
- Recommended downstream action: plan (tidy the sweep-side open/closed message to
|
||||
match the mc-side quality).
|
||||
|
||||
### [friction] `mc reproduce` lines omit the seed (blank member label)
|
||||
- Example: w3 (`w3_reproduce.out`).
|
||||
- MC reproduce prints `w3_mc-0 member reproduced: bit-identical` — the member
|
||||
label between "member" and "reproduced" is blank, so a consumer cannot tell
|
||||
*which seed* reproduced (sweep/walkforward show the params). The `mc` **run**
|
||||
output does carry `"seed":N`, so the information exists; only the reproduce line
|
||||
drops it.
|
||||
- Why friction: reproduction succeeds; the audit line is just less legible for the
|
||||
seed-varying family kind.
|
||||
- Recommended downstream action: plan (label MC reproduce lines with `seed=N`).
|
||||
|
||||
### [spec_gap] Every open knob is MANDATORY on `sweep`/`walkforward`, but the docs frame list-axes as a menu
|
||||
- Examples: w1 (first attempt), w4 (`w4_4f_missingknob_subset.err`).
|
||||
- `--list-axes` presented 3 open knobs; sweeping the two "obvious" ones
|
||||
(`graph.fast.length`, `graph.slow.length`) failed with
|
||||
`MissingKnob("graph.bias.scale")` (exit 2). Every open knob must be assigned ≥1
|
||||
value; there is **no default** (consistent with C19's value-empty leaf / no
|
||||
baked default — but that consequence is nowhere in the family-verb docs). The
|
||||
glossary/ledger call `--list-axes` "discover sweepable knobs" and say the names
|
||||
are "exactly what `--axis` binds" — true, but silent that they are *all
|
||||
required*. I picked the reading "supply every listed knob; pin the ones you
|
||||
don't want to vary with a single-value axis" and it worked; an equally plausible
|
||||
reading — "unspecified knobs take a default / stay at their authored value" — is
|
||||
what the engine rejects. The diagnostic is actionable (names the missing knob).
|
||||
- Recommended downstream action: ratify + tighten the docs (state that a sweep
|
||||
binds the blueprint's *entire* open param-space; a subset needs the rest bound
|
||||
out at authoring time or pinned via single-value axes). Optionally reconsider
|
||||
whether an un-swept open knob could error at *parse* time listing all missing
|
||||
knobs at once rather than one-at-a-time.
|
||||
|
||||
### [spec_gap] The whole blueprint-data verb family is undiscoverable from `--help` (no README)
|
||||
- Examples: all — first thing a consumer runs is `aura --help`.
|
||||
- `aura --help`, `aura graph --help`, `aura graph build --help`, and
|
||||
`aura graph introspect --help` **all print the identical generic usage string**,
|
||||
which lists only the hard-wired `--harness`/`--strategy` forms. None of the
|
||||
milestone verbs appear: `graph build`, `graph introspect`, `run <bp.json>`,
|
||||
`sweep <bp> --list-axes`, `sweep <bp> --axis`, `mc <bp> --seeds`,
|
||||
`walkforward <bp> --axis`. The repo has **no README**. So the entire milestone
|
||||
surface is discoverable *only* from the design ledger (a design doc, not a user
|
||||
guide) and the op-script grammar block inside C24. A downstream consumer with
|
||||
just the binary + `--help` cannot find any of it.
|
||||
- This matches the deferred #159 (CLI discoverability of `build`/`introspect`),
|
||||
but empirically it means the milestone's own surface is invisible at the CLI.
|
||||
- Recommended downstream action: plan (surface the blueprint-data verbs in
|
||||
`--help` and/or a README; tracked as #159). Until then, treat the ledger as the
|
||||
only entry point — a real gap for anyone but the author.
|
||||
|
||||
## Recommendation summary
|
||||
|
||||
| Finding | Class | Action |
|
||||
|---|---|---|
|
||||
| Consumer-authored blueprint round-trips whole family surface | working | carry-on |
|
||||
| All three FamilyKinds reproduce bit-identically | working | carry-on |
|
||||
| list-axes→sweep composes; rank best-first | working | carry-on |
|
||||
| `aura run` on open blueprint panics (exit 101) | bug | debug |
|
||||
| closed→walkforward prints diagnostic twice | bug | debug |
|
||||
| closed→sweep error terser than mc-side equivalent | friction | plan |
|
||||
| mc reproduce lines omit the seed | friction | plan |
|
||||
| every open knob mandatory on sweep, undocumented | spec_gap | ratify + tighten docs |
|
||||
| blueprint-data verbs undiscoverable from `--help` / no README | spec_gap | plan (#159) |
|
||||
Reference in New Issue
Block a user