Pin the IC offline-join duplicate-timestamp semantics #294
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Latent: undefended duplicate-timestamp assumption in the IC offline join
information_coefficient(crates/aura-cli/src/main.rs,let sig_at: HashMap<i64, f64> = signal.iter().map(|(t, v)| (t.0, *v)).collect();) keys the signal series by epoch-ns timestamp and aligns the forward-return series to it by exact-ts match. Building the map with.collect()makes duplicate timestamps last-wins, silently — the code comments the assumption "a tap fires at most once per ts", but nothing defends or tests it.Claim (latent, not currently reachable via a shipped path): under C4 a single timestamp can carry multiple distinct cycles (same-timestamp multi-source records break by source declaration order), so a tap CAN emit more than one value at one ts. A measurement blueprint fed such a multi-source stream would produce a persisted trace with duplicate
ts[]entries, and the join would silently drop all but the last — a wrong IC, not a crash. No shipped path exercises this today: the only measurement blueprints in the tree tap a single per-bar synthetic stream (one value per ts), so this is a latent correctness gap, not an observed bug.Why it is filed, not fixed now: the correct duplicate-ts semantics for an IC join (drop, error, first-wins, or aggregate) is itself a design question that belongs with the measurement-metric path — see #147 item 2 (how measurement metrics enter the family/deflation machinery) and #290 (where the IC reduction landed). Surfaced by the #290 cycle-close audit; the recommendation was to pin this before measurement gains a second metric consumer.
When fixed: RED-first — construct a persisted trace with duplicate timestamps on the signal tap and assert the chosen (defined) semantics, rather than the current silent last-wins.
Re-anchoring after the #295 extraction:
information_coefficientand thesig_atjoin described here no longer live incrates/aura-cli/src/main.rs. They moved verbatim tocrates/aura-measurement/src/ic.rs(theHashMap<i64, f64>collect/last-wins join is now atic.rs:80, inside the function starting atic.rs:70; the doc comment atic.rs:62-69still asserts EXACT-timestamp alignment without defending the duplicate case).crates/aura-cli/src/main.rs:2132is now only a call site (function imported atmain.rs:40). The latent gap itself is untouched by the move — no duplicate-timestamp test or handling exists anywhere in the tree today.The issue's blocking reference to #147 item 2 is also stale: #147 closed on 2026-07-20 (
0651e16,2cf4574), shortly after this issue was filed. That closure answered how measurement metrics enter the family/deflation machinery (theMetricVocabularytrait), which was never actually a hard prerequisite for choosing the join's duplicate-ts semantics — the two questions are orthogonal. #147's closure does not resolve this issue.When picked up, the RED-first test and fix belong in
crates/aura-measurement/src/ic.rs, notaura-cli.