Stratification — ladder, process column, shell
All file references are at engine commit 592750b. Design-ledger contract codes (C-numbers) are glossed inline; their full texts live in docs/design/INDEX.md.
The responsibility model
The codebase divides into eight responsibilities: six ladder layers ordered by domain specificity (inner to outer), one process column standing beside the ladder, and the shell.
The ladder, inner to outer:
- engine — the domain-free deterministic streaming runtime and vocabulary: cells/kinds/freshness/firing, graph building, compilation, execution, taps/trace (the determinism/causality/composition contracts C1–C9, construction C19, compilation C23, blueprint-as-data C24); the domain-free node roster (24 arithmetic/logic/rolling nodes plus the 3 generic sink nodes
recorder/gated_recorder/series_reducer, out of the 41 node files incrates/aura-std/src/); and generic statistics (the Monte-Carlo mechanicsmonte_carlo/resample_block/MetricStatsincrates/aura-engine/src/mc.rs, the multiple-comparison hurdle math currently inaura-analysis). As a layer name, engine is wider than the crateaura-engine: the layer spansaura-core,aura-engine, the domain-free part ofaura-std, and the generic statistics. - market — what a market is, carrying no analysis or strategy intent: instruments and pip/point geometry (contract C15), session anchoring (
crates/aura-std/src/session.rs), bar resampling (resample.rs), market-data ingestion (aura-ingest). - measurement — descriptive statistics over market streams: session statistics, conditional rates, distributions. Sibling of strategy: both consume market, neither imports the other.
- strategy — the definition of trading signals: bias, stop rules, sizing, cost models (
bias.rs,stop_rule.rs,sizer.rs,longonly.rs, the five cost nodes inaura-std; the composite graphs inaura-composites). - backtest — the evaluation of strategies: simulated execution without money (
sim_broker.rs,position_management.rs), the R-metric reductions and the position-event table (aura-analysis), and the run scaffold currently welded into the CLI (wrap_r,crates/aura-cli/src/main.rs:1489-1667). Backtest mirrors execution on the research side — execution semantics in R units, money exiled. - execution — money, sizing in account terms, the live broker. Exists today only as a ratified boundary (C10/C13: account money lives only at the live deploy edge).
The process column — the research-process machinery: run records and the append-only registry (contract C18, aura-registry), the process/campaign document types (aura-research), campaign execution (aura-campaign). It consumes run artifacts, not market streams, and orchestrates runs of any ladder layer; it stands beside the ladder, not on it. Under this assignment the aura-registry → aura-research production dependency is column-internal and legal.
The shell — the CLI verbs and dispatch (aura-cli). Imports everything; imported by nothing.
Bridge to the earlier numbering: #286 (the shape-dispatch proposal — a blueprint declaring only taps runs bare, without the backtest scaffold) states the same model as five numbered layers. The mapping: layer 1 keeps the name engine, 2 trading = market, 3a = measurement, 3b splits into strategy + backtest (definition vs evaluation — the split is new), 4 = execution; the process column is new — it has no place on a five-rung ladder, which is why aura-registry/aura-research/aura-campaign resisted layer assignment.
Import rules
- Ladder: an outer layer may import inner layers, never the reverse. measurement and strategy are siblings (no import either way); backtest may import strategy.
- Column: imports the engine layer plus the run-artifact and metric interfaces; no ladder crate imports the column; column-internal edges are free.
- Shell: imports everything; nothing imports the shell.
dev-dependenciesare exempt — tests may cross layers. The existingengine→std,ingest→std,registry→stdedges are dev-only and stay.- The rules bind crate structure, not graph composition: a blueprint may feed a measurement statistic into a bias input — data flow inside a graph is free. Layers govern imports; graphs compose freely.
Verified state at HEAD
- The dependency direction already nearly obeys the rules. The only hard production violation is
aura-engine→aura-analysis(the engine layer importing backtest reductions; declared incrates/aura-engine/Cargo.toml, re-exported via the engine'sreport::), plus R-typed halves inside the engine's ownmc.rs(bias_sign_flipsatcrates/aura-engine/src/mc.rs:41,RBootstrap/r_bootstrapatmc.rs:181-213, sharing a file with the generic mechanics). - The interweaving is inside crates, not between them.
aura-stdholds four layers in one roster: engine (27 of 41 node files), market (session.rs,resample.rs), strategy (bias/stops/sizer/costs) and backtest (sim_broker.rs,position_management.rs).aura-analysisholds backtest reductions and generic hurdle math in one crate — its own header: "R-based signal-quality metrics, the broker-independent position-event table, and the multiple-comparison hurdle math". - measurement has no run verb:
dispatch_runrefuses any blueprint without abiasoutput (crates/aura-cli/src/main.rs:3589-3603) and welds the backtest scaffold onto every run. Measured cost for a measurement-shaped run: 2013 MB peak RSS over 12 years, linear in cycles; full evidence in #286.
Target crate structure
| Crate | Layer | Content |
|---|---|---|
aura-core, aura-engine |
engine | runtime unchanged; the crate aura-engine loses the report:: re-exports and the R-typed halves of mc.rs |
aura-std |
engine | reduced to the domain-free roster |
aura-stats (new) |
engine | MC mechanics from mc.rs, hurdle math from aura-analysis |
aura-market (new) |
market | session/resample from aura-std, C15 instrument geometry |
aura-ingest |
market | unchanged |
aura-measure (new) |
measurement | trace reducers; gains its run verb via the shape dispatch (#286) |
aura-strategy (new) |
strategy | bias/stops/sizer/costs from aura-std, plus aura-composites |
aura-backtest (new) |
backtest | sim_broker/position_management from aura-std, the wrap_r scaffold as a library, R metrics from aura-analysis |
aura-research, aura-registry, aura-campaign |
process column | unchanged |
aura-cli |
shell | thinned: shape dispatch instead of the inline scaffold |
Crate names are provisional. Enforcement is the crate graph itself: once crates are cut along these cells, a layer violation is a compile error and every new edge a visible Cargo.toml diff — no linter, no discipline appeals.
Interfaces
Five of the six seams are already ratified contracts; only the metric interface is new:
| Seam | What crosses it | Anchor |
|---|---|---|
| engine ↔ any vocabulary | the node contract + kinds | C8 |
| topology ↔ engine | blueprint as data; the blueprint's shape (exposes bias vs declares only taps) selects the scaffold |
C24, #286 |
| run ↔ analysis | declared taps / trace — the only way values leave a run | C27 |
| run ↔ process column | the run record, append-only | C18 |
| process column ↔ metrics | a named metric vocabulary, supplied by measurement and backtest instead of baked in R-only | new |
| everything ↔ money | the deploy edge | C10/C13 |
Phases
Each independently shippable; behaviour byte-identical except the purely additive shape dispatch:
- Ratify a ledger contract naming the layers, the column, and the import rules.
- Cut the one hard edge
aura-engine→aura-analysis: splitmc.rs(generic mechanics stay engine-side, R-typed halves move backtest-side), dissolve thereport::re-exports. - Shape dispatch plus the
wrap_rscaffold as a library — the seed ofaura-backtest; gives measurement its run verb and removes the measured 2 GB retention (#286). - Split the
aura-stdroster along engine / market / strategy+backtest — pure moves with re-exports. - Split
aura-analysisinto generic statistics and backtest metrics. - Generify the column's metric interface — demand-driven, once measurement campaigns need it (the hurdle math then applies verbatim to, e.g., a statistic swept across instruments under multiple-comparison discipline).
Open detail questions (where exactly the cost models land, whether Latch is domain-free, re-export deprecation windows) belong to the phases, not to this description.