Commit Graph

2 Commits

Author SHA1 Message Date
Brummel 521a16e56f docs(aura-std): document Add/LinComb firing policy + multi-row-per-ts shape
Resolves the two spec_gaps from the cycle-0008 fieldtest
(docs/specs/fieldtest-0008-sum-combinators.md), the same class the 0007 fieldtest
raised for SimBroker (and which e9f4352 patched there) — the combinators shipped
without the equivalent note:

  - per-input firing policy: both Add and every LinComb leg are Firing::Any
    (mode-A as-of join) — the node fires on every cycle in which any leg is
    fresh, once all legs have a value, pairing the fresh leg with the held value
    of the others; None until all present (no cold-leg-as-0.0). A consumer
    combining different-rate sources (e.g. an M5 signal with a daily-bias leg)
    needs this to predict whether the bias is held-and-combined every cycle
    (mode A, what ships) or only on rare both-fresh cycles (mode B).
  - multi-row-per-timestamp: a fired node emits one row per *cycle*, and two
    sources sharing a timestamp are two distinct cycles (C4 tie-break by source
    order), so a recorded combined stream may carry >1 row per timestamp. Correct
    and forced by C4/C5; ratified here, now stated on the surface so "one row per
    timestamp" is not silently assumed.

Doc-only change; no behaviour change. Verified: RUSTDOCFLAGS="-D warnings" cargo
doc -p aura-std clean (intra-doc links to aura_core::Firing::Any resolve); clippy
--all-targets -D warnings clean; cargo test -p aura-std 14 passed.

refs #11
2026-06-04 18:23:04 +02:00
Brummel 84130c2cab feat(aura-std): Add + LinComb sum combinators
aura-std shipped Sma, Sub, Exposure, SimBroker but no sum, so the north-star
"combine one signal with another" research move (C10) could not be expressed
from shipped blocks — the cycle-0007 fieldtest had to hand-author a project-local
Add2. This adds the missing combinator(s):

- Add — two-input f64 sum (a + b), the parameterless companion to Sub. Mirrors
  sub.rs modulo the operator.
- LinComb { weights } — N-input weighted sum (Σ wᵢ·xᵢ). The weights are the
  node's tunable parameters (C8/C12) and fix its arity (weights.len() inputs);
  this is the form the north-star "combine A and B *with weights*" reaches for.
  LinComb([1,1]) is Add; LinComb([1,-1]) is Sub.

Both withhold output (None) until *all* inputs are present — consistent with Sub,
and causally clean: a cold input leg is never silently folded in as 0.0.
LinComb::new panics on empty weights (build-time param error, like Sma::new).

Both ship because each is independently reached-for: Add for readability symmetry
with Sub, LinComb for the weighted/tunable combination — mirroring the project's
already-shipped choice to keep Sub as a named node beside a general form.

Hand-driven unit tests in the established aura-std style (5 new): Add sum, the
Add == LinComb([1,1]) identity, the N>2 warm-up, and the empty-weights panic.
Verified: cargo test -p aura-std (14 passed), clippy --all-targets -D warnings
clean, RUSTDOCFLAGS="-D warnings" cargo doc -p aura-std --no-deps clean.

closes #11
2026-06-04 18:10:16 +02:00