Repository navigation
chore!: mark off-main public callbacks @Sendable for v4 - #914
Merged
turnipdabeets merged 4 commits intoOct 7, 2026
Merged
Conversation
Contributor
posthog-ios Compliance ReportDate: 2026-10-07 02:18:33 UTC
|
| Test | Status | Duration |
|---|---|---|
| Format Validation.Event Has Required Fields | ✅ | 2895ms |
| Format Validation.Event Has Uuid | ✅ | 2678ms |
| Format Validation.Event Has Lib Properties | ✅ | 325ms |
| Format Validation.Distinct Id Is String | ✅ | 2819ms |
| Format Validation.Token Is Present | ✅ | 573ms |
| Format Validation.Custom Properties Preserved | ✅ | 2949ms |
| Format Validation.Event Has Timestamp | ✅ | 2834ms |
| Retry Behavior.Retries On 503 | ✅ | 11799ms |
| Retry Behavior.Does Not Retry On 400 | ✅ | 4734ms |
| Retry Behavior.Does Not Retry On 401 | ✅ | 4760ms |
| Retry Behavior.Respects Retry After Header | ✅ | 7757ms |
| Retry Behavior.Implements Backoff | ✅ | 21802ms |
| Retry Behavior.Retries On 500 | ✅ | 5279ms |
| Retry Behavior.Retries On 502 | ✅ | 5443ms |
| Retry Behavior.Retries On 504 | ✅ | 5457ms |
| Retry Behavior.Max Retries Respected | ❌ | 21845ms |
| Deduplication.Generates Unique Uuids | ✅ | 3152ms |
| Deduplication.Preserves Uuid On Retry | ✅ | 9322ms |
| Deduplication.Preserves Uuid And Timestamp On Retry | ✅ | 10431ms |
| Deduplication.Preserves Uuid And Timestamp On Batch Retry | ✅ | 7992ms |
| Deduplication.No Duplicate Events In Batch | ✅ | 2894ms |
| Deduplication.Different Events Have Different Uuids | ✅ | 2821ms |
| Compression.Sends Gzip When Enabled | ✅ | 2781ms |
| Batch Format.Uses Proper Batch Structure | ✅ | 2701ms |
| Batch Format.Flush With No Events Sends Nothing | ✅ | 312ms |
| Batch Format.Multiple Events Batched Together | ✅ | 2985ms |
| Error Handling.Does Not Retry On 403 | ✅ | 4810ms |
| Error Handling.Does Not Retry On 413 | ✅ | 4809ms |
| Error Handling.Retries On 408 | ✅ | 9325ms |
Failures
retry_behavior.max_retries_respected
Expected 4 requests, got 6
Feature_Flags Tests
✅ 16/16 tests passed
View Details
| Test | Status | Duration |
|---|---|---|
| Request Payload.Request With Person Properties Device Id | ✅ | 2888ms |
| Request Payload.Flags Request Uses V2 Query Param | ✅ | 3075ms |
| Request Payload.Flags Request Hits Flags Path Not Decide | ✅ | 2934ms |
| Request Payload.Flags Request Omits Authorization Header | ✅ | 2795ms |
| Request Payload.Token In Flags Body Matches Init | ✅ | 2736ms |
| Request Payload.Groups Round Trip | ✅ | 2854ms |
| Request Payload.Groups Default To Empty Object | ✅ | 2788ms |
| Request Payload.Person Properties Distinct Id Auto Populated When Caller Omits It | ✅ | 2808ms |
| Request Payload.Disable Geoip False Propagates As Geoip Disable False | ✅ | 2842ms |
| Request Payload.Disable Geoip Omitted Defaults To False | ✅ | 2830ms |
| Request Payload.Flag Keys To Evaluate Contains Only Requested Key | ✅ | 2749ms |
| Request Lifecycle.No Flags Request On Init Alone | ✅ | 57ms |
| Request Lifecycle.No Flags Request On Normal Capture | ✅ | 2816ms |
| Request Lifecycle.Two Flag Calls Produce Two Remote Requests | ✅ | 5504ms |
| Request Lifecycle.Mock Response Value Is Returned To Caller | ✅ | 2761ms |
| Side Effect Events.Get Feature Flag Captures Feature Flag Called Event | ✅ | 3068ms |
dustinbyrne
reviewed
Oct 6, 2026
dustinbyrne
left a comment
Contributor
There was a problem hiding this comment.
Thanks—the callback annotations and major-version migration notes match the execution paths. One important issue remains in the loaded-flags payload: accepted mutable Foundation bootstrap variants can survive the filter, undermining its new unchecked Sendable guarantee. Could we store the bridged Bool/String values and add the snapshot regression described inline?
Agent-led review, human-reviewed before posting. Validation was static inspection plus existing CI evidence.
The reloadFeatureFlags callback, beforeSend blocks, getAnonymousId, pushIdentityProvider and logSanitizer run off the main thread but weren't @sendable. In Swift 6 apps a reloadFeatureFlags closure written in main-actor code traps at runtime; the other callbacks race silently. Also make PostHogFeatureFlagsLoaded Sendable and add a Swift 6 language-mode test target that calls the API as an app would. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Xcode 26.3's symbol graph leaves @sendable out of declaration fragments, which 26.4 prints; the mangled names still differ. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The init kept the original variant values after filtering, so a mutable NSString passed via bootstrap stayed mutable inside a Sendable payload. Store the `as? Bool`/`as? String` results instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Name the config properties unambiguously and warn that array conversions crash in both directions. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
turnipdabeets
force-pushed
the
chore/v4-reload-flags-result
branch
from
October 7, 2026 02:05
ba7eefe to
59786d9
Compare
turnipdabeets
force-pushed
the
chore/v4-sendable-callbacks
branch
from
October 7, 2026 02:05
f83d9d2 to
be9478f
Compare
dustinbyrne
approved these changes
Oct 7, 2026
turnipdabeets
added a commit
that referenced
this pull request
Oct 7, 2026
* chore!: pass the reload result to reloadFeatureFlags' callback reloadFeatureFlags(_:) now hands its callback a PostHogFeatureFlagsLoaded, the same type onFeatureFlags receives, so callers can tell a failed reload from a successful one. errorsLoading is true when the request failed or the SDK isn't set up; flags and variants then hold the last known values. Part of #557. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: snapshot a failed reload's last known flags once for all callbacks Coalesced reload callbacks each read the live cache on failure, so a reset() in one callback emptied the last known flags reported to the next. The load now captures its result once, before fan-out. Also updates the setPersonPropertiesForFlags example and note for the new callback argument. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: gate the first failed reload so the reset regression always coalesces The coalesced-failure + reset() test assumed the first reload was still in flight when the next two registered. Hold its response until both callbacks are pending, and check both shared one request. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore!: mark off-main public callbacks @sendable for v4 (#914) * chore!: mark off-main public callbacks @sendable for v4 The reloadFeatureFlags callback, beforeSend blocks, getAnonymousId, pushIdentityProvider and logSanitizer run off the main thread but weren't @sendable. In Swift 6 apps a reloadFeatureFlags closure written in main-actor code traps at runtime; the other callbacks race silently. Also make PostHogFeatureFlagsLoaded Sendable and add a Swift 6 language-mode test target that calls the API as an app would. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: match the public API snapshot to CI's Xcode 26.3 output Xcode 26.3's symbol graph leaves @sendable out of declaration fragments, which 26.4 prints; the mangled names still differ. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: store bridged flag values in PostHogFeatureFlagsLoaded The init kept the original variant values after filtering, so a mutable NSString passed via bootstrap stayed mutable inside a Sendable payload. Store the `as? Bool`/`as? String` results instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: clarify the Sendable callbacks changeset Name the config properties unambiguously and warn that array conversions crash in both directions. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
4 of 5 tasks
turnipdabeets
added a commit
that referenced
this pull request
Oct 9, 2026
* chore!: pass the reload result to reloadFeatureFlags' callback reloadFeatureFlags(_:) now hands its callback a PostHogFeatureFlagsLoaded, the same type onFeatureFlags receives, so callers can tell a failed reload from a successful one. errorsLoading is true when the request failed or the SDK isn't set up; flags and variants then hold the last known values. Part of #557. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: snapshot a failed reload's last known flags once for all callbacks Coalesced reload callbacks each read the live cache on failure, so a reset() in one callback emptied the last known flags reported to the next. The load now captures its result once, before fan-out. Also updates the setPersonPropertiesForFlags example and note for the new callback argument. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: gate the first failed reload so the reset regression always coalesces The coalesced-failure + reset() test assumed the first reload was still in flight when the next two registered. Hold its response until both callbacks are pending, and check both shared one request. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore!: mark off-main public callbacks @sendable for v4 (#914) * chore!: mark off-main public callbacks @sendable for v4 The reloadFeatureFlags callback, beforeSend blocks, getAnonymousId, pushIdentityProvider and logSanitizer run off the main thread but weren't @sendable. In Swift 6 apps a reloadFeatureFlags closure written in main-actor code traps at runtime; the other callbacks race silently. Also make PostHogFeatureFlagsLoaded Sendable and add a Swift 6 language-mode test target that calls the API as an app would. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: match the public API snapshot to CI's Xcode 26.3 output Xcode 26.3's symbol graph leaves @sendable out of declaration fragments, which 26.4 prints; the mangled names still differ. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: store bridged flag values in PostHogFeatureFlagsLoaded The init kept the original variant values after filtering, so a mutable NSString passed via bootstrap stayed mutable inside a Sendable payload. Store the `as? Bool`/`as? String` results instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: clarify the Sendable callbacks changeset Name the config properties unambiguously and warn that array conversions crash in both directions. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
turnipdabeets
added a commit
that referenced
this pull request
Oct 9, 2026
turnipdabeets
added a commit
that referenced
this pull request
Oct 20, 2026
* chore!: pass the reload result to reloadFeatureFlags' callback reloadFeatureFlags(_:) now hands its callback a PostHogFeatureFlagsLoaded, the same type onFeatureFlags receives, so callers can tell a failed reload from a successful one. errorsLoading is true when the request failed or the SDK isn't set up; flags and variants then hold the last known values. Part of #557. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: snapshot a failed reload's last known flags once for all callbacks Coalesced reload callbacks each read the live cache on failure, so a reset() in one callback emptied the last known flags reported to the next. The load now captures its result once, before fan-out. Also updates the setPersonPropertiesForFlags example and note for the new callback argument. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: gate the first failed reload so the reset regression always coalesces The coalesced-failure + reset() test assumed the first reload was still in flight when the next two registered. Hold its response until both callbacks are pending, and check both shared one request. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore!: mark off-main public callbacks @sendable for v4 (#914) * chore!: mark off-main public callbacks @sendable for v4 The reloadFeatureFlags callback, beforeSend blocks, getAnonymousId, pushIdentityProvider and logSanitizer run off the main thread but weren't @sendable. In Swift 6 apps a reloadFeatureFlags closure written in main-actor code traps at runtime; the other callbacks race silently. Also make PostHogFeatureFlagsLoaded Sendable and add a Swift 6 language-mode test target that calls the API as an app would. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: match the public API snapshot to CI's Xcode 26.3 output Xcode 26.3's symbol graph leaves @sendable out of declaration fragments, which 26.4 prints; the mangled names still differ. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: store bridged flag values in PostHogFeatureFlagsLoaded The init kept the original variant values after filtering, so a mutable NSString passed via bootstrap stayed mutable inside a Sendable payload. Store the `as? Bool`/`as? String` results instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: clarify the Sendable callbacks changeset Name the config properties unambiguously and warn that array conversions crash in both directions. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
turnipdabeets
added a commit
that referenced
this pull request
Oct 23, 2026
* chore!: pass the reload result to reloadFeatureFlags' callback reloadFeatureFlags(_:) now hands its callback a PostHogFeatureFlagsLoaded, the same type onFeatureFlags receives, so callers can tell a failed reload from a successful one. errorsLoading is true when the request failed or the SDK isn't set up; flags and variants then hold the last known values. Part of #557. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: snapshot a failed reload's last known flags once for all callbacks Coalesced reload callbacks each read the live cache on failure, so a reset() in one callback emptied the last known flags reported to the next. The load now captures its result once, before fan-out. Also updates the setPersonPropertiesForFlags example and note for the new callback argument. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: gate the first failed reload so the reset regression always coalesces The coalesced-failure + reset() test assumed the first reload was still in flight when the next two registered. Hold its response until both callbacks are pending, and check both shared one request. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore!: mark off-main public callbacks @sendable for v4 (#914) * chore!: mark off-main public callbacks @sendable for v4 The reloadFeatureFlags callback, beforeSend blocks, getAnonymousId, pushIdentityProvider and logSanitizer run off the main thread but weren't @sendable. In Swift 6 apps a reloadFeatureFlags closure written in main-actor code traps at runtime; the other callbacks race silently. Also make PostHogFeatureFlagsLoaded Sendable and add a Swift 6 language-mode test target that calls the API as an app would. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: match the public API snapshot to CI's Xcode 26.3 output Xcode 26.3's symbol graph leaves @sendable out of declaration fragments, which 26.4 prints; the mangled names still differ. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: store bridged flag values in PostHogFeatureFlagsLoaded The init kept the original variant values after filtering, so a mutable NSString passed via bootstrap stayed mutable inside a Sendable payload. Store the `as? Bool`/`as? String` results instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: clarify the Sendable callbacks changeset Name the config properties unambiguously and warn that array conversions crash in both directions. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
turnipdabeets
added a commit
that referenced
this pull request
Oct 26, 2026
* chore!: pass the reload result to reloadFeatureFlags' callback reloadFeatureFlags(_:) now hands its callback a PostHogFeatureFlagsLoaded, the same type onFeatureFlags receives, so callers can tell a failed reload from a successful one. errorsLoading is true when the request failed or the SDK isn't set up; flags and variants then hold the last known values. Part of #557. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: snapshot a failed reload's last known flags once for all callbacks Coalesced reload callbacks each read the live cache on failure, so a reset() in one callback emptied the last known flags reported to the next. The load now captures its result once, before fan-out. Also updates the setPersonPropertiesForFlags example and note for the new callback argument. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: gate the first failed reload so the reset regression always coalesces The coalesced-failure + reset() test assumed the first reload was still in flight when the next two registered. Hold its response until both callbacks are pending, and check both shared one request. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore!: mark off-main public callbacks @sendable for v4 (#914) * chore!: mark off-main public callbacks @sendable for v4 The reloadFeatureFlags callback, beforeSend blocks, getAnonymousId, pushIdentityProvider and logSanitizer run off the main thread but weren't @sendable. In Swift 6 apps a reloadFeatureFlags closure written in main-actor code traps at runtime; the other callbacks race silently. Also make PostHogFeatureFlagsLoaded Sendable and add a Swift 6 language-mode test target that calls the API as an app would. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: match the public API snapshot to CI's Xcode 26.3 output Xcode 26.3's symbol graph leaves @sendable out of declaration fragments, which 26.4 prints; the mangled names still differ. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: store bridged flag values in PostHogFeatureFlagsLoaded The init kept the original variant values after filtering, so a mutable NSString passed via bootstrap stayed mutable inside a Sendable payload. Store the `as? Bool`/`as? String` results instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: clarify the Sendable callbacks changeset Name the config properties unambiguously and warn that array conversions crash in both directions. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
5 of 6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
💡 Motivation and Context
Part of the "Migrate to Swift 6 (and strong concurrency?)" item in #557. This PR only covers the part that needs a major version: the callbacks apps pass to the SDK. Compiling the SDK itself in Swift 6 language mode is internal work with no API impact, so it can follow in a 4.x minor.
Several public callbacks run off the main thread but aren't typed
@Sendable. That causes two problems for apps:reloadFeatureFlags { _ in ... }closure written in main-actor code (a@MainActorclass or a SwiftUI view) is main-actor isolated, and the SDK calls it from its network completion queue. The Swift 6 runtime check traps (_swift_task_checkIsolatedSwift→ SIGTRAP). The closure doesn't need to touch any state;{ _ in print("x") }is enough. Swift 5 apps don't crash.setBeforeSend) or assigned to a property (getAnonymousId,logSanitizer,pushIdentityProvider), Swift doesn't insert that runtime check. A main-actor closure there compiles cleanly and then mutates main-actor state off the main thread.reloadFeatureFlags(_:)callbacksetBeforeSend(_:)(events and logs)capture/captureLoggetAnonymousIdlogSanitizerpushIdentityProviderChanges:
@Sendable. The compiler now catches main-actor access inside them, in Swift 5 and Swift 6 apps alike, and apps hop explicitly (Task { @MainActor in ... }). Objective-C is unaffected; the generated header doesn't change.PostHogFeatureFlagsLoadedSendable(@unchecked: alllets, andvariantsonly holdsBool/String). Swift 6 apps can then pass it across tasks.onFeatureFlagskeeps its signature. It already delivers on the main thread, so main-actor closures pass the runtime check. Typing it@MainActoradds a Swift 6 error for apps that use plain classes and fixes nothing, so I left it out.getAnonymousIdandlogSanitizer, and tell callers ofreloadFeatureFlags(_:)how to hop to the main actor. FixPostHogExample, which set a@Publishedproperty from the callback on a background thread.Who breaks:
self@State@MainActorclass touching its own stateEvery error lands on code that today either crashes (Swift 6) or races (Swift 5).
One upgrade hazard: a Swift 5 app that passes a pre-typed array such as
let hooks: [(PostHogEvent) -> PostHogEvent?]tosetBeforeSend(_:)gets only a warning, then aborts at runtime ("Could not cast value of type '(…) -> …' to '@sendable (…) -> …'"). Swift can't convert arrays of function types that differ only in@Sendable. Swift 6 apps get a compile error instead. Array literals, single closures, variadic calls and arrays built withmapare fine. The SDK hit the same thing internally, which is whyBeforeSendChainnow stores@Sendableblocks. The changeset tells apps to type those arrays as[BeforeSendBlock]/[PostHogBeforeSendLogBlock].Open question for reviewers: we could prevent that crash instead of documenting it. A Swift-only
@available(swift, obsoleted: 6.0) @_disfavoredOverload setBeforeSend(_: [(PostHogEvent) -> PostHogEvent?])on each config would take typed arrays in Swift 5 and box them, without changing overload resolution for literals or[BeforeSendBlock]. I left it out because it adds public API using an underscored attribute for a narrow pattern.The Swift-only
setBeforeSend(_:)overloads get new mangled symbol names, so prebuilt binaries need rebuilding. That's expected for a major version.Spec:
reload-feature-flagslists the iOS signature asreloadFeatureFlags(_ callback: @escaping () -> Void). With #913 and this PR it becomes@escaping @Sendable (PostHogFeatureFlagsLoaded) -> Void. Neither it noron-feature-flagssays anything about threads, so there's no behavior divergence.Stacked on #913, which passes a
PostHogFeatureFlagsLoadedto the reload callback. This PR adds@Sendableto that new signature, so the API breaks only once. #913 sits on #873, whose tools bump to 6.2 the per-target Swift 6 test setting needs. #912 renamesPostHogLogEntrytoPostHogConsoleLogEntry, so thelogSanitizerline will conflict trivially.💚 How did you test it?
PostHogSwift6Teststarget compiled in Swift 6 language mode. It calls the API from main-actor code the way an app does:reloadFeatureFlagswith a closure written in main-actor code, which passes its result into a main-actorTask. Without@Sendablethe test process traps (signal 5); with this PR it passes.onFeatureFlagsdelivers on main and its payload can be sent to another task. Without theSendableconformance the target doesn't compile.make test: XCTest 169/169 passes. Swift Testing has 13 issues, all inPostHogStorageTest's app-group container tests; the base branch fails the same way on this machine, and nothing else fails.make buildSdk: all 6 platforms build, with no concurrency warnings.make buildExamplesPlatforms: all 8 example builds succeed.PostHogConsoleLogInterceptorTestandPostHogSessionReplayPluginTestspass (logSanitizeronly runs on iOS).make lint: no serious violations.api/posthog-ios.public-api.txtwithmake apiUpdate(xcprettyisn't installed here, so I ran it with a pass-through shim).vars inside these callbacks. Tests still pass. They'll be fixed with the SDK's Swift 6 language-mode migration, or I can do it here if reviewers prefer./flagsrequest failing.make testjob, not the simulator job.📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
onFeatureFlagsas@MainActor, and switching the SDK to Swift 6 language mode in this PR. A first build in Swift 6 mode shows at least 35 errors, mostly mutable globals, and that's internal work.PostHogSDK: @unchecked Sendable(so Swift 6 apps can pass SDK instances into tasks and actors) is additive and goes in a separate PR.🤖 Generated with Claude Code