Skip to content

docs(capture): specify the client-level GeoIP option and per-call override - #131

Merged
turnipdabeets merged 4 commits into
mainfrom
posthog/client-level-geoip-option
Oct 21, 2026
Merged

turnipdabeets merged 4 commits into
mainfrom
posthog/client-level-geoip-option

Conversation

@posthog

@posthog posthog Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Why

The specs describe GeoIP control only as a per-call argument — capture, identify, alias, group-identify and the flag specs all list disable_geoip / disableGeoip, and no requirement says what an omitted value means or that server SDKs carry a client-level setting behind it. SDKs resolved that gap differently.

posthog-php#263 (merged 2026-10-16) added a client-level disableGeoip option with per-call overrides, and had to derive its inheritance rules and default by reading Node, Python and Go, because the contract does not state them. Its description notes the spec only defines a per-call option.

Changes

Adds one capture requirement, "Client-level GeoIP control with per-call override":

  • Server SDKs expose a client-level GeoIP option, defaulting to disabling backend enrichment; client SDKs do not need one.
  • An explicit per-call boolean wins in both directions; an omitted or null value inherits the client setting rather than meaning false.
  • $geoip_disable: true sits among the event's ordinary properties, never inside $set / $set_once / $group_set, is stamped before before_send, and is absent when enrichment stays on. A caller-supplied $geoip_disable is left alone.
  • Remote flag-evaluation requests carry the same effective value as the body's geoip_disable field.

Proposed, applied and archived on this branch as 2026-10-18-add-client-geoip-configuration.

Verified SDK behavior

SDK Client-level setting Default Per-call override
Node (core stateless) disableGeoip disables GeoIP yes (?? client setting)
Python disable_geoip disables GeoIP yes (None inherits)
Go Config.DisableGeoIP disables GeoIP no — Enqueue overwrites the per-message field from config
PHP disableGeoip (new) allows GeoIP (deliberate compatibility default) yes
Ruby, .NET, Elixir none n/a (.NET defaults the event property to disabled but flag-request control to enabled) per-call / property only

Uncertain — worth a human call

  • The default. Node, Python and Go agree on disabling by default, so the requirement states that. PHP chose false deliberately for release compatibility, and .NET's event and flag paths default differently. Confirm whether PHP's default is a sanctioned temporary divergence with a target major, and which of .NET's two defaults is intended.
  • Go's override. The requirement makes an explicit per-call value authoritative, which Go does not do today. That is listed as a required implementation change rather than a spec concession; confirm it is wanted.
  • No acceptance feature scenarios were added — the requirement's scenarios are spec-level only.

How did you test this code?

openspec validate --specs --strict reports the same 33 passed / 31 failed totals as the base branch (all pre-existing "requirement text is very long" warnings; the new requirement raises the same warning as its neighbours).


Created with PostHog Desktop

🤖 Generated with Claude Code

@turnipdabeets turnipdabeets self-assigned this Oct 20, 2026
@turnipdabeets
turnipdabeets force-pushed the posthog/client-level-geoip-option branch from dcb74f9 to 1713595 Compare October 20, 2026 18:01
@turnipdabeets
turnipdabeets marked this pull request as ready for review October 20, 2026 19:47
@turnipdabeets
turnipdabeets requested a review from a team as a code owner October 20, 2026 19:47
posthog Bot and others added 3 commits October 20, 2026 17:06
…rride

The specs listed a per-call disable_geoip argument on capture, identify,
alias, group_identify, and the flag APIs, but never said what an omitted
value means or that server SDKs carry a client-level setting behind it.
SDKs diverged as a result.

Adds a capture requirement covering the client-level option and its
default, per-call inheritance (explicit boolean wins, null inherits),
$geoip_disable marker placement, and the geoip_disable field on remote
flag-evaluation requests.

Co-Authored-By: Claude Opus 5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: 840fad87-610e-4e40-8719-c99b2c5616d2
posthog-php and posthog-rs ship with GeoIP enrichment enabled by
default, so requiring a disabled default would force a breaking change.
The default is now recommended rather than required; inheritance of an
unset per-call value, explicit per-call overrides, and keeping
$geoip_disable out of $set/$set_once/$group_set stay SHALL.

posthog-go's per-message DisableGeoIP is a plain bool, so it conforms
by keeping the client setting authoritative until a major release can
tell unset from false. The explicit-override scenario is tagged
@geoip_per_call_unset_capable. The proposal and design now list Rust
and drop the "majority" framing.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…st and .NET

Ruby and Elixir only send geoip_disable on flags requests; events never carry
$geoip_disable. Java has no GeoIP option. Rust and .NET keep a caller-supplied
$geoip_disable over the client setting, which the requirement forbids.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@turnipdabeets
turnipdabeets force-pushed the posthog/client-level-geoip-option branch from 1713595 to b35ba85 Compare October 20, 2026 21:20
@turnipdabeets
turnipdabeets changed the base branch from docs/acceptance-step-catalogue to main October 20, 2026 21:20

@marandaneto marandaneto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The code looks good; no qualifying findings. Verdict: correct.

# Conflicts:
#	openspec/specs/capture/spec.md
@turnipdabeets
turnipdabeets merged commit 52fb046 into main Oct 21, 2026
2 checks passed
@turnipdabeets
turnipdabeets deleted the posthog/client-level-geoip-option branch October 21, 2026 14:32
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.

2 participants