From 8b20e0c560135bdc9e4bcac5e229bc26cfaf00da Mon Sep 17 00:00:00 2001 From: Anders Olsson Date: Tue, 8 Sep 2026 21:03:16 +0200 Subject: [PATCH] fix!: reject non-finite weights at ingestion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Measured, a NaN weight behaved exactly as `0.0`: weight NaN -> Ok, converged: true, 1 iteration, step (0.0, 0.0) skill pi 0.027777777777777776, tau 0.0 weight 0.0 -> Ok, same skill, bit for bit So a NaN arriving from a division or a parse was indistinguishable from a deliberate zero, and the fit reported itself as cleanly converged. Worth correcting an earlier description of this: the event does not vanish. The member contributes nothing, which is precisely what weight zero means, and that equivalence is what makes it undetectable rather than merely wrong. Zero and negative weights stay accepted. Both are expressible choices about how much a member contributes, and tests/degenerate_inputs.rs pins their behaviour deliberately; only values that are not quantities at all are rejected. A test asserts they still ingest, so the new check cannot quietly widen. This completes the boundary: every malformed input that previously produced a plausible answer — a one-team event, an empty team, a non-finite score, a non-finite weight — now fails where it enters. BREAKING CHANGE: an event carrying a non-finite weight returns `InvalidParameter` instead of silently treating that member as weightless. Refs #18 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_011hcFjNDmHXZF8URGLku5zZ --- src/history.rs | 23 +++++++++++++++++++++ tests/ingestion_shape.rs | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/history.rs b/src/history.rs index a2a4c2c..bd86277 100644 --- a/src/history.rs +++ b/src/history.rs @@ -1753,6 +1753,29 @@ impl, O: Observer, K: Eq + Hash + Clone> History