Skip to content

[P2] trimpToStrain diverges for denominator at the logarithm boundary #36

Open

Description

@bhelm

Summary

Swift and Kotlin return materially different results when trimpToStrain receives a positive TRIMP with denominator == 1.

This was found by the Strain differential rollout tracked in #17.

Minimal reproduction

trimp = 1.0
denominator = 1.0

Observed behavior

Platform Result
Swift +Inf
Kotlin 9.223372036854776E16 (bits 43747ae147ae147b)

The Swift parity runner rejects the non-finite result. Kotlin succeeds with a very large finite value.

Likely cause

Neither implementation validates the denominator before evaluating the logarithmic formula. The intermediate result becomes infinite at this boundary:

  • Swift preserves +Inf.
  • Kotlin applies roundToLong(), which saturates before division by 100.

The normal default denominator (7201) is unaffected.

Impact

A public non-default calibration parameter can produce either a rejected non-finite result or an extreme finite strain value depending on platform.

Severity: P2.

Acceptance criteria

  • Define the valid denominator domain consistently on both platforms.
  • Invalid boundary inputs fail or normalize identically.
  • Add mirrored deterministic Swift and Kotlin regression tests for 1, values below 1, and a valid denominator.
  • Re-run the Strain differential corpus.

No hardware testing is required; this is pure analytics behavior.

Activity

  1. bhelm commented on Sep 7, 2026

    @bhelm
    OwnerAuthor

    PR opened upstream: ryanbr#1977 — it rejects D <= 1 (and NaN) as out of domain on both platforms
    and moves the Kotlin rounding into the Double domain, so the two implementations agree across the
    whole input space; the default denominator is unaffected, so no shipped Effort number moves.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions