Files
Aura/README.md
T
claude 9eb6d6b4f6 docs(readme, guides, glossary, ledger), bench: the surviving surface everywhere
Slice 8, closing the #319 retirement's prose and bench debt. Bench argv
rides exec (fixed_cost single-run probe, campaign surfaces, and the seed
helper that still called the retired sweep at runtime — caught by the
bench run itself); all five fingerprints unchanged against the committed
baselines, confirming record-line parity through the retirement. Live
docs (README, authoring guide, project layout, glossary) describe only
exec + campaign documents + graph introspect --params; three glossary
entries explicitly mark their verb retired. Ledger amendments per the C29
discipline — C25's executor-verb-set re-settled (exec + the --override
residue), C14's dual grammar reduced to the one dispatch, C24's
document-built runs/families + gated-intake route list (lockstep with the
code comment), C12's override clause and identity anchor repointed to the
runner-layer hash computation, C18/C22/C27/C01 mention rewrites —
superseded sentences moved verbatim to the history sidecars (c25's
created). Stale dual-grammar doc comment on is_blueprint_file rewritten.

refs #319
2026-07-25 22:45:24 +02:00

136 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# aura
**aura is a "game engine for traders."** It is a Rust framework — and a
playground — for authoring trading strategies as composable dataflow nodes,
backtesting them deterministically and massively in parallel, validating them
(sweep / Monte-Carlo / walk-forward), and freezing a validated strategy into a
standalone bot with a broker connection. Its differentiator is the **World**: a
program that constructs and orchestrates whole *families* of backtests, not the
single run.
This README is a discoverability map of the shipped `aura` CLI — *what commands
exist and what they do*. It deliberately keeps per-flag detail light; the two
authoritative sources for exact syntax are always:
- `aura <command> --help` — the exhaustive flag grammar.
- The design ledger (`docs/design/INDEX.md`) and glossary (`docs/glossary.md`)
— the concepts and invariants behind the surface.
## Build & run
aura is a Cargo workspace. Build everything and you get one binary named `aura`:
```sh
cargo build --workspace # binary at target/debug/aura
cargo build --workspace --release # optimized, at target/release/aura
```
Invoke it as `aura <command> …` (examples below use the plain name).
## Concepts in one breath
- **Blueprint** — a serialized signal graph as data: a param-generic
`price → bias` node graph. A blueprint file (`blueprint.json`) is the unit a
downstream consumer loads and executes or varies.
- **Open vs. closed** — a blueprint with unbound (free) numeric knobs is *open*;
one with every knob bound is *closed*. A plain `exec` wants closed; naming a
knob as a campaign axis (or an `exec --override`) is what reopens it.
- **Family** — the set of runs a campaign document's process pipeline produces
over a blueprint (a sweep grid, a Monte-Carlo seed set, a walk-forward window
sequence). Families are persisted in a content-addressed store and can be
listed, ranked, and reproduced.
- **Axis** — one named, sweepable knob of a blueprint (e.g. `fast.length`),
bound with a comma-separated value list. A **gang** fuses several sibling
knobs into one axis (one value drives all members).
## Executing a document
`aura exec <target>` (#319) is the one executor verb: `<target>` is either a
loaded **blueprint** file (a single synthetic run) or a **campaign document**
(a `.json` file or its registered 64-hex content id — instruments × windows ×
strategy × param axes × process, see `docs/authoring-guide.md` §3). `graph`
renders a blueprint's structure so a mis-wire is visible before a run.
| Command | Purpose |
|---|---|
| `aura exec <bp.json>` | Run one backtest of a **closed** blueprint and print its report. An open (free-knob) blueprint is refused with a clean error — bind it, or vary it as a campaign axis. |
| `aura exec <bp.json> --override <node.param>=<value>` | Reopen one **bound** param for this single execution only (the value is recorded raw in the manifest); repeatable. |
| `aura exec <bp.json> --tap <name>=<fold>` | Subscribe a declared tap to a fold (`record`/`count`/`sum`/`mean`/`min`/`max`/`first`/`last`) for this run; repeatable. |
| `aura graph <bp.json>` | **Render** the blueprint's structure as an interactive HTML DAG so a mis-wire is visible before a run. Omit the file to render the built-in sample; a named-but-unreadable file is a usage error. |
| `aura graph introspect --params <bp.json\|id>` | **Discover** a blueprint's open, sweepable knobs. Prints each as `<name>:<kind>`, bound params trailing `default=<value>`. Run this first to learn the axis names for a campaign document. |
| `aura exec <campaign.json\|id> [--parallel-instruments <n>]` | Execute a **campaign document** — a grid family, gates, walk-forward, Monte-Carlo, and cross-instrument generalization per its process document, one cell per (strategy, instrument, window). |
| `aura runs families` | List every persisted family (id, kind, member count). |
| `aura runs family <id> [rank <metric>]` | List one family's members, optionally ranked best-first by an R metric (e.g. `sqn_normalized`, `expectancy_r`). |
| `aura reproduce <family-id>` | Re-derive every member of a persisted family from the content-addressed store and check it is bit-identical (the C18/C1 determinism guarantee). |
**Important contract — every open knob is mandatory on a campaign axis.** A
campaign document's `strategies[].axes` must name every open knob
`graph introspect --params` lists: there is no default value — pin a knob you
don't want to vary with a single-value axis (`{"kind":"I64","values":[4]}`).
Omitting one is a clean error naming the missing knob, not a silent default.
Use `aura exec --help` for the exact flag grammar, `docs/authoring-guide.md`
for the campaign document shape (data window, naming, presentation/emit).
## Authoring & introspecting topology
A blueprint is authored declaratively from a **JSON op-list**: an ordered list
of by-identifier construction ops replayed against the standard node vocabulary.
Adding a new node *type* to that vocabulary is Rust, not JSON — see
`docs/authoring-guide.md`, §0, "Authoring a new node in Rust".
| Command | Purpose |
|---|---|
| `aura graph build` | Read an op-list document on **stdin**, build the blueprint, and print its canonical JSON to **stdout** (no trailing newline — it is the content-addressed artifact). |
| `aura graph introspect --vocabulary` | List every node type available to op-lists. |
| `aura graph introspect --node <T>` | Show one type's input ports, output fields, and param paths (with the bind-value form). |
| `aura graph introspect --unwired` | Read a *partial* op-list on stdin and list its still-open interior slots. |
| `aura graph introspect --content-id` | Read an op-list on stdin and print the SHA-256 content id of the blueprint it would build. |
| `aura graph introspect --identity-id` | Read an op-list on stdin and print the SHA-256 **identity id** — the topology's debug-name-blind id, so two documents (or an op-script and a Rust-built blueprint) expressing the same topology print the same id. Combinable with `--content-id` (both ids, one per line, content id first). |
### Op-list shape
Each element is one op, tagged by `"op"`. Node params are bound with the **typed
`Scalar` form** — a tagged, capitalized-kind object: `{"I64": 5}`, `{"F64":
1.5}`, `{"Bool": true}`. A worked example (an SMA-crossover → bias signal):
```json
[
{"op":"source","role":"price","kind":"F64"},
{"op":"add","type":"SMA","name":"fast","bind":{"length":{"I64":2}}},
{"op":"add","type":"SMA","name":"slow","bind":{"length":{"I64":4}}},
{"op":"add","type":"Sub"},
{"op":"add","type":"Bias"},
{"op":"feed","role":"price","into":["fast.series","slow.series"]},
{"op":"connect","from":"fast.value","to":"sub.lhs"},
{"op":"connect","from":"slow.value","to":"sub.rhs"},
{"op":"connect","from":"sub.value","to":"bias.signal"},
{"op":"expose","from":"bias.bias","as":"bias"}
]
```
Piping this document into `aura graph build` emits a `blueprint.json` you can
then feed to `exec` above:
```sh
aura graph build < crossover.ops.json > crossover.bp.json
aura graph introspect --params crossover.bp.json
```
The op kinds are `source`, `input`, `add`, `feed`, `connect`, `expose`, `tap`,
`gang`, `doc`, and `use` (`tap` declares a recorded measurement point on an
interior wire; `doc` declares the composite's one-line meaning, required at
register — C29; `use` splices a registered blueprint in as a nested composite,
by content id or label; `add` additionally takes an `args` object for
**arg-bearing** types (`Session`, `LinComb`, `CostSum`) — structural,
non-scalar construction consumed before `bind`; see the authoring guide). See
`aura graph introspect --node <T>` for a type's exact ports and the op-script
grammar in the design ledger for the full semantics.
## Where to go deeper
- `aura <command> --help` — exhaustive, always-current flag grammar.
- `docs/design/INDEX.md` — the design ledger: architecture, invariants, the World.
- `docs/glossary.md` — canonical terminology (blueprint, family, axis, sweep /
Monte-Carlo / walk-forward, R, content-id, …).