Files
Aura/crates/aura-core/src/lib.rs
T
Brummel 77a1d26017 feat(core): the node contract — Node, schema/eval, Ctx, and a worked SMA
Cycle 0002, the second walking-skeleton slice on top of the 0001 substrate:
the interface every node forever implements (C8), proven end-to-end by a real
node with no engine present.

- `Node` (aura-core) — `schema() -> NodeSchema` declares inputs (kind +
  lookback) and the single output kind; `eval(&mut self, Ctx) -> Option<Scalar>`
  computes one cycle's output (`None` = filter / not-yet-warmed-up). `&mut self`
  so a node may keep its own derived state.
- `Ctx<'a>` (aura-core) — a `Copy` borrow-wrapper handing `eval` zero-copy,
  financial-indexed `Window`s per input (`ctx.f64_in(i)[k]`, index 0 = newest).
  A kind mismatch panics ("engine bug") — wiring guarantees the kind, so a
  mismatch can only mean the wiring layer is broken; this keeps node-author code
  clean (`w[k]`, not `w?[k]`).
- `AnyColumn::as_f64/as_i64/as_bool/as_ts` (aura-core) — the read-side mirror of
  the existing `as_*_mut`, the mechanism `Ctx` uses to get a typed window from a
  type-erased edge. Closes the read-side gap the cycle-0001 audit recorded.
- `Sma` (aura-std) — the skeleton's first real block: a producer node computing
  the moving mean of one f64 input, emitting `None` until warmed up. Authored in
  a downstream crate (proving aura-core's contract is usable across the crate
  boundary) and driven by a hand-written test that mimics exactly what the sim
  loop will later generalize: push fresh input, eval, collect.

Deliberately deferred (spec 0002 "Out of scope", recorded as decisions): the
firing policies (C6 — InputSpec carries no firing field yet), the sim loop (C4)
and freshness gating (C5), schema-level tunable params (C12/C19), and the
no-output sink refinement (C8 consumer side).

Gates green: cargo build/test (20: 18 aura-core + 2 aura-std)/clippy -D warnings
all clean; surface-purity grep (no dyn-Any / Rc / RefCell) clean.

refs walking-skeleton
2026-06-03 12:17:33 +02:00

43 lines
1.6 KiB
Rust

//! `aura-core` — the shared contract every aura component links against.
//!
//! This crate is the boundary forced by the cdylib hot-reload model: both the
//! engine and every hot-reloadable node cdylib depend on it, so it stays small
//! and stable.
//!
//! Delivered so far (cycle 0001 — the streaming substrate):
//!
//! - the four scalar base types streamed as SoA: [`Scalar`] / [`ScalarKind`] /
//! [`Timestamp`] (C7);
//! - [`Column`] — a fixed-capacity, bounded-lookback ring with financial
//! indexing (index 0 = newest) and a `run_count` freshness primitive (C5/C8),
//! read zero-copy through a [`Window`];
//! - [`AnyColumn`] — the type-erased edge over the four column kinds, with an
//! edge-time kind check ([`KindMismatch`]) (C7).
//!
//! Delivered in cycle 0002 — the node contract:
//!
//! - [`Node`] — the `schema`/`eval` contract every node implements (C8), with
//! [`NodeSchema`] / [`InputSpec`] declaring inputs (kind + lookback) and the
//! single output kind;
//! - [`Ctx`] — the per-`eval` read-side: zero-copy, financial-indexed [`Window`]
//! access into each input (closing the cycle-0001 read-side gap on
//! [`AnyColumn`]).
//!
//! Still to come (subsequent cycles): the firing policies (A: fire-on-any-fresh +
//! hold; B: all-fresh barrier), the deterministic sim loop, sources, and
//! ingestion.
mod any;
mod column;
mod ctx;
mod error;
mod node;
mod scalar;
pub use any::AnyColumn;
pub use column::{Column, Window};
pub use ctx::Ctx;
pub use error::KindMismatch;
pub use node::{InputSpec, Node, NodeSchema};
pub use scalar::{Scalar, ScalarKind, Timestamp};