3 Commits
Author SHA1 Message Date
Facundo MenzellaandClaude Opus 5.5 06cd8c171c other: Add trace_id to the checkpoint hit event (#7811)
* Add trace_id to the checkpoint hit event

The id is created when the checkpoint is evaluated and handed to the workflow it
starts, so the hit, the workflow's step and paywall events and the receipt's
paywall trace_id all share it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Drop Android references from trace id comments

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Remove remaining Android references in workflow event comments

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 10:43:35 +02:00
Rick 4cb71a6ad5 feat(checkpoints): Resolve the offering per workflow step (#7658)
* Treat unresolved rule variables as no match

* Read checkpoint offering from initial step

* Support untyped checkpoint workflows

* Resolve offerings per checkpoint workflow step

* Refactor workflow presentation failure state

* Unify workflow presentation error logging

* Fix workflow test lint

* Test invalid workflow offering identifiers

* Restore workflow step type fallback

* Restrict workflow error handling to supported platforms

* Report unavailable initial workflow screens

* fix(checkpoints): preserve outcomes on workflow errors

* refactor: model workflow presentation failures explicitly

* refactor: make workflow error callback optional

* fix: preserve back navigation on first workflow transition

* refactor: refine workflow presentation error handling

* Align initial workflow errors with Android

* test: guard UIKit workflow tests by platform

* refactor: split workflow offering resolution

* fix: compile workflow offering resolution
2026-09-14 15:30:26 +02:00
Facundo MenzellaandClaude Opus 5 02b4a0a850 other: echo step experiment params on workflow events (#7659)
* Parse workflow experiment enrollment from the config item combo_key

The workflows topic serves each workflow item with a combo_key that
encodes the experiment variants the user was bucketed into
(experiment_id=variant_key pairs joined by ;, or default). Parse it
into WorkflowDataResult.enrolledVariants on every read path so steps
can report experiment exposure in a follow-up. Workflows without an
experiment keep enrolledVariants nil.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Tighten combo_key parsing after review

Drop the redundant default sentinel guard (no pair parses out of it
anyway), keep the moved helpers private, pin that = inside a variant
key is kept, and trim the doc comments.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Echo the step's experiment params on workflow step events

Khepri bakes experiment_id and experiment_variant into the steps of the
enrolled variant (khepri #24946, one experiment per screen) and enrolls
the subscriber on the first step_started that echoes them. Read both
from the step's param_values and put them on every step event.

Drops the combo_key parsing from the previous commits: enrollment must
not be derived from what the config endpoint served, only from exposure.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Trim comments to the ones that carry information

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Reword the experiment param comments

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Plainer wording on the experiment param comments

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Address review: plainer param docs and wire coverage for close

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Delete isLastVariantStep from the SDK

Khepri computes it server side and never puts it in the workflow blob,
so the SDK has nothing to read or send.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Report the workflow blob ref on step events

Khepri needs the blob the client rendered to validate the experiment
params it reports, instead of trusting them. Carry the config item's
blob_ref from the workflows topic through to every step event.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Group the experiment fields and name the ref workflowBlobRef

Per the thread: the blob ref only means something as proof of an
experiment claim, so it travels with the experiment instead of riding
on every workflow event. SDK-level naming is workflowBlobRef so it
does not read as a bare config-layer concept; the wire keys stay
experiment_id, experiment_variant and blob_ref.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Drop comments that restate the code

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Require the workflow blob ref alongside the experiment params

A workflow can only be read through a blob, so a rendered step that has
experiment params always has a ref. Making it required means khepri
never receives a claim it cannot validate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Carry the blob ref through the checkpoint presentation path

Checkpoint workflows build their context through WorkflowPreview, which
left the ref nil, so a checkpoint-presented experiment step reported
nothing once the ref became required. Thread it from the resolved
workflow. Injected dashboard previews still pass none.

ResolvedCheckpointWorkflow moves to its own file, unchanged, to keep the
resolver under the file length limit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Register ResolvedCheckpointWorkflow.swift in RevenueCat.xcodeproj

The legacy project enumerates sources by hand, so a file added outside
Xcode is invisible to it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Name the request property workflowBlobRef

Matches the Android rename; wire name stays blob_ref.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 15:30:46 +02:00