@revturbine/sdk 0.11.10 → 0.11.12

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,95 @@ also require a changelog entry.
47
47
 
48
48
  ---
49
49
 
50
+ ## 0.11.12
51
+
52
+ ### `builtin_dimensions` now reaches the browser SDK from the client-context fetch (BL-0312, plan 279 TASK-5)
53
+
54
+ **What changed.** `0.11.11` (BL-0310/BL-0311) taught the shared evaluator to
55
+ stamp `rt_<dimension>` segment traits from a `builtin_dimensions` object on the
56
+ user context, but nothing yet delivered that object into `web-sdk`'s held
57
+ context. `fetchClientContext` (`GET /api/sdk/client-context`) now maps the
58
+ response's `builtin_dimensions` onto `RevTurbineUserContext.builtin_dimensions`,
59
+ overlaying per leaf the same way it overlays `plan_handle`: a leaf the server
60
+ evaluated on this fetch replaces the held value; a leaf it did not evaluate
61
+ leaves whatever the app (or a prior fetch) had set untouched. A leaf absent on
62
+ both sides stays absent — unknown is trait absence (plan 255), never a
63
+ sentinel.
64
+
65
+ The hash-skip that decides whether a fetch actually changed anything and
66
+ should re-apply (and so re-evaluate segments) now accounts for
67
+ `builtin_dimensions`. This surfaced a real gap: the shared
68
+ `computeUserContextHash` helper re-projects its input to a fixed key set
69
+ (`plan_handle`, `plan`, `usage`, `custom`, `trial`, `instances`) and silently
70
+ drops anything outside it, so simply adding `builtin_dimensions` to the object
71
+ passed to it was a no-op. `builtin_dimensions` is folded into the skip key as
72
+ a literal suffix instead — the same technique already used for the coarse
73
+ `payment_at_risk` signal, which has the identical problem.
74
+
75
+ **Landed in:** 0.11.12 (`web-sdk` only; `server-python`/`server-rust` bumped
76
+ in lockstep with no behavior change — the ports have no client-context fetch
77
+ of their own and resolve built-ins only from an app-supplied
78
+ `builtin_dimensions`, per plan 279's TASK-17 backlog note).
79
+ **Fail-closed in:** 0.11.12. Before this release, a client-context response
80
+ that changed only `builtin_dimensions` was hash-skipped and segments never
81
+ re-evaluated against the new value.
82
+ **Proving test:** `web-sdk/customer-side-client-context.test.ts`, describe
83
+ block `builtin_dimensions (plan 279 AC-4)` — server-overlays-app, an
84
+ unevaluated leaf survives, a changed value re-applies (new context object),
85
+ an unchanged value does not.
86
+
87
+ ## 0.11.11
88
+
89
+ ### Built-in segment dimensions: reserved `rt_*` segment traits (BL-0310/BL-0311, plan 279 TASK-3/TASK-4)
90
+
91
+ **What changed.** The user context gains an optional `builtin_dimensions` object with the
92
+ built-in segment dimension values: `activity_level`, `subscription_state`, `trial_type`,
93
+ `seat_type`, `buyer_role`, `email_type`, `billing_health`, `region` and `device_type`.
94
+ Targeting-state derivation (`buildTargetingState`, Python `build_targeting_state`, Rust
95
+ `build_targeting_state`) now:
96
+
97
+ - always stamps `rt_registration_state`: `registered` when the context has a non-empty
98
+ `id`, otherwise `unregistered`;
99
+ - stamps each other `rt_<dimension>` segment trait **only** from an in-vocabulary
100
+ `builtin_dimensions` value. An absent or unknown value stamps nothing, so every
101
+ built-in segment of that dimension fails closed;
102
+ - **deletes** any `rt_*` key that arrives through `custom`, `entitlements`, usage
103
+ entries or usage overrides. `rt_` is now a reserved trait-key prefix, like
104
+ `plan_handle`.
105
+
106
+ Before this release, an app trait named `rt_<anything>` reached segment evaluation. It is
107
+ now removed. Python and Rust also export the new helpers: `derive_builtin_dimension_traits`,
108
+ `is_reserved_trait_key`, `BUILTIN_DIMENSION_VOCABULARIES` and `BUILTIN_TRAIT_KEY_PREFIX`.
109
+ Contract: targeting-studio-ui.md §4.1 "Built-in segment resolution contract".
110
+
111
+ **Landed in:** 0.11.11 (all three ports, `@revt-eng/core` 0.1.359).
112
+ **Fail-closed in:** 0.11.11. A custom `rt_*` trait is dropped from the first version that
113
+ reserves the prefix.
114
+ **Proving test:** parity fixture `tests/parity/fixtures/builtin_dimension_traits.json`
115
+ (ts == py == rs) with `tests/parity/builtin-dimension-chain.test.ts`, plus
116
+ `server-python/tests/test_builtin_dimension_traits.py` and the
117
+ `user_context::builtin_dimension_tests` Rust module.
118
+
119
+ ## Unreleased (no version bump — docs and TSDoc only)
120
+
121
+ ### `RevTurbineServer` documents `apiKey` as the server key (BL-0107, plan 256 TASK-4)
122
+
123
+ **What changed.** The control plane's `POST /api/sdk/client-sessions` now accepts
124
+ the customer's **server key** (`rtk_…`, type `server`) as the minting authority;
125
+ the separate `rt_secret_` mint secret it used to require was never issuable and
126
+ is retired (revturbine-web, plan 256 TASK-2/3). `RevTurbineServer`'s TSDoc,
127
+ `server-node/README.md` and the `@revt-eng/sdk/server` example now say so: pass
128
+ the server key as `apiKey`, read from `REVTURBINE_API_KEY` (was
129
+ `REVTURBINE_SECRET_KEY`). The examples also now call
130
+ `createClientSession({ subject })` and read `client_token` — the shapes the
131
+ method has always had (the old examples passed `userId` and read `token`).
132
+
133
+ **Landed in:** no release — no signature changed; the `apiKey` option already
134
+ existed and already sent the server key as the Bearer.
135
+ **Fail-closed in:** n/a — no customer-visible behaviour changed in this package.
136
+ **Proving test:** `tests/server-node-client-sessions.test.ts` (mints via the
137
+ endpoint with the key as Bearer; the key never reaches errors or the console).
138
+
50
139
  ## 0.11.9
51
140
 
52
141
  ### The SDK can record app-owned trial revisions and evidenced account creation (BL-0237, plan 276 TASK-13)
@@ -212,10 +212,73 @@ declare const UserPlanContextSchema: z.ZodObject<{
212
212
  none: "none";
213
213
  }>>;
214
214
  }, z.core.$strip>;
215
+ /**
216
+ * Server-evaluated built-in segment dimension values for the user (plan 279
217
+ * PD-3). `buildTargetingState` stamps each present, in-vocabulary leaf onto
218
+ * the reserved `rt_<dimension>` segment trait; nothing else may set an `rt_*`
219
+ * trait (PD-1). An ABSENT leaf means "not evaluated" and stamps nothing, so
220
+ * every built-in of that dimension fails closed (PD-4, unknown is absence);
221
+ * when the control plane evaluated a dimension and found no classification it
222
+ * delivers the dimension's explicit fallback value instead.
223
+ *
224
+ * Assembled at retrieval — never persisted as a blob; the sources keep their
225
+ * own columns.
226
+ */
227
+ declare const UserBuiltinDimensionsSchema: z.ZodObject<{
228
+ activity_level: z.ZodOptional<z.ZodEnum<{
229
+ inactive: "inactive";
230
+ new: "new";
231
+ high: "high";
232
+ medium: "medium";
233
+ low: "low";
234
+ }>>;
235
+ subscription_state: z.ZodOptional<z.ZodEnum<{
236
+ trial: "trial";
237
+ none: "none";
238
+ paid: "paid";
239
+ cancelled: "cancelled";
240
+ }>>;
241
+ trial_type: z.ZodOptional<z.ZodEnum<{
242
+ none: "none";
243
+ free_trial: "free_trial";
244
+ reverse_trial: "reverse_trial";
245
+ }>>;
246
+ seat_type: z.ZodOptional<z.ZodString>;
247
+ buyer_role: z.ZodOptional<z.ZodEnum<{
248
+ buyer: "buyer";
249
+ non_buyer: "non_buyer";
250
+ }>>;
251
+ email_type: z.ZodOptional<z.ZodEnum<{
252
+ unknown: "unknown";
253
+ business: "business";
254
+ personal: "personal";
255
+ }>>;
256
+ billing_health: z.ZodOptional<z.ZodEnum<{
257
+ payment_failed: "payment_failed";
258
+ payment_method_missing: "payment_method_missing";
259
+ cancelled: "cancelled";
260
+ no_billing: "no_billing";
261
+ good_standing: "good_standing";
262
+ trial_payment_method_attached: "trial_payment_method_attached";
263
+ payment_overdue: "payment_overdue";
264
+ }>>;
265
+ region: z.ZodOptional<z.ZodEnum<{
266
+ us_canada: "us_canada";
267
+ europe: "europe";
268
+ rest_of_world: "rest_of_world";
269
+ }>>;
270
+ device_type: z.ZodOptional<z.ZodEnum<{
271
+ unknown: "unknown";
272
+ desktop: "desktop";
273
+ mobile: "mobile";
274
+ tablet: "tablet";
275
+ }>>;
276
+ }, z.core.$strip>;
215
277
 
216
278
  // AUTO-GENERATED by scripts/generate-zod-outputs.ts - do not edit.
217
279
 
218
280
 
281
+ type UserBuiltinDimensions = z.infer<typeof UserBuiltinDimensionsSchema>;
219
282
  type UserPlanContext = z.infer<typeof UserPlanContextSchema>;
220
283
  type UserUsageEntry = z.infer<typeof UserUsageEntrySchema>;
221
284
 
@@ -257,6 +320,15 @@ interface UserContextSnapshot {
257
320
  personalization?: Record<string, JsonValue>;
258
321
  /** Canonical experiment-handle to variant-handle assignments. */
259
322
  experiments?: Record<string, string>;
323
+ /**
324
+ * Built-in segment dimension values (plan 279 PD-3; targeting-studio-ui.md
325
+ * §4.1 "Built-in segment resolution contract"). The ONLY source of the
326
+ * reserved `rt_<dimension>` segment traits: `buildTargetingState` stamps
327
+ * each present, in-vocabulary value and ignores the rest. Delivered by the
328
+ * control plane's client context, or set by the app itself in `local_only`
329
+ * mode and on the server ports — a server-delivered value wins.
330
+ */
331
+ builtin_dimensions?: UserBuiltinDimensions;
260
332
  }
261
333
 
262
334
  /**