9c7f60b269
The cycle's design principle enters the ledger: every closed-vocabulary entry the binary exposes carries a one-line meaning behind one shared deterministic shape gate (doc_gate) at three seams -- compile/unit for engine-shipped entries, load for native node crates, register for the content-addressed store (documents: an additive-optional gated description). Forbids the engine evaluating description text (C17 / invariant 10), any influence on execution/identity/determinism (C1), retroactive invalidation of registered artifacts, and machine-invented meaning lines. Why: the audience is headless LLM agents (#319); field evidence #314 showed schema knowledge being recovered by CAS forensics from the release binary -- the removed failure class. All spec acceptance criteria are now met across the four iterations of this cycle (core carrier + std texts; domain threading; load seam; register seam + op-script doc slot + document description). closes #316
228 lines
14 KiB
Markdown
228 lines
14 KiB
Markdown
# aura design ledger — INDEX
|
||
|
||
The ledger records the load-bearing design contracts and their rationale. Each
|
||
contract states what it **guarantees**, what it **forbids**, and **why**. A
|
||
change that breaks a contract is a design decision (amend the contract with its
|
||
new rationale), never a silent refactor.
|
||
|
||
This file is the sole addressable entry point. Each contract lives in its own
|
||
file under [`contracts/`](contracts/) as `cNN-<slug>.md`; durable artifacts
|
||
cite contracts by C-id (`C10`), which resolves here. Contracts C1–C18 were
|
||
settled in the initial design interview (2026-06-03); later contracts carry
|
||
their ratification refs inline. The `CLAUDE.md` **Domain invariants** section
|
||
is the compressed, always-loaded summary of the subset agents must never
|
||
violate; the contract files are the fuller form with rationale.
|
||
|
||
**Ledger discipline** (adopted with the 2026-07-21 refactor):
|
||
|
||
- A live contract file carries **current truth only** — present-tense design
|
||
law plus a code-anchored *Current state*. A supersession marker
|
||
(`[HISTORY]`, "superseded", "pre-reframe") appearing in a live file is
|
||
itself an audit finding: it signals a move to the history sidecar was
|
||
skipped.
|
||
- **At cycle close**, realization notes are edited **in place** in the
|
||
contract's *Current state*; text they supersede moves **verbatim** (stamps
|
||
and issue refs intact) to the contract's `cNN-<slug>.history.md` sidecar,
|
||
appended newest-last. The sidecars — not specs, plans, or git archaeology —
|
||
are the durable record of superseded design intent.
|
||
- **The audit walk** is this file plus every `contracts/cNN-*.md`. History
|
||
sidecars are read on demand (why-questions, retired-design lookups), never
|
||
as part of the per-cycle drift walk, and are never a grounding surface.
|
||
|
||
---
|
||
|
||
## Foundation — what aura is
|
||
|
||
aura is a framework **and** a playground for traders. A human and (primarily)
|
||
LLMs author trading **nodes** directly in Rust; the engine backtests them
|
||
deterministically and massively in parallel, composes them fractally, validates
|
||
them (sweep / Monte-Carlo / walk-forward), and freezes a validated strategy into
|
||
a standalone bot with a broker connection.
|
||
|
||
The predecessor RustAst (`myc`) tried this as a custom DSL and failed: too slow,
|
||
too buggy, and LLMs author far better in Rust than in an unfamiliar DSL. aura
|
||
inverts it — engine in Rust, strategies in Rust — but keeps RustAst's *concepts*
|
||
(synchronous reactive streams, bounded-lookback series, run-counting, SoA).
|
||
|
||
What sets aura apart is **not** the single backtest — every quant system does
|
||
that — but the **World**: the meta-level where harnesses are dynamically
|
||
constructed and *families* of them orchestrated and explored (walk-forward,
|
||
sweeps, Monte-Carlo, comparison). The deterministic single-harness engine is the
|
||
*substrate*; the World is the *product* (C20–C22, C24).
|
||
|
||
## External components
|
||
|
||
Two sibling projects live outside this repo. Their location is recorded here so
|
||
the repo, not session memory, is the source of truth.
|
||
|
||
- **`data-server`** — `~/dev/libs/data-server`, Gitea `Brummel/data-server`
|
||
(`http://192.168.178.103:3000/Brummel/data-server.git`). aura's **first data
|
||
source**: a standalone leaf crate that loads Pepperstone **M1/tick** binary
|
||
archives and shares them lock-free as `Arc<[T]>` chunks; records are **AoS**
|
||
with Unix-ms timestamps, transposed to aura's SoA columns and normalized to
|
||
canonical epoch-ns at the ingestion boundary (C3/C7). It enters the workspace
|
||
as a cargo git dependency at exactly the seams C28 pins: the ingestion edge
|
||
(`aura-ingest`), the assembly position (`aura-runner`), and the shell.
|
||
- **RustAst (`myc`)** — `~/dev/RustAst`, Gitea `Brummel/RustAst`. The
|
||
predecessor DSL attempt: **a conceptual reference, never a dependency** — its
|
||
DSL authoring surface and `Value`/HM-inference machinery are exactly what aura
|
||
rejects (C17). Its `src/ast/rtl/` layer served as the reference
|
||
implementation for `aura-core`'s streaming substrate; the file-by-file
|
||
reading list from the pre-authoring era is preserved in
|
||
[INDEX.history.md](INDEX.history.md).
|
||
|
||
---
|
||
|
||
## Contracts
|
||
|
||
- **[C1 — Determinism and disjoint parallelism](contracts/c01-determinism.md)** —
|
||
A backtest is a deterministic, synchronous, non-concurrent event loop — same
|
||
(inputs, seed) yields per-run bit-identical output; parallelism runs across
|
||
disjoint sims (and campaign cells), never within one.
|
||
- **[C2 — Causality / no look-ahead](contracts/c02-causality.md)** —
|
||
A node sees only the past: input windows are read-only and end at the cursor,
|
||
and a resampler emits a bar only once complete — the future is physically
|
||
absent, not merely discouraged.
|
||
- **[C3 — One merge, at ingestion only](contracts/c03-single-merge.md)** —
|
||
Heterogeneous timestamped sources are k-way-merged by timestamp into one
|
||
chronological cycle stream at the ingestion boundary (normalized to canonical
|
||
epoch-ns there); no merge or as-of join inside the graph.
|
||
- **[C4 — Cycle granularity](contracts/c04-cycle-granularity.md)** —
|
||
The clock is data-driven — one input record equals one cycle in global
|
||
timestamp order with a monotonic `cycle_id`, ties breaking by source
|
||
declaration order.
|
||
- **[C5 — Freshness-gated recompute and sample-and-hold](contracts/c05-freshness-gating.md)** —
|
||
`cycle_id` advances everywhere, but a node re-evaluates only when at least one
|
||
of its inputs is fresh this cycle; otherwise it holds its last output.
|
||
- **[C6 — Firing policy A and B, per input group](contracts/c06-firing-policy.md)** —
|
||
A node declares per input group one of two firing policies — A
|
||
(fire-on-any-fresh + hold, as-of join) or B (all-fresh barrier synchronized
|
||
on the cycle timestamp) — and may mix them freely.
|
||
- **[C7 — Four scalar base types, streamed as SoA](contracts/c07-scalar-soa.md)** —
|
||
Only `i64`/`f64`/`bool`/`timestamp` stream, as columnar SoA type-erased at the
|
||
edge (kind checked once at wiring): the hot-path carrier is the tag-free
|
||
64-bit `Cell`; the self-describing `Scalar` serves the dynamic boundaries.
|
||
- **[C8 — The node contract](contracts/c08-node-contract.md)** —
|
||
A node's static signature (typed input ports, a one-port output record of
|
||
base-scalar columns, typed param knobs) is declared once pre-build on the
|
||
value-empty recipe; the engine provides zero-copy input windows, `eval`
|
||
returns a borrowed row or `None`, and `lookbacks`/`finalize`/`label` complete
|
||
the lifecycle.
|
||
- **[C9 — Fractal, acyclic composition](contracts/c09-fractal-composition.md)** —
|
||
A composite is an authoring-level Node (typed inputs + one output port
|
||
carrying a 1..K-field record) that inlines away at compile into the flat,
|
||
acyclic `FlatGraph`; feedback only via an explicit delay node; topology
|
||
round-trips both ways as World-owned data.
|
||
- **[C10 — Bias stream; signal quality in R; cost model; money at the deploy edge](contracts/c10-bias-r-cost.md)** —
|
||
A strategy emits an unsized signed bias `f64 ∈ [-1,+1]`; a decoupled
|
||
downstream executor (stop-rule → position-management, the stop defining the
|
||
risk unit R) turns it into a managed trade in R; signal quality is measured
|
||
in R (gross → net via a composable cost-model graph, pure feed-forward, no
|
||
Sizer); money and real-broker fill live only at the live deploy edge.
|
||
- **[C11 — Generalized sources; record-then-replay](contracts/c11-sources-record-replay.md)** —
|
||
Anything nondeterministic, external, or slow is materialized into a recorded,
|
||
timestamped stream before it enters the engine; a backtest replays the
|
||
recording and never makes a live call mid-replay.
|
||
- **[C12 — The atomic sim unit and the four orchestration axes](contracts/c12-atomic-sim-unit.md)** —
|
||
The atomic unit is `(frozen topology + param-set + data-window + RNG-seed) →
|
||
deterministic run → metrics`, orchestrated by param-sweep, optimization,
|
||
walk-forward, and Monte-Carlo (= sweep over seeds) over read-only
|
||
`Arc`-shared data.
|
||
- **[C13 — Hot-reload is authoring-only; deploy is frozen](contracts/c13-hot-reload-frozen-deploy.md)** —
|
||
Research code hot-reloads as native Rust cdylibs through the two-tier
|
||
ABI-stamped `AURA_PROJECT` descriptor; the live bot is a statically-linked,
|
||
versioned, frozen artifact — never hot-swapped.
|
||
- **[C14 — Headless core, two faces](contracts/c14-headless-two-faces.md)** —
|
||
The engine is a UI-agnostic library with a primary programmatic/CLI face (a
|
||
four-way exit-code automation contract) and a visual playground face; no UI
|
||
knowledge inside the engine.
|
||
- **[C15 — Resampling-as-node; sessions/calendars](contracts/c15-resampling-sessions.md)** —
|
||
A resampler is a clock-sensitive node emitting a completed bar only at the
|
||
boundary; calendars and instrument specs are metadata beside the hot path;
|
||
session context arrives as scalar streams via a `Session` node.
|
||
- **[C16 — Engine / project separation; node reuse](contracts/c16-engine-project-split.md)** —
|
||
aura is the reusable engine each research project depends on via cargo, with
|
||
three-tier cargo-native node reuse and a two-tier project model (data-only
|
||
`Aura.toml` project, or a native node crate attached via `[nodes]`).
|
||
- **[C17 — Authoring surface](contracts/c17-authoring-surface.md)** —
|
||
All computational logic is authored in native Rust via Claude Code + the
|
||
skills pipeline; topology is serializable World-owned data; aura ships no
|
||
embedded coding-LLM.
|
||
- **[C18 — Project management and the run registry](contracts/c18-registry.md)** —
|
||
One repo = one project (git + Gitea), plus an Aura-native run registry storing
|
||
per-run manifests + metrics with content-addressed topology, re-deriving full
|
||
results on demand; lineage lives in family/campaign stores.
|
||
- **[C19 — Bootstrap: blueprint → instance](contracts/c19-bootstrap.md)** —
|
||
Construction is a distinct, recursive bootstrap phase compiling a
|
||
param-generic named blueprint into a frozen, raw-index-wired `FlatGraph`
|
||
instance by binding params + data + seed.
|
||
- **[C20 — Strategy ↔ harness](contracts/c20-strategy-harness.md)** —
|
||
A strategy is a reusable, context-free composite blueprint; the harness is
|
||
the closed root sim graph (sources + strategy + brokers + sinks under a
|
||
clock) — C1's disjoint unit, not a node.
|
||
- **[C21 — The World: the meta-level is the product](contracts/c21-world.md)** —
|
||
The World — the program that dynamically constructs and orchestrates families
|
||
of harnesses whose topology is World-owned data (C24) — is aura's product;
|
||
the single-harness engine is its substrate.
|
||
- **[C22 — The playground is a trace explorer](contracts/c22-playground-traces.md)** —
|
||
The only durable, displayable substance is the recorded trace captured by
|
||
sinks (declared taps, C27) persisted into the registry; the playground is an
|
||
execution viewer, never a persistent scene editor.
|
||
- **[C23 — Graph compilation and behaviour-preserving optimisation](contracts/c23-graph-compilation.md)** —
|
||
The bootstrap is a compilation into a flat, index-wired `FlatGraph` that is
|
||
the target of behaviour-preserving (bit-identical, C1) optimisation —
|
||
intra-graph CSE/DCE and sweep-invariant hoisting (both still deferred).
|
||
- **[C24 — The blueprint is a serializable, World-owned data value](contracts/c24-blueprint-data.md)** —
|
||
A blueprint is a first-class, canonically serialized, versioned data value
|
||
with an engine load path (data → blueprint → `FlatGraph`), referencing nodes
|
||
by compiled-in type identity and carrying topology but no node logic.
|
||
- **[C25 — The role model: nine authoring roles](contracts/c25-role-model.md)** —
|
||
aura's user-facing design is organized by nine authoring roles cut by owned
|
||
artifact + surface + iteration cost, all fillable by one actor; text-first /
|
||
headless-first is an invariant, and every control surface is a projection
|
||
over the canonical text-artifact vocabulary.
|
||
- **[C26 — Harness input binding: role names bind archive columns](contracts/c26-input-binding.md)** —
|
||
A strategy declares its data needs as root input-role names from a closed
|
||
column vocabulary, overridable per campaign without touching content
|
||
identity, resolved into one canonically-ordered open-and-declare plan.
|
||
- **[C27 — Declared taps](contracts/c27-declared-taps.md)** —
|
||
A blueprint may declare named, pure output-side taps (the twin of
|
||
`input_roles`) that compile into `FlatGraph.taps` and bind run-mode-aware to
|
||
caller-built sinks; an unbound tap is inert, not a fault.
|
||
- **[C28 — Internal stratification: ladder, process column, shell](contracts/c28-stratification.md)** —
|
||
The workspace crates realize a domain-specificity ladder (engine → market →
|
||
measurement/strategy → backtest → execution) beside a process column, an
|
||
assembly position, and an import-only shell — the import direction enforced
|
||
structurally by the full-workspace `c28_layering` guard.
|
||
- **[C29 — Self-description: every surface explains itself](contracts/c29-self-description.md)** —
|
||
Every closed-vocabulary entry carries a one-line meaning behind one shared
|
||
shape gate (`doc_gate`) at three seams — compile/unit (engine-shipped),
|
||
load (native node crates), register (the content-addressed store, incl. an
|
||
optional gated document `description`); descriptions never influence
|
||
execution or identity ids, and registered artifacts are never
|
||
retroactively invalidated.
|
||
|
||
---
|
||
|
||
## Open architectural threads
|
||
|
||
Genuinely open only; resolved threads live in the contracts that absorbed them
|
||
(pre-refactor wording in [INDEX.history.md](INDEX.history.md)).
|
||
|
||
- **Playground & World UI surface** — the visual face is a web frontend served
|
||
from disk-persisted traces (C22); shipped: per-tap chart pages, the
|
||
families-comparison view, decimation, run-context header. Open: richer
|
||
comparison meta-views (sweep-surface heatmaps, cross-family comparison,
|
||
multi-column tap selection #47), a local server, run/replay clock controls.
|
||
- **Parameter-space search strategies** (Bayesian/genetic) — pluggable policies
|
||
atop the atomic sim unit (C12), not yet designed. Search over *structure*
|
||
(graph mutation/crossover) additionally rides on topology-as-data (C24).
|
||
- **Composable orchestration** (#109 remainder) — the axes (sweep / MC /
|
||
walk-forward) as composable tools a World program wires, beyond today's
|
||
document-driven executor verbs; the campaign/process document layer (C18,
|
||
C25) is the shipped substrate.
|
||
- **`strategies/` split** — a later split, inside a project, of top-level
|
||
strategies from reusable building blocks in `nodes/`; not a day-1 cut.
|
||
|
||
> History: [INDEX.history.md](INDEX.history.md)
|