Skip to content
PostHogPublic

About

The cross-SDK contracts for PostHog SDKs

Resources

Code of conduct

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

sdk-specs

Platform-agnostic specifications for PostHog SDK capabilities — the canonical contract every SDK must satisfy so behavior stays on par across platforms (Android, iOS, React Native, JavaScript/Web, Flutter, …).

This repo holds specs and archived change history, not proposal-only RFCs or SDK code. Implementations live in their own repos (posthog-android, posthog-ios, posthog-js, posthog-flutter, …). Each spec here is the canonical behavior derived from the shipped implementations plus the relevant backend service, stating the winner wherever SDKs currently diverge.

Acceptance specs

The acceptance/ directory contains Gherkin feature files for cross-SDK acceptance tests. acceptance/public/ covers public SDK API behavior, while acceptance/private/ covers shared internal SDK behavior such as batching, storage, feature flags, sessions, and replay. Tags on each feature indicate whether scenarios apply to client SDKs, server SDKs, or both.

Use @sdk:server and @sdk:client only after verifying the scenarios end to end through the shared harness with a real SDK adapter. Controlled hosts alone do not qualify. These tags opt scenarios into the integration suite; legacy @server, @client, and @both describe applicability without opting scenarios in.

The server cases in acceptance/public/identify.feature, acceptance/public/alias.feature, and acceptance/public/group-identify.feature call the SDK, flush, and inspect mock-server traffic using the draft2 harness. They check delivery rather than private queue state. Group-identify cases check group identity and supplied scalar or nested properties under $group_set. Server cases in acceptance/public/capture-exception.feature report a native handled exception, flush, and check the received structured exception summary, handled state, stack frames, identity and caller properties. Migrated server scenarios use @sdk:server for adapter-declared SDK type selection; the parameterized examples have per-row @case: labels. An ordinary single-case scenario needs no authored case ID. Unmigrated client and negative scenarios retain their preconditions and are not selected by the opt-in tags. Server cases in acceptance/public/evaluate-flags.feature evaluate once per request, then call public getters and filters on the native snapshot. They compare documented scalar/rich values and decoded/serialized payloads, and inspect remote context and flushed exposure delivery. Integration tags identify executable coverage, not a passing conformance verdict: non-compliant SDK results remain failing assertions. The YAML-parity scenarios use the same Gherkin harness but retain their own capability-driven selection.

Capabilities

Capability Spec Scope Status
Logs openspec/specs/logs/spec.md product Canonical
Traces openspec/specs/traces/spec.md product Canonical
MCP Analytics openspec/specs/mcp-analytics/spec.md product Canonical
Tracing Headers openspec/specs/tracing-headers/spec.md cross-SDK correlation Canonical
Alias openspec/specs/alias/spec.md public API Canonical
Bootstrap openspec/specs/bootstrap/spec.md public API (configuration) Canonical
Capture openspec/specs/capture/spec.md public API Canonical
Capture AI openspec/specs/capture-ai/spec.md public API (server) Canonical
Capture Exception openspec/specs/capture-exception/spec.md public API Canonical
Create Person Profile openspec/specs/create-person-profile/spec.md public API Canonical
Debug openspec/specs/debug/spec.md public API Canonical
Exception Steps openspec/specs/exception-steps/spec.md public API Canonical
Flush openspec/specs/flush/spec.md public API Canonical
Get Anonymous ID openspec/specs/get-anonymous-id/spec.md public API Canonical
Get Distinct ID openspec/specs/get-distinct-id/spec.md public API Canonical
Get Feature Flag openspec/specs/get-feature-flag/spec.md public API Canonical
Get Feature Flag Payload openspec/specs/get-feature-flag-payload/spec.md public API Canonical
Get Feature Flag Result openspec/specs/get-feature-flag-result/spec.md public API Canonical
Get Feature Flags openspec/specs/get-feature-flags/spec.md public API Canonical
Get Feature Flags And Payloads openspec/specs/get-feature-flags-and-payloads/spec.md public API Canonical
Evaluate Flags openspec/specs/evaluate-flags/spec.md public API (server) Canonical
Get Session ID openspec/specs/get-session-id/spec.md public API Canonical
Group openspec/specs/group/spec.md public API Canonical
Group Identify openspec/specs/group-identify/spec.md public API Canonical
Identify openspec/specs/identify/spec.md public API Canonical
Is Feature Enabled openspec/specs/is-feature-enabled/spec.md public API Canonical
Is Opt Out openspec/specs/is-opt-out/spec.md public API Canonical
Is Session Replay Active openspec/specs/is-session-replay-active/spec.md public API Canonical
On Feature Flags openspec/specs/on-feature-flags/spec.md public API Canonical
Opt In openspec/specs/opt-in/spec.md public API Canonical
Register openspec/specs/register/spec.md public API Canonical
Reload Feature Flags openspec/specs/reload-feature-flags/spec.md public API Canonical
Reset openspec/specs/reset/spec.md public API Canonical
Reset Group Properties For Flags openspec/specs/reset-group-properties-for-flags/spec.md public API Canonical
Reset Person Properties For Flags openspec/specs/reset-person-properties-for-flags/spec.md public API Canonical
Screen openspec/specs/screen/spec.md public API Canonical
Set Group Properties For Flags openspec/specs/set-group-properties-for-flags/spec.md public API Canonical
Set Person Properties openspec/specs/set-person-properties/spec.md public API Canonical
Set Person Properties For Flags openspec/specs/set-person-properties-for-flags/spec.md public API Canonical
Setup openspec/specs/setup/spec.md public API Canonical
Shutdown openspec/specs/shutdown/spec.md public API Canonical
Start Session Recording openspec/specs/start-session-recording/spec.md public API Canonical
Stop Session Recording openspec/specs/stop-session-recording/spec.md public API Canonical
Unregister openspec/specs/unregister/spec.md public API Canonical
Application Lifecycle openspec/specs/application-lifecycle/spec.md internal behavior Canonical
Autocapture openspec/specs/autocapture/spec.md internal behavior Canonical
Before Send Hook openspec/specs/before-send-hook/spec.md internal behavior Canonical
Consent Gating openspec/specs/consent-gating/spec.md internal behavior Canonical
Device ID Generator openspec/specs/device-id-generator/spec.md internal behavior Canonical
Event Batcher openspec/specs/event-batcher/spec.md internal behavior Canonical
Exception Event Metadata openspec/specs/exception-event-metadata/spec.md internal behavior (client/server) Canonical
Feature Flag Cache openspec/specs/feature-flag-cache/spec.md internal behavior Canonical
Feature Flag Called Tracker openspec/specs/feature-flag-called-tracker/spec.md internal behavior Canonical
Flag Definition Loader openspec/specs/flag-definition-loader/spec.md internal behavior Canonical
HTTP Client openspec/specs/http-client/spec.md internal behavior Canonical
Local Feature Flag Evaluator openspec/specs/local-feature-flag-evaluator/spec.md internal behavior Canonical
Persistent Storage openspec/specs/persistent-storage/spec.md internal behavior Canonical
Remote Config openspec/specs/remote-config/spec.md internal behavior Canonical
Retry Queue openspec/specs/retry-queue/spec.md internal behavior Canonical
Session Manager openspec/specs/session-manager/spec.md internal behavior Canonical
Session Replay Debug Properties openspec/specs/session-replay-debug-properties/spec.md internal behavior Canonical
Session Replay Ingestion Controls openspec/specs/session-replay-ingestion-controls/spec.md internal behavior Canonical
Session Replay Privacy openspec/specs/session-replay-privacy/spec.md internal behavior Canonical
Surveys openspec/specs/surveys/spec.md internal behavior Canonical

Each capability is one folder under openspec/specs/<capability>/. A new capability is a new sibling folder — never folded into an existing spec.

How this repo works (OpenSpec)

This repo uses OpenSpec for spec-driven development. Install the CLI to propose and validate changes:

npm install -g @fission-ai/openspec

The repo includes shared OpenSpec agent skills for Codex and pi under .agents/skills/. Claude Code uses the same files through the .claude symlink, while pi-specific prompt templates remain under .pi/prompts/. The commands below use Claude Code syntax; in pi, replace : with - (for example, /opsx-propose). All integrations also support standalone OpenSpec stores when a store is named.

The source of truth is openspec/specs/<capability>/spec.md. You never hand-edit it — you propose a change, implement it, and archiving syncs the change into the spec.

openspec/
├── config.yaml                workflow schema and artifact rules
├── project.md                 project context + conventions
├── specs/<capability>/spec.md current truth (one folder per capability)
└── changes/                   in-flight changes; archive/ holds finished ones

Workflow (OpenSpec CLI + /opsx agent commands):

  1. Propose — /opsx:propose add-<capability> (or openspec new change "<name>"). Creates changes/<name>/ with proposal.md, design.md, tasks.md, and a delta spec under changes/<name>/specs/<capability>/spec.md.
  2. Apply — /opsx:apply to work through tasks.md.
  3. Archive — /opsx:archive syncs the delta into specs/<capability>/spec.md and moves the change to changes/archive/YYYY-MM-DD-<name>/.

All three steps happen on one branch and in the same PR. Before merging, sync the delta into openspec/specs/ and archive the change. Do not merge proposal-only PRs or defer applying and archiving to a follow-up PR.

Archived proposal.md files record change history, not active RFCs. Archiving means the spec change is complete; SDK implementations live in their own repositories and do not need to be complete before the spec change is archived. See AGENTS.md for agent instructions.

Two kinds of change:

  • New capability → add-<capability> (e.g. add-feature-flags) creates a new spec folder.
  • Porting a capability to a new SDK → add-<capability>-<platform> (e.g. add-logs-android), a delta measured against the existing contract.

Spec format

### Requirement: Public capture API
The SDK SHALL expose ...

#### Scenario: missing level defaults to info
- **WHEN** the app calls `captureLog({ body: "hello" })` with no level
- **THEN** the record has severityNumber 9 (`INFO`)

Every requirement needs at least one scenario. Validate with:

openspec validate --specs --strict

Status

Conformance matrix (per-SDK parity against each spec) — TODO. Track which SDKs satisfy each requirement and where they currently diverge.

About

The cross-SDK contracts for PostHog SDKs

Resources

Code of conduct

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages