Repository navigation
chore(compliance): audit posthog-ios 4.0 - #187
Conversation
dustinbyrne
left a comment
There was a problem hiding this comment.
Please correct the HTTP Client compliance score: compression = .none leaves the AI lane compressed, contrary to the current whole-client requirement. The optional inline notes clarify the draft retry policy and SwiftUI masking precedence. Retain the documented merge-after-iOS-4.0-publication prerequisite.
AI-assisted review.
0c0478e to
54d4be1
Compare
dustinbyrne
left a comment
There was a problem hiding this comment.
The implementation evidence and conditional baseline are clear, but HTTP Client is counted as fully compliant while the pinned specifications retain an unresolved whole-client compression requirement. Consider retaining Partial or Unknown until that scope is resolved. Preserve the iOS 4.0 publication and final-#146 recheck prerequisites.
AI-assisted review.
Re-audit all 64 posthog-ios rows at 3460e534a (4.0 release branch) against sdk-specs dd11a6b, add the five rows added to the README table since the last audit, and update the iOS roll-up and gap entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
compression = .none leaves captureAi requests gzipped through the separate captureAiCompression setting, so iOS 4.0 has no whole-client compression opt-out. Roll-up becomes 40/17/1/11 (58%), 18 gaps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Draft #146 already permits the client-SDK durable queue, unlimited attempts, 1-30 s backoff and multi-event 413 halving for iOS 4.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SwiftUI's postHogMask() wins over an enclosing postHogNoMask(), the reverse of the spec's unmask-over-mask precedence. It over-masks rather than leaks. Roll-up becomes 39/18/1/11 (57%), 19 gaps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#146 Re-checks the iOS audit at 1f91c5b2 and sdk-specs 8306698. #1036 keeps $lib/$lib_version, which now matches #146. Opt In meets the #138 replay restart requirements. Surveys gains a #102 gap: setSurveySeen moves the last-seen date on submit and dismiss. HTTP Client goes back to ✅: its compression gap comes from conflicting http-client and capture-ai rules in #146, raised on that PR. Tally 40/17/1/11. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…as merged Scores Capture, Capture AI, Before Send Hook, Event Batcher, HTTP Client and Retry Queue against #146 at 5c26b9b, treated as merged. The capture v1 wire, transport and retry policy conform. Capture AI applies to iOS 4.0 and is 🟡 for the same NSNull serialization gap as Capture; starting the AI queue at setup is what #146 asks of client SDKs. Tally 40/18/1/10. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… for clients Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…52f899 and #146 d387ab7 Capture, Capture Exception and Capture AI move to Pass now that null-valued properties are omitted (posthog-ios#1047) and the SDK fills its own $lib pair after the caller's properties (posthog-ios#1050). On Feature Flags moves to Pass: loads in flight across reset() are dropped (posthog-ios#1048) and empty variants are left out of listener flags. HTTP Client is scored Pass on its merits, since #146 now leaves a lane with its own compression setting out of the whole-client opt-out. Surveys stays Partial only for the popup-delay eligibility re-check (SHOULD); posthog-ios#1049 fixed the rest. Opt In meets the new deferred-crash consent requirement (#199); the empty variant (#193), variant key rename (#203) and job-retry (#205) changes need no other status change. Line references move to e27cbe4cb. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
88f99ae to
9d7f9da
Compare
The popup-delay and wait-period SHALLs are met since posthog-ios#1049. The one unmet requirement is a SHOULD (re-check eligibility when the delay elapses), which is recorded but not scored. Totals become 45/13/1/10. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dustinbyrne
left a comment
There was a problem hiding this comment.
The refreshed audit addresses the previous feedback and clearly identifies its release-branch and proposed-specification baselines. The inline exception-step classification suggestion is a nonblocking audit follow-up. Retain the documented release-tag repinning, iOS 4.0 publication and final-#146 recheck prerequisites.
AI-assisted review.
…zation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| | 6 | Capture AI | ➖ | unchanged — Applicability still `server`; the new null-drop requirement/scenario is `@server`; no AI capture in iOS (repo grep for `captureAi`/`capture_ai`/`$ai_generation` → no hits) | | ||
| | 7 | Capture Exception | 🟡 | [n5]; partly fixed by [#930](https://github.com/PostHog/posthog-ios/pull/930) | | ||
| | 8 | Create Person Profile | ➖ | unchanged — spec Applicability still says only the posthog-js family exposes it; no `createPersonProfile` in iOS (repo grep → no hits) | | ||
| | 5 | Capture | ✅ | was 🟡; [n4]; capture v1 wire conforms (#146); empty event names dropped (also after `beforeSend`); `NSNull` properties omitted (#1047); own `$lib` pair filled after caller properties (#1050); empty variant left out of `$active_feature_flags` | |
There was a problem hiding this comment.
#146 now requires migration guides to show a call option process_person_profile: true as the way to keep identifying under a registered false. The SDK behaves that way, but MIGRATION.md here has no such example until posthog-ios#1053 merges. Capture is 🟡 at this commit, or say it's met once #1053 lands.
There was a problem hiding this comment.
Fixed in 85d4acd — Capture 🟡 until posthog-ios#1053 merges; requirement checked at 15501ca.
There was a problem hiding this comment.
Changed in 2fd35bd — this audit tracks 4.0 and #1053 targets it, so Capture stays ✅ with a note; we'll recheck when #1053 merges.
| | posthog-python | 13/64 fully compliant (20%; 30 contracts N/A on a server SDK) | 13 | 16 | 5 | 30 | 0 | 2026-10-12 · `509c8525` | 21 | [posthog-python.md](posthog-python.md) | | ||
| | posthog-android | 37/64 fully compliant (58%) | 37 | 16 | 5 | 6 | 0 | 2026-10-19 · `c5e788bd` (targeted re-audit — see file header) | 21 | [posthog-android.md](posthog-android.md) | | ||
| | posthog-ios | 38/64 fully compliant (59%) | 38 | 16 | 4 | 6 | 0 | 2026-10-08 · `f5cbe87c` + PostHog/posthog-ios#924–#934 (out-of-cycle refresh, see below) | 20 | [posthog-ios.md](posthog-ios.md) | | ||
| | posthog-ios | 44/69 fully compliant (64%) | 44 | 14 | 1 | 10 | 0 | 2026-11-10 · `e27cbe4cb` (4.0 release branch, before 4.0.0 is published; capture v1 rows against #146 at `d387ab79` as merged; see below) | 15 | [posthog-ios.md](posthog-ios.md) | |
There was a problem hiding this comment.
The README still says 64 contracts per SDK, but the iOS row is now out of 69, so its percentage doesn't compare with the other rows.
There was a problem hiding this comment.
Fixed in a50f0e3 — README notes 69 contracts and gives iOS as 43/64 for comparison.
There was a problem hiding this comment.
Reworded in 720117c — the 69-contract note is now SDK-neutral; each 69-row line also gives its /64 score.
…on guide shows the identity call option #146 at 15501ca requires migration guides to show a per-call process_person_profile: true on identity calls; MIGRATION.md at e27cbe4cb lacks it until PostHog/posthog-ios#1053 merges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-row basis Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The identity-call migration-guide example #146 requires lands in 4.0 with PostHog/posthog-ios#1053, which targets the release branch. This audit tracks 4.0, so a pending release-branch PR is noted rather than scored as a gap. Reverts 85d4acd. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The same paragraph lands from both the iOS and Android 4.0 audits, so it merges cleanly in either order and stays true after both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ompliance # Conflicts: # compliance/README.md
…ompliance # Conflicts: # compliance/README.md
…ompliance # Conflicts: # compliance/README.md
Problem
compliance/posthog-ios.mdscores 3.x (f5cbe87c, 2026-10-08, with #924–#934 counted as pending PRs). posthog-ios 4.0 changes several rows, and the README table has five contracts the file doesn't list yet.Important
Merge after posthog-ios 4.0.0 is published (PostHog/posthog-ios#873). The capture v1 rows are scored against #146 at
d387ab79as if merged; re-check them against #146's final text.Changes
Audited all 64 rows on the 4.0 release branch
chore/v4-remove-deprecatedat posthog-iose27cbe4cbagainst sdk-specsmain752f899plus #146 atd387ab79(capture v1, including #147's AI lane), treated as merged. Every line reference on the page is ate27cbe4cb. #924–#934 are merged there, so nothing is counted as pending. Summary: 38/16/4/6 on 64 rows → 44 ✅ · 14 🟡 · 1 ❌ · 10 ➖ on 69 rows.Rows that changed:
getFeatureFlagPayload(_:)is removed. The read isgetFeatureFlagResult(_:sendFeatureFlagEvent: false)?.payload, which "Payload reads through the flag result getter" (docs(flags): record the mobile majors' getFeatureFlagPayload removal #170) permits. A malformed payload →nil, and bootstrap payloads are decoded once.nil; an empty variant reads as disabled (docs(flags): read an empty variant as disabled in get-feature-flag-result #193).isFeatureEnabled(_:defaultValue:).NSNullproperties are omitted on the queue and the wire, with$set/$set_once/$group_setnulls kept (PostHog/posthog-ios#1047); the SDK fills its own$lib/$lib_versionpair after the caller's properties and beforebeforeSend, as docs(capture): specify capture v1 delivery for every v1 SDK #146's "Events name their own library" now asks of client SDKs (PostHog/posthog-ios#1050); an empty variant is left out of$active_feature_flags.NSNullfix.ph-no-capturechildren is gone. SwiftUI's explicit mask still wins over an enclosingpostHogNoMask(), the reverse of the spec's precedence.getAllFeatureFlags()'s result list as the iOS 4.0 surface. It is still not the canonical map shape.NSNullcleanup).NSNullmembers that the queue and the capture v1 wire strip after #1047, so the representations "Normalize to the wire form once, before processing" requires to be identical differ./flags?v=2), AI Datasets, AI Scorers, Offline Evaluations, Emails (server only).Note-only:
$lib/$lib_versionkept in properties (PostHog/posthog-ios#1036), retry status set, jittered backoff,Retry-After, no attempt limit, retries that exclude new events (docs(capture): keep new events out of a capture v1 retry #180), byte-aware batching and same-origin redirects all conform. AfterbeforeSendthe SDK only re-imposes the uuid, which docs(capture): specify capture v1 delivery for every v1 SDK #146 allows.compression = .noneturns off compression for every request exceptcaptureAi, which has its owncaptureAiCompression. docs(capture): specify capture v1 delivery for every v1 SDK #146'shttp-clientnow leaves such a lane out of the whole-client opt-out./flagsload in flight acrossreset()is dropped (PostHog/posthog-ios#1048), and an empty variant is left out of listener flags (docs(flags): read an empty variant as disabled in get-feature-flag-result #193).$feature_flag_variant_key), docs(exceptions): clarify handled state for job retries #205 (job-retry handled state) and the other server-only changes onmainchange no iOS row.$group_set(Group Identify), caller precedence (Capture, Register, Debug Properties),quotaLimitedwith unknown values ignored (Remote Config).compliance/README.md: the iOS roll-up row, the out-of-cycle refresh paragraph, the iOS gap entries and the iOS non-Pass count (15).How did you test this code?
e27cbe4cb.main752f899. Re-tallied: 44/14/1/10 = 69; every note anchor has a heading.git diff --checkclean. Docs only, no spec changes.compliance/README.mdconflicts with docs(compliance): weekly SDK compliance matrix #148, docs(compliance): re-audit posthog-android capture rows for 4.0 #186, chore(compliance): audit posthog-flutter 6.0 #200 and docs(compliance): re-audit posthog-react-native rows for react-native-plugin 3.0 #201; whichever lands later needs a manual merge.🤖 Generated with Claude Code