From b99912ca5959866fad03e9eea95859f807ee79f8 Mon Sep 17 00:00:00 2001 From: Brummel Date: Wed, 3 Jun 2026 02:04:18 +0200 Subject: [PATCH] docs+scaffold: engine/project split (C16-C18), aura-std, usage doc Refine the structure per interview: aura is the reusable engine, research projects are separate external repos depending on it (C16). Add aura-std (universal standard-node tier) to the workspace; remove nodes/ from the engine (project concept). Record authoring-surface = Claude Code + skills pipeline, no embedded coding-LLM (C17), and project management = one-repo-one-project + Aura-native run registry (C18). Add CLAUDE.md invariants 9-10, code_roots -> [crates], and docs/project-layout.md documenting the day-in-the-life and project repo layout. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/dev-cycle-profile.yml | 2 +- CLAUDE.md | 11 +++++ Cargo.lock | 7 +++ Cargo.toml | 1 + crates/aura-std/Cargo.toml | 9 ++++ crates/aura-std/src/lib.rs | 17 +++++++ docs/design/INDEX.md | 59 +++++++++++++++++++++-- docs/project-layout.md | 88 +++++++++++++++++++++++++++++++++++ nodes/README.md | 15 ------ 9 files changed, 190 insertions(+), 19 deletions(-) create mode 100644 crates/aura-std/Cargo.toml create mode 100644 crates/aura-std/src/lib.rs create mode 100644 docs/project-layout.md delete mode 100644 nodes/README.md diff --git a/.claude/dev-cycle-profile.yml b/.claude/dev-cycle-profile.yml index 819d6c5..a29a3a6 100644 --- a/.claude/dev-cycle-profile.yml +++ b/.claude/dev-cycle-profile.yml @@ -5,7 +5,7 @@ paths: spec_dir: docs/specs plan_dir: docs/plans design_ledger: docs/design/INDEX.md - code_roots: [crates, nodes] + code_roots: [crates] naming: counter_dirs: [] diff --git a/CLAUDE.md b/CLAUDE.md index 736a749..0bd125e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -80,3 +80,14 @@ design decision, not a refactor, and belongs in the ledger. 8. **Deploy artifacts are frozen.** Hot-reload (cdylib) is an authoring-loop tool only. The live bot is a statically-linked, versioned, frozen artifact — never hot-swapped (audit trail: this bot = this commit). +9. **Engine / project separation.** This repo is the reusable *engine*. Research + projects are separate external repos that depend on it. Project-specific + signals live in a project's `nodes/`; cross-project-reusable nodes in shared + crates; universal blocks in `aura-std` (shipped here). Reuse is cargo-native; + the hot-reload unit is always the project-side `cdylib`. No user/project + signals in this repo (only `examples/` fixtures for the engine's own tests); + no multi-project manager or node registry inside aura. +10. **Authoring surface.** Nodes are authored in native Rust via Claude Code + + the skills pipeline. aura ships no embedded coding-LLM. IONOS LLMs are used + only as a runtime data source (news bias), with per-session consent, never + in the code path. diff --git a/Cargo.lock b/Cargo.lock index 1144ffd..d9bd6c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,3 +19,10 @@ version = "0.1.0" dependencies = [ "aura-core", ] + +[[package]] +name = "aura-std" +version = "0.1.0" +dependencies = [ + "aura-core", +] diff --git a/Cargo.toml b/Cargo.toml index a9a4806..85d2e3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ resolver = "3" members = [ "crates/aura-core", + "crates/aura-std", "crates/aura-engine", "crates/aura-cli", ] diff --git a/crates/aura-std/Cargo.toml b/crates/aura-std/Cargo.toml new file mode 100644 index 0000000..db7090f --- /dev/null +++ b/crates/aura-std/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "aura-std" +edition.workspace = true +version.workspace = true +license.workspace = true +publish.workspace = true + +[dependencies] +aura-core = { path = "../aura-core" } diff --git a/crates/aura-std/src/lib.rs b/crates/aura-std/src/lib.rs new file mode 100644 index 0000000..5739963 --- /dev/null +++ b/crates/aura-std/src/lib.rs @@ -0,0 +1,17 @@ +//! `aura-std` — the standard node library shipped with the engine. +//! +//! The universal, batteries-included building blocks every project gets for +//! free: common indicators (SMA, ATR, RSI, …), resamplers, the `SessionNode`, +//! standard combinators, and broker profiles. Depends only on `aura-core` (the +//! shared contract). +//! +//! This is the top tier of the three-tier node-reuse model (contract C16): +//! +//! - `aura-std` — universal blocks, here, ship with the engine; +//! - shared node crates — cross-project-reusable blocks, in their own repos, +//! pulled in as cargo git dependencies; +//! - project-local `nodes/` — experimental, project-specific blocks. +//! +//! Types are intentionally absent until the first spec needs them (the +//! walking-skeleton milestone). This crate documents intent; it does not yet +//! define API. diff --git a/docs/design/INDEX.md b/docs/design/INDEX.md index 65181e6..ae5f46b 100644 --- a/docs/design/INDEX.md +++ b/docs/design/INDEX.md @@ -221,6 +221,53 @@ stream model. **Why.** Keeps the line consistent — everything a signal needs arrives as a stream; reference data feeds source/session nodes from beside the hot path. +### C16 — Engine / project separation; three-tier node reuse +**Guarantee.** aura is the reusable **engine**; each research project is a +separate external repo that depends on aura via cargo (the game-engine / game +split). Node reuse is cargo-native, in three tiers: **`aura-std`** (universal +blocks, ship with the engine) / **shared node crates** (cross-project-reusable, +their own repos, pulled as cargo git deps) / **project-local `nodes/`** +(experimental, project-specific). A reusable node is an `rlib` dependency; the +hot-reload unit stays the project-side `cdylib` that composes it (consistent +with C13). +**Forbids.** Project-specific signals in the aura repo (it keeps at most +example/fixture nodes under `examples/` for its own tests); a multi-project +manager inside aura; a bespoke node registry/marketplace (cargo + Gitea *is* the +package mechanism). +**Why.** The engine/game split keeps the engine sharp and reusable while each +project versions its own research with its own forward-queue. Promotion +(local → shared → std) is the ordinary Rust reuse gradient, no new mechanism. + +### C17 — Authoring surface +**Guarantee.** Nodes are authored in native Rust through **Claude Code + the +skills pipeline**: the human describes, Claude writes the node crate, builds it, +runs it via the `aura` CLI, and reports metrics. aura ships **no embedded +coding-LLM**. IONOS LLMs are used only as a *runtime data source* (news-agent +bias, C11), gated by per-session consent, never in the code path. +**Forbids.** An in-app LLM chat that generates node code inside aura; using +IONOS (weaker models) as the authoring brain. +**Why.** LLMs author Rust well in Claude Code — that is the fix to RustAst's +failure; making weaker models the coding brain reintroduces the very problem. +Keeps aura's scope an engine + playground, not an LLM-IDE. + +### C18 — Project management: one repo = one project, plus a run registry +**Guarantee.** Management has two planes. (1) **Code & forward-queue:** git +(commit = identity; the frozen bot *is* a commit) + Gitea (ideas/hypotheses as +the forward-queue, a research thrust = a milestone, the +`idea → experimental → validated → deployed` label gradient). (2) **Experiments +& results:** an Aura-native **run registry** — one record per run = a *manifest* +(node-commit + params + data-window + seed + broker profile) + *metrics*, +queryable, with *lineage* (composite ← signals; run ← inputs). Determinism +(C1/C12) makes a run reproducible from its tiny manifest, so the registry stores +manifests + metrics and re-derives full results on demand. Depth: **structured** +(promotion/status, lineage, run-diff). +**Forbids.** Storing results not reproducible from a recorded manifest; +duplicating git/Gitea inside aura; a multi-project workspace manager. +**Why.** Comparing experiments over time is the heart of the research loop and +has no home in git/Gitea; determinism makes a structured registry cheap. +Sequencing: the walking skeleton emits a manifest + metrics per run from day +one; the registry/index is a later milestone over manifests that already exist. + --- ## Open architectural threads not yet resolved @@ -229,7 +276,13 @@ stream; reference data feeds source/session nodes from beside the hot path. (C14) makes deferring it free. - **Parameter-space search strategies** (Bayesian/genetic) — pluggable policies atop the atomic sim unit (C12), not yet designed. -- **`strategies/` split** — a later split of top-level strategies from reusable - building blocks in `nodes/`; not a day-1 cut. +- **`aura new` scaffolder + `Aura.toml` schema** — the project-config surface + (symbols in scope, default data-window, broker profile, runs dir) and the + command that scaffolds a project repo against the engine (C16/C18); not yet + designed. +- **`aura-std` contents** — the crate exists (doc-only); which universal blocks + land first follows the walking-skeleton's needs. +- **`strategies/` split** — a later split, *inside a project*, of top-level + strategies from reusable building blocks in `nodes/`; not a day-1 cut. - **Sequencing** — engine + CLI face first; walking-skeleton milestone before - hot-reload, sweep, sessions, and the visual playground. + hot-reload, sweep, sessions, the run registry, and the visual playground. diff --git a/docs/project-layout.md b/docs/project-layout.md new file mode 100644 index 0000000..22e3854 --- /dev/null +++ b/docs/project-layout.md @@ -0,0 +1,88 @@ +# 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. This is where you and Claude author signals and where + the runs live. (See contract **C16**.) + +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 repo + +``` +ger40-lab/ # your research project — a separate repo +├── Aura.toml # project config: symbols in scope, default data +│ # window, broker profile, runs dir (schema TBD) +├── Cargo.toml # depends on aura-core (+ shared node crates) +├── CLAUDE.md # the project's own skills wiring (authoring discipline) +├── .claude/dev-cycle-profile.yml +├── nodes/ # project-local, experimental nodes (cdylib) +│ └── third-candle-long/ +├── runs/ # the run registry: manifest + metrics per run +└── (frozen bots, results, …) +``` + +## 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 node crate, builds it, runs it, and reports back. 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 --broker pepperstone` → a metrics table (trades, + hit-rate, P&L, max-DD, Sharpe) + a run record (manifest + metrics) under + `runs/`. +4. **Sweep + Monte-Carlo:** `aura sweep … --grid lookback=5..50,thresh=0.5..0.9 + --mc-seeds 1000` → a distribution of metrics, best params, robustness bands. +5. **Compose:** "combine it with `momentum-filter` as a weighted sum" → Claude + writes a composite node (fractal, C9). +6. **Walk-forward:** `aura walkforward …` → an out-of-sample verdict. +7. **Freeze:** `aura freeze nodes/strategy-y --broker pepperstone + --out bots/strategy-y` → a standalone, statically-linked bot (C13). +8. **(Later) Look:** `aura play` opens the egui playground — equity curve, trade + overlays on the chart, sweep heatmaps. For *looking*, not authoring (C14). + +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). diff --git a/nodes/README.md b/nodes/README.md deleted file mode 100644 index dba8bad..0000000 --- a/nodes/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# `nodes/` - -Hot-reloadable, LLM-authored node crates (`cdylib`). Everything that plugs into -the engine is fractally a `Node`: indicators, signals, sources (e.g. news-agent -nodes that emit a recorded/live bias stream), decision nodes, broker profiles, -session nodes, resamplers, and sinks/visualizers. A composite — and ultimately a -whole strategy — is also just a `Node` that wires a sub-graph and exposes one -output. - -Each crate here links only against `aura-core` (the shared contract) and is -built with the same toolchain as the engine (Rust-ABI hot-reload). For the -deploy bot, the wired graph is frozen and statically linked — never hot-swapped. - -A later split may separate top-level `strategies/` from reusable building blocks; -for now this is the single bucket.