# C2 — Causality / no look-ahead **Guarantee.** A node sees only the past. Input history is a read-only window that ends at the current cursor; a resampler emits a bar only once it is complete. **Forbids.** Any node access to data with `timestamp > now`; emitting a partial / still-forming bar. **Why.** Look-ahead is the cardinal backtester bug — a fast backtester that leaks the future is worse than none. Making the future *physically absent* from what a node receives beats merely discouraging it. ## Current state A node's `eval` receives `Ctx::new(&inputs, ts)` (`crates/aura-engine/src/harness.rs`): the input windows are read-only slices whose head (`window[0]`) is the value pushed at or before the current `cycle_id`. The engine forwards exactly one merged record per cycle in ascending timestamp order, so a node structurally cannot reach a record with `timestamp > now` — the future is absent from what it receives, not merely off-limits. The resampler (`crates/aura-market/src/resample.rs`) emits a completed coarse bar only on bucket rollover; a still-forming bar is never emitted, and an incomplete final bucket with no following rollover tick simply never emits. The completed bar carries no timestamp of its own — it takes the rollover instant, the close instant of the bar just emitted (C4). ## See also - [C3](c03-single-merge.md) — the single ingestion merge is what makes a read-only, monotone cursor possible. - [C4](c04-cycle-granularity.md) — the data-driven cycle clock the cursor advances along. - [C5](c05-freshness-gating.md) — held (stale) values are real past values, not a look-ahead escape hatch.