Skip to content

docs(capture): specify the environment-sourced release identifier - #80

Merged
ioannisj merged 4 commits into
mainfrom
posthog/spec-release-id-env-property
Oct 8, 2026
Merged

ioannisj merged 4 commits into
mainfrom
posthog/spec-release-id-env-property

Conversation

@posthog

@posthog posthog Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Three server SDKs now read a deploy-time release id from POSTHOG_RELEASE_ID and send it as $release_id on every event:

The capture spec does not mention $release_id at all. The only existing reference is in exception-event-metadata, which requires exception builders to preserve release context "where supplied" and forbids them from inventing release identifiers — it never says where a supplied value comes from. So the producer contract is missing: the variable name, when it is read, how blank values are handled, which event types carry it, and what wins when a caller sets the property explicitly.

Changes

Adds one capture requirement, applied and archived on this branch:

  • POSTHOG_RELEASE_ID is read once while the client is constructed, trimmed, and a blank value counts as unset (no empty $release_id).
  • The property is stamped on the shared event path, so ordinary captures, exception captures, identify, alias, and group_identify all carry it. Low-level passthrough APIs that bypass that path (PHP's raw()) are out of scope.
  • The environment value is a default: an explicit $release_id in call properties, super/registered properties, or an ambient request context wins.
  • The stamp happens before before_send, so a hook can remove it.
  • The value never lands in $set, $set_once, or $group_set.
  • A minimized $feature_flag_called event keeps $release_id, matching PHP and Ruby; Python needs a follow-up to add it to its allowlist.
  • Eleven scenarios covering the above, worded so a harness can bind them on every server SDK (ambient context instead of super properties, $identify or $set for the person-properties event, person and group exclusions split).

Scoped to server SDKs that can read process environment — browser bundles get $release_id injected by posthog-cli instead.

Needs review

  • Minimized $feature_flag_called events keep $release_id. PHP and Ruby include it in their minimal allowlist with tests; Python excludes it. The property is static and low-cardinality per process, the category the feature-flag-called-tracker allowlist already keeps, so the spec follows the two SDKs and posthog-python needs a one-line follow-up.
  • The requirement is scoped as "a server SDK that can read its process environment" rather than naming the three SDKs. That leaves the boundary soft for embedded or sandboxed runtimes.

Validation

  • openspec validate document-release-id-env-property --strict: valid.
  • openspec validate --specs --strict: 63 passed, 0 failed.
  • Canonical/delta parity and git diff --check pass.
  • This is a spec change only. No executable SDK conformance tests were added, and the scenarios are contracts rather than a claim that any SDK has been tested against them.

Created with PostHog Desktop

🤖 Generated with Claude Code

Three server SDKs now read POSTHOG_RELEASE_ID and stamp $release_id on
every event they produce, but the capture contract never described the
property, its precedence, or the paths that carry it.

Adds a capture requirement covering the read-once-at-construction timing,
trimming with blank-as-unset, shared-path placement, explicit-value
precedence, before_send visibility, and exclusion from person and group
property payloads. Leaves the minimized $feature_flag_called divergence
unspecified.

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

Generated-By: PostHog Desktop
Task-Id: fb243d92-37c8-4181-8365-9985f279f6a8
@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 three fixes on top of the bot's draft:

  • The "not specified" sentence on minimized $feature_flag_called events contradicted openspec/specs/feature-flag-called-tracker/spec.md:212, which strips everything outside the allowlist. PHP and Ruby keep $release_id there and only Python strips it, so the clause now says minimized events keep it, with a scenario. Python needs a one-line follow-up (52aad23)
  • design.md, proposal.md and tasks.md described the split as Python vs PHP and left Ruby out (8ecee33)
  • Three scenarios couldn't bind on PHP or Ruby. Registered-wins needed super properties, which server SDKs don't have (openspec/specs/capture/spec.md:18). The examples table listed $identify, which Python can't emit. The exclusion scenario asserted $set, $set_once and $group_set on one event. Reworded around ambient context, added a person-properties scenario, and split the exclusion in two (947aa60)

Left out on purpose: an explicit null $release_id suppresses the env value in all three SDKs but the spec doesn't say so. There's no acceptance/public/capture.feature mirror for the new scenarios yet, since the harness has no env-var step. The minimized scenario's steps are also worded differently from the tracker's sibling scenarios. Any of those could be a follow-up.

@ioannisj
ioannisj marked this pull request as ready for review October 7, 2026 09:18
@ioannisj
ioannisj requested a review from a team as a code owner October 7, 2026 09:18
@ioannisj
ioannisj merged commit dadf28d into main Oct 8, 2026
10 checks passed
@ioannisj
ioannisj deleted the posthog/spec-release-id-env-property branch October 8, 2026 17:05
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