Repository navigation
fix(flags): load shared definitions without a secret key - #259
dustinbyrne wants to merge 2 commits into
Conversation
posthog-php-lib_curl Compliance ReportDate: 2026-10-10T04:16:34.967310+00:00 ✅ All Tests Passed!47/47 tests passed Capture Tests✅ 30/30 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
|
posthog-php-fork_curl Compliance ReportDate: 2026-10-10T04:16:31.274216+00:00
|
| Test | Status | Duration |
|---|---|---|
| Format Validation.Event Has Required Fields | ✅ | 38ms |
| Format Validation.Event Has Uuid | ✅ | 529ms |
| Format Validation.Event Has Lib Properties | ✅ | 531ms |
| Format Validation.Distinct Id Is String | ✅ | 531ms |
| Format Validation.Token Is Present | ✅ | 533ms |
| Format Validation.Custom Properties Preserved | ✅ | 532ms |
| Format Validation.Event Has Timestamp | ✅ | 533ms |
| Format Validation.Non Utc Event Timestamp Is Converted To Utc | ✅ | 531ms |
| Retry Behavior.Retries On 503 | ❌ | 5536ms |
| Retry Behavior.Does Not Retry On 400 | ✅ | 2533ms |
| Retry Behavior.Does Not Retry On 401 | ✅ | 2535ms |
| Retry Behavior.Respects Retry After Header | ❌ | 5539ms |
| Retry Behavior.Implements Backoff | ❌ | 15548ms |
| Retry Behavior.Retries On 500 | ❌ | 5540ms |
| Retry Behavior.Retries On 502 | ❌ | 5536ms |
| Retry Behavior.Retries On 504 | ❌ | 5537ms |
| Retry Behavior.Max Retries Respected | ❌ | 15545ms |
| Deduplication.Generates Unique Uuids | ✅ | 541ms |
| Deduplication.Preserves Uuid On Retry | ❌ | 5536ms |
| Deduplication.Preserves Uuid And Timestamp On Retry | ❌ | 10542ms |
| Deduplication.Preserves Uuid And Timestamp On Batch Retry | ❌ | 5541ms |
| Deduplication.No Duplicate Events In Batch | ✅ | 538ms |
| Deduplication.Different Events Have Different Uuids | ✅ | 534ms |
| Compression.Sends Gzip When Enabled | ✅ | 534ms |
| Batch Format.Uses Proper Batch Structure | ✅ | 532ms |
| Batch Format.Flush With No Events Sends Nothing | ✅ | 518ms |
| Batch Format.Multiple Events Batched Together | ✅ | 525ms |
| Error Handling.Does Not Retry On 403 | ✅ | 2533ms |
| Error Handling.Does Not Retry On 413 | ✅ | 2535ms |
| Error Handling.Retries On 408 | ❌ | 5536ms |
Failures
retry_behavior.retries_on_503
Expected at least 3 requests, got 1
retry_behavior.respects_retry_after_header
Expected at least 2 requests, got 1
retry_behavior.implements_backoff
Expected at least 3 requests, got 1
retry_behavior.retries_on_500
Expected at least 2 requests, got 1
retry_behavior.retries_on_502
Expected at least 2 requests, got 1
retry_behavior.retries_on_504
Expected at least 2 requests, got 1
retry_behavior.max_retries_respected
Expected 4 requests, got 1
deduplication.preserves_uuid_on_retry
Need at least 2 requests to check retry
deduplication.preserves_uuid_and_timestamp_on_retry
Expected at least 3 requests, got 1
deduplication.preserves_uuid_and_timestamp_on_batch_retry
Expected at least 2 requests, got 1
error_handling.retries_on_408
Expected at least 2 requests, got 1
Feature_Flags Tests
✅ 17/17 tests passed
View Details
| Test | Status | Duration |
|---|---|---|
| Request Payload.Request With Person Properties Device Id | ✅ | 525ms |
| Request Payload.Flags Request Uses V2 Query Param | ✅ | 522ms |
| Request Payload.Flags Request Hits Flags Path Not Decide | ✅ | 521ms |
| Request Payload.Flags Request Omits Authorization Header | ✅ | 524ms |
| Request Payload.Token In Flags Body Matches Init | ✅ | 521ms |
| Request Payload.Groups Round Trip | ✅ | 522ms |
| Request Payload.Groups Default To Empty Object | ✅ | 522ms |
| Request Payload.Disable Geoip False Propagates As Geoip Disable False | ✅ | 522ms |
| Request Payload.Disable Geoip Omitted Defaults To False | ✅ | 523ms |
| Request Payload.Flag Keys To Evaluate Contains Only Requested Key | ✅ | 522ms |
| Request Lifecycle.No Flags Request On Init Alone | ✅ | 517ms |
| Request Lifecycle.No Flags Request On Normal Capture | ✅ | 519ms |
| Request Lifecycle.Two Flag Calls Produce Two Remote Requests | ✅ | 524ms |
| Request Lifecycle.Mock Response Value Is Returned To Caller | ✅ | 526ms |
| Retry Behavior.Retries Flags On 502 | ✅ | 626ms |
| Retry Behavior.Retries Flags On 504 | ✅ | 625ms |
| Side Effect Events.Get Feature Flag Captures Feature Flag Called Event | ✅ | 535ms |
posthog-php-socket Compliance ReportDate: 2026-10-10T04:17:12.957978+00:00
|
| Test | Status | Duration |
|---|---|---|
| Format Validation.Event Has Required Fields | ✅ | 31ms |
| Format Validation.Event Has Uuid | ✅ | 522ms |
| Format Validation.Event Has Lib Properties | ✅ | 524ms |
| Format Validation.Distinct Id Is String | ✅ | 524ms |
| Format Validation.Token Is Present | ✅ | 524ms |
| Format Validation.Custom Properties Preserved | ✅ | 525ms |
| Format Validation.Event Has Timestamp | ✅ | 524ms |
| Format Validation.Non Utc Event Timestamp Is Converted To Utc | ✅ | 524ms |
| Retry Behavior.Retries On 503 | ❌ | 9234ms |
| Retry Behavior.Does Not Retry On 400 | ✅ | 2528ms |
| Retry Behavior.Does Not Retry On 401 | ✅ | 2526ms |
| Retry Behavior.Respects Retry After Header | ❌ | 9234ms |
| Retry Behavior.Implements Backoff | ❌ | 19245ms |
| Retry Behavior.Retries On 500 | ❌ | 9238ms |
| Retry Behavior.Retries On 502 | ❌ | 9235ms |
| Retry Behavior.Retries On 504 | ❌ | 9236ms |
| Retry Behavior.Max Retries Respected | ❌ | 19231ms |
| Deduplication.Generates Unique Uuids | ✅ | 46ms |
| Deduplication.Preserves Uuid On Retry | ❌ | 9233ms |
| Deduplication.Preserves Uuid And Timestamp On Retry | ❌ | 14241ms |
| Deduplication.Preserves Uuid And Timestamp On Batch Retry | ❌ | 9241ms |
| Deduplication.No Duplicate Events In Batch | ✅ | 532ms |
| Deduplication.Different Events Have Different Uuids | ✅ | 525ms |
| Compression.Sends Gzip When Enabled | ✅ | 524ms |
| Batch Format.Uses Proper Batch Structure | ✅ | 524ms |
| Batch Format.Flush With No Events Sends Nothing | ✅ | 519ms |
| Batch Format.Multiple Events Batched Together | ✅ | 513ms |
| Error Handling.Does Not Retry On 403 | ✅ | 2524ms |
| Error Handling.Does Not Retry On 413 | ✅ | 2526ms |
| Error Handling.Retries On 408 | ❌ | 5531ms |
Failures
retry_behavior.retries_on_503
Expected at least 3 requests, got 1
retry_behavior.respects_retry_after_header
Expected at least 2 requests, got 1
retry_behavior.implements_backoff
Expected at least 3 requests, got 1
retry_behavior.retries_on_500
Expected at least 2 requests, got 1
retry_behavior.retries_on_502
Expected at least 2 requests, got 1
retry_behavior.retries_on_504
Expected at least 2 requests, got 1
retry_behavior.max_retries_respected
Expected 4 requests, got 1
deduplication.preserves_uuid_on_retry
Need at least 2 requests to check retry
deduplication.preserves_uuid_and_timestamp_on_retry
Expected at least 3 requests, got 1
deduplication.preserves_uuid_and_timestamp_on_batch_retry
Expected at least 2 requests, got 1
error_handling.retries_on_408
Expected at least 2 requests, got 1
Feature_Flags Tests
✅ 17/17 tests passed
View Details
| Test | Status | Duration |
|---|---|---|
| Request Payload.Request With Person Properties Device Id | ✅ | 524ms |
| Request Payload.Flags Request Uses V2 Query Param | ✅ | 521ms |
| Request Payload.Flags Request Hits Flags Path Not Decide | ✅ | 523ms |
| Request Payload.Flags Request Omits Authorization Header | ✅ | 522ms |
| Request Payload.Token In Flags Body Matches Init | ✅ | 521ms |
| Request Payload.Groups Round Trip | ✅ | 523ms |
| Request Payload.Groups Default To Empty Object | ✅ | 523ms |
| Request Payload.Disable Geoip False Propagates As Geoip Disable False | ✅ | 521ms |
| Request Payload.Disable Geoip Omitted Defaults To False | ✅ | 522ms |
| Request Payload.Flag Keys To Evaluate Contains Only Requested Key | ✅ | 523ms |
| Request Lifecycle.No Flags Request On Init Alone | ✅ | 516ms |
| Request Lifecycle.No Flags Request On Normal Capture | ✅ | 509ms |
| Request Lifecycle.Two Flag Calls Produce Two Remote Requests | ✅ | 526ms |
| Request Lifecycle.Mock Response Value Is Returned To Caller | ✅ | 522ms |
| Retry Behavior.Retries Flags On 502 | ✅ | 626ms |
| Retry Behavior.Retries Flags On 504 | ✅ | 624ms |
| Side Effect Events.Get Feature Flag Captures Feature Flag Called Event | ✅ | 524ms |
💡 Motivation and Context
Like PostHog/posthog-python#1039, a worker consuming shared feature flag definitions should not need a privileged secret key. Existing initialization gates prevent that supported cache-consumer configuration from evaluating flags locally.
Changes
Cache-only readers bypass the shared loader specification's decision-first provider step; credentialed consumers retain that step.
Automatic construction loading accepts provider-only consumers.
loadFeatureFlags:falseremains effective and explicitloadFlags()remains the refresh mechanism; no polling is introduced.💚 How did you test it?
testForkCurlRejectsExpandedShellPayloadWithoutLeakingTempFile: 737 tests, 5,557 assertions, no failures.ForkCurl.php:53due to theescapeshellarg1 MiB limit. The exact test fails identically against prior Client code. No transport change is included.Release scope
Patch release for posthog-php. Existing signatures, capture defaults and wire formats are unchanged.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Implemented with Pi worker agents and reviewed by separate fresh-context Pi reviewers. A simplify pass covered the scoped source/tests/docs before final local validation. Human review remains required.