@revturbine/sdk 0.10.8 → 0.10.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -47,6 +47,53 @@ also require a changelog entry.
47
47
 
48
48
  ---
49
49
 
50
+ ## 0.10.9
51
+
52
+ ### The trial-status overlay no longer changes a number's type (BL-0155)
53
+
54
+ **What changed.** The `UserTrialStatus` → `trial_*` PlanProviderState overlay now
55
+ passes each numeric field through on every port, instead of two ports widening
56
+ it to a float. The canonical behaviour is the TS SDK's
57
+ `synthesizeProviderContext` (`web-sdk/customer-side.ts`, the `planTrialFields`
58
+ block), which spreads every `UserTrialStatus` member verbatim: an integer
59
+ `progress_percent` stays an integer on the provider state, and
60
+ `trial_days_total` is `day_number + days_remaining` in the inputs' own kind, so
61
+ `7 + 3` is `14`. The two server ports diverged from it:
62
+
63
+ | field | Python before | Rust before | all three now |
64
+ |---|---|---|---|
65
+ | `progress_percent` → `trial_progress_percent` | `float(v)` | verbatim | verbatim |
66
+ | `days_remaining` → `trial_days_remaining` | `float(v)` | verbatim | verbatim |
67
+ | `usage_consumed` → `trial_usage_consumed` | `float(v)` | verbatim | verbatim |
68
+ | `usage_limit` → `trial_usage_limit` | `float(v)` | verbatim | verbatim |
69
+ | `in_trial` → `trial_active` | `bool(v)` | verbatim | verbatim |
70
+ | derived `trial_days_total` | `float(a) + float(b)` | `f64` sum | `int + int` → `int`; any fractional half → float |
71
+
72
+ **Who this reaches.** Only a host that reads the provider state it built —
73
+ `revturbine::overlay_trial_status_on_plan_provider` on Rust, or the merged
74
+ `PlanProviderState` on Python — and cares whether it holds `70` or `70.0`
75
+ (serializing it, comparing it to an integer, or logging it). No decision
76
+ changes: every reader in the trial-gating layer widens on read, which is exactly
77
+ why the divergence survived. A non-numeric `day_number`/`days_remaining` half
78
+ now derives no total on Python instead of raising, matching Rust's existing
79
+ numeric guard.
80
+
81
+ **Landed in.** `0.10.9`.
82
+
83
+ **Fail-closed in.** `0.10.9` — there was no tolerated-old-shape window; the
84
+ representation simply changes.
85
+
86
+ **Proving test.**
87
+ `server-python/tests/test_trial_overlay_upsert.py::test_overlay_preserves_integer_numeric_representation`
88
+ and `server-rust/src/sdk.rs::overlay_preserves_integer_numeric_representation`
89
+ — both assert the *type*, not just the value, because `100 == 100.0` in Python.
90
+ The parity corpus cannot see this class of divergence (`tests/parity/normalize.*`
91
+ rule 4 collapses integral floats by design); scenario
92
+ `trial_overlay_integer_fields` locks that the three ports still decide
93
+ identically from an all-integer trial status.
94
+
95
+ ---
96
+
50
97
  ## 0.10.8
51
98
 
52
99
  ### `{{recommended_plan_name}}` and `{{plan_name}}` no longer reach end users as raw tokens (BL-0121)