The stage1 ordinal has been dead vocabulary since the C10 reframe dropped
the two-stage research model: a 1 structurally implies a 2 that no longer
exists. The family is renamed by its live discriminator - the R yardstick -
with members named by their signal, uniform with their signal-named
siblings (sma, macd, momentum):
- selectors: stage1-r -> r-sma, stage1-breakout -> r-breakout,
stage1-meanrev -> r-meanrev (old tokens are usage errors, exit 2 - no
silent alias)
- identifiers: Strategy::RSma/RBreakout/RMeanRev, HarnessKind::RSma,
r_sma_*/r_breakout_*/r_meanrev_*, wrap_r, run_signal_r, RGrid, R_SMA_*
- persisted identity: the sma_signal composite (param prefix
sma_signal.fast.length / .slow.length; fixtures regenerated; content-ids
shift - no test pins a literal hash, the registry parses no record names)
- e2e test files git-mv'd to r_sma_e2e / r_breakout_e2e / r_meanrev_e2e
- dead Stage-1/Stage-2 prose reworded to post-C10 vocabulary across
rustdoc, Cargo.tomls, ledger live lines, and the glossary (historical
entries stay; fieldtests corpus untouched)
- CLAUDE.md invariant 7 rewritten to record the ratified C10 reframe
faithfully (the token-swap alone would have laundered the retired
gated-currency/realistic-broker design into unmarked live prose); the
unbacked account-mode clause dropped
Verification: cargo build/test --workspace green (51 targets), clippy
-D warnings clean, doc build clean, acceptance grep gate leaves exactly
the one resampling-stage false positive (harness.rs), smoke: --harness
r-sma runs, --harness stage1-r exits 2 with the new usage line.
Decision log: forks and rationale recorded on the issue (reconciliation
+ implementation-phase comments).
closes#174
Iteration 2 of cycle 0065 (Stage-1 R signal quality) — the node + metric layer.
Builds on iter-1's PositionManagement dense R-record + core summarize_r.
What ships:
- PositionManagement gains a 4th `size` input (slot 3 -> col 10), fed by the
Sizer. R is computed size-INVARIANTLY (pure stop-distance ratio), so size
never touches realized_r — pinned by a RED test (scaling size leaves every
realized_r unchanged) at the node and again end-to-end through the executor.
- Sizer (aura-std): `size = risk_budget / stop_distance` — flat-1R (risk_budget
1.0 => one risk unit per trade, size inversely proportional to the stop, not a
constant). Reads bias (firing/presence) + stop_distance; the Stage-2
fixed-fractional sizer slots in unchanged (swap risk_budget for
risk_fraction*equity, same node shape).
- summarize_r enrichment: SQN (sqrt(n)*mean_R/sample-stdev_R; n<2 or zero-variance
-> 0), conviction_terciles_r (E[R] by |bias_at_entry| tercile), net_expectancy_r
(gross minus one round-trip cost per trade, charged in R via the latched_dist
recovered from the entry_price/stop_price columns). summarize_r gains a
`round_trip_cost` param (price units). The net-of-cost recovery is tested
through the real producer->consumer seam, not just hand-built rows.
- RunMetrics.r: Option<RMetrics> with #[serde(default, skip_serializing_if =
"Option::is_none")] — legacy runs.jsonl (no `r` key) deserialise to None and a
pip-only run's on-disk shape stays byte-unchanged (C14/C18 back-compat). Every
RunMetrics literal threaded (report.rs, aura-registry, aura-engine/mc).
- RiskExecutor (aura-engine integration-test fixture, sibling of
vol_stop_composite): FixedStop -> Sizer -> PositionManagement behind open
bias+price input roles, price fanned to both the stop and PM, the Sizer's size
into PM. Bias is produced in-graph from the single price source (a second bias
*source* would k-way-merge into separate cycles and mark stale prices). The
Veto is a DOCUMENTED SEAM, not a runtime node (a pass-through identity is what
C19/C23 DCE deletes). Tests: the composite bootstraps + runs + folds to the
documented hand value; R invariant under risk_budget while the size column
scales; a live-folded RMetrics survives the RunMetrics serde round-trip.
The dense-record size column (10) is brought under the cross-crate layout guard
(stage1_r_e2e r_col_indices_match_producer_field_layout) so the executor
fixture's size-invariance read is drift-protected like the others.
Scope: the CLI/recording surface (#129) is sub-split into a separate iteration 3
and is NOT in this commit.
Verified: cargo build --workspace clean; cargo test --workspace 500 passed,
0 failed; cargo clippy --workspace --all-targets -D warnings clean.
refs #117#127#128#129