Skip to content

feat(desktop): captureAi on the AI endpoint, native property order and options passthrough - #679

Open
turnipdabeets wants to merge 43 commits into
feat/v6-desktop-capture-v1from
feat/v6-desktop-capture-ai
Open

turnipdabeets wants to merge 43 commits into
feat/v6-desktop-capture-v1from
feat/v6-desktop-capture-ai

Conversation

@turnipdabeets

@turnipdabeets turnipdabeets commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

💡 Motivation and Context

Targets #673 (feat/v6-desktop-capture-v1), so all the capture v1 work lands in #673 before #673 merges onto #637. This PR includes #649, #663 and #674, which it was stacked on, plus #678's final commit. The desktop follow-up promised on #674: Windows and Linux now match posthog-ios 4.0 and posthog-android 4.0 on three points.

  1. AI events (captureAi) go to the capture v1 AI endpoint, /i/v1/ai/events. Before, desktop dropped them and returned null.
  2. Property order. Event properties are built in the native order: SDK-set properties first, then registered properties, then the event's own. beforeSend runs after that merge.
  3. Options passthrough. Event options go into the v1 event unchanged instead of being mapped to legacy $ properties.

This branch merges fix/v6-desktop-retry-404-429 (#678, which contains #673) instead of #673 alone. The AI endpoint shares the desktop send loop, so it uses #678's retry rules too (404 and 429 are retried, as on the native AI endpoint once PostHog/posthog-android#897 and PostHog/posthog-ios#979 land; parity depends on them), and #678's backoff, idle timeout, 413 handling and 5 MiB queued-bytes trigger apply to each endpoint separately. If #678 changes, the AI endpoint follows it.

Per-platform behavior (updates the #674 table)

options captureAi
iOS / macOS unchanged from #674 unchanged from #674
Android unchanged from #674 unchanged from #674
Windows / Linux Sent in the capture v1 event's options exactly as given, unknown keys included. An option wins over its legacy $ property. The legacy property is moved into options only when the option is unset, as in #673's captureV1Event. Builds the event like capture, runs beforeSend, queues it on disk in its own queue (posthog_ai_queue/) and sends it to /i/v1/ai/events. Returns the UUID, or null when the event isn't queued: beforeSend dropped it, the SDK is opted out, disabled or closed, or the event is over the size limit. The captureAi* config settings apply.
Web unchanged (legacy mapping) unchanged (no-op, returns null)

1. AI endpoint (desktop)

  • Wire format: same as analytics capture v1: {created_at, batch}, Authorization: Bearer, PostHog-Sdk-Info, PostHog-Attempt, PostHog-Request-Id, PostHog-Request-Timestamp, per-event results and same-origin 307/308 redirects. A name that doesn't start with $ai_ gets a debug log and is still sent, like native. capture never sends to the AI endpoint.
  • Size limit: a serialized event (as queued, before gzip) over captureAiMaxEventBytes is dropped and captureAi returns null. The limit defaults to 8 MiB + 64 KiB and is capped there. The log names only the event and its size.
  • Queue: separate from analytics and persisted across restarts. It keeps captureAiMaxQueueSize events (100 by default) and at most 50 MiB, drops the oldest first and always keeps the newest. It uses flushAt, maxBatchSize, flushInterval and the 5 MiB batch cap from feat!: send Windows and Linux events through capture v1 #673, and also flushes once 5 MiB is queued.
  • Requests: compressed with captureAiCompression (gzip by default). A request fails after captureAiTimeout (60 s by default) without progress, using fix: retry desktop capture v1 requests that get 404 or 429 #678's idle timeout in place of analytics' 10 s. Connecting is still bounded by the shared 10 s connection timeout, as on Android, where the AI client only overrides the read and write timeouts.
  • Retries: the AI endpoint has its own retry identity, timers, fix: retry desktop capture v1 requests that get 404 or 429 #678 backoff (1 s doubling to 30 s, ±25% jitter, Retry-After as a floor), and its own 413 batch size and flushAt. A failing AI request doesn't hold back analytics, and the reverse is also true. The send code from feat!: send Windows and Linux events through capture v1 #673 is reused. Its per-endpoint state moved into a small _CaptureLane, so the code isn't duplicated.
  • Queue size tracking: one running byte total in the file queue serves both fix: retry desktop capture v1 requests that get 404 or 429 #678's 5 MiB flush trigger and the 50 MiB AI cap. The AI path passes its already encoded event in, so it is encoded once.

2. Property order (desktop)

  • _enrichProperties now applies context, $timezone, $lib, flag properties, $recording_status, $session_id, $is_identified and the $sdk_debug_* keys first. The current-screen session property comes next, then registered properties, then the event's own. A caller or registered value changes that event only.
  • $session_id: an empty or non-string value still falls back to the SDK's session.
  • beforeSend (Dart) runs on the fully built event. It sees and can change every SDK property and option. The event is then queued as the callbacks leave it, with the timestamp taken before they ran. $set/$set_once are still handed over as userProperties/userPropertiesSetOnce.
  • Person processing is no longer a $process_person_profile property on every event. The event gets process_person_profile: false in options only while person processing is off and no option or property sets it. Otherwise the option is omitted (sdk-specs "Unset control options are omitted"). A personless $set still skips the dedup hash, as in feat: add per-event capture options and captureAi #674.
  • Exception steps are still attached after beforeSend, as before, so steps recorded while a callback is pending are kept and a renamed $exception gets them.

3. Options passthrough (desktop)

capture, screen, captureException, identify, setPersonProperties, alias, group and captureAi pass the options map through unchanged, with null values stripped as on mobile. The properties maps that #674 added to the desktop core's identify/setPersonProperties/alias/group for this are replaced by options.

Spec divergences

  • The sdk-specs capture-ai spec targets server SDKs. Like the native mobile SDKs, desktop captureAi takes no uuid and returns the generated one.
  • captureAiMaxEventBytes limits the whole serialized event, as on iOS. On Android a set value limits the properties, plus 64 KiB. The defaults agree. I updated the config doc, which said "8 MiB on Android"; that is out of date with posthog-android#884.
  • The capture spec (step 4) lists $process_person_profile among SDK-set properties. Desktop follows native 4.0 and the capture v1 outcomes scenario instead and sends it as an option only when it's off.

💚 How did you test it?

  • flutter test in posthog_flutter: 1370 passed, 1 skipped (after merging the latest fix: retry desktop capture v1 requests that get 404 or 429 #678 and addressing review). dart analyze .: no issues. dart format --set-exit-if-changed . from the repo root: clean. scripts/check-api-dart.sh: snapshot up to date.
  • New test/core/capture_ai_test.dart, against a local server:
    • AI endpoint, headers and payload; capture of an $ai_ event stays on analytics
    • captureAiCompression separate from compression; opted out returns null
    • Size limit: null, and the log has name and size only, never the values; the cap at 8 MiB + 64 KiB
    • captureAiMaxQueueSize separate from maxQueueSize; the 50 MiB cap keeps the newest
    • Flush at 5 MiB; persistence across clients
    • A 400 drops only the AI batch; a per-event retry; a 503 retried 4 times under one request id while analytics sends at attempt 1
    • AI and analytics back off independently: analytics starts at 1 s while AI is at 4 s, and a delivered analytics batch leaves AI's next retry at its own schedule
  • Desktop platform tests:
    • captureAi through beforeSend (returns the UUID, sees $session_id, edits sent), dropped by beforeSend, oversized, opted out, a non-$ai_ name logged
    • Options passthrough, including unknown and nested keys and options on identify/setPersonProperties/group/alias
    • beforeSend seeing and changing SDK properties and options, with nothing re-added after it; the timestamp taken before a slow callback
    • /flags person_properties get only what beforeSend keeps (redacted values, nothing from a dropped event); $feature/*, $active_feature_flags and $recording_status removed by beforeSend stay removed
    • The file queue's byte-limited peek stops before the event that would pass 5 MiB without reading it
    • Existing tests updated for the new order: registered and event values now win over context, $recording_status and debug keys; person processing asserted on options
  • Not run on a Windows or Linux device, and nothing sent to PostHog.

📝 Checklist

  • All commits are signed (see Commit signing)
  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

New .changeset/v6-desktop-capture-ai.md (major, the stack releases as 6.0.0). I also updated the #674 changeset, which said desktop captureAi and options were no-ops or legacy-mapped.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Claude Code built this from the posthog-android feat/v4-capture-ai sources (PostHog.captureAi, buildProperties, personProcessingOptions, EndpointSpec.ai, PostHogApi.captureAi) and posthog-ios feat/v4-capture-v1 (QueueEndpoint+Factories.swift, buildProperties, captureAi), plus sdk-specs capture, capture-ai and the capture v1 outcomes feature. Decisions:

  • captureAi reuses the desktop capture v1 send loop. Its per-endpoint state moved into a lane object; no second transport.
  • beforeSend sees SDK keys because the core now builds the event (prepareEvent) before the callbacks and queues it as-is afterwards (capturePrepared). SDK-internal events ($identify, $set, $groupidentify, $create_alias, $feature_flag_called, lifecycle) still skip the Dart callbacks, as documented.
  • Exception steps stay attached after beforeSend, to keep the existing desktop behavior and tests.

Open questions for review:

  • Should captureAiMaxEventBytes mean the same thing on iOS and Android?
  • The compliance adapter still declares only capture_v0/encoding_gzip. I left it alone.

🤖 Generated with Claude Code

turnipdabeets and others added 23 commits October 26, 2026 14:36
- Require posthog-ios 4.x.
- Adapt to the reloadFeatureFlags(_:) callback that now passes a
  PostHogFeatureFlagsLoaded (PostHog/posthog-ios#913).
- Note the payload decoding changes from PostHog/posthog-ios#903.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PostHog/posthog-ios#905 removes the legacy version/build properties from
lifecycle events in 4.0, so Flutter iOS and macOS apps stop sending them.

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

posthog-ios 4.0 removes the didReceiveFeatureFlags notification.
Passes options and captureAi through to posthog-ios and posthog-android 4.0; Windows, Linux and web send known options as their legacy properties.
Add captureAiCompression, captureAiMaxQueueSize, captureAiTimeout and
captureAiMaxEventBytes. Set values are sent to native setup and applied to
the posthog-ios and posthog-android config; unset values are omitted so the
native defaults apply. They have no effect on Windows, Linux and web.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
null means the event wasn't admitted: dropped by beforeSend, oversized on
iOS and macOS, SDK disabled or opted out, or an unsupported platform. On
Windows, Linux and web captureAi is a no-op that sends nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
posthog-android now checks the size before queuing (f46a9711).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A 404 usually means a misconfigured proxy and a 429 an overloaded Envoy; both are worth retrying with the same backoff, Retry-After handling and retry budget. Redirects stay terminal.
…e 404

After a batch fails its retries, later flushes make one attempt each and
pause 6s doubling to 30s until a batch is delivered. Before, every flush,
including the one each capture starts at flushAt, sent 4 requests, so a
missing capture route kept resending the batch.

A 404 prints one warning per client even without debug, naming the URL
and the path a proxy or self-hosted instance must serve.
A host with proxy credentials in its userinfo would print them to app logs.
… fix/v6-desktop-retry-404-429

# Conflicts:
#	.changeset/v6-desktop-capture-v1.md
#664)

* chore!: pass the loaded flags to onFeatureFlags and reloadFeatureFlags

onFeatureFlags and reloadFeatureFlags now carry a PostHogFeatureFlagsLoaded with the enabled flags, their values and whether loading failed, matching posthog-ios 4.0 and posthog-android 4.0. On web, reloadFeatureFlags completes right away with the flags loaded so far, because posthog-js doesn't report when a reload finishes.

* fix: complete the web reloadFeatureFlags with the reloaded flags

Wait for the next posthog-js onFeatureFlags call instead of returning the flags already loaded, so a failed reload reports errorsLoading. Complete right away when flags are disabled, and after twice the flags request timeout when posthog-js skips the request without calling back.

* chore: use PostHogFeatureFlagsCallback from posthog-android 4.0

* chore: fix ktlint function-signature

* fix: await posthog-js reloadFeatureFlagsAsync on web

The next onFeatureFlags callback can carry a response from a request already in flight, so reloadFeatureFlags() could complete with flags from before the reload. posthog-js 1.438.2+ settles reloadFeatureFlagsAsync() after this reload's own request; use it when present and keep the callback path for older posthog-js.

* docs: pass the loaded flags in the setup example

* docs: drop best-effort web note from the person and group property methods

* fix(web): wait for posthog-js flags retries before reporting a reload failure

posthog-js retries a timed-out /flags request once by default, 500 ms later, inside the same reload. The older-JS deadline of twice the request timeout reported cached flags with errorsLoading set before a successful retry landed.

* docs: note where onFeatureFlags and errorsLoading differ on Android and web

* docs: describe the older posthog-js reload timeout as the full retry budget

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… fix/v6-desktop-retry-404-429

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Windows and Linux, the options of capture, screen, captureException,
identify, setPersonProperties, alias and group now go into the event's
capture v1 `options` as they are, unknown keys included, instead of being
mapped to legacy `$` properties. An option still wins over its legacy
property, which is moved into `options` only when the option is unset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Windows and Linux, an event's properties are now the ones the SDK
sets, then the registered ones, then the event's own, each winning over
the ones before, and the Dart beforeSend callbacks run after that merge.
They see and can change every property and option the SDK adds, and the
event is queued as they leave it. A caller or registered value changes
that event only.

Person processing is no longer a `$process_person_profile` property: the
event carries `process_person_profile: false` in its options only while
person processing is off and neither an option nor a property sets it,
and omits it otherwise. The event's timestamp is taken before the
callbacks run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g-android

A transient failure or a 2xx whose per-event results ask to retry no longer
resends within the flush (3 tries, 3 s apart). Each one pauses the queue for
1 s doubling to 30 s, with ±25% jitter from an injectable source. A
Retry-After is a floor applied after the jitter, capped at 30 s, instead of
replacing the backoff, so `Retry-After: 1` no longer resends every 3 s.
A delivered or dropped batch resets the backoff.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uration

The 10 s whole-call timeout could fail a large batch on a slow uplink on
every attempt. A request now fails only after 10 s without progress:
connecting (HttpClient.connectionTimeout), the socket taking a 64 KiB body
chunk, the response headers, or a response body chunk. This is the closest
dart:io gets to the per-read/per-write idle timeouts of OkHttp and
URLSession: like them, it can't see the bytes still in the kernel send
buffer, so the wait for headers starts once the last chunk is handed over.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A 413 halved only the batch size and resent at once in the same flush. Like
posthog-ios and posthog-android, it now also halves flushAt, kept within
the batch size, and the smaller batches go out with the next flush (the
next capture over flushAt, or the periodic flush). No backoff is added:
posthog-ios ends the flush without one; posthog-android pauses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Windows and Linux, captureAi now builds the event like capture, runs
the Dart beforeSend callbacks, and queues it on disk apart from other
events, in posthog_ai_queue/. It is sent to /i/v1/ai/events with the
same wire format, batching, retry rules and backoff as analytics events,
and returns the event's uuid, or null when the event isn't queued:
dropped by beforeSend, opted out, or over the size limit.

- A serialized event over captureAiMaxEventBytes, capped at and by
  default 8 MiB plus 64 KiB, measured before compression, is dropped with
  a log line naming only the event and its size.
- The queue keeps captureAiMaxQueueSize events (100 by default) and at
  most 50 MiB, dropping the oldest first, and flushes as soon as 5 MiB
  is queued.
- Requests use captureAiCompression (gzip by default) and are bounded by
  captureAiTimeout (60 seconds by default).
- Each endpoint keeps its own retry identity, timers, backoff and 413
  batch size, so a failing AI request doesn't hold back other events.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…esets

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Like posthog-ios and posthog-android, a full capture v1 request's worth of
queued bytes (captureV1MaxBatchBytes) now flushes as flushAt does, so a few
large events go out before the queue starts dropping them. The file queue
keeps each event's serialized size: measured when it is added, and read
from the file sizes when a later process loads the queue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review · Standard · reviewed 280ae5e: 1 Must fix, 2 Should fix. This pull request is large, so the review ran in 4 parts with less depth than usual.

This is the only automatic review while this pull request is a draft. Comment @posthog review to review new changes sooner. Otherwise, a review of the new changes runs when you mark it ready for review.

See this review and its findings in PostHog Review. Comment @posthog review --deep for a Deep review. A Deep review takes longer and looks deeper than a Standard review.

Comment thread posthog_flutter/lib/src/core/posthog_core.dart Outdated
Comment thread posthog_flutter/lib/src/core/posthog_core_stateless.dart Outdated
Comment thread posthog_flutter/lib/src/core/posthog_core_stateless.dart Outdated
@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

posthog-flutter Compliance Report

Date: 2026-10-29T15:39:45.239912+00:00
Duration: 97728ms

✅ All Tests Passed!

47/47 tests passed


Capture Tests

✅ 30/30 tests passed

View Details
Test Status Duration
Format Validation.Event Has Required Fields ✅ 147ms
Format Validation.Event Has Uuid ✅ 119ms
Format Validation.Event Has Lib Properties ✅ 117ms
Format Validation.Distinct Id Is String ✅ 116ms
Format Validation.Token Is Present ✅ 117ms
Format Validation.Custom Properties Preserved ✅ 117ms
Format Validation.Event Has Timestamp ✅ 119ms
Format Validation.Non Utc Event Timestamp Is Converted To Utc ✅ 118ms
Retry Behavior.Retries On 503 ✅ 5332ms
Retry Behavior.Does Not Retry On 400 ✅ 2119ms
Retry Behavior.Does Not Retry On 401 ✅ 2119ms
Retry Behavior.Respects Retry After Header ✅ 8128ms
Retry Behavior.Implements Backoff ✅ 15440ms
Retry Behavior.Retries On 500 ✅ 5229ms
Retry Behavior.Retries On 502 ✅ 5229ms
Retry Behavior.Retries On 504 ✅ 5226ms
Retry Behavior.Max Retries Respected ✅ 15447ms
Deduplication.Generates Unique Uuids ✅ 125ms
Deduplication.Preserves Uuid On Retry ✅ 5225ms
Deduplication.Preserves Uuid And Timestamp On Retry ✅ 10339ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 5233ms
Deduplication.No Duplicate Events In Batch ✅ 126ms
Deduplication.Different Events Have Different Uuids ✅ 119ms
Compression.Sends Gzip When Enabled ✅ 117ms
Batch Format.Uses Proper Batch Structure ✅ 117ms
Batch Format.Flush With No Events Sends Nothing ✅ 110ms
Batch Format.Multiple Events Batched Together ✅ 128ms
Error Handling.Does Not Retry On 403 ✅ 2119ms
Error Handling.Does Not Retry On 413 ✅ 2118ms
Error Handling.Retries On 408 ✅ 5228ms

Feature_Flags Tests

✅ 17/17 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id ✅ 14ms
Request Payload.Flags Request Uses V2 Query Param ✅ 12ms
Request Payload.Flags Request Hits Flags Path Not Decide ✅ 13ms
Request Payload.Flags Request Omits Authorization Header ✅ 12ms
Request Payload.Token In Flags Body Matches Init ✅ 12ms
Request Payload.Groups Round Trip ✅ 14ms
Request Payload.Groups Default To Empty Object ✅ 12ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False ✅ 12ms
Request Payload.Disable Geoip Omitted Defaults To False ✅ 12ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key ✅ 11ms
Request Lifecycle.No Flags Request On Init Alone ✅ 5ms
Request Lifecycle.No Flags Request On Normal Capture ✅ 115ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests ✅ 19ms
Request Lifecycle.Mock Response Value Is Returned To Caller ✅ 11ms
Retry Behavior.Retries Flags On 502 ✅ 121ms
Retry Behavior.Retries Flags On 504 ✅ 116ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event ✅ 120ms

Brings in #678's backoff, idle-progress timeout, 413 handling and 5 MiB
queued-bytes flush trigger, applied per capture lane so the analytics and
AI endpoints each keep their own backoff, flushAt and batch size.

- FileEventQueue: one size tracker, a running total (byteCount) kept on
  add, remove and load, used by both the 5 MiB flush trigger and the AI
  50 MiB cap. add() still takes pre-encoded json/bytes to skip a second
  encode.
- _CaptureLane gains flushAt; failedFlushes now drives captureRetryDelay
  per lane, and a 413 halves the lane's batch size and flushAt and ends
  its flush.
- captureAiTimeout is the AI lane's idle-progress timeout, like
  analytics' 10 s, instead of a whole-request bound.
- Test: the AI and analytics endpoints back off independently.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@turnipdabeets
turnipdabeets marked this pull request as ready for review October 28, 2026 17:29
@turnipdabeets
turnipdabeets requested a review from a team as a code owner October 28, 2026 17:29

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review · Standard · reviewed aba2752: 1 Must fix. This pull request is large, so the review ran in 4 parts with less depth than usual.

This is review round 3 on this pull request. When findings keep coming back in the same code, the approach is usually the problem. Before the next fix, check whether a different design would remove the whole class of findings.

Comment thread posthog_flutter/lib/src/core/posthog_core.dart Outdated
A flush that kept finding queued events held every delivered payload
until it ended. Emit flush per batch so multi-megabyte AI events are
released as soon as they are sent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@dustinbyrne dustinbyrne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed c3a3c04. The per-batch retention correction passes previous/head, later-failure and reentrancy controls. Public AI HTTP smoke and exact-head Windows/Linux plugin integrations pass.

One required correction remains: nested beforeSend edits mutate registered context and affect later events. Optional feedback clarifies migration wording and rejected-update person-processing policy.

AI-assisted review.

Comment thread posthog_flutter/lib/src/posthog_flutter_desktop.dart
Comment thread .changeset/v6-desktop-capture-v1.md Outdated
Comment thread .changeset/v6-desktop-capture-ai.md Outdated
@dustinbyrne
dustinbyrne requested a review from a team October 28, 2026 19:30
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review · Standard · reviewed 83ff3bb: no findings. This pull request is large, so the review ran in 4 parts with less depth than usual.

turnipdabeets and others added 4 commits October 28, 2026 16:13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orms

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A body that trickles in more often than the 10 s idle timeout reset it
forever, holding the flush. The body now also fails after 30 s in total.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread posthog_flutter/lib/src/core/posthog_core_stateless.dart
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
turnipdabeets and others added 3 commits October 28, 2026 18:39
…to consolidate-679

# Conflicts:
#	posthog_flutter/lib/src/core/posthog_core_stateless.dart
#673's head already matches #678's branch, merged in the previous commit;
this records #673's squashed #678 as merged so #679 can target #673.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@turnipdabeets
turnipdabeets changed the base branch from feat/v6-capture-options-ai to feat/v6-desktop-capture-v1 October 28, 2026 22:40

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review · Standard · reviewed 462f1ee: 3 Should fix. This pull request is large, so the review ran in 4 parts with less depth than usual.

This is review round 4 on this pull request. When findings keep coming back in the same code, the approach is usually the problem. Before the next fix, check whether a different design would remove the whole class of findings.

Comment thread posthog_flutter/lib/src/core/posthog_core.dart
Comment thread posthog_flutter/lib/src/posthog_flutter_desktop.dart Outdated
Comment thread posthog_flutter/lib/src/posthog_flutter_desktop.dart Outdated
@veria-ai

veria-ai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 1 · PR risk: 0/10

turnipdabeets and others added 4 commits October 29, 2026 10:19
* ci: update SDK compliance harness to 1.25.0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(compliance): bump the test harness to 1.26.0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review · Standard · reviewed 13cd119: 1 Must fix, 1 Should fix. This pull request is large, so the review ran in 4 parts with less depth than usual.

This is review round 5 on this pull request. When findings keep coming back in the same code, the approach is usually the problem. Before the next fix, check whether a different design would remove the whole class of findings.

Comment thread posthog_flutter/android/build.gradle
Comment thread posthog_flutter/lib/src/posthog_flutter_desktop.dart
Picks up #664's posthog-android 4.0 feature-flags callback; the desktop test's onFeatureFlags now takes the loaded flags.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants