Skip to content

feat: add hook data per-hook mutable state#222

Merged
josecolella merged 1 commit intomainfrom
feat/hook-data-per-hook-state
Mar 5, 2026
Merged

feat: add hook data per-hook mutable state#222
josecolella merged 1 commit intomainfrom
feat/hook-data-per-hook-state

Conversation

@josecolella
Copy link
Collaborator

Summary

  • Add hook_data_for(hook) method to HookContext that provides per-hook isolated mutable state persisting across all hook stages (before → after → error → finally)
  • Add spec tests verifying hook_data isolation between hook instances (spec 4.1.5)
  • Add spec tests verifying finally hook receives evaluation details on both success and error paths (spec 4.3.8)

Spec References

Part of the spec compliance roadmap: #220

Test plan

  • bundle exec rspec spec/specification/hooks_spec.rb — 22 examples, 0 failures
  • bundle exec standardrb — no offenses

🤖 Jose's AI agent

…(spec 4.1.5, 4.3.8)

- Add hook_data_for(hook) to HookContext for per-hook isolated mutable
  state that persists across all hook stages (spec 4.1.5, 4.6.1)
- Add spec tests verifying hook_data isolation between hook instances
- Add spec tests verifying finally hook receives evaluation details
  on both success and error paths (spec 4.3.8)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jose Colella <jose.colella@gusto.com>
@josecolella josecolella requested a review from a team as a code owner March 5, 2026 16:38
@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the OpenFeature SDK by implementing a crucial feature for hooks: the ability to maintain mutable state specific to each hook instance throughout its lifecycle. This change ensures that hooks can store and retrieve data across their various stages, improving their utility and adherence to the OpenFeature specification. Accompanying these functional changes are comprehensive tests that validate the correct isolation of this per-hook data and confirm the finally hook's proper reception of evaluation details under both successful and erroneous conditions.

Highlights

  • Per-Hook Mutable State: Introduced a hook_data_for(hook) method to HookContext which provides an isolated, mutable hash for each hook instance, allowing state to persist across all hook stages (before, after, error, finally) as per OpenFeature specification 4.1.5 and 4.6.1.
  • Hook Data Isolation Tests: Added new spec tests to verify that the hook_data provided by hook_data_for is correctly isolated between different hook instances, ensuring no unintended state leakage.
  • Finally Hook Evaluation Details Tests: Implemented spec tests to confirm that the finally hook receives comprehensive evaluation details, including the resolved value on success and default value with error information on failure, aligning with OpenFeature specification 4.3.8.
Changelog
  • lib/open_feature/sdk/hooks/hook_context.rb
    • Initialized @hook_data as an empty hash in the constructor.
    • Added hook_data_for(hook) method to return a mutable hash scoped to a specific hook instance using its object_id.
  • spec/specification/hooks_spec.rb
    • Added a new context block for Requirement 4.1.5, including tests for per-hook data persistence across stages and isolation between hook instances.
    • Added a new context block for Requirement 4.3.8, including tests to verify that the finally hook receives correct evaluation details on both success and error paths.
Activity
  • The pull request author, josecolella, has added new functionality to support per-hook mutable state.
  • New spec tests have been added to cover OpenFeature specification requirements 4.1.5, 4.6.1, and 4.3.8.
  • The author confirmed that all existing RSpec tests pass and no StandardRB offenses were found.
  • The PR description indicates that an AI agent was involved in the process.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a mechanism for hooks to maintain mutable state across their lifecycle stages, along with corresponding specification tests. The implementation in HookContext uses hook.object_id to scope data, which could lead to potential data leakage in long-running applications due to object_id reuse. I've suggested a more robust approach using the hook object itself as the key. The new tests are well-written and cover the intended functionality.

# The same hash is returned across all hook stages (before, after, error, finally),
# allowing hooks to share state across their lifecycle (spec 4.1.5, 4.6.1).
def hook_data_for(hook)
@hook_data[hook.object_id] ||= {}

Choose a reason for hiding this comment

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

high

Using hook.object_id as a key in the hash can be problematic. While unlikely in short-lived processes, object_ids can be reused by the Ruby garbage collector for new objects after old ones are destroyed. This could lead to data leakage between different hook instances over the lifetime of a long-running application. A more robust approach is to use the hook object itself as the key. Ruby's Hash handles object keys correctly based on their identity, which is safer and more idiomatic.

          @hook_data[hook] ||= {}

@josecolella josecolella merged commit 28518a0 into main Mar 5, 2026
4 checks passed
@josecolella josecolella deleted the feat/hook-data-per-hook-state branch March 5, 2026 16:49
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.

1 participant