Skip to content

feat: Add environment ID support for hooks - #414

Open
kinyoklion wants to merge 3 commits into
mainfrom
devin/1786659538-ruby-hook-environment-id
Open

feat: Add environment ID support for hooks#414
kinyoklion wants to merge 3 commits into
mainfrom
devin/1786659538-ruby-hook-environment-id

Conversation

@kinyoklion

@kinyoklionkinyoklion commented Aug 13, 2026

Copy link
Copy Markdown
Member

Requirements

  • I have added test coverage for new or changed functionality
  • I have followed the repository's pull request submission guidelines
  • I have validated my changes against all supported platform versions

Related issues

Part of the cross-SDK work to expose the LaunchDarkly environment ID on hook contexts, per the hooks and OTEL specs. Equivalent implementations: launchdarkly/dotnet-core#81, launchdarkly/python-server-sdk#484, launchdarkly/cpp-sdks#594.

Describe the solution you've provided

EvaluationSeriesContext gains an optional environment_id, populated by LDClient from the active data system:

Interfaces::Hooks::EvaluationSeriesContext.new(key,context,default,method,@data_system.environment_id)

Both data systems now report it, so the value is only visible once LaunchDarkly has actually answered:

  • FDv1 — X-LD-EnvID is read from the streaming connection response headers (SSE::Client#on_connect) and from polling responses (Requestor#request_all_data_with_headers), then recorded on the data source UpdateSink, which the FDv1 data system exposes.
  • FDv2 — the ID was already parsed into Basis/Update by the polling and streaming data sources but discarded; the FDv2 data system now latches it from a successful initializer basis and from VALID synchronizer updates. This also covers the FDv1 fallback synchronizer, which reports headers the same way.

Error responses, missing headers, and empty header values are ignored and never clear a previously known ID.

The contract test service reports environmentId on the evaluation series context and declares the hook-environment-id capability.

Describe alternatives you've considered

A shared environment-ID holder threaded into each data source was rejected as a side channel; carrying the value with the data/response metadata matches the other SDKs and the existing FDv2 Basis/Update shape.

Additional context

  • No ld-eventsource change is needed: SSE::Client#on_connect already yields the successful response headers on every connection and reconnection.
  • hooks/evaluation/provides the environment ID passes against the released v2.39.0 harness (default/streaming and polling modes). The repo's v3 contract-test run is pinned to v3.0.0-alpha.6, which predates that test; bumping the pin can be a separate ci: change.
  • ruby-server-sdk-otel's tracing hook only uses the configured environment ID today; adding the series-context fallback is a follow-up in that repo.

Link to Devin session: https://app.devin.ai/sessions/bfe54128e2804a96bb100e6120e9a3ef
Requested by: @kinyoklion


Note

Overview
Hooks now receive the LaunchDarkly environment ID on EvaluationSeriesContext when the SDK has learned it from the server. LDClient passes @data_system.environment_id into each evaluation series.

FDv1 records X-LD-EnvID from streaming connect headers and from polling via a new request_all_data_with_headers path on the requestor; values land on the data source UpdateSink and are exposed through the FDv1 data system.

FDv2 retains environment_id from successful initializer bases and from synchronizer updates in VALID state (empty or error responses do not clear a known ID).

Contract test service advertises hook-environment-id and includes environmentId in hook callbacks; CI contract tests are pinned to v3 instead of v3.0.0-alpha.6.

Reviewed by Cursor Bugbot for commit f3fe346. Bugbot is set up for automated code reviews on this repo. Configure here.

Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
@kinyoklionkinyoklion self-assigned this Aug 13, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration

Copy link
Copy Markdown
Contributor

@cursor review

Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
@kinyoklion
kinyoklion marked this pull request as ready for review August 18, 2026 21:10
@kinyoklion
kinyoklion requested a review from a team as a code ownerAugust 18, 2026 21:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@kinyoklion@jsonbailey