audit(stage1-r): cycle-0065 close — ledger records the Stage-1 R signal-quality layer

Architect drift review of cycle 0065 (Stage-1 R: the exposure->bias rename, the
stop-rule + vol_stop, PositionManagement's dense R-record, the Sizer, summarize_r,
the public RiskExecutor, and the CLI surface): code is drift-clean - C10 fidelity
holds (bias->stop->Sizer->PositionManagement, flat-1R feed-forward, R stop-defined
and size-invariant, guarded by the cross-crate layout lockstep test), C9/C23
acyclic, the --harness selector is a compile-time match (no runtime registry/DSL,
C17). The milestone fieldtest is green after the tiny-pip tolerance fix (2ee0d74).

Lifted to the ledger (docs/design/INDEX.md):
- A C10 realization note for cycle 0065 recording the built Stage-1 R layer (the
  chain, the public RiskExecutor + StopRule axis, the CLI surface, the scale-robust
  guard, the aura-engine->aura-std normal dep) and that Stage 2
  (currency/compounding/realistic brokers) stays the deferred downstream layer.
- Amended the C10 contract's "pending Stage-1 implementation" line (it landed).

Fixed stale prose introduced by iter-3's dependency-tier change: report.rs and
position_management.rs comments cited "aura-std is only a dev-dependency" as the
rationale for the by-convention dense-record layout contract; iter-3 made it a
normal dependency, so that rationale was false. Reworded to the real,
dep-tier-independent reason - the record crosses the crate boundary as a
type-erased Scalar vector (C4 SoA), read positionally, guarded by stage1_r_e2e.rs.

Carry-on filed as follow-ons (not actioned): the exposure->bias rename tail (the
serde-stable exposure_sign_flips key + slot/param names - commented on #126, the
recommended next iteration); CLI UX friction (#131); stage1-r harness cosmetic
smells (#132); R-sweep families + rank-by-sqn (#133).

This is a drift-clean cycle-close audit, NOT a milestone-container close: the
ephemeral spec/plans stay (spec 0065's change (a) still scopes the deferred rename
tail) and the milestone close stays a deliberate act for the user.

cargo build/test --workspace green; clippy --workspace --all-targets -D warnings clean.

refs #117 #126
This commit is contained in:
2026-06-24 12:35:15 +02:00
parent 2ee0d74a8c
commit 4e6b1d9b53
3 changed files with 45 additions and 6 deletions
+39 -2
View File
@@ -558,8 +558,8 @@ history and as the **Stage-1 ancestor**: `Exposure { scale }` is the ancestor of
the unsized `bias` node, and `SimBroker`'s pip integral is the ancestor of the
R-evaluator (which additionally requires a stop, since R is stop-defined, so it
consumes a flat-1R RiskExecutor rather than raw bias). The `exposure → bias`
rename, the RiskExecutor / Sizer / Veto nodes, and the R-evaluator are **pending
Stage-1 implementation**; the position-event schema (0063, #114) survives
rename, the RiskExecutor / Sizer / Veto nodes, and the R-evaluator **landed in
cycle 0065** (Stage-1; see the realization note below); the position-event schema (0063, #114) survives
unchanged as the Stage-2 audit layer, though its derivation is now the **book**
first-difference (`deal = target book in_flight`), not the flawed 0064
exposure-integral derive (abandoned). Industry grounding for this reframe: LEAN /
@@ -604,6 +604,43 @@ construction rather than by researcher discipline. Threaded through the CLI
`aura run --real` path; the manifest broker label records the looked-up pip. The
runnable GER40 examples (already at the correct `1.0`) are routed through the same
lookup separately (#98).
**Realization (cycle 0065 — Stage-1 R signal quality, #119/#126/#127/#128/#129).**
The Stage-1 chain above is now built. `Exposure → Bias` renames the unsized strategy
output (the node + its output field); the persisted `exposure_sign_flips` metric key,
the `SimBroker` `exposure` input slot, and the `exposure_scale` manifest param keep
the old name as **serde-stable residue** — a deferred rename tail. A **stop-rule**
defines 1R: `FixedStop` (a triggered-constant primitive) and a `vol_stop(length, k)`
**composition** `k·√EMA(Δ²)` (the originally-fused node was corrected to a composition
of new `Mul`/`Sqrt` primitives — a node is a primitive only if not DAG-expressible
from others). **`PositionManagement`** (`aura-std`) is the stateful heart: it latches
the entry-cycle stop distance as the immutable R-denominator, marks against the
one-cycle-lagged fill (no look-ahead, C2), and emits a **dense 14-column per-cycle
R-record** (one row per eval, C8; the trade ledger is the `closed_this_cycle` subset,
the R-equity is `cum_realized_r + unrealized_r`, the window-end open trade is the last
`open=true` row). The **`Sizer`** (`size = risk_budget / stop_distance`, flat-1R) is
the feed-forward sizing seam, and **R is size-invariant** — scaling `risk_budget`
leaves every `realized_r` unchanged (pinned by a RED test). **`summarize_r`** is a
post-run fold (sibling of `summarize`, **not** an in-graph node) → `RMetrics` (E[R],
SQN, win-rate, profit-factor, max-R-drawdown, conviction terciles, net-of-cost). The
**RiskExecutor** ships as a public `aura-engine` composite-builder
(`risk_executor(StopRule, risk_budget)` — bias+price roles embedding
`stop-rule → Sizer → PositionManagement`, beside `vol_stop`) with a `StopRule{Fixed,Vol}`
**structural axis** (C11); the **Veto** stays a documented seam, not a runtime node (a
pass-through identity is exactly what C19/C23 DCE deletes). The layer is **operable
from the CLI**: `aura run --harness <sma|macd|stage1-r>` — a **compile-time** selector
over Rust-authored harnesses (C9/C17: the CLI *runs*, it does not wire) — folds
`summarize_r` into `RunMetrics.r` (additive; `skip_serializing_if` keeps pip-only and
legacy `runs.jsonl` JSON byte-unchanged), the `stage1-r` harness fanning one bias into
both `SimBroker` (pip) and the RiskExecutor (R) for an honest dual yardstick; an
`r_equity` tap charts the by-trade R-equity through the existing `aura chart --tap`.
The R-record redundancy `debug_assert` uses a **scale-robust relative tolerance** (an
absolute `1e-9` panicked on tiny-pip FX where the `entry stop` denominator
reconstruction loses precision; the stored `realized_r` is exact). Composites live in
`aura-engine` (the engine's convenience layer over the standard nodes, sibling of
`summarize_r`), making `aura-engine → aura-std` a normal dependency — the graph stays
acyclic. **Stage 2** (currency P&L, fixed-fractional compounding through the z⁻¹
fill-edge register, realistic brokers consuming the position-event table) remains the
deferred downstream layer, entered only after `E[R] > 0`.
### C11 — Generalized sources; record-then-replay determinism boundary
**Guarantee.** A source is anything that produces timestamped scalar streams —