Skip to content

docs(compliance): weekly SDK compliance matrix - #82

Merged
ioannisj merged 10 commits into
mainfrom
posthog-code/weekly-sdk-compliance-matrix
Oct 8, 2026
Merged

ioannisj merged 10 commits into
mainfrom
posthog-code/weekly-sdk-compliance-matrix

Conversation

@posthog

@posthog posthog Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Living SDK compliance matrix in compliance/, maintained by a bounded weekly audit: ≤3 SDKs are deeply re-verified per run (spec-affected → code-changed → pending-initial-audit → staleness-backstop), so every SDK is re-checked roughly every 4 weeks rather than all at once.

This is the accumulating baseline for the loop. Each run pushes onto this branch; it is not merged until a human reviews it.

Why

The repo's root README.md has carried a > Conformance matrix (per-SDK parity against each spec) — TODO placeholder since the specs were written. Spec changes land here continuously while the SDKs that must satisfy them live in 12 other repositories, so there was no record of which SDK satisfies which contract, where they diverge, or whether closing a gap needs a breaking change. This PR is that record, built incrementally so each run can be reviewed on its own.

Audited so far

64 contracts tracked per SDK: the 64 capabilities in the root README.md table, including bootstrap (added to the table by #97).

SDK Last audited Rows ✅ / 🟡 / ❌ / ➖ / ❓
posthog-js 2026-10-05 · 6538babc 64 26 / 21 / 12 / 5 / 0
posthog-go 2026-10-05 · 08549f42 64 8 / 14 / 9 / 33 / 0
posthog-dotnet 2026-10-05 · ae4d019c 64 5 / 19 / 10 / 30 / 0
posthog-php 2026-09-28 · 5451f4e0 63 11 / 11 / 8 / 33 / 0
posthog-ruby 2026-09-28 · 185060ab 63 9 / 13 / 8 / 33 / 0
posthog-python 2026-08-17 · 95c7f6e0 62 14 / 12 / 7 / 29 / 0
posthog-node 2026-08-17 · fbdb6c7b 62 10 / 16 / 8 / 28 / 0
posthog-ios 2026-08-17 · c0218386 62 32 / 18 / 7 / 5 / 0
posthog-android 2026-08-10 · 8659a7b4 59 31 / 16 / 9 / 3 / 0
posthog-java 2026-08-10 · 8659a7b4 59 12 / 13 / 6 / 28 / 0
posthog-flutter 2026-08-06 · 05b53dc 59 20 / 22 / 6 / 5 / 6
posthog-react-native 2026-08-06 · e1efa57 59 31 / 23 / 2 / 2 / 1

Pending initial audit: none — all 12 in-scope SDKs have at least one full audit on file.

Queued for next run (9): posthog-python and posthog-node first (both named by the new MCP Analytics spec and both reference implementations for Capture AI), then posthog-react-native and posthog-flutter (stalest; Flutter holds the matrix's entire ❓ backlog), then posthog-android with posthog-java, then posthog-ios, then posthog-php and posthog-ruby (one ➖ row each).

This run (2026-10-05) — posthog-go, posthog-dotnet, posthog-js

sdk-specs main advanced 1d5fe42 → 75c8f5d: a brand-new MCP Analytics capability (#87), the Evaluate Flags runtime-filter reshape (#77), the browser Session Replay Privacy body-scrubber replacement (#79), and the Logs 1 µs timestamp floor (#91). All three SDKs were selected on priority rule 1 — MCP Analytics names posthog-js's and posthog-go's packages explicitly, #79 can only land on the browser, and both server SDKs carry the flags delta — and all three were also in the oldest staleness cohort. The three-SDK cap was used in full for the first time.

Gaps discovered this run

  • posthog-go — MCP Analytics 🟡 (first audit, strong implementation): the $exception side-car omits the required $exception_source: "mcp.tool_call", and mechanism.synthetic is hardcoded true on a path only ever reached for a thrown error — the one case the spec says is not synthetic. Also no client_metadata intent source; the manual API rejects the value outright.
  • posthog-go — Exception Event Metadata ❌ (first audit): no exception_id/parent_id linkage, no $exception_source, no $exception_level on the core capture path.
  • posthog-go — Evaluate Flags 🟡 (first audit): no negative-knowledge retention, and GetFlagPayload returns a malformed serialized payload unvalidated and unlogged.
  • posthog-dotnet — Exception Event Metadata ❌ (first audit): the whole mechanism object is a fixed literal (source: "", synthetic: false, handled: true) emitted identically for every entry — two forbidden unknown-placeholders, handled copied onto every nested entry, no linkage fields.
  • posthog-dotnet — one defect explains four rows: an unguarded JsonDocument.Parse in both FeatureFlag factories makes a malformed payload throw during flag construction, discarding the flag's correctly evaluated local value on one path and the entire remote response on the other. Fixing that one call pair moves Evaluate Flags, Get Feature Flag Payload, Get Feature Flag Result, and Get Feature Flags And Payloads together.
  • posthog-dotnet — Capture AI 🟡 (first audit): PostHog.AI ships real $ai_* support but routes it through ordinary Capture(...), with no isolated AI route. The capture-ai spec's applicability list does not name .NET at all, which is worth correcting upstream.
  • posthog-js — MCP Analytics 🟡 (first audit): @posthog/mcp is the richest implementation in the matrix, but an unknown tool is misreported as a failed $mcp_tool_call on both instrumentation paths — inflating the server's own tool error rate with names it never registered — and neither $mcp_unknown_tool nor $mcp_input_required is emitted.
  • posthog-js — Exception Event Metadata 🟡 (first audit): the most complete producer envelope audited, missing only $exception_source and a capture category on the window.onerror / unhandledrejection handlers, which fall back to generic.
  • posthog-js — Session Replay Debug Properties 🟡 (first audit, re-scored against docs(session-replay): split replay debug properties into required keys and a throttled optional bundle #96): the required keys, the $-prefix gate, and the 30 s throttle on the optional bundle all conform. The one gap is that after stopSessionRecording() on a loaded recorder, events keep active/buffering instead of $recording_status: disabled.
  • Four for four, twice over: experiment holdouts (docs: specify experiment holdouts in local flag evaluation #76) and Evaluate Flags negative-knowledge retention are now confirmed unimplemented in every server SDK checked since those requirements landed — posthog-php, posthog-ruby, posthog-go, posthog-dotnet. The holdout gap is a silent correctness divergence (a flag with a holdout is evaluated locally as though it had none), the definition data is already loaded and simply unread, and it is the highest-value single fix in the matrix right now.

Gaps resolved this run

  • posthog-go — Flag Definition Loader: the missing shared-cache extension point is now a full FlagDefinitionCacheProvider with fail-safe fallback in both directions.
  • posthog-go — Flush: a real blocking Flush()/FlushWithContext() now exists and drains pending uploads (the retry-exhaustion drop issue persists, so the row stays 🟡).
  • posthog-js — Session Replay Privacy ✅ reconfirmed on fresh evidence against the new docs: clarify custom replay body scrubber replacement #79 requirement, including both subtle scenarios: the initial-entry fallback is built from metadata captured before the callback runs, and a throwing callback is caught per record while the rest of the batch keeps flowing. Last run's n31 withdrawal was a contract correction made without re-auditing; this run verified it against the merged text.

Needs human attention

#103 made $exception_list[0] canonical for Capture Exception. posthog-php and posthog-ruby are re-scored ✅ here and posthog-go drops that gap, but the other seven SDK files still mark Capture Exception down for missing top-level $exception_type/$exception_message (posthog-android and posthog-node at ❌). Their next audit should re-score them.

Two upstream items: the capture-ai spec's applicability list should name posthog-dotnet among the SDKs with AI support, and the long-standing Applicability: client prose versus @both acceptance tags on the four Set/Reset Person/Group Properties For Flags specs still needs reconciling — it is the most consistent gap in the entire matrix (7 of 7 server SDKs) and the right remediation depends on which way that is resolved.

Scope

Documentation only — every file is under compliance/. No spec content, no SDK code, nothing outside that directory.


Created with PostHog Desktop

🤖 Generated with Claude Code

…xpanded flag specs

Weekly bounded SDK compliance audit for 2026-09-28.

sdk-specs advanced 27 commits across 23 capability specs since the last run,
dominated by server-side feature-flag semantics (local-feature-flag-evaluator
+929 lines, evaluate-flags +209, the three get-feature-flag-* payload contracts,
flag-definition-loader +73), plus a new client-only Session Replay Debug
Properties capability. Selection followed priority rule 1 (affected by spec
changes): posthog-php and posthog-ruby are the server SDKs with local-evaluation
engines that this delta lands on most directly, and both were confirmed
code-drifted and past the ~4-week window.

Both files grow from 59 to 63 rows (Capture AI, Evaluate Flags, Exception Event
Metadata, Session Replay Debug Properties audited for the first time).

Two cross-cutting findings:
- Experiment holdouts are unimplemented in both evaluators, a silent correctness
  divergence from the backend for any flag configured with a holdout.
- The new malformed-payload rule is a real gap: php returns the correct sentinel
  but logs nothing; ruby returns the raw serialized string on three public paths.

One row improved on a real code change (ruby's before-send hook now drops the
event when a hook raises). Six rows were downgraded on new spec requirements
rather than regressions.

Scope: compliance/ documentation only.

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

Generated-By: PostHog Desktop
Task-Id: e5d845ad-60cf-4b6d-a294-f997f51b0845
@posthog
posthog Bot force-pushed the posthog-code/weekly-sdk-compliance-matrix branch from c5af5b5 to 773261c Compare October 5, 2026 06:21
…ainst the MCP analytics spec

Weekly bounded re-audit, 2026-10-05. sdk-specs main advanced 1d5fe42 -> 75c8f5d:
a new MCP Analytics capability (#87), the Evaluate Flags runtime filter reshape
(#77), the browser replay network body-scrubber replacement (#79), and the 1us
log timestamp floor (#91). Contract count is now 64 per SDK.

Selected posthog-go, posthog-dotnet, and posthog-js on priority rule 1 (all
three are named or directly implicated by this cycle's spec changes) plus the
oldest staleness cohort, using the full three-SDK cap for the first time.
All five previously-missing contract rows were audited from scratch on each.

Notable: experiment holdouts and Evaluate Flags negative-knowledge retention are
now unimplemented in four for four of the server SDKs checked since those
requirements landed; posthog-js has the most complete exception-metadata producer
envelope in the matrix but misreports unknown MCP tools as failed tool calls; and
one unguarded JsonDocument.Parse explains four posthog-dotnet rows at once.

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

Generated-By: PostHog Desktop
Task-Id: a3ec4da7-040c-499d-9222-23e683e09387
@posthog posthog Bot changed the title docs(compliance): weekly SDK compliance matrix — posthog-php, posthog-ruby docs(compliance): weekly SDK compliance matrix Oct 5, 2026
@ioannisj ioannisj self-assigned this Oct 7, 2026
@ioannisj

ioannisj commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

🤖 An AI agent wrote this on behalf of @ioannisj.

Pushed a few corrections on top of the bot's run, mostly rows that main had already moved past:

The other SDK files still carry that same top-level exception gap (android and node at ❌), so their next audit should pick it up.

@ioannisj
ioannisj marked this pull request as ready for review October 7, 2026 08:46
@ioannisj
ioannisj requested a review from a team as a code owner October 7, 2026 08:46
@ioannisj
ioannisj merged commit 7e459b2 into main Oct 8, 2026
9 checks passed
@ioannisj
ioannisj deleted the posthog-code/weekly-sdk-compliance-matrix branch October 8, 2026 17:02
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