# How aura is used — engine, projects, and a day in the life This document describes the *outside* of aura: how you sit in front of it and what a research session looks like. The *inside* (the engine's contracts) is the design ledger (`docs/design/INDEX.md`). ## Engine vs. project (the game-engine split) aura is a **game engine for traders**, and like any game engine it is separate from the things built with it: - **This repo (`aura`)** is the **engine**: `aura-core` (the shared contract), `aura-std` (universal standard nodes), `aura-engine` (the deterministic sim runtime), `aura-cli` (the `aura` binary), and later the egui playground. It ships at most `examples/` fixture nodes for its own tests — never your real signals. - **A research project** is its **own external repo** (e.g. `~/dev/ger40-lab/`), with its own git history, its own Gitea repo (its own forward-queue), and a cargo dependency on aura. **It is itself a Rust crate** (a `cdylib` library of node / strategy / experiment blueprints); the `aura` host loads and runs it during research (hot-reload), and freezes a chosen strategy + broker into a standalone binary for deploy. This is where you and Claude author signals *and experiments* — all in Rust — and where the runs live. (Contracts **C16**, **C20**.) The `aura` CLI is a tool you run *inside* a project directory — it finds the project root by walking up to an `Aura.toml`, the way `cargo` finds `Cargo.toml`. A project is always a Rust program built on the engine. ## A project repo ``` ger40-lab/ # your research project — a separate Rust crate (cdylib) ├── Aura.toml # STATIC context only, paths only: the runs dir (all │ # the scaffold emits today), plus a data archive root │ # once real data enters; no logic — instrument │ # geometry is the recorded sidecar (C15), never │ # authored here ├── Cargo.toml # cdylib; depends on aura-core/aura-std (+ shared node crates); │ # carries an empty [workspace] table (see note below) ├── CLAUDE.md # the project's own skills wiring (authoring discipline) ├── .claude/dev-cycle-profile.yml ├── nodes/ # project-local node & strategy blueprints (Rust) │ └── third-candle-long/ ├── experiments/ # experiment/harness definitions (Rust): matrices, sweeps ├── runs/ # the run registry: manifest + metrics per run └── (frozen bots, …) ``` > **The empty `[workspace]` table.** A project crate is its own cargo workspace, > never a member of the engine's. This matters the moment a project lives *under* > the engine repo (common while authoring, before it moves to its own repo): > cargo otherwise walks up, finds the engine's root manifest, and refuses to > build — > > ``` > error: current package believes it's in a workspace when it's not: > ... to keep it out of the workspace, add an empty [workspace] table ... > ``` > > The fix is cargo's own hint: an empty `[workspace]` table in the project's > `Cargo.toml`. It pins the crate as a standalone workspace root and costs > nothing when the project later sits in its own repo. The `aura new` > scaffolder emits this line (cycle 0103); a hand-rolled project adds it > itself. ## Where reusable nodes live (three tiers) Everything that plugs into the engine is fractally a `Node`. Reuse is plain cargo, layered by maturity (contract C16): 1. **`aura-std`** — universal blocks shipped with the engine (SMA/ATR/RSI, resamplers, the `SessionNode`, standard combinators, broker profiles). 2. **Shared node crates** — cross-project-reusable blocks in their own repos (e.g. `Brummel/aura-nodes-fx`), pulled in as cargo git dependencies. 3. **Project-local `nodes/`** — experimental, project-specific blocks. Promotion is the ordinary Rust gradient: a node proves itself project-local → gets extracted into a shared crate → if it turns universal, into `aura-std`. Shared nodes are `rlib` dependencies; the hot-reload unit stays the project-side `cdylib` that composes them, so editing a shared node still rebuilds and reloads the dependent. ## Authoring happens in Claude Code (contract C17) aura has no built-in coding-LLM. You author by talking to Claude Code, which writes the Rust — nodes, strategies, *and experiments* — builds it, runs it, and reports back. Declarative config (`Aura.toml`) holds only static context, never logic. IONOS LLMs appear only as a *runtime data source* (e.g. a news-agent node emitting a bias), recorded before it enters a backtest, and only with your per-session consent. ## A day in the life 1. **You** (in Claude Code, inside `ger40-lab/`): "I suspect the 3rd 15m candle after GER40 open is long-biased when the first two close bullish — build it as a signal." 2. **Claude** (via the skills pipeline) writes `nodes/third-candle-long/`, implements `schema` + `eval` against `aura-core`. 3. **Backtest:** `aura backtest nodes/third-candle-long --symbol GER40 --from 2020 --to 2024` → the strategy produces a broker-independent, unsized **bias stream** (one signed, bounded `f64 ∈ [-1,+1]` per cycle — sign = direction, magnitude = optional conviction). A downstream **risk-based executor** (stop-rule → position-management, in **R**, the protective stop defining 1R) turns the bias into tracked trades, and the **R-evaluator** integrates the per-trade R-outcomes into an **R-expectancy / R-curve** — the signal's *quality*, measured account- and instrument-agnostically in **R** (E[R], SQN), not currency. Optionally compose a **cost model** — a C9 graph of cost nodes, in R (`net R = gross R − cost-in-R`) — to draw the **net-R** curve beside the gross one. The run yields an R-metrics table + a run record (manifest + metrics) under `runs/`. (Contract C10.) Money, a real broker, and a currency curve are a later **live/deploy-edge** concern (the only reliable ground truth, measured forward — never an authored historical "realistic broker"); the legacy `SimBroker` pip yardstick survives only as an optional dual readout, not the model. 4. **Sweep / Monte-Carlo / matrix — a Rust experiment.** Anything beyond a single backtest is an *experiment* in `experiments/` (Rust, builder API): a parameter sweep, Monte-Carlo over seeds, or a structural matrix like "these 10 strategies × these 3 instruments × {fixed-stop, vol-stop} risk-executors". The matrix is plain Rust loops, not a config schema (C20). `aura run experiments/compare` bootstraps the matrix, fans the disjoint sims over all cores (C1), and writes the comparable runs to `runs/`. 5. **Compose:** "combine it with `momentum-filter` as a weighted sum" → Claude writes a composite node (fractal, C9). 6. **Walk-forward:** another experiment kind (rolling in-sample optimize + out-of-sample test) → an out-of-sample verdict. 7. **Freeze:** `aura freeze nodes/strategy-y --out bots/strategy-y` → a standalone, statically-linked bot (C13); the live broker connection (e.g. cTrader Open API) is bound at this **deploy edge** — the only place account money appears, measured forward against a real venue, never an authored historical broker. 8. **Explore — `aura play`.** The playground plays *any* harness and shows what your **sinks** recorded (C22): live equity/signal streams while a run executes, and recorded traces + meta-views afterwards — stitched walk-forward equity, sweep surfaces, multi-strategy comparison. It is a trace explorer, not a scene editor (the World is a *program*; only sink-recorded data is visible — no sink, nothing to see). Topology you grow in Rust (hot-reload); runtime params you tune with sliders (C12). The real value is not step 3 (one backtest — every quant system does that) but the **World**: steps 4/6 dynamically construct and orchestrate *families* of harnesses, and the playground explores those families. The single-harness engine is the substrate; the World is the product (C20–C22). CLI command names and `Aura.toml` are illustrative; the concrete surface is designed with the relevant milestone (see the open threads in the design ledger). The forward-queue — what to try next — lives in the project's Gitea tracker, not in code (contract C18).