Files
Aura/docs/specs/0038-dedup-sma-cross-test-fixtures.md
T
Brummel 47179ce5a4 spec: 0038 dedup-sma-cross-test-fixtures (boss-signed)
Collapse the three verbatim-duplicated SMA-cross harness test fixtures
(synthetic_prices, sma_cross, composite_sma_cross_harness) in aura-engine's
blueprint.rs and sweep.rs #[cfg(test)] modules into one shared crate-root
#[cfg(test)] mod test_fixtures. Behaviour-preserving, test-only.

Auto-signed under /boss: all objective gates green (precondition, self-review,
grounding-check PASS) and a unanimous five-lens spec-skeptic panel returned
SOUND.

refs #53
2026-06-14 00:04:55 +02:00

11 KiB
Raw Blame History

Dedup the SMA-cross harness test fixtures inside aura-engine — Design Spec

Date: 2026-06-13 Status: Draft — awaiting user spec review Authors: orchestrator + Claude

Goal

Collapse the verbatim-duplicated SMA-cross harness test fixtures that currently live in two separate #[cfg(test)] modules of aura-engine into a single shared, crate-local fixture module that both modules import. This is a pure, behaviour-preserving tidy: #[cfg(test)]-only, no production code change.

Closes #53 (re-scoped today three-way → two-way: cycle 0036 drifted the CLI sample off this topology, so the CLI binary is no longer a third peer; the surviving duplication is entirely inside aura-engine).

What is duplicated today

Three fixtures are defined verbatim in both crates/aura-engine/src/blueprint.rs (#[cfg(test)] mod tests) and crates/aura-engine/src/sweep.rs (#[cfg(test)] mod tests):

Fixture blueprint.rs sweep.rs Status
synthetic_prices() -> Vec<(Timestamp, Scalar)> :1520 :256 byte-identical (diff clean)
sma_cross() -> Composite :1593 :274 identical modulo whitespace
composite_sma_cross_harness() -> (Composite, Receiver, Receiver) :1614 :298 identical modulo whitespace/comments

sweep.rs:271 already documents its copies as "duplicated from blueprint.rs". No test pins the copies equal, so an edit to one silently diverges the other — the exact hazard #53 names.

Explicitly out of scope (must NOT be touched)

  • blueprint.rs:1114 sma_cross_under_root(named: bool) — a different fixture (a naming-test variant), not a verbatim copy.
  • blueprint.rs:1538 hand_wired_sma_cross_harness() — the flat hand-wired baseline the composite is compared bit-for-bit against; blueprint-local.
  • sweep.rs:335 run_point() / sweep.rs:355 sma_cross_grid() — sweep-local helpers that consume the shared fixtures but are not duplicated.
  • graph_model.rs:311 sma_cross() / :340 sample_root — a fourth, intentionally minimal copy kept small and standalone for the graph-model golden test. Leaving it independent is deliberate; do not fold it in.

Architecture

Add one new crate-local, test-only module to aura-engine:

  • crates/aura-engine/src/test_fixtures.rs, declared in lib.rs as #[cfg(test)] mod test_fixtures; — consistent with the existing #[cfg(test)] mod reexport_tests precedent at lib.rs:53.
  • The three fixtures move there unchanged, as pub(crate) free functions.
  • blueprint.rs and sweep.rs test modules delete their local copies and gain use crate::test_fixtures::*; (or named imports).

Why a crate-root #[cfg(test)] module, not "make one file canonical and import from it": the two copies live in private #[cfg(test)] mod tests submodules. A sibling module cannot import another module's private test items. A pub(crate) #[cfg(test)] module hung off the crate root is the idiomatic Rust home for fixtures shared across unit-test modules, and the crate already uses exactly this shape (reexport_tests). The C16 "engine ships no sample" constraint is untouched: a #[cfg(test)] module is never compiled into a shipped artifact.

Concrete code shapes

Delivered code — the new shared fixture module

crates/aura-engine/src/test_fixtures.rs (test-only; the three fixtures moved verbatim, made pub(crate)):

//! Shared `#[cfg(test)]` fixtures for the SMA-cross signal-quality harness,
//! consumed by the `blueprint` and `sweep` unit-test modules. Kept in one place
//! so the harness topology cannot silently diverge between them (see #53).
//! Gated test-only at the declaration site in `lib.rs`
//! (`#[cfg(test)] mod test_fixtures;`), matching the `reexport_tests` precedent.

use crate::blueprint::{BlueprintNode, Composite, Edge, OutField, Role};
use crate::harness::Target;
use aura_core::{Firing, Scalar, ScalarKind, Timestamp};
use aura_std::{Exposure, Recorder, SimBroker, Sma, Sub};
use std::sync::mpsc;

/// Seven synthetic F64 ticks driving the harness; deterministic input fixture.
pub(crate) fn synthetic_prices() -> Vec<(Timestamp, Scalar)> {
    [
        (1_i64, 1.0000_f64),
        (2, 1.0010),
        (3, 1.0030),
        (4, 1.0060),
        (5, 1.0040),
        (6, 1.0010),
        (7, 0.9990),
    ]
    .iter()
    .map(|&(t, p)| (Timestamp(t), Scalar::F64(p)))
    .collect()
}

/// The SMA-cross signal as a reusable value-empty composite: one input role
/// (price), one output (fast-minus-slow spread). Lengths injected at compile.
pub(crate) fn sma_cross() -> Composite {
    Composite::new(
        "sma_cross",
        vec![
            Sma::builder().named("fast").into(),
            Sma::builder().named("slow").into(),
            Sub::builder().into(),
        ],
        vec![
            Edge { from: 0, to: 2, slot: 0, from_field: 0 },
            Edge { from: 1, to: 2, slot: 1, from_field: 0 },
        ],
        vec![Role {
            name: "price".into(),
            targets: vec![Target { node: 0, slot: 0 }, Target { node: 1, slot: 0 }],
            source: None,
        }],
        vec![OutField { node: 2, field: 0, name: "out".into() }],
    )
}

/// The signal-quality harness as a value-empty composite blueprint with two
/// recording sinks (equity, exposure).
#[allow(clippy::type_complexity)]
pub(crate) fn composite_sma_cross_harness() -> (
    Composite,
    mpsc::Receiver<(Timestamp, Vec<Scalar>)>,
    mpsc::Receiver<(Timestamp, Vec<Scalar>)>,
) {
    let (tx_eq, rx_eq) = mpsc::channel();
    let (tx_ex, rx_ex) = mpsc::channel();
    let bp = Composite::new(
        "root",
        vec![
            BlueprintNode::Composite(sma_cross()),
            Exposure::builder().into(),
            SimBroker::builder(0.0001).into(),
            Recorder::builder(vec![ScalarKind::F64], Firing::Any, tx_eq).into(),
            Recorder::builder(vec![ScalarKind::F64], Firing::Any, tx_ex).into(),
        ],
        vec![
            Edge { from: 0, to: 1, slot: 0, from_field: 0 }, // composite out -> Exposure
            Edge { from: 1, to: 2, slot: 0, from_field: 0 }, // exposure -> broker slot 0
            Edge { from: 2, to: 3, slot: 0, from_field: 0 }, // equity -> sink
            Edge { from: 1, to: 4, slot: 0, from_field: 0 }, // exposure -> sink
        ],
        vec![Role {
            name: "src".into(),
            targets: vec![
                Target { node: 0, slot: 0 }, // price -> sma_cross role 0
                Target { node: 2, slot: 1 }, // price -> SimBroker price slot
            ],
            source: Some(ScalarKind::F64),
        }],
        vec![], // output: the root ends in sinks
    );
    (bp, rx_eq, rx_ex)
}

The exact use paths above are illustrative — the planner resolves the real import paths against the crate's actual item visibility (e.g. whether Composite/Edge/Role/Target/OutField/BlueprintNode are reached via crate::blueprint::…, crate::harness::…, or a pub use re-export). The shape — one #[cfg(test)] module, three pub(crate) fns moved verbatim — is what this spec fixes.

Before → after — the two consuming test modules

crates/aura-engine/src/blueprint.rs, #[cfg(test)] mod tests:

BEFORE:
    fn synthetic_prices() -> Vec<(Timestamp, Scalar)> { ... }   // :1520
    fn sma_cross() -> Composite { ... }                         // :1593
    fn composite_sma_cross_harness() -> (...) { ... }           // :1614
    (callers: composite_sma_cross_runs_bit_identical_to_hand_wired, etc.)

AFTER:
    use crate::test_fixtures::{synthetic_prices, sma_cross, composite_sma_cross_harness};
    // the three local fn defs deleted; callers unchanged.

crates/aura-engine/src/sweep.rs, #[cfg(test)] mod tests:

BEFORE:
    fn synthetic_prices() -> Vec<(Timestamp, Scalar)> { ... }   // :256
    fn sma_cross() -> Composite { ... }                         // :274 ("duplicated from blueprint.rs")
    fn composite_sma_cross_harness() -> (...) { ... }           // :298
    (callers: run_point, sma_cross_grid)

AFTER:
    use crate::test_fixtures::{synthetic_prices, sma_cross, composite_sma_cross_harness};
    // the three local fn defs (and the "duplicated from" doc-comment) deleted;
    // callers unchanged.

Any use import in either test module that was needed only by a moved fn becomes unused and must be removed (the surviving local helpers — hand_wired_sma_cross_harness, sma_cross_under_root, run_point, sma_cross_grid — keep their own imports). cargo clippy --workspace --all-targets -- -D warnings is the backstop: an unused import fails the lint gate, so this cannot ship un-cleaned.

Components

  • New: aura-engine/src/test_fixtures.rs — test-only module, three pub(crate) fixture fns.
  • Modified: aura-engine/src/lib.rs — add #[cfg(test)] mod test_fixtures;.
  • Modified: aura-engine/src/blueprint.rs — delete three local fixtures, import from crate::test_fixtures, drop now-unused imports.
  • Modified: aura-engine/src/sweep.rs — same, plus delete the stale "duplicated from blueprint.rs" doc-comments.

Data flow

No runtime data-flow change. The fixtures construct the same Composite blueprints and the same synthetic_prices input vector as before; the only difference is the definition site. Every existing test calls the same-named functions with the same signatures, so call sites are untouched.

Error handling

None introduced. This is a mechanical move of test-only code; there are no new runtime paths, results, or panics. Compile errors during the move (wrong import path, visibility) are caught by cargo build/cargo test; an unused import by clippy -D warnings.

Testing strategy

The dedup is its own correctness witness: there is now one definition of each fixture, so the divergence hazard is eliminated structurally rather than guarded by a pin-them-equal test (which becomes meaningless once there is a single definition). Verification is that the existing suite still passes unchanged:

  • cargo test --workspace — green, identical results. The load-bearing tests that exercise these fixtures continue to pass:
    • blueprint.rs::composite_sma_cross_runs_bit_identical_to_hand_wired (the composite-vs-hand-wired bit-identical determinism test, C1),
    • sweep.rs::sweep_equals_n_independent_runs (C11/C12 sweep equivalence).
  • cargo clippy --workspace --all-targets -- -D warnings — green (no unused imports left behind).

No new test is added; adding one would assert a property (two definitions agree) that the change deletes the premise of.

Acceptance criteria

aura declares no numbered feature-acceptance criterion; the default applies — the change removes real redundancy without contradicting a design commitment. Judged against the concrete code above:

  1. Removes measurable redundancy. Three verbatim fixtures × two sites → one shared definition. The silent-divergence hazard #53 names is gone.
  2. Behaviour-preserving. #[cfg(test)]-only; no production code, no runtime path, no public API touched. cargo test --workspace is green with identical results.
  3. Reintroduces no failure class. It strengthens the integrity of the C1 determinism and C11/C12 sweep-equivalence fixtures (they can no longer drift apart between modules). C16 is untouched — a #[cfg(test)] module ships in no artifact.
  4. The intended audience reaches for it. An engine developer editing the harness topology now edits one fixture, the natural shared-fixture shape the crate already uses (reexport_tests).