# C28 — Internal stratification: the trading ladder, the process column, the shell: history > FROZEN HISTORICAL RECORD. Each block below was true as of its cycle/date stamp > and may be superseded; this file is NOT current truth and NOT a grounding > surface. Current contract: [c28-stratification.md](c28-stratification.md). **Status (2026-07-19, milestone "Stratification — ladder, process column, shell", #286).** This contract states the *target*. At HEAD the crates cut by mechanical role (vocabulary / reductions / documents / orchestration / CLI), not cleanly by layer, so the layering is realized only partially: - The dependency *direction* now obeys the rule across the engine stack. The `aura-engine → aura-backtest` production violation is cut (phase 2, #292): `RunReport` is generic over its metric payload `M` (the engine names no concrete metric type), the pip/R reductions and the MC assembly (`summarize`, `McAggregate`/`RBootstrap`/`monte_carlo`) moved to `aura-backtest`, and the statistics kernel (`MetricStats`/`quantile`/`resample_block`/`SplitMix64`) moved to the `aura-analysis` foundation. The engine's `[dependencies]` are now `aura-core` + `aura-analysis` only; the backtest layer instantiates `M = RunMetrics` (`aura-backtest → aura-engine`, an outer→inner edge). The ladder direction is enforced for the engine/backtest/analysis rungs by the structural test (`c28_layering`, seven-row table). - **#147 retired (user-ratified direction 2026-07-20; shipped the same day).** Item 1 — the metric genericity `RunReport` — shipped as phase 2 above (#292). Item 2 — the registry deflation vocabulary — shipped as the ratified "A1" cut, its deferral trigger having fired when measurement supplied its first deflatable metric (the IC, #290): the deliberately narrow `MetricVocabulary` trait (resolve/roster/direction/value/one null draw) lives in `aura-analysis`, re-exported through `aura-engine`; the R vocabulary (`RunMetricKey`, `r_based`, the rosters, the centred moving-block `null_draw`) is supplied by `aura-backtest`; the registry's rank/optimize/deflate machinery is generic over `M: MetricVocabulary` with refusal prose derived from the carried roster; the IC (`aura-cli`) is the second production implementor, bringing its within-run permutation null. The C10 wall stays monomorphic (`check_r_metric`/`generalization` accept only the R vocabulary; `r_based` is the enforcement point). Explicitly still deferred ("A2"): measurement runs as sweep-family citizens (report unification, campaign engine generic-over-M) — until a concrete family/campaign demand exists. The #136 one-implementor rationale is superseded by the second implementor; the registry's process-column trading-awareness holds unchanged. See #147 for the full disposition. - The `aura-std` four-layer roster is now cut by layer (phase 4, #288): `aura-std` holds the engine nodes only (arithmetic/logic/rolling + the generic sinks); `aura-market` (`session`, `resample`), `aura-strategy` (`bias`/`stop_rule`/ `sizer` + the cost nodes) and `aura-backtest` (`sim_broker`, `position_management`) carry the outer rungs, each depending only on `aura-core`; the closed node roster moved to `aura-vocabulary`. The `aura-analysis` interweave is resolved (phase 5, #291): the backtest reductions live in `aura-backtest::metrics` beside their `position_management` producer, and `aura-analysis` is reduced to domain-free statistics + selection provenance (`[dependencies]` = serde only). The *measurement* rung is seeded (#295): `aura-measurement` carries the IC vocabulary + reduction (its run verb remains the additive shape dispatch, #286). No crate exists yet for *execution* (unbuilt — the C10/C13 edge only). Under this model the `aura-registry → aura-research` edge is column-internal and legal. - Phased realization (each independently shippable; behaviour byte-identical except the purely additive shape dispatch): (1) this contract; (2) cut the engine's backtest-metrics edge via `RunReport` — **done** (#292: metric-generic run record, the pip/R reductions + MC assembly relocated to `aura-backtest`, the statistics kernel to `aura-analysis`, dependency inversion, ladder enforced by the structural test; realizes item 1 of #147); (3) the #286 shape dispatch plus the per-run scaffold as a library — **done** (#295: the pure per-run scaffold pieces live in `aura-backtest::scaffold`; the composed recipe — harness assembly, binding, translators, the default `MemberRunner` — is the assembly crate `aura-runner`; the measurement rung is seeded as `aura-measurement` with the IC; the shell is reduced to argv/translation/presentation, enforced structurally. Residual: ~20 refusal sites inside `aura-runner`'s single-run verb paths still terminate the process; their conversion to `RunnerError` propagation is tracked as #297 — the campaign path already refuses via `MemberFault`, never a process exit); (4) split the `aura-std` roster along engine / market / strategy / backtest — **done** (#288: four `aura-core`-only node crates, the closed roster moved to `aura-vocabulary`, the ladder direction enforced by a structural test); (5) split `aura-analysis` into generic statistics and backtest metrics — **done** (#291: metrics moved to `aura-backtest::metrics`, `aura-analysis` reduced to the domain-free half, engine re-export surface name-unchanged); (6) generify the column's metric interface (demand-driven — this is #147). Crate names now realized (`aura-market`/`aura-strategy`/`aura-backtest`/ `aura-vocabulary`); full evidence on #288, #286 and the milestone. Provenance note (#295): the shell-boundary cut closes a ratified structural debt (this contract's own phase plan) and un-blocks the future World program; it was not a demonstrated downstream blocker — the first downstream project's observed friction was document-vocabulary gaps, never Rust-level recipe reachability.