Files
claude 9c7f60b269 docs(ledger): C29 self-description contract -- INDEX entry + domain invariant 13
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
2026-07-23 20:34:33 +02:00

14 KiB
Raw Permalink Blame History

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/ as cNN-<slug>.md; durable artifacts cite contracts by C-id (C10), which resolves here. Contracts C1C18 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 (C20C22, 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.

Contracts

  • C1 — Determinism and disjoint parallelism — 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 — 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 — 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 — 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-holdcycle_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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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 — 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).

  • 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